On 2/12/21 6:12 PM, Marek Polacek wrote:
We represent deduction guides with FUNCTION_DECLs, but they are built
without DECL_CONTEXT

Hmm, that seems wrong: "A deduction-guide shall be declared in the
same scope as the corresponding class template and, for a member class template, with the same access." But it probably isn't necessary to change this:

leading to an ICE in type_dependent_expression_p
on the assert that the type of a function template with no dependent
(innermost!) template arguments must be non-dependent.  Consider the
attached class-deduction79.C: we create a deduction guide:

   template<class T> G(T)-> E<Z>::G<T>

we deduce T and create a partial instantiation:

   G(T) -> E<Z>::G<T> [with T = int]

And then do_class_deduction wants to create a CALL_EXPR from the above
using build_new_function_call -> build_over_call which calls mark_used
-> maybe_instantiate_noexcept -> type_dependent_expression_p.

There, the innermost template arguments are non-dependent (<int>), but
the fntype is dependent -- the return type is a TYPENAME_TYPE, and
since we have no DECL_CONTEXT, this check holds:

   /* Otherwise, if the function decl isn't from a dependent scope, it can't be
      type-dependent.  Checking this is important for functions with auto return
      type, which looks like a dependent type.  */
   if (TREE_CODE (expression) == FUNCTION_DECL
       && !(DECL_CLASS_SCOPE_P (expression)
            && dependent_type_p (DECL_CONTEXT (expression)))

whereupon we ICE.

Experiments with setting DECL_CONTEXT didn't pan out.

In c8 of the PR it looks like you were using the class itself as DECL_CONTEXT; the quote above says that the right context is the enclosing scope of the class.

So perhaps we
just want to skip the assert for deduction guides, because they are
a little special.  Better ideas solicited.

In c3 you mention that one of the variants broke with r269093; this is because my change to check CLASSTYPE_TEMPLATE_INSTANTIATION is false for the template pattern itself (E<Z>).

But I think probably the right answer is to defer this deduction until the enclosing scope is non-dependent, i.e. (untested)

>From a0c19e712b8d8e6048d7371b237dc38cad2b9119 Mon Sep 17 00:00:00 2001
From: Jason Merrill <ja...@redhat.com>
Date: Thu, 25 Feb 2021 10:55:28 -0500
Subject: [PATCH] dep
To: gcc-patches@gcc.gnu.org

---
 gcc/cp/pt.c | 4 ++++
 1 file changed, 4 insertions(+)

diff --git a/gcc/cp/pt.c b/gcc/cp/pt.c
index 3576e0effb6..0e383d2434e 100644
--- a/gcc/cp/pt.c
+++ b/gcc/cp/pt.c
@@ -29214,6 +29214,10 @@ do_class_deduction (tree ptype, tree tmpl, tree init,
   if (DECL_TEMPLATE_TEMPLATE_PARM_P (tmpl))
     return ptype;
 
+  if (DECL_CLASS_SCOPE_P (tmpl)
+      && dependent_type_p (DECL_CONTEXT (tmpl)))
+    return ptype;
+
   /* Initializing one placeholder from another.  */
   if (init && TREE_CODE (init) == TEMPLATE_PARM_INDEX
       && is_auto (TREE_TYPE (init))
-- 
2.27.0

Reply via email to