Here, in the thunk returned from the captureless lambda conversion to
pointer-to-function, we try to pass through invisible reference parameters
by reference, without doing a copy. The empty class copy optimization was
messing that up.
gcc/cp/ChangeLog:
PR c++/98326
PR c++/20408
* cp-gimplify.c (simple_empty_class_p): Don't touch an invisiref
parm.
gcc/testsuite/ChangeLog:
PR c++/98326
* g++.dg/cpp1y/lambda-generic-empty1.C: New test.
&& TYPE_HAS_TRIVIAL_DESTRUCTOR (type))
/* The TARGET_EXPR is itself a simple copy, look through it. */
return simple_empty_class_p (type, TARGET_EXPR_INITIAL (op), code);
+
+ if (TREE_CODE (op) == PARM_DECL
+ && TREE_ADDRESSABLE (TREE_TYPE (op)))
+ {
+ tree fn = DECL_CONTEXT (op);
+ if (DECL_THUNK_P (fn)
+ || lambda_static_thunk_p (fn))
+ /* In a thunk, we pass through invisible reference parms, so this isn't
+ actually a copy. */
+ return false;
+ }
+
return
(TREE_CODE (op) == EMPTY_CLASS_EXPR
|| code == MODIFY_EXPR
--- /dev/null
+// PR c++/98326
+// { dg-do compile { target c++14 } }
+
+struct A {
+ A() = default;
+ A(const A&) {}
+};
+
+void (*fptr)(A) = [](auto){};