diff options
author | Marek Polacek <polacek@redhat.com> | 2025-02-18 12:18:31 -0500 |
---|---|---|
committer | Marek Polacek <polacek@redhat.com> | 2025-02-28 12:27:36 -0500 |
commit | 96572464234a88949ebfc07207ae2ae04c63e53b (patch) | |
tree | 69372dfd7b7b3cd414d25a733057a1b0c5368695 /gcc/testsuite/g++.dg/cpp0x | |
parent | 22018a4a8caa806a8f673eb0713de16d64d25063 (diff) | |
download | gcc-96572464234a88949ebfc07207ae2ae04c63e53b.zip gcc-96572464234a88949ebfc07207ae2ae04c63e53b.tar.gz gcc-96572464234a88949ebfc07207ae2ae04c63e53b.tar.bz2 |
c++: fix rejects-valid and ICE with constexpr NSDMI [PR110822]
Since r10-7718 the attached tests produce an ICE in verify_address:
error: constant not recomputed when 'ADDR_EXPR' changed
but before that we wrongly rejected the tests with "is not a constant
expression". This patch fixes both problems.
Since r10-7718 replace_decl_r can replace
{._M_dataplus=&<retval>._M_local_buf, ._M_local_buf=0}
with
{._M_dataplus=&HelloWorld._M_local_buf, ._M_local_buf=0}
The initial &<retval>._M_local_buf was not constant, but since
HelloWorld is a static VAR_DECL, the resulting &HelloWorld._M_local_buf
should have been marked as TREE_CONSTANT. And since we're taking
its address, the whole thing should be TREE_ADDRESSABLE.
PR c++/114913
PR c++/110822
gcc/cp/ChangeLog:
* constexpr.cc (replace_decl_r): If we've replaced something
inside of an ADDR_EXPR, call cxx_mark_addressable and
recompute_tree_invariant_for_addr_expr on the resulting ADDR_EXPR.
gcc/testsuite/ChangeLog:
* g++.dg/cpp0x/constexpr-nsdmi4.C: New test.
* g++.dg/cpp0x/constexpr-nsdmi5.C: New test.
Reviewed-by: Jason Merrill <jason@redhat.com>
Diffstat (limited to 'gcc/testsuite/g++.dg/cpp0x')
-rw-r--r-- | gcc/testsuite/g++.dg/cpp0x/constexpr-nsdmi4.C | 19 | ||||
-rw-r--r-- | gcc/testsuite/g++.dg/cpp0x/constexpr-nsdmi5.C | 15 |
2 files changed, 34 insertions, 0 deletions
diff --git a/gcc/testsuite/g++.dg/cpp0x/constexpr-nsdmi4.C b/gcc/testsuite/g++.dg/cpp0x/constexpr-nsdmi4.C new file mode 100644 index 0000000..360470d --- /dev/null +++ b/gcc/testsuite/g++.dg/cpp0x/constexpr-nsdmi4.C @@ -0,0 +1,19 @@ +// PR c++/114913 +// { dg-do compile { target c++11 } } + +struct strt { + char *_M_dataplus; + char _M_local_buf = 0; + constexpr strt() + : _M_dataplus(&_M_local_buf) {} + constexpr strt(const strt &) + : _M_dataplus(&_M_local_buf) {} +}; + +constexpr strt +f () +{ + return {}; +} +constexpr strt HelloWorld = f(); +const char *a() { return HelloWorld._M_dataplus; } diff --git a/gcc/testsuite/g++.dg/cpp0x/constexpr-nsdmi5.C b/gcc/testsuite/g++.dg/cpp0x/constexpr-nsdmi5.C new file mode 100644 index 0000000..0a0acaa --- /dev/null +++ b/gcc/testsuite/g++.dg/cpp0x/constexpr-nsdmi5.C @@ -0,0 +1,15 @@ +// PR c++/110822 +// { dg-do compile { target c++11 } } + +void __ostream_insert(const char*); +struct basic_string { + const char* _M_p; + char _M_local_buf[16] = {}; + constexpr basic_string() : _M_p(_M_local_buf) {} + const char *data() const { return _M_p; } +}; +constexpr basic_string f() { return {}; } +constexpr basic_string text = f(); +int main() { + __ostream_insert(text._M_p); +} |