Hi again,
On 03/26/2012 09:31 PM, Jason Merrill wrote:
On 03/26/2012 07:22 AM, Paolo Carlini wrote:
My basic idea so far is very simple:
--- class.c (revision 185792)
+++ class.c (working copy)
@@ -1001,6 +1001,10 @@ add_method (tree type, tree method, tree
using_dec
"destructor",
type);
}
+ else if (cxx_dialect >= cxx0x
+ && !TYPE_RAISES_EXCEPTIONS (TREE_TYPE (method)))
+ TREE_TYPE (method) = build_exception_variant (TREE_TYPE (method),
+ noexcept_true_spec);
}
That would implement N1366, but implementing N3204 is a bit more
involved. You need to copy TYPE_RAISES_EXCEPTIONS from the result of
implicitly_declare_fn; see defaulted_late_check for something similar.
Also, this is too early, since we can't know what the eh specification
of the implicit declaration would be until the closing brace of the
class.
I think I understand your explanation and the below appears already to
work pretty well. Is it on the right track? What about the
check_redeclaration_exception_specification bits?
Thanks in advance for any further feedback,
Paolo.
////////////////////////
Index: class.c
===================================================================
--- class.c (revision 185911)
+++ class.c (working copy)
@@ -4321,6 +4321,37 @@ clone_constructors_and_destructors (tree t)
clone_function_decl (OVL_CURRENT (fns), /*update_method_vec_p=*/1);
}
+/* For each destructor in T, deduce noexcept per:
+
+ 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))
+ {
+ tree fn = OVL_CURRENT (fns);
+ if (!TYPE_RAISES_EXCEPTIONS (TREE_TYPE (fn)))
+ {
+ tree ctx = DECL_CONTEXT (fn);
+ tree implicit_fn = implicitly_declare_fn (sfk_destructor, ctx,
+ /*const_p=*/false);
+ tree eh_spec = TYPE_RAISES_EXCEPTIONS (TREE_TYPE (implicit_fn));
+
+ TREE_TYPE (fn) = build_exception_variant (TREE_TYPE (fn), eh_spec);
+ }
+ }
+}
+
/* 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. */
@@ -5129,6 +5160,10 @@ check_bases_and_members (tree t)
do anything with non-static member functions. */
finalize_literal_type_property (t);
+ /* Deduce noexcept. */
+ if (cxx_dialect >= cxx0x)
+ deduce_noexcept_on_destructors (t);
+
/* Create the in-charge and not-in-charge variants of constructors
and destructors. */
clone_constructors_and_destructors (t);
Index: decl.c
===================================================================
--- decl.c (revision 185911)
+++ decl.c (working copy)
@@ -1144,7 +1144,13 @@ check_redeclaration_exception_specification (tree
if ((pedantic || ! DECL_IN_SYSTEM_HEADER (old_decl))
&& ! DECL_IS_BUILTIN (old_decl)
&& flag_exceptions
- && !comp_except_specs (new_exceptions, old_exceptions, ce_normal))
+ && !comp_except_specs (new_exceptions, old_exceptions, ce_normal)
+ /* Special case in C++11: noexcept has been deduced as true for
+ the declaration and there is no exception-specification on the
+ definition. */
+ && !(DECL_DESTRUCTOR_P (new_decl)
+ && cxx_dialect >= cxx0x
+ && !new_exceptions && TYPE_NOEXCEPT_P (old_type)))
{
error ("declaration of %qF has a different exception specifier",
new_decl);
Index: method.c
===================================================================
--- method.c (revision 185911)
+++ method.c (working copy)
@@ -1444,7 +1444,7 @@ explain_implicit_non_constexpr (tree decl)
reference argument or a non-const reference. Returns the
FUNCTION_DECL for the implicitly declared function. */
-static tree
+tree
implicitly_declare_fn (special_function_kind kind, tree type, bool const_p)
{
tree fn;
Index: cp-tree.h
===================================================================
--- cp-tree.h (revision 185911)
+++ cp-tree.h (working copy)
@@ -5264,6 +5264,8 @@ extern tree get_copy_assign (tree);
extern tree get_default_ctor (tree);
extern tree get_dtor (tree, tsubst_flags_t);
extern tree locate_ctor (tree);
+extern tree implicitly_declare_fn (special_function_kind, tree,
+ bool);
/* In optimize.c */
extern bool maybe_clone_body (tree);