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

--- Comment #12 from Adam Butcher <abutcher at gcc dot gnu.org> ---
If the containing context is made a template (as per pr64382 and pr64466) or if
the patch below is made to lambda.c, the synthesized default 'this' looks to
get captured OK, but gimplification process crashes.

The start looks promising.  From gimplify_return_expr:

  return D.2190 = X::f (__closure->__this, x) 

through gimplify_call_expr:

  X::f (__closure->__this, x)

but the gimplification of the subject argument

  __closure->__this

crashes due to component_ref_field_offset returning NULL for it.

I'm thinking the 'this' reference built with build_x_indirect_ref in
maybe_resolve_dummy may need some extra bolstering in the generic lambda case.

Another point maybe worthy of note: If a non-static, non-function member is
referenced within the generic lambda, it causes 'this' to be default captured
correctly (as it does when explicitly specifying "this->") and the compilation
completes as expected.


-------------------------------------------------------------------
Patch to default capture 'this' in generic lambdas 
-------------------------------------------------------------------
@@ -781,21 +797,38 @@ maybe_resolve_dummy (tree object, bool add_capture_p)
   tree type = TYPE_MAIN_VARIANT (TREE_TYPE (object));
   gcc_assert (!TYPE_PTR_P (type));

-  if (type != current_class_type
-      && current_class_type
-      && LAMBDA_TYPE_P (current_class_type)
-      && lambda_function (current_class_type)
-      && DERIVED_FROM_P (type, current_nonlambda_class_type ()))
+  if (type == current_class_type)
+    return object;
+
+  tree lambda = ((current_class_type && LAMBDA_TYPE_P (current_class_type))?
+                lambda_function (current_class_type) : 0);
+  if (lambda &&
+      (DERIVED_FROM_P (type, current_nonlambda_class_type ())
+       || (DECL_TEMPLATE_INFO (lambda)
+          && DECL_TEMPLATE_RESULT (DECL_TI_TEMPLATE (lambda)) == lambda)))
     {
       /* In a lambda, need to go through 'this' capture.  */
       tree lam = CLASSTYPE_LAMBDA_EXPR (current_class_type);
       tree cap = lambda_expr_this_capture (lam, add_capture_p);
-------------------------------------------------------------------

Reply via email to