From: Jason Merrill Date: Mon, 8 Feb 2021 22:04:03 +0000 (-0500) Subject: c++: generic lambda, fn* conv, empty class [PR98326] X-Git-Url: https://git.libre-soc.org/?a=commitdiff_plain;h=bdbca69e0720fa9062fe71782235141f629ae006;p=gcc.git c++: generic lambda, fn* conv, empty class [PR98326] 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. --- diff --git a/gcc/cp/cp-gimplify.c b/gcc/cp/cp-gimplify.c index 4d0e92c3321..1c5e15b957f 100644 --- a/gcc/cp/cp-gimplify.c +++ b/gcc/cp/cp-gimplify.c @@ -324,6 +324,18 @@ simple_empty_class_p (tree type, tree op, tree_code code) && 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 diff --git a/gcc/testsuite/g++.dg/cpp1y/lambda-generic-empty1.C b/gcc/testsuite/g++.dg/cpp1y/lambda-generic-empty1.C new file mode 100644 index 00000000000..ffb0cf149ce --- /dev/null +++ b/gcc/testsuite/g++.dg/cpp1y/lambda-generic-empty1.C @@ -0,0 +1,9 @@ +// PR c++/98326 +// { dg-do compile { target c++14 } } + +struct A { + A() = default; + A(const A&) {} +}; + +void (*fptr)(A) = [](auto){};