diff options
author | Jason Merrill <jason@redhat.com> | 2019-10-23 16:41:26 -0400 |
---|---|---|
committer | Jason Merrill <jason@gcc.gnu.org> | 2019-10-23 16:41:26 -0400 |
commit | 0998d2fd59e7a5eb3a3566c57625702bbdc6a05f (patch) | |
tree | 18bcab37dfecdae810feb52e18f4461f970f4fbe /gcc/cp/method.c | |
parent | cbb28ef1534b13373bc38533c9e05035fe84894b (diff) | |
download | gcc-0998d2fd59e7a5eb3a3566c57625702bbdc6a05f.zip gcc-0998d2fd59e7a5eb3a3566c57625702bbdc6a05f.tar.gz gcc-0998d2fd59e7a5eb3a3566c57625702bbdc6a05f.tar.bz2 |
Implement P1286R2, Contra CWG1778
The C++11 requirement that an explicit exception-specification on a
defaulted function match the implicit one was found to be problematic for
std::atomic. This paper, adopted in February, simply removes that
requirement: if an explicitly defaulted function has a different
exception-specification, that now works just like a user-written function:
either it isn't noexcept when it could be, or it is noexcept and will call
terminate if an exception is thrown.
* method.c (defaulted_late_check): Don't check explicit
exception-specification on defaulted function.
(after_nsdmi_defaulted_late_checks): Remove.
* parser.h (struct cp_unparsed_functions_entry): Remove classes.
* parser.c (unparsed_classes): Remove.
(push_unparsed_function_queues, cp_parser_class_specifier_1):
Adjust.
From-SVN: r277351
Diffstat (limited to 'gcc/cp/method.c')
-rw-r--r-- | gcc/cp/method.c | 69 |
1 files changed, 6 insertions, 63 deletions
diff --git a/gcc/cp/method.c b/gcc/cp/method.c index 73a0114..b613e5d 100644 --- a/gcc/cp/method.c +++ b/gcc/cp/method.c @@ -2204,40 +2204,12 @@ defaulted_late_check (tree fn) return; } - /* 8.4.2/2: An explicitly-defaulted function (...) may have an explicit - exception-specification only if it is compatible (15.4) with the - exception-specification on the implicit declaration. If a function - is explicitly defaulted on its first declaration, (...) it is - implicitly considered to have the same exception-specification as if - it had been implicitly declared. */ - maybe_instantiate_noexcept (fn); - tree fn_spec = TYPE_RAISES_EXCEPTIONS (TREE_TYPE (fn)); - if (!fn_spec) - { - if (DECL_DEFAULTED_IN_CLASS_P (fn)) - TREE_TYPE (fn) = build_exception_variant (TREE_TYPE (fn), eh_spec); - } - else if (UNEVALUATED_NOEXCEPT_SPEC_P (fn_spec)) - /* Equivalent to the implicit spec. */; - else if (DECL_DEFAULTED_IN_CLASS_P (fn) - && !CLASSTYPE_TEMPLATE_INSTANTIATION (ctx)) - /* We can't compare an explicit exception-specification on a - constructor defaulted in the class body to the implicit - exception-specification until after we've parsed any NSDMI; see - after_nsdmi_defaulted_late_checks. */; - else - { - tree eh_spec = get_defaulted_eh_spec (fn); - if (!comp_except_specs (fn_spec, eh_spec, ce_normal)) - { - if (DECL_DEFAULTED_IN_CLASS_P (fn)) - DECL_DELETED_FN (fn) = true; - else - error ("function %q+D defaulted on its redeclaration " - "with an exception-specification that differs from " - "the implicit exception-specification %qX", fn, eh_spec); - } - } + /* If a function is explicitly defaulted on its first declaration without an + exception-specification, it is implicitly considered to have the same + exception-specification as if it had been implicitly declared. */ + if (!TYPE_RAISES_EXCEPTIONS (TREE_TYPE (fn)) + && DECL_DEFAULTED_IN_CLASS_P (fn)) + TREE_TYPE (fn) = build_exception_variant (TREE_TYPE (fn), eh_spec); if (DECL_DEFAULTED_IN_CLASS_P (fn) && DECL_DECLARED_CONSTEXPR_P (implicit_fn)) @@ -2264,35 +2236,6 @@ defaulted_late_check (tree fn) } } -/* OK, we've parsed the NSDMI for class T, now we can check any explicit - exception-specifications on functions defaulted in the class body. */ - -void -after_nsdmi_defaulted_late_checks (tree t) -{ - if (uses_template_parms (t)) - return; - if (t == error_mark_node) - return; - for (tree fn = TYPE_FIELDS (t); fn; fn = DECL_CHAIN (fn)) - if (!DECL_ARTIFICIAL (fn) - && DECL_DECLARES_FUNCTION_P (fn) - && DECL_DEFAULTED_IN_CLASS_P (fn)) - { - tree fn_spec = TYPE_RAISES_EXCEPTIONS (TREE_TYPE (fn)); - if (UNEVALUATED_NOEXCEPT_SPEC_P (fn_spec)) - continue; - - tree eh_spec = get_defaulted_eh_spec (fn); - if (eh_spec == error_mark_node) - continue; - - if (!comp_except_specs (TYPE_RAISES_EXCEPTIONS (TREE_TYPE (fn)), - eh_spec, ce_normal)) - DECL_DELETED_FN (fn) = true; - } -} - /* Returns true iff FN can be explicitly defaulted, and gives any errors if defaulting FN is ill-formed. */ |