[vala/0.40] codegen: Don't initialize stack-allocated array with local-constant length



commit f26b462e7a3ec1b13b9cabc0405a6cd38f976e8a
Author: Rico Tzschichholz <ricotz ubuntu com>
Date:   Mon Feb 17 17:43:24 2020 +0100

    codegen: Don't initialize stack-allocated array with local-constant length
    
    Fixes https://gitlab.gnome.org/GNOME/vala/issues/910

 codegen/valaccodebasemodule.vala                 | 19 ++++++++++++++++---
 tests/Makefile.am                                |  1 +
 tests/arrays/fixed-length-init0-not-allowed.vala | 13 +++++++++++++
 3 files changed, 30 insertions(+), 3 deletions(-)
---
diff --git a/codegen/valaccodebasemodule.vala b/codegen/valaccodebasemodule.vala
index 16224a4dd..ebd1f179d 100644
--- a/codegen/valaccodebasemodule.vala
+++ b/codegen/valaccodebasemodule.vala
@@ -2471,8 +2471,10 @@ public abstract class Vala.CCodeBaseModule : CodeGenerator {
 
                                // try to initialize uninitialized variables
                                // initialization not necessary for variables stored in closure
-                               cvar.initializer = default_value_for_type (local.variable_type, true);
-                               cvar.init0 = true;
+                               if (is_init_allowed (local.variable_type)) {
+                                       cvar.initializer = default_value_for_type (local.variable_type, true);
+                                       cvar.init0 = true;
+                               }
 
                                ccode.add_declaration (get_ccode_name (local.variable_type), cvar);
                        }
@@ -3639,7 +3641,7 @@ public abstract class Vala.CCodeBaseModule : CodeGenerator {
                        }
                } else {
                        var cvar = new CCodeVariableDeclarator (local.name, null, get_ccode_declarator_suffix 
(local.variable_type));
-                       if (init) {
+                       if (init && is_init_allowed (local.variable_type)) {
                                cvar.initializer = default_value_for_type (local.variable_type, true, 
on_error);
                                cvar.init0 = true;
                        }
@@ -6284,6 +6286,17 @@ public abstract class Vala.CCodeBaseModule : CodeGenerator {
                return true;
        }
 
+       public bool is_init_allowed (DataType type) {
+               unowned ArrayType? array_type = type as ArrayType;
+               if (array_type != null && array_type.inline_allocated
+                  && array_type.fixed_length) {
+                  unowned Constant? c = array_type.length.symbol_reference as Constant;
+                  // our local constants are not actual constants in C
+                  return (c == null || !(c.parent_symbol is Block));
+               }
+               return true;
+       }
+
        public CCodeDeclaratorSuffix? get_ccode_declarator_suffix (DataType type) {
                var array_type = type as ArrayType;
                if (array_type != null) {
diff --git a/tests/Makefile.am b/tests/Makefile.am
index d312b0dc2..f3d97b2d3 100644
--- a/tests/Makefile.am
+++ b/tests/Makefile.am
@@ -65,6 +65,7 @@ TESTS = \
        arrays/cast-silent-invalid.test \
        arrays/class-field-length-cname.vala \
        arrays/expression-bracket.test \
+       arrays/fixed-length-init0-not-allowed.vala \
        arrays/field-global-length-cname.vala \
        arrays/fixed-length-concat-invalid.test \
        arrays/fixed-length-non-const.test \
diff --git a/tests/arrays/fixed-length-init0-not-allowed.vala 
b/tests/arrays/fixed-length-init0-not-allowed.vala
new file mode 100644
index 000000000..932f011b3
--- /dev/null
+++ b/tests/arrays/fixed-length-init0-not-allowed.vala
@@ -0,0 +1,13 @@
+void main () {
+       const int FOO = 4;
+
+       char bar[FOO] = { 'f', 'o', 'o', '\0' };
+       assert ((string) bar == "foo");
+
+       char baz[FOO];
+       baz[0] = 'f';
+       baz[1] = 'o';
+       baz[2] = 'o';
+       baz[3] = '\0';
+       assert ((string) baz == "foo");
+}


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