From 6a9263f7ef63cbaa9c0a4aa98d53372721602090 Mon Sep 17 00:00:00 2001 From: Jason Merrill Date: Tue, 9 Jun 2015 10:13:22 -0400 Subject: [PATCH] re PR c++/66383 (ICE in gimplify_expr on this passed in inline initialization) PR c++/66383 * tree.c (replace_placeholders_r): Handle placeholders for an outer object. * typeck2.c (store_init_value): Only replace_placeholders for objects of class type. From-SVN: r224282 --- gcc/cp/ChangeLog | 8 +++++ gcc/cp/tree.c | 18 +++++----- gcc/cp/typeck2.c | 2 +- gcc/testsuite/g++.dg/cpp1y/nsdmi-aggr3.C | 43 ++++++++++++++++++++++++ 4 files changed, 61 insertions(+), 10 deletions(-) create mode 100644 gcc/testsuite/g++.dg/cpp1y/nsdmi-aggr3.C diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog index 5160324db43..b71893c2fc6 100644 --- a/gcc/cp/ChangeLog +++ b/gcc/cp/ChangeLog @@ -1,3 +1,11 @@ +2015-06-09 Jason Merrill + + PR c++/66383 + * tree.c (replace_placeholders_r): Handle placeholders for an + outer object. + * typeck2.c (store_init_value): Only replace_placeholders for + objects of class type. + 2015-06-08 Andrew MacLeod * call.c : Adjust include files. diff --git a/gcc/cp/tree.c b/gcc/cp/tree.c index 3c4b5276eb3..3553d7c2c9d 100644 --- a/gcc/cp/tree.c +++ b/gcc/cp/tree.c @@ -2552,15 +2552,15 @@ replace_placeholders_r (tree* t, int* walk_subtrees, void* data_) switch (TREE_CODE (*t)) { case PLACEHOLDER_EXPR: - gcc_assert (same_type_ignoring_top_level_qualifiers_p - (TREE_TYPE (*t), TREE_TYPE (obj))); - *t = obj; - *walk_subtrees = false; - break; - - case TARGET_EXPR: - /* Don't mess with placeholders in an unrelated object. */ - *walk_subtrees = false; + { + tree x = obj; + for (; !(same_type_ignoring_top_level_qualifiers_p + (TREE_TYPE (*t), TREE_TYPE (x))); + x = TREE_OPERAND (x, 0)) + gcc_assert (TREE_CODE (x) == COMPONENT_REF); + *t = x; + *walk_subtrees = false; + } break; case CONSTRUCTOR: diff --git a/gcc/cp/typeck2.c b/gcc/cp/typeck2.c index affa2657f45..22a55801601 100644 --- a/gcc/cp/typeck2.c +++ b/gcc/cp/typeck2.c @@ -836,7 +836,7 @@ store_init_value (tree decl, tree init, vec** cleanups, int flags) TREE_CONSTANT (decl) = const_init && decl_maybe_constant_var_p (decl); } - if (cxx_dialect >= cxx14) + if (cxx_dialect >= cxx14 && CLASS_TYPE_P (strip_array_types (type))) /* Handle aggregate NSDMI in non-constant initializers, too. */ value = replace_placeholders (value, decl); diff --git a/gcc/testsuite/g++.dg/cpp1y/nsdmi-aggr3.C b/gcc/testsuite/g++.dg/cpp1y/nsdmi-aggr3.C new file mode 100644 index 00000000000..185ea10d1ba --- /dev/null +++ b/gcc/testsuite/g++.dg/cpp1y/nsdmi-aggr3.C @@ -0,0 +1,43 @@ +// PR c++/66383 +// { dg-do compile { target c++11 } } + +namespace N1 { + struct B; + + struct A + { + B* b; + A(B* b); + }; + + struct B + { + A a{ this }; + }; + + A::A(B* b): b{ b } {} + + void foo() + { + auto b = B{}; + } +} + +namespace N2 { + struct B; + + struct A + { + B* b; + }; + + struct B + { + A a{ this }; + }; + + void foo() + { + auto b = B{}; + } +} -- 2.30.2