summaryrefslogtreecommitdiff
path: root/gcc/cp/class.c
diff options
context:
space:
mode:
Diffstat (limited to 'gcc/cp/class.c')
-rw-r--r--gcc/cp/class.c39
1 files changed, 39 insertions, 0 deletions
diff --git a/gcc/cp/class.c b/gcc/cp/class.c
index bc17c82c6a0..7b6559c4231 100644
--- a/gcc/cp/class.c
+++ b/gcc/cp/class.c
@@ -4321,6 +4321,41 @@ clone_constructors_and_destructors (tree t)
clone_function_decl (OVL_CURRENT (fns), /*update_method_vec_p=*/1);
}
+/* Deduce noexcept for a destructor DTOR. */
+
+void
+deduce_noexcept_on_destructor (tree dtor)
+{
+ if (!TYPE_RAISES_EXCEPTIONS (TREE_TYPE (dtor)))
+ {
+ tree ctx = DECL_CONTEXT (dtor);
+ tree implicit_fn = implicitly_declare_fn (sfk_destructor, ctx,
+ /*const_p=*/false);
+ tree eh_spec = TYPE_RAISES_EXCEPTIONS (TREE_TYPE (implicit_fn));
+ TREE_TYPE (dtor) = build_exception_variant (TREE_TYPE (dtor), eh_spec);
+ }
+}
+
+/* For each destructor in T, deduce noexcept:
+
+ 12.4/3: A declaration of a destructor that does not have an
+ exception-specification is implicitly considered to have the
+ same exception-specification as an implicit declaration (15.4). */
+
+static void
+deduce_noexcept_on_destructors (tree t)
+{
+ tree fns;
+
+ /* If for some reason we don't have a CLASSTYPE_METHOD_VEC, we bail
+ out now. */
+ if (!CLASSTYPE_METHOD_VEC (t))
+ return;
+
+ for (fns = CLASSTYPE_DESTRUCTORS (t); fns; fns = OVL_NEXT (fns))
+ deduce_noexcept_on_destructor (OVL_CURRENT (fns));
+}
+
/* Subroutine of set_one_vmethod_tm_attributes. Search base classes
of TYPE for virtual functions which FNDECL overrides. Return a
mask of the tm attributes found therein. */
@@ -4994,6 +5029,10 @@ check_bases_and_members (tree t)
cant_have_const_ctor = 0;
no_const_asn_ref = 0;
+ /* Deduce noexcept on destructors. */
+ if (cxx_dialect >= cxx0x)
+ deduce_noexcept_on_destructors (t);
+
/* Check all the base-classes. */
check_bases (t, &cant_have_const_ctor,
&no_const_asn_ref);