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

Reply via email to