Core 1135
authorJason Merrill <jason@redhat.com>
Fri, 25 Mar 2011 16:17:08 +0000 (12:17 -0400)
committerJason Merrill <jason@gcc.gnu.org>
Fri, 25 Mar 2011 16:17:08 +0000 (12:17 -0400)
Core 1135
* method.c (defaulted_late_check): Check for exception spec mismatch.
(defaultable_fn_check): Allow exception spec and virtual.
* class.c (check_for_override): A virtual dtor is non-trivial.

From-SVN: r171462

gcc/cp/ChangeLog
gcc/cp/class.c
gcc/cp/method.c
gcc/testsuite/ChangeLog
gcc/testsuite/g++.dg/cpp0x/defaulted15.C
gcc/testsuite/g++.dg/cpp0x/defaulted22.C [new file with mode: 0644]
gcc/testsuite/g++.dg/cpp0x/defaulted23.C [new file with mode: 0644]

index b9fb0cdffac5f1deefebcd32f8bb2273eff00f8e..7a99acd883f99e9f8c9e3720b8fb48a086694df1 100644 (file)
@@ -1,5 +1,10 @@
 2011-03-25  Jason Merrill  <jason@redhat.com>
 
+       Core 1135
+       * method.c (defaulted_late_check): Check for exception spec mismatch.
+       (defaultable_fn_check): Allow exception spec and virtual.
+       * class.c (check_for_override): A virtual dtor is non-trivial.
+
        PR c++/48289
        * pt.c (build_non_dependent_expr): Keep dereferences outside the
        NON_DEPENDENT_EXPR.
index 1325260f51e2a0a34b316154fa1c381cd66da68d..adae51f1989ccf0a6630be1f0fea8c83bc734ae1 100644 (file)
@@ -2474,6 +2474,8 @@ check_for_override (tree decl, tree ctype)
       if (!DECL_VINDEX (decl))
        DECL_VINDEX (decl) = error_mark_node;
       IDENTIFIER_VIRTUAL_P (DECL_NAME (decl)) = 1;
+      if (DECL_DESTRUCTOR_P (decl))
+       TYPE_HAS_NONTRIVIAL_DESTRUCTOR (ctype) = true;
     }
 }
 
index 0366988d155438547ee9533274a898ccf1a85196..386a818ed1ba79346ced4062809e7949d4231f1c 100644 (file)
@@ -1554,6 +1554,12 @@ defaulted_late_check (tree fn)
   if (DECL_DEFAULTED_IN_CLASS_P (fn))
     {
       tree eh_spec = TYPE_RAISES_EXCEPTIONS (TREE_TYPE (implicit_fn));
+      if (TYPE_RAISES_EXCEPTIONS (TREE_TYPE (fn))
+         && !comp_except_specs (TYPE_RAISES_EXCEPTIONS (TREE_TYPE (fn)),
+                                eh_spec, ce_normal))
+       error ("function %q+D defaulted on its first declaration "
+              "with an exception-specification that differs from "
+              "the implicit declaration %q#D", fn, implicit_fn);
       TREE_TYPE (fn) = build_exception_variant (TREE_TYPE (fn), eh_spec);
       if (DECL_DECLARED_CONSTEXPR_P (implicit_fn))
        /* Hmm...should we do this for out-of-class too? Should it be OK to
@@ -1619,14 +1625,7 @@ defaultable_fn_check (tree fn)
            break;
          }
       if (TYPE_BEING_DEFINED (DECL_CONTEXT (fn)))
-       {
-         if (TYPE_RAISES_EXCEPTIONS (TREE_TYPE (fn)))
-           error ("function %q+D defaulted on its first declaration "
-                  "must not have an exception-specification", fn);
-         if (DECL_VIRTUAL_P (fn))
-           error ("%qD declared virtual cannot be defaulted in the class "
-                  "body", fn);
-       }
+       /* Defer checking.  */;
       else if (!processing_template_decl)
        defaulted_late_check (fn);
 
index 57a7102d9f9c5a8c8966d109abb894b99f8f59d7..e2aab84bf6b4a1a7a0c84c1ac68539a4f46ae443 100644 (file)
@@ -1,3 +1,9 @@
+2011-03-25  Jason Merrill  <jason@redhat.com>
+
+       * g++.dg/cpp0x/defaulted22.C: New.
+       * g++.dg/cpp0x/defaulted23.C: New.
+       * g++.dg/cpp0x/defaulted15.C: Adjust.
+
 2011-03-25  Jason Merrill  <jason@redhat.com>
 
        * g++.dg/cpp0x/move1.C: New.
index 4c5b11c9e19a4d033cfb751f71218ec5c764c644..0a47c20f7786f4f543202521ff6034aa3eb78ece 100644 (file)
@@ -54,5 +54,5 @@ struct G: public F
 
 struct H
 {
-  virtual ~H() = default;      // { dg-error "declared virtual" }
+  virtual ~H() = default;
 };
diff --git a/gcc/testsuite/g++.dg/cpp0x/defaulted22.C b/gcc/testsuite/g++.dg/cpp0x/defaulted22.C
new file mode 100644 (file)
index 0000000..61e9d32
--- /dev/null
@@ -0,0 +1,23 @@
+// Test that a virtual defaulted constructor is still virtual.
+// { dg-do run }
+// { dg-options -std=c++0x }
+
+int r = 1;
+
+struct A
+{
+  virtual ~A() = default;
+};
+
+struct B: A
+{
+  ~B() noexcept { r = 0; }
+};
+
+A* ap = new B();
+
+int main()
+{
+  delete ap;
+  return r;
+}
diff --git a/gcc/testsuite/g++.dg/cpp0x/defaulted23.C b/gcc/testsuite/g++.dg/cpp0x/defaulted23.C
new file mode 100644 (file)
index 0000000..5b4438d
--- /dev/null
@@ -0,0 +1,27 @@
+// Test for checking of exception specifications on defaulted fns
+// { dg-options -std=c++0x }
+
+struct A
+{
+  A() noexcept = default;
+};
+
+struct B
+{
+  B() throw (int) = default; // { dg-error "exception-specification that differs from the implicit declaration" }
+};
+
+struct C
+{
+  C() throw (int) { }
+};
+
+struct D: C
+{
+  D() throw (int) = default;
+};
+
+struct E
+{
+  E() = default;
+};