diff options
author | Jason Merrill <jason@redhat.com> | 2020-05-14 11:15:27 -0400 |
---|---|---|
committer | Jason Merrill <jason@redhat.com> | 2020-05-14 16:38:30 -0400 |
commit | 4e1592f8e1d6366699e05c0824fc3dc39ca7314b (patch) | |
tree | fcfc2b956b48825684aa6b62923e73e523e21026 | |
parent | 3a36428b5fbc825e2d3455f5770b5d6e71c63413 (diff) | |
download | gcc-4e1592f8e1d6366699e05c0824fc3dc39ca7314b.zip gcc-4e1592f8e1d6366699e05c0824fc3dc39ca7314b.tar.gz gcc-4e1592f8e1d6366699e05c0824fc3dc39ca7314b.tar.bz2 |
c++: Fix deferred noexcept on constructor [PR93901].
My change in r10-4394 to only update clones when we actually instantiate a
deferred noexcept-spec broke this because deferred parsing updates the
primary function but not the clones. For GCC 10 I just reverted that
change; this patch adjusts maybe_instantiate_noexcept to update only the
clone passed as the argument.
gcc/cp/ChangeLog
2020-05-14 Jason Merrill <jason@redhat.com>
PR c++/93901
* pt.c (maybe_instantiate_noexcept): Change clone handling.
-rw-r--r-- | gcc/cp/ChangeLog | 5 | ||||
-rw-r--r-- | gcc/cp/pt.c | 55 |
2 files changed, 32 insertions, 28 deletions
diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog index 4374954..0a32052 100644 --- a/gcc/cp/ChangeLog +++ b/gcc/cp/ChangeLog @@ -1,3 +1,8 @@ +2020-05-14 Jason Merrill <jason@redhat.com> + + PR c++/93901 + * pt.c (maybe_instantiate_noexcept): Change clone handling. + 2020-05-14 Patrick Palka <ppalka@redhat.com> PR c++/78446 diff --git a/gcc/cp/pt.c b/gcc/cp/pt.c index 61e6fa7..2a0b18f 100644 --- a/gcc/cp/pt.c +++ b/gcc/cp/pt.c @@ -25174,7 +25174,7 @@ always_instantiate_p (tree decl) bool maybe_instantiate_noexcept (tree fn, tsubst_flags_t complain) { - tree fntype, spec, noex, clone; + tree fntype, spec, noex; /* Don't instantiate a noexcept-specification from template context. */ if (processing_template_decl @@ -25193,8 +25193,16 @@ maybe_instantiate_noexcept (tree fn, tsubst_flags_t complain) return !DECL_MAYBE_DELETED (fn); } - if (DECL_CLONED_FUNCTION_P (fn)) - fn = DECL_CLONED_FUNCTION (fn); + fntype = TREE_TYPE (fn); + spec = TYPE_RAISES_EXCEPTIONS (fntype); + + if (!spec || !TREE_PURPOSE (spec)) + return true; + + noex = TREE_PURPOSE (spec); + if (TREE_CODE (noex) != DEFERRED_NOEXCEPT + && TREE_CODE (noex) != DEFERRED_PARSE) + return true; tree orig_fn = NULL_TREE; /* For a member friend template we can get a TEMPLATE_DECL. Let's use @@ -25206,15 +25214,14 @@ maybe_instantiate_noexcept (tree fn, tsubst_flags_t complain) fn = DECL_TEMPLATE_RESULT (fn); } - fntype = TREE_TYPE (fn); - spec = TYPE_RAISES_EXCEPTIONS (fntype); - - if (!spec || !TREE_PURPOSE (spec)) - return true; - - noex = TREE_PURPOSE (spec); - - if (TREE_CODE (noex) == DEFERRED_NOEXCEPT) + if (DECL_CLONED_FUNCTION_P (fn)) + { + tree prime = DECL_CLONED_FUNCTION (fn); + if (!maybe_instantiate_noexcept (prime, complain)) + return false; + spec = TYPE_RAISES_EXCEPTIONS (TREE_TYPE (prime)); + } + else if (TREE_CODE (noex) == DEFERRED_NOEXCEPT) { static hash_set<tree>* fns = new hash_set<tree>; bool added = false; @@ -25284,27 +25291,19 @@ maybe_instantiate_noexcept (tree fn, tsubst_flags_t complain) if (added) fns->remove (fn); - - if (spec == error_mark_node) - { - /* This failed with a hard error, so let's go with false. */ - gcc_assert (seen_error ()); - spec = noexcept_false_spec; - } - - TREE_TYPE (fn) = build_exception_variant (fntype, spec); - if (orig_fn) - TREE_TYPE (orig_fn) = TREE_TYPE (fn); } - FOR_EACH_CLONE (clone, fn) + if (spec == error_mark_node) { - if (TREE_TYPE (clone) == fntype) - TREE_TYPE (clone) = TREE_TYPE (fn); - else - TREE_TYPE (clone) = build_exception_variant (TREE_TYPE (clone), spec); + /* This failed with a hard error, so let's go with false. */ + gcc_assert (seen_error ()); + spec = noexcept_false_spec; } + TREE_TYPE (fn) = build_exception_variant (fntype, spec); + if (orig_fn) + TREE_TYPE (orig_fn) = TREE_TYPE (fn); + return true; } |