Re: [C++ PATCH] Fix ICE in build_ctor_subob_ref during replace_placeholders (PR c++/92524, take 2)

2019-11-26 Thread Jason Merrill

On 11/26/19 6:42 PM, Jakub Jelinek wrote:

On Tue, Nov 26, 2019 at 04:58:01PM -0500, Jason Merrill wrote:

Hmm, we shouldn't have any PLACEHOLDER_EXPR under a RANGE_EXPR; if we did,
any references to its address would end up all referring to the first
element of the range, which would be wrong.  How about skipping RANGE_EXPR
in replace_placeholders_r?


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


OK.


2019-11-27  Jakub Jelinek  

PR c++/92524
* tree.c (replace_placeholders_r): Don't walk constructor elts with
RANGE_EXPR indexes.

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

--- gcc/cp/tree.c.jj2019-11-26 23:09:55.904101392 +0100
+++ gcc/cp/tree.c   2019-11-26 23:13:14.308070759 +0100
@@ -3144,6 +3144,11 @@ replace_placeholders_r (tree* t, int* wa
tree type = TREE_TYPE (*valp);
tree subob = obj;
  
+	/* Elements with RANGE_EXPR index shouldn't have any

+  placeholders in them.  */
+   if (ce->index && TREE_CODE (ce->index) == RANGE_EXPR)
+ continue;
+
if (TREE_CODE (*valp) == CONSTRUCTOR
&& AGGREGATE_TYPE_P (type))
  {
--- gcc/testsuite/g++.dg/cpp0x/pr92524.C.jj 2019-11-26 23:09:46.810240310 
+0100
+++ gcc/testsuite/g++.dg/cpp0x/pr92524.C2019-11-26 23:09:46.810240310 
+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





[C++ PATCH] Fix ICE in build_ctor_subob_ref during replace_placeholders (PR c++/92524, take 2)

2019-11-26 Thread Jakub Jelinek
On Tue, Nov 26, 2019 at 04:58:01PM -0500, Jason Merrill wrote:
> Hmm, we shouldn't have any PLACEHOLDER_EXPR under a RANGE_EXPR; if we did,
> any references to its address would end up all referring to the first
> element of the range, which would be wrong.  How about skipping RANGE_EXPR
> in replace_placeholders_r?

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

2019-11-27  Jakub Jelinek  

PR c++/92524
* tree.c (replace_placeholders_r): Don't walk constructor elts with
RANGE_EXPR indexes.

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

--- gcc/cp/tree.c.jj2019-11-26 23:09:55.904101392 +0100
+++ gcc/cp/tree.c   2019-11-26 23:13:14.308070759 +0100
@@ -3144,6 +3144,11 @@ replace_placeholders_r (tree* t, int* wa
tree type = TREE_TYPE (*valp);
tree subob = obj;
 
+   /* Elements with RANGE_EXPR index shouldn't have any
+  placeholders in them.  */
+   if (ce->index && TREE_CODE (ce->index) == RANGE_EXPR)
+ continue;
+
if (TREE_CODE (*valp) == CONSTRUCTOR
&& AGGREGATE_TYPE_P (type))
  {
--- gcc/testsuite/g++.dg/cpp0x/pr92524.C.jj 2019-11-26 23:09:46.810240310 
+0100
+++ gcc/testsuite/g++.dg/cpp0x/pr92524.C2019-11-26 23:09:46.810240310 
+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



Re: [C++ PATCH] Fix ICE in build_ctor_subob_ref during replace_placeholders (PR c++/92524)

2019-11-26 Thread Jason Merrill

On 11/22/19 9:19 AM, Jakub Jelinek wrote:

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.


Hmm, we shouldn't have any PLACEHOLDER_EXPR under a RANGE_EXPR; if we 
did, any references to its address would end up all referring to the 
first element of the range, which would be wrong.  How about skipping 
RANGE_EXPR in replace_placeholders_r?



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



2019-11-22  Jakub Jelinek  

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.jj2019-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.C2019-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





[C++ PATCH] Fix ICE in build_ctor_subob_ref during replace_placeholders (PR c++/92524)

2019-11-22 Thread Jakub Jelinek
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  

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.jj2019-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.C2019-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