aboutsummaryrefslogtreecommitdiff
path: root/gcc/testsuite/g++.dg/cpp0x
diff options
context:
space:
mode:
authorMarek Polacek <polacek@redhat.com>2025-02-18 12:18:31 -0500
committerMarek Polacek <polacek@redhat.com>2025-02-28 12:27:36 -0500
commit96572464234a88949ebfc07207ae2ae04c63e53b (patch)
tree69372dfd7b7b3cd414d25a733057a1b0c5368695 /gcc/testsuite/g++.dg/cpp0x
parent22018a4a8caa806a8f673eb0713de16d64d25063 (diff)
downloadgcc-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.C19
-rw-r--r--gcc/testsuite/g++.dg/cpp0x/constexpr-nsdmi5.C15
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);
+}