This is the mail archive of the gcc-patches@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

Re: [C++ PATCH] Fix wrong-code with generic lambda (PR c++/86943)


On 11/27/18 5:41 PM, Jakub Jelinek wrote:
On Tue, Nov 27, 2018 at 05:20:56PM -0500, Jason Merrill wrote:
On 11/23/18 4:15 PM, Jakub Jelinek wrote:
Hi!

On the following testcase, the call to operator () is marked as
CALL_FROM_THUNK_P and therefore genericization ignores all subtrees thereof.
Unfortunately, one of the arguments is a move ctor call which is not itself
CALL_FROM_THUNK_P and thus we need to genericize its arguments, otherwise
we pass address of a temporary which holds a reference value instead of the
reference itself.

Bootstrapped/regtested on x86_64-linux and i686-linux, ok for trunk?
Or should CALL_FROM_THUNK_P not be set in this call (it is set in
maybe_add_lambda_conv_op and then copied over during tsubst*).

The call with CALL_FROM_THUNK_P set should be inside the thunk whose address
we get when converting the lambda to a function pointer (on return from
foo).  Its arguments should just be the parms of that thunk, I don't know
where this temporary is coming from.

In the *.original dump this is:
<<cleanup_point <<< Unknown tree: expr_stmt
   foo()::<lambda(auto:1)>::operator()<S> (0B, &TARGET_EXPR <D.2406, <<< Unknown tree: aggr_init_expr
   5
   __ct_comp
   D.2406
   (struct S *) <<< Unknown tree: void_cst >>>
   (struct S &) &D.2402 >>>>) >>>>>;
return;

where CALL_FROM_THUNK_P is set on the call to
foo()::<lambda(auto:1)>::operator()<S> and D.2402 is the
PARM_DECL which shouldn't have the &.
In *.gimple it is:
foo()::<lambda(auto:1)>::_FUN<S> (struct S & restrict D.2402) // the arg is DECL_BY_REFERENCE
{
   struct S D.2406;
   struct S & D.2413;

   D.2413 = D.2402;
   S::S (&D.2406, &D.2413); // this ctor wants S & arg, so it should be just D.2402
   try
     {
       try
         {
           foo()::<lambda(auto:1)>::operator()<S> (0B, &D.2406);
         }
       finally
         {
           S::~S (&D.2406);
         }
     }
   finally
     {
       D.2406 = {CLOBBER};
     }
   return;
}

CALL_FROM_THUNK_P is set on the operator() call in maybe_add_lambda_conv_op
and at that the call is:
  <call_expr 0x7fffefc8b2a0
     fn <component_ref 0x7fffefde9f30
         arg:0 <indirect_ref 0x7fffefdf4880 type <record_type 0x7fffefdf9150 __lambda0>
             readonly
             arg:0 <nop_expr 0x7fffefdf4860 type <pointer_type 0x7fffefdf92a0>
                 constant
                 arg:0 <nop_expr 0x7fffefdf4840 type <pointer_type 0x7fffefdf9348>
                     constant
                     arg:0 <integer_cst 0x7fffefca1228 constant 0>>>>
         arg:1 <identifier_node 0x7fffefc97800 operator() tree_2
             simple-op local bindings <0x7fffefdd7488>>>
     arg:0 <indirect_ref 0x7fffefdf48c0
         type <template_type_parm 0x7fffefded7e0 auto:1 type_0 type_6 VOID
             align:8 warn_if_not_align:0 symtab:0 alias-set -1 canonical-type 0x7fffefded7e0
            index 0 level 1 orig_level 1
             reference_to_this <reference_type 0x7fffefdf93f0> chain <type_decl 0x7fffefda1ab0 auto:1>>
         side-effects
         arg:0 <static_cast_expr 0x7fffefdf48a0 type <reference_type 0x7fffefdf9498>
             side-effects arg:0 <parm_decl 0x7fffefdf2e00 val>>>>
The rest (TARGET_EXPR, ctor etc.) appears during instantiation.

Sounds like that's the bug, then; instantiation is failing to preserve the pass-through nature of the call.

Jason


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]