[vala/0.40] codegen: Use specified indices to access multidimensional array constants



commit 419be8fd594b8357cf7f4481354639d463f4939e
Author: Rico Tzschichholz <ricotz ubuntu com>
Date:   Mon Apr 13 15:29:56 2020 +0200

    codegen: Use specified indices to access multidimensional array constants
    
    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         | 21 ++++++++++++++++----
 codegen/valaccodearraymodule.vala         |  8 ++++++++
 codegen/valaccodebasemodule.vala          |  2 +-
 tests/Makefile.am                         |  1 +
 tests/arrays/constant-element-access.vala | 33 +++++++++++++++++++++++++++++++
 5 files changed, 60 insertions(+), 5 deletions(-)
---
diff --git a/ccode/valaccodeelementaccess.vala b/ccode/valaccodeelementaccess.vala
index dc62485ba..c93d55a2a 100644
--- a/ccode/valaccodeelementaccess.vala
+++ b/ccode/valaccodeelementaccess.vala
@@ -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 ("]");
        }
 }
diff --git a/codegen/valaccodearraymodule.vala b/codegen/valaccodearraymodule.vala
index fccbf3746..ee614340f 100644
--- a/codegen/valaccodearraymodule.vala
+++ b/codegen/valaccodearraymodule.vala
@@ -162,6 +162,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++) {
diff --git a/codegen/valaccodebasemodule.vala b/codegen/valaccodebasemodule.vala
index f9b07c9f1..f6d0d88e9 100644
--- a/codegen/valaccodebasemodule.vala
+++ b/codegen/valaccodebasemodule.vala
@@ -1473,7 +1473,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);
diff --git a/tests/Makefile.am b/tests/Makefile.am
index 7f52a72bb..045ed0187 100644
--- a/tests/Makefile.am
+++ b/tests/Makefile.am
@@ -65,6 +65,7 @@ TESTS = \
        basic-types/bug788775.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
index 000000000..6d366d80b
--- /dev/null
+++ b/tests/arrays/constant-element-access.vala
@@ -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));
+}


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