From 5bb1c2be88b8f99e050df8ec9052771b122b769f Mon Sep 17 00:00:00 2001 From: Jason Merrill Date: Fri, 26 Jan 2018 15:47:32 -0500 Subject: [PATCH] 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. From-SVN: r257107 --- gcc/cp/ChangeLog | 5 +++++ gcc/cp/method.c | 11 ++++++++++- gcc/testsuite/g++.dg/cpp0x/anon-union2.C | 12 ++++++++++++ 3 files changed, 27 insertions(+), 1 deletion(-) create mode 100644 gcc/testsuite/g++.dg/cpp0x/anon-union2.C diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog index 70b01346e02..c526645e380 100644 --- a/gcc/cp/ChangeLog +++ b/gcc/cp/ChangeLog @@ -1,5 +1,10 @@ 2018-01-26 Jason Merrill + 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. + PR c++/84036 - ICE with variadic capture. PR c++/82249 * pt.c (tsubst_pack_expansion): When optimizing a simple 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; + }; +}; -- 2.30.2