[vala/staging] codegen: Improve array-dup-wrapper for empty arrays



commit 48679761c7298f14bdab9c6ea3bd4c48db192cf5
Author: Rico Tzschichholz <ricotz ubuntu com>
Date:   Sun May 24 19:25:41 2020 +0200

    codegen: Improve array-dup-wrapper for empty arrays
    
    Guard against negative lengths and consistently return NULL if allocated
    size would be 0.
    
    See https://gitlab.gnome.org/GNOME/vala/issues/999

 codegen/valaccodearraymodule.vala | 18 ++++++++++++++
 tests/Makefile.am                 |  2 ++
 tests/arrays/empty-length-0.vala  | 52 +++++++++++++++++++++++++++++++++++++++
 3 files changed, 72 insertions(+)
---
diff --git a/codegen/valaccodearraymodule.vala b/codegen/valaccodearraymodule.vala
index 5fa9ea23d..0192f2cc9 100644
--- a/codegen/valaccodearraymodule.vala
+++ b/codegen/valaccodearraymodule.vala
@@ -541,9 +541,13 @@ public class Vala.CCodeArrayModule : CCodeMethodCallModule {
                        }
 
                        CCodeExpression length_expr = new CCodeIdentifier ("length");
+                       CCodeBinaryOperator length_check_op;
                        // add extra item to have array NULL-terminated for all reference types
                        if (array_type.element_type.type_symbol != null && 
array_type.element_type.type_symbol.is_reference_type ()) {
                                length_expr = new CCodeBinaryExpression (CCodeBinaryOperator.PLUS, 
length_expr, new CCodeConstant ("1"));
+                               length_check_op = CCodeBinaryOperator.GREATER_THAN_OR_EQUAL;
+                       } else {
+                               length_check_op = CCodeBinaryOperator.GREATER_THAN;
                        }
                        gnew.add_argument (length_expr);
 
@@ -553,6 +557,10 @@ public class Vala.CCodeArrayModule : CCodeMethodCallModule {
                                gnew.add_argument (csizeof);
                        }
 
+                       // only attempt to dup if length >=/> 0, this deals with negative lengths and returns 
NULL
+                       var length_check = new CCodeBinaryExpression (length_check_op, new CCodeIdentifier 
("length"), new CCodeConstant ("0"));
+                       ccode.open_if (length_check);
+
                        ccode.add_declaration (get_ccode_name (array_type), cvardecl);
                        ccode.add_assignment (new CCodeIdentifier ("result"), gnew);
 
@@ -566,7 +574,14 @@ public class Vala.CCodeArrayModule : CCodeMethodCallModule {
                        ccode.close ();
 
                        ccode.add_return (new CCodeIdentifier ("result"));
+
+                       ccode.close ();
+                       ccode.add_return (new CCodeIdentifier ("NULL"));
                } else {
+                       // only dup if length > 0, this deals with negative lengths and returns NULL
+                       var length_check = new CCodeBinaryExpression (CCodeBinaryOperator.GREATER_THAN, new 
CCodeIdentifier ("length"), new CCodeConstant ("0"));
+                       ccode.open_if (length_check);
+
                        var sizeof_call = new CCodeFunctionCall (new CCodeIdentifier ("sizeof"));
                        sizeof_call.add_argument (new CCodeIdentifier (get_ccode_name 
(array_type.element_type)));
                        var length_expr = new CCodeIdentifier ("length");
@@ -597,6 +612,9 @@ public class Vala.CCodeArrayModule : CCodeMethodCallModule {
 
                                ccode.add_return (dup_call);
                        }
+
+                       ccode.close ();
+                       ccode.add_return (new CCodeIdentifier ("NULL"));
                }
 
                // append to file
diff --git a/tests/Makefile.am b/tests/Makefile.am
index 78c939a2f..263e8975e 100644
--- a/tests/Makefile.am
+++ b/tests/Makefile.am
@@ -79,6 +79,7 @@ TESTS = \
        arrays/cast-silent-invalid.test \
        arrays/class-field-length-cname.vala \
        arrays/constant-element-access.vala \
+       arrays/empty-length-0.vala \
        arrays/expression-bracket.test \
        arrays/fixed-length-init0-not-allowed.vala \
        arrays/field-global-length-cname.vala \
@@ -949,6 +950,7 @@ LINUX_TESTS = \
 
 POSIX_TESTS = \
        basic-types/arrays.vala \
+       arrays/empty-length-0.vala \
        structs/struct_only.vala \
        delegates/delegate_only.vala \
        enums/enum_only.vala \
diff --git a/tests/arrays/empty-length-0.vala b/tests/arrays/empty-length-0.vala
new file mode 100644
index 000000000..8d64f304a
--- /dev/null
+++ b/tests/arrays/empty-length-0.vala
@@ -0,0 +1,52 @@
+struct Manam {
+       string s;
+}
+
+string[] foo;
+int[] bar;
+Manam[] manam;
+
+string[] get_foo () {
+       return foo;
+}
+
+int[] get_bar () {
+       return bar;
+}
+
+Manam[] get_manam () {
+       return manam;
+}
+
+void main () {
+       {
+               foo = new string[0];
+               assert (foo != null);
+               assert (get_foo () != null);
+       }
+       {
+               foo = {};
+               assert (foo != null);
+               assert (get_foo () != null);
+       }
+       {
+               bar = new int[0];
+               //assert (bar != null);
+               assert (get_bar () == null);
+       }
+       {
+               bar = {};
+               //assert (bar != null);
+               assert (get_bar () == null);
+       }
+       {
+               manam = new Manam[0];
+               //assert (manam != null);
+               assert (get_manam () == null);
+       }
+       {
+               manam = {};
+               //assert (manam != null);
+               assert (get_manam () == null);
+       }
+}


[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]