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.
This commit is contained in:
parent
3a36428b5f
commit
4e1592f8e1
@ -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
|
||||
|
55
gcc/cp/pt.c
55
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;
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user