aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJason Merrill <jason@redhat.com>2020-05-14 11:15:27 -0400
committerJason Merrill <jason@redhat.com>2020-05-14 16:38:30 -0400
commit4e1592f8e1d6366699e05c0824fc3dc39ca7314b (patch)
treefcfc2b956b48825684aa6b62923e73e523e21026
parent3a36428b5fbc825e2d3455f5770b5d6e71c63413 (diff)
downloadgcc-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/ChangeLog5
-rw-r--r--gcc/cp/pt.c55
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;
}