]> git.ipfire.org Git - thirdparty/vala.git/commitdiff
codegen: Don't initialize stack-allocated array with local-constant length a0bb129e5a2e8580eb272d9a68ba054e7b170dba
authorRico Tzschichholz <ricotz@ubuntu.com>
Mon, 17 Feb 2020 16:43:24 +0000 (17:43 +0100)
committerRico Tzschichholz <ricotz@ubuntu.com>
Mon, 17 Feb 2020 16:54:29 +0000 (17:54 +0100)
Fixes https://gitlab.gnome.org/GNOME/vala/issues/910

codegen/valaccodebasemodule.vala
tests/Makefile.am
tests/arrays/fixed-length-init0-not-allowed.vala [new file with mode: 0644]

index 52bc6d930a9d60670e28f72570b8a83f3a17144f..4336fb37f6f8284cfd745eea261c26a4b5d93446 100644 (file)
@@ -2547,8 +2547,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);
                        }
@@ -3802,7 +3804,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;
                        }
@@ -6350,6 +6352,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) {
index 8079e335a4eb0e5a6e9a97ae6b46400112774c89..f683d18c7ac8ba049bf72cf20fd9595137c501e8 100644 (file)
@@ -75,6 +75,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 (file)
index 0000000..932f011
--- /dev/null
@@ -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");
+}