[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