commit 26b958fac8f8c42ab0158583c6a362caf4a9ab73 Author: Jason Merrill Date: Fri Jun 5 17:07:23 2015 -0400 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. diff --git a/gcc/cp/tree.c b/gcc/cp/tree.c index 3c4b527..3553d7c 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 affa265..22a5580 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 0000000..185ea10 --- /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{}; + } +}