https://gcc.gnu.org/bugzilla/show_bug.cgi?id=94645

--- Comment #9 from Patrick Palka <ppalka at gcc dot gnu.org> ---
Thanks for the reduced testcases.


The problem in #c8 seems to start in grokfndecl() when processing the
operator() of the lambda.  During grokfndecl on the operator(),
processing_template_decl is 1 but template_class_depth is 0 (seems it should be
1 here?).  So the condition for 'memtmpl' in

      tree ctx = friendp ? current_class_type : ctype;
      bool memtmpl = (processing_template_decl > template_class_depth (ctx));

is true for this non-templated lambda, but IIUC 'memtmpl' should be true only
if the declaration in question has its own set of template parameters, which is
not the case here.

Since memtmpl is true, we then attach the innermost constraints (belonging to
struct l) to this non-templated operator() via:

      if (memtmpl)
        tmpl_reqs = TEMPLATE_PARMS_CONSTRAINTS (current_template_parms);
      tree ci = build_constraints (tmpl_reqs, decl_reqs);
      ...
      set_constraints (decl, ci);

and thing goes downhill from there.


I tried fixing template_class_depth to return 1 in this case via

--- a/gcc/cp/pt.c
+++ b/gcc/cp/pt.c
@@ -390,7 +390,12 @@ template_class_depth (tree type)
        ++depth;

       if (DECL_P (type))
-       type = CP_DECL_CONTEXT (type);
+       {
+         if (tree fctx = DECL_FRIEND_CONTEXT (type))
+           type = fctx;
+         else
+           type = CP_DECL_CONTEXT (type);
+       }
       else if (LAMBDA_TYPE_P (type) && LAMBDA_TYPE_EXTRA_SCOPE (type))
        type = LAMBDA_TYPE_EXTRA_SCOPE (type);
       else

but this change causes a bunch of ICEs in the cmcstl2 testsuite.

It seems that the condition for 'memtmpl' needs adjusting, but I'm not sure
how.

Reply via email to