[pushed] c++: Fix deferred noexcept on constructor [PR93901].
Jason Merrill
jason@redhat.com
Thu May 14 20:39:01 GMT 2020
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.
Tested x86_64-pc-linux-gnu, applying to trunk.
gcc/cp/ChangeLog
2020-05-14 Jason Merrill <jason@redhat.com>
PR c++/93901
* pt.c (maybe_instantiate_noexcept): Change clone handling.
---
gcc/cp/pt.c | 55 ++++++++++++++++++++++++++---------------------------
1 file changed, 27 insertions(+), 28 deletions(-)
diff --git a/gcc/cp/pt.c b/gcc/cp/pt.c
index 61e6fa7484d..2a0b18f5517 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;
}
base-commit: 3a36428b5fbc825e2d3455f5770b5d6e71c63413
--
2.18.1
More information about the Gcc-patches
mailing list