aboutsummaryrefslogtreecommitdiff
path: root/gcc
diff options
context:
space:
mode:
authorJason Merrill <jason@redhat.com>2018-01-26 15:47:32 -0500
committerJason Merrill <jason@gcc.gnu.org>2018-01-26 15:47:32 -0500
commit5bb1c2be88b8f99e050df8ec9052771b122b769f (patch)
tree35108788c8a893b1a10902ad6cddbc1c02e047c8 /gcc
parentf8862a1b2afad9d107ad505de2bf554705ebdb38 (diff)
downloadgcc-5bb1c2be88b8f99e050df8ec9052771b122b769f.zip
gcc-5bb1c2be88b8f99e050df8ec9052771b122b769f.tar.gz
gcc-5bb1c2be88b8f99e050df8ec9052771b122b769f.tar.bz2
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
Diffstat (limited to 'gcc')
-rw-r--r--gcc/cp/ChangeLog5
-rw-r--r--gcc/cp/method.c11
-rw-r--r--gcc/testsuite/g++.dg/cpp0x/anon-union2.C12
3 files changed, 27 insertions, 1 deletions
diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog
index 70b0134..c526645 100644
--- a/gcc/cp/ChangeLog
+++ b/gcc/cp/ChangeLog
@@ -1,5 +1,10 @@
2018-01-26 Jason Merrill <jason@redhat.com>
+ 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 5bc830c..33029d7 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 0000000..38c91f4
--- /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;
+ };
+};