diff mbox series

[pushed] c++: Invisible refs are not restrict [PR97474]

Message ID 20210126221127.649832-1-jason@redhat.com
State New
Headers show
Series [pushed] c++: Invisible refs are not restrict [PR97474] | expand

Commit Message

Jason Merrill Jan. 26, 2021, 10:11 p.m. UTC
In this testcase, we refer to the a parameter through a reference in its own
member, which we asserted couldn't happen by marking the parameter as
'restrict'.  This assumption could also be broken if the address escapes
from the constructor.

Tested x86_64-pc-linux-gnu, applying to trunk.

gcc/cp/ChangeLog:

	PR c++/97474
	* call.c (type_passed_as): Don't mark invisiref restrict.

gcc/testsuite/ChangeLog:

	PR c++/97474
	* g++.dg/torture/pr97474.C: New test.
---
 gcc/cp/call.c                          |  6 +-----
 gcc/testsuite/g++.dg/torture/pr97474.C | 28 ++++++++++++++++++++++++++
 2 files changed, 29 insertions(+), 5 deletions(-)
 create mode 100644 gcc/testsuite/g++.dg/torture/pr97474.C


base-commit: a4dfd0f089af33f2af57bf422f9859405b9b4a16
diff mbox series

Patch

diff --git a/gcc/cp/call.c b/gcc/cp/call.c
index 5977582e279..87a7af12796 100644
--- a/gcc/cp/call.c
+++ b/gcc/cp/call.c
@@ -8263,11 +8263,7 @@  type_passed_as (tree type)
 {
   /* Pass classes with copy ctors by invisible reference.  */
   if (TREE_ADDRESSABLE (type))
-    {
-      type = build_reference_type (type);
-      /* There are no other pointers to this temporary.  */
-      type = cp_build_qualified_type (type, TYPE_QUAL_RESTRICT);
-    }
+    type = build_reference_type (type);
   else if (targetm.calls.promote_prototypes (NULL_TREE)
 	   && INTEGRAL_TYPE_P (type)
 	   && COMPLETE_TYPE_P (type)
diff --git a/gcc/testsuite/g++.dg/torture/pr97474.C b/gcc/testsuite/g++.dg/torture/pr97474.C
new file mode 100644
index 00000000000..6ce117e43a5
--- /dev/null
+++ b/gcc/testsuite/g++.dg/torture/pr97474.C
@@ -0,0 +1,28 @@ 
+// PR c++/97474
+// { dg-do run }
+
+extern "C" int printf (const char *, ...);
+extern "C" void abort ();
+
+struct A {
+    int a;
+    int& b;
+
+    A(int x) : a(x), b(a) {}
+    A(const A& other) : a(other.a), b(a) {}
+    A() : a(0), b(a) {}
+};
+
+int foo(A a) {
+    a.a *= a.b;
+    return a.b;
+}
+
+
+int main() {
+    A a(3);
+
+    int r = foo (a);
+    if (r != 9)
+      abort ();
+}