From: Rico Tzschichholz Date: Mon, 13 Apr 2020 13:29:56 +0000 (+0200) Subject: codegen: Use specified indices to access multidimensional array constants X-Git-Tag: 0.49.1~178 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=241491d291e3545c431dfe6499dce8eb5bfa41c0;p=thirdparty%2Fvala.git 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 --- diff --git a/ccode/valaccodeelementaccess.vala b/ccode/valaccodeelementaccess.vala index 3586aec1f..a99af44b5 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 indices { get; set; } public CCodeElementAccess (CCodeExpression cont, CCodeExpression i) { container = cont; - index = i; + indices = new ArrayList (); + indices.add (i); + } + + public CCodeElementAccess.with_indices (CCodeExpression cont, List 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 f35ac5325..5fa9ea23d 100644 --- a/codegen/valaccodearraymodule.vala +++ b/codegen/valaccodearraymodule.vala @@ -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 (); + 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 559119341..ed167c56a 100644 --- a/codegen/valaccodebasemodule.vala +++ b/codegen/valaccodebasemodule.vala @@ -1502,7 +1502,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 8f942e8e3..712c5b83a 100644 --- a/tests/Makefile.am +++ b/tests/Makefile.am @@ -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 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)); +}