Re: [C++ PATCH] Fix ICE in build_ctor_subob_ref during replace_placeholders (PR c++/92524, take 2)
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)
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)
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)
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