On Nov 27, 2018, Jason Merrill <ja...@redhat.com> 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