Here, when we walk the subobjects to determine the exception specification of a defaulted destructor in order to apply it to a user-provided destructor, we shouldn't look at variant members dtors, which aren't called.
We really shouldn't be looking at variant members here at all except to determine deletedness, but decided to go with a more limited change since we're in stage 4. Tested x86_64-pc-linux-gnu, applying to trunk.
commit df8979f62c2977bd18a2e085e90dbdd4c2f8f98e Author: Jason Merrill <ja...@redhat.com> Date: Fri Jan 26 11:38:19 2018 -0500 PR c++/83956 - wrong dtor error with anonymous union * method.c (walk_field_subobs): Variant members only affect deletedness. (maybe_explain_implicit_delete): Pass &deleted_p for diagnostic. diff --git a/gcc/cp/method.c b/gcc/cp/method.c index 5bc830cd820..33029d7967e 100644 --- a/gcc/cp/method.c +++ b/gcc/cp/method.c @@ -1305,6 +1305,15 @@ walk_field_subobs (tree fields, tree fnname, special_function_kind sfk, || DECL_ARTIFICIAL (field)) continue; + /* Variant members only affect deletedness. In particular, they don't + affect the exception-specification of a user-provided destructor, + which we're figuring out via get_defaulted_eh_spec. So if we aren't + asking if this is deleted, don't even look up the function; we don't + want an error about a deleted function we aren't actually calling. */ + if (sfk == sfk_destructor && deleted_p == NULL + && TREE_CODE (DECL_CONTEXT (field)) == UNION_TYPE) + break; + mem_type = strip_array_types (TREE_TYPE (field)); if (assign_p) { @@ -1850,7 +1859,7 @@ maybe_explain_implicit_delete (tree decl) "%q#D is implicitly deleted because the default " "definition would be ill-formed:", decl); synthesized_method_walk (ctype, sfk, const_p, - NULL, NULL, NULL, NULL, true, + NULL, NULL, &deleted_p, NULL, true, &inh, parms); } else if (!comp_except_specs diff --git a/gcc/testsuite/g++.dg/cpp0x/anon-union2.C b/gcc/testsuite/g++.dg/cpp0x/anon-union2.C new file mode 100644 index 00000000000..38c91f41a5c --- /dev/null +++ b/gcc/testsuite/g++.dg/cpp0x/anon-union2.C @@ -0,0 +1,12 @@ +// PR c++/83956 +// { dg-do compile { target c++11 } } + +struct a { + ~a() = delete; +}; +struct b { + ~b() {} + union { + a c; + }; +};