aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorPatrick Palka <ppalka@redhat.com>2024-01-30 10:44:56 -0500
committerPatrick Palka <ppalka@redhat.com>2024-01-30 10:44:56 -0500
commit0857a00fe3226db8801384743b6d44353dcac9da (patch)
treed05cbfc17c31b84beb751de92f38e0270367f5e5
parentaf37bef86199e50368cbfbc97befe0622a07f12f (diff)
downloadgcc-0857a00fe3226db8801384743b6d44353dcac9da.zip
gcc-0857a00fe3226db8801384743b6d44353dcac9da.tar.gz
gcc-0857a00fe3226db8801384743b6d44353dcac9da.tar.bz2
c++: duplicated side effects of xobj arg [PR113640]
We miscompile the below testcase because keep_unused_object_arg thinks the object argument of an xobj member function is unused, and so it ends up duplicating the argument's side effects. PR c++/113640 gcc/cp/ChangeLog: * call.cc (keep_unused_object_arg): Punt for an xobj member function. gcc/testsuite/ChangeLog: * g++.dg/cpp23/explicit-obj-lambda14.C: New test. Reviewed-by: Jason Merrill <jason@redhat.com>
-rw-r--r--gcc/cp/call.cc2
-rw-r--r--gcc/testsuite/g++.dg/cpp23/explicit-obj-lambda14.C27
2 files changed, 28 insertions, 1 deletions
diff --git a/gcc/cp/call.cc b/gcc/cp/call.cc
index 9de0d77..451a189 100644
--- a/gcc/cp/call.cc
+++ b/gcc/cp/call.cc
@@ -5256,7 +5256,7 @@ keep_unused_object_arg (tree result, tree obj, tree fn)
{
if (result == NULL_TREE
|| result == error_mark_node
- || TREE_CODE (TREE_TYPE (fn)) == METHOD_TYPE
+ || DECL_OBJECT_MEMBER_FUNCTION_P (fn)
|| !TREE_SIDE_EFFECTS (obj))
return result;
diff --git a/gcc/testsuite/g++.dg/cpp23/explicit-obj-lambda14.C b/gcc/testsuite/g++.dg/cpp23/explicit-obj-lambda14.C
new file mode 100644
index 0000000..5c1d566
--- /dev/null
+++ b/gcc/testsuite/g++.dg/cpp23/explicit-obj-lambda14.C
@@ -0,0 +1,27 @@
+// PR c++/113640
+// { dg-do run { target c++23 } }
+
+static int total;
+
+struct A {
+ A f(this auto self, int n) {
+ total += n;
+ return self;
+ }
+};
+
+int main() {
+ A a;
+ a.f(1).f(42).f(100);
+ if (total != 143)
+ __builtin_abort();
+
+ auto l = [](this auto self, int n) {
+ total += n;
+ return self;
+ };
+ total = 0;
+ l(1)(42)(100);
+ if (total != 143)
+ __builtin_abort();
+}