PR c++/83956 - wrong dtor error with anonymous union
authorJason Merrill <jason@redhat.com>
Fri, 26 Jan 2018 20:47:32 +0000 (15:47 -0500)
committerJason Merrill <jason@gcc.gnu.org>
Fri, 26 Jan 2018 20:47:32 +0000 (15:47 -0500)
* 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
gcc/cp/method.c
gcc/testsuite/g++.dg/cpp0x/anon-union2.C [new file with mode: 0644]

index 70b01346e0247a581e06e0f5070b404b511fe761..c526645e380d3e5d53813dd2174e7755dc41fd22 100644 (file)
@@ -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
index 5bc830cd820fbb199d7bc30e2b23dabd3f78730e..33029d7967e6e658df3e5319b23d020838f4c562 100644 (file)
@@ -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 (file)
index 0000000..38c91f4
--- /dev/null
@@ -0,0 +1,12 @@
+// PR c++/83956
+// { dg-do compile { target c++11 } }
+
+struct a {
+  ~a() = delete;
+};
+struct b {
+  ~b() {}
+  union {
+    a c;
+  };
+};