[Bug c++/86943] [8/9 Regression] Wrong code when converting stateless generic lambda to function pointer

jakub at gcc dot gnu.org gcc-bugzilla@gcc.gnu.org
Fri Nov 23 16:16:00 GMT 2018


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

Jakub Jelinek <jakub at gcc dot gnu.org> changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
                 CC|                            |jakub at gcc dot gnu.org,
                   |                            |nathan at gcc dot gnu.org

--- Comment #2 from Jakub Jelinek <jakub at gcc dot gnu.org> ---
extern "C" int printf (const char *fmt, ...);

struct S
{
  S () { printf ("default-construct %p\n", this); }
  S (const S &x) { printf ("copy-construct %p from %p\n", this, &x); }
  S (S &&x) noexcept { printf ("move-construct %p from %p\n", this, &x); }
  ~S () { printf ("destroy %p\n", this); }
};

using F = void (*) (S);

F
foo ()
{
  return [] (auto val) { printf ("called %p\n", &val); };
}

int
main ()
{
  volatile F cb = foo ();
  cb ({});
  return 0;
}

The extra indirection is because in _FUN we have:
<<cleanup_point <<< Unknown tree: expr_stmt
  foo()::<lambda(auto:1)>::operator()<S> (0B, &TARGET_EXPR <D.2164, <<< Unknown
tree: aggr_init_expr
  5
  __ct_comp 
  D.2164
  (struct S *) <<< Unknown tree: void_cst >>>
  (struct S &) &D.2160 >>>>) >>>>>;
return;
and CALL_FROM_THUNK_P is set on the operator() call.
cp_genericize on _FUN changes the D.2160 argument, originally with type S, is
changed to S & and the PARM_DECL turned into DECL_BY_REFERENCE one, but because
the call is CALL_FROM_THUNK_P, no adjustment of the arguments is done:
  /* Don't dereference parms in a thunk, pass the references through. */
  if ((TREE_CODE (stmt) == CALL_EXPR && CALL_FROM_THUNK_P (stmt))
      || (TREE_CODE (stmt) == AGGR_INIT_EXPR && AGGR_INIT_FROM_THUNK_P (stmt)))
    {
      *walk_subtrees = 0;
      return NULL;
    }
Do we want to just prevent changing the direct PARM_DECL arguments of such
calls, but still recurse into more complex arguments?  Or is it incorrect that
CALL_FROM_THUNK_P is set here?


More information about the Gcc-bugs mailing list