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

Reply via email to