]> git.ipfire.org Git - thirdparty/vala.git/commitdiff
codegen: Use specified indices to access multidimensional array constants
authorRico Tzschichholz <ricotz@ubuntu.com>
Mon, 13 Apr 2020 13:29:56 +0000 (15:29 +0200)
committerRico Tzschichholz <ricotz@ubuntu.com>
Mon, 20 Apr 2020 20:03:58 +0000 (22:03 +0200)
This fixes compile issues together with -Waggressive-loop-optimizations
and warnings with -Warray-bounds.

Fixes https://gitlab.gnome.org/GNOME/vala/issues/905

ccode/valaccodeelementaccess.vala
codegen/valaccodearraymodule.vala
codegen/valaccodebasemodule.vala
tests/Makefile.am
tests/arrays/constant-element-access.vala [new file with mode: 0644]

index 3586aec1f0120925c4198e36d4f07a5bc3c50ff7..a99af44b5c406837bbb77cbfdd3eb4388b363c60 100644 (file)
@@ -37,17 +37,30 @@ public class Vala.CCodeElementAccess : CCodeExpression {
         * Expression representing the index we want to access inside the
         * container.
         */
-       public CCodeExpression index { get; set; }
+       public List<CCodeExpression> indices { get; set; }
 
        public CCodeElementAccess (CCodeExpression cont, CCodeExpression i) {
                container = cont;
-               index = i;
+               indices = new ArrayList<CCodeExpression> ();
+               indices.add (i);
+       }
+
+       public CCodeElementAccess.with_indices (CCodeExpression cont, List<CCodeExpression> i) {
+               container = cont;
+               indices = i;
        }
 
        public override void write (CCodeWriter writer) {
                container.write_inner (writer);
                writer.write_string ("[");
-               index.write (writer);
+               bool first = true;
+               foreach (var index in indices) {
+                       if (!first) {
+                               writer.write_string ("][");
+                       }
+                       index.write (writer);
+                       first = false;
+               }
                writer.write_string ("]");
        }
 }
index ebef8879305be144f096083df1dee4e2623073af..afa30692ed715a5b935ef3b5f33ac5bd8a444acb 100644 (file)
@@ -174,6 +174,14 @@ public class Vala.CCodeArrayModule : CCodeMethodCallModule {
                        } else {
                                Report.error (expr.source_reference, "internal error: only integer literals supported as index");
                        }
+               } else if (expr.container.symbol_reference is Constant && rank > 1) {
+                       // access to element in a multi-dimensional array constant
+                       var cindices = new ArrayList<CCodeExpression> ();
+                       cindices.add (cindex);
+                       for (int i = 1; i < rank; i++) {
+                               cindices.add (get_cvalue (indices[i]));
+                       }
+                       set_cvalue (expr, new CCodeElementAccess.with_indices (ccontainer, cindices));
                } else {
                        // access to element in an array
                        for (int i = 1; i < rank; i++) {
index af7378a1dbc51d39cd6b2a6ace4c6341a93c2306..44e391a76034c0534ca55f0e2cd81f4c267fec39 100644 (file)
@@ -1482,7 +1482,7 @@ public abstract class Vala.CCodeBaseModule : CodeGenerator {
                        return is_pure_ccode_expression (cma.inner);
                } else if (cexpr is CCodeElementAccess) {
                        var cea = (CCodeElementAccess) cexpr;
-                       return is_pure_ccode_expression (cea.container) && is_pure_ccode_expression (cea.index);
+                       return is_pure_ccode_expression (cea.container) && is_pure_ccode_expression (cea.indices[0]);
                } else if (cexpr is CCodeCastExpression) {
                        var ccast = (CCodeCastExpression) cexpr;
                        return is_pure_ccode_expression (ccast.inner);
index 878d8cd46a1715336c28d97110f09b76b9ce622e..5e70ffcd4d38f7e1b899bea8bdf87c57f28a1352 100644 (file)
@@ -76,6 +76,7 @@ TESTS = \
        constants/glog.vala \
        arrays/cast-silent-invalid.test \
        arrays/class-field-length-cname.vala \
+       arrays/constant-element-access.vala \
        arrays/expression-bracket.test \
        arrays/fixed-length-init0-not-allowed.vala \
        arrays/field-global-length-cname.vala \
diff --git a/tests/arrays/constant-element-access.vala b/tests/arrays/constant-element-access.vala
new file mode 100644 (file)
index 0000000..6d366d8
--- /dev/null
@@ -0,0 +1,33 @@
+const string[,] FOO = {
+    { "00", "01", "02" },
+    { "10", "11", "12" },
+    { "20", "21", "22" }
+};
+
+void main () {
+       const string[,] BAR = {
+               { "00", "01", "02" },
+               { "10", "11", "12" },
+               { "20", "21", "22" }
+       };
+
+       for (int i = 0; i < FOO.length[0]; i++) {
+               assert (FOO[i,0] == "%d%d".printf (i, 0));
+               assert (FOO[i,1] == "%d%d".printf (i, 1));
+               assert (FOO[i,2] == "%d%d".printf (i, 2));
+       }
+
+       for (int i = 0; i < BAR.length[0]; i++) {
+               assert (BAR[i,0] == "%d%d".printf (i, 0));
+               assert (BAR[i,1] == "%d%d".printf (i, 1));
+               assert (BAR[i,2] == "%d%d".printf (i, 2));
+       }
+
+       assert (FOO[0,0] == "%d%d".printf (0, 0));
+       assert (FOO[1,1] == "%d%d".printf (1, 1));
+       assert (FOO[2,2] == "%d%d".printf (2, 2));
+
+       assert (BAR[0,0] == "%d%d".printf (0, 0));
+       assert (BAR[1,1] == "%d%d".printf (1, 1));
+       assert (BAR[2,2] == "%d%d".printf (2, 2));
+}