aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJason Merrill <jason@redhat.com>2021-02-08 17:04:03 -0500
committerJason Merrill <jason@redhat.com>2021-02-08 20:51:51 -0500
commitbdbca69e0720fa9062fe71782235141f629ae006 (patch)
treeb5725094dbdc7b69cac93772cd65a2cfae07ea83
parenta8dd2b3e96590ceccead63d28fc91c956a5f1a73 (diff)
downloadgcc-bdbca69e0720fa9062fe71782235141f629ae006.zip
gcc-bdbca69e0720fa9062fe71782235141f629ae006.tar.gz
gcc-bdbca69e0720fa9062fe71782235141f629ae006.tar.bz2
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.
-rw-r--r--gcc/cp/cp-gimplify.c12
-rw-r--r--gcc/testsuite/g++.dg/cpp1y/lambda-generic-empty1.C9
2 files changed, 21 insertions, 0 deletions
diff --git a/gcc/cp/cp-gimplify.c b/gcc/cp/cp-gimplify.c
index 4d0e92c..1c5e15b 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 0000000..ffb0cf1
--- /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){};