Hi!

On the following testcase, replace_placeholders is called on a CONSTRUCTOR
{ a, [1..63] = NON_LVALUE_EXPR<42> }
and call build_ctor_subob_ref in that case.  The problem is that index is
RANGE_EXPR and as it is not INTEGER_CST, we call
build_class_member_access_expr which is not appropriate for array indexes.
cp_build_array_ref will not really work with RANGE_EXPR either, the
following patch just usesthe low bound of the range.  At least when trying
to read it, it should be equivalent to any other value in the range.

Bootstrapped/regtested on x86_64-linux and i686-linux, ok for trunk?

2019-11-22  Jakub Jelinek  <ja...@redhat.com>

        PR c++/92524
        * tree.c (build_ctor_subob_ref): For RANGE_EXPR index, build
        array reference for the low bound.

        * g++.dg/cpp0x/pr92524.C: New test.

--- gcc/cp/tree.c.jj    2019-11-16 18:13:28.571821577 +0100
+++ gcc/cp/tree.c       2019-11-21 12:22:27.260660874 +0100
@@ -3064,6 +3064,10 @@ build_ctor_subob_ref (tree index, tree t
     obj = NULL_TREE;
   else if (TREE_CODE (index) == INTEGER_CST)
     obj = cp_build_array_ref (input_location, obj, index, tf_none);
+  else if (TREE_CODE (index) == RANGE_EXPR)
+    /* Use low bound for ranges.  */
+    obj = cp_build_array_ref (input_location, obj, TREE_OPERAND (index, 0),
+                             tf_none);
   else
     obj = build_class_member_access_expr (obj, index, NULL_TREE,
                                          /*reference*/false, tf_none);
--- gcc/testsuite/g++.dg/cpp0x/pr92524.C.jj     2019-11-21 12:34:53.350406680 
+0100
+++ gcc/testsuite/g++.dg/cpp0x/pr92524.C        2019-11-21 12:34:18.943925681 
+0100
@@ -0,0 +1,12 @@
+// PR c++/92524
+// { dg-do compile { target c++11 } }
+
+struct A { char a = '*'; };
+struct B { A b[64]; };
+
+void
+foo ()
+{
+  A a;
+  B{a};
+}

        Jakub

Reply via email to