diff options
author | Jason Merrill <jason@redhat.com> | 2021-01-26 16:04:24 -0500 |
---|---|---|
committer | Jason Merrill <jason@redhat.com> | 2021-01-26 17:10:58 -0500 |
commit | 96253f069ead0736536de803b06a8053a85039a6 (patch) | |
tree | 86ffdaf30dbb91f5a29cb8b38abf83d07e53970f | |
parent | a4dfd0f089af33f2af57bf422f9859405b9b4a16 (diff) | |
download | gcc-96253f069ead0736536de803b06a8053a85039a6.zip gcc-96253f069ead0736536de803b06a8053a85039a6.tar.gz gcc-96253f069ead0736536de803b06a8053a85039a6.tar.bz2 |
c++: Invisible refs are not restrict [PR97474]
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.
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.
-rw-r--r-- | gcc/cp/call.c | 6 | ||||
-rw-r--r-- | gcc/testsuite/g++.dg/torture/pr97474.C | 28 |
2 files changed, 29 insertions, 5 deletions
diff --git a/gcc/cp/call.c b/gcc/cp/call.c index 5977582..87a7af1 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 0000000..6ce117e --- /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 (); +} |