On Nov 27, 2018, Jason Merrill <[email protected]> wrote:
> On 11/22/18 6:40 PM, Alexandre Oliva wrote:
>> Mangling visits the base template function type, prior to template
>> resolution, and on such types, exception specifications may contain
>> unresolved noexcept expressions. nothrow_spec_p is called on them
>> even when exception specifications are not part of function types, and
>> it rejects unresolved noexcept expressions if processing_template_decl
>> is not set.
> The problem here is that the noexcept expression is unresolved even
> though it isn't dependent
Yeah, but that seems to be on purpose, according to these comments, that
precede the hunk below.
/* This isn't part of the signature, so don't bother trying to evaluate
it until instantiation. */
Taking out the 'flag_noexcept_type && ' subexpr fixes the problem, but
defeats the intended deferral of unnecessary computation:
diff --git a/gcc/cp/except.c b/gcc/cp/except.c
index 3449b59b3cc0..dbd233c94c3a 100644
--- a/gcc/cp/except.c
+++ b/gcc/cp/except.c
@@ -1193,7 +1193,7 @@ build_noexcept_spec (tree expr, tsubst_flags_t complain)
it until instantiation. */
if (TREE_CODE (expr) != DEFERRED_NOEXCEPT
&& (!processing_template_decl
- || (flag_noexcept_type && !value_dependent_expression_p (expr))))
+ || !value_dependent_expression_p (expr)))
{
expr = perform_implicit_conversion_flags (boolean_type_node, expr,
complain,
In order to retain that deferral, we could change the mangling logic to
also refrain from canonicalizing the EH spec when it's not part of the
type:
diff --git a/gcc/cp/mangle.c b/gcc/cp/mangle.c
index 64415894bc57..4c8086c9f9bd 100644
--- a/gcc/cp/mangle.c
+++ b/gcc/cp/mangle.c
@@ -418,9 +418,12 @@ canonicalize_for_substitution (tree node)
|| TREE_CODE (node) == METHOD_TYPE)
{
node = build_ref_qualified_type (node, type_memfn_rqual (orig));
- tree r = canonical_eh_spec (TYPE_RAISES_EXCEPTIONS (orig));
+ tree r = TYPE_RAISES_EXCEPTIONS (orig);
if (flag_noexcept_type)
- node = build_exception_variant (node, r);
+ {
+ r = canonical_eh_spec (r);
+ node = build_exception_variant (node, r);
+ }
else
/* Set the warning flag if appropriate. */
write_exception_spec (r);
This would bypass the nothrow_spec_p call in canonical_eh_spec at
C++1[14], but it might produce unintended -Wnoexcept-type warnings when
the noexcept expression would resolve to false. The canonical_eh_spec
call wouldn't have avoided it anyway.
Which one?
--
Alexandre Oliva, freedom fighter https://FSFLA.org/blogs/lxo
Be the change, be Free! FSF Latin America board member
GNU Toolchain Engineer Free Software Evangelist
Hay que enGNUrecerse, pero sin perder la terGNUra jamás-GNUChe