On Thu, Feb 25, 2021 at 10:59:49AM -0500, Jason Merrill wrote: > 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.
Sadly, using CP_TYPE_CONTEXT (type) would result in a crash in retrieve_specialization: /* There should be as many levels of arguments as there are levels of parameters. */ gcc_assert (TMPL_ARGS_DEPTH (args) == (TREE_CODE (tmpl) == TEMPLATE_DECL ? TMPL_PARMS_DEPTH (DECL_TEMPLATE_PARMS (tmpl)) : template_class_depth (DECL_CONTEXT (tmpl)))); > > 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>). And the original test started with my r11-1713 because using TREE_TYPE directly instead of decltype (which is a non-deduced context) means we can deduced from the argument. > But I think probably the right answer is to defer this deduction until the > enclosing scope is non-dependent, i.e. (untested) Thanks. That mostly works, except the new class-deduction-aggr[89].C tests. Consider 8: namespace N { template <typename, typename> struct S { template <typename T, typename U> S(T, U); }; } // namespace N template <int> struct E { template <typename T> struct G { T t; }; void fn() { G{N::S<char, int>{'a', 1}}; } }; void g () { E<1> e; e.fn (); } With your patch, when in do_class_deduction when processing_template_decl, we just return. When we call do_class_deduction again when p_t_d is 0, maybe_aggr_guide returns early here: if (!CP_AGGREGATE_TYPE_P (type)) return NULL_TREE because G is not complete (and rightly so, we didn't instantiate it). So we aren't able to deduce the template parameters. I'm not sure if I should pursue this direction further. :( Marek