https://gcc.gnu.org/g:96572464234a88949ebfc07207ae2ae04c63e53b

commit r15-7762-g96572464234a88949ebfc07207ae2ae04c63e53b
Author: Marek Polacek <pola...@redhat.com>
Date:   Tue Feb 18 12:18:31 2025 -0500

    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 <ja...@redhat.com>

Diff:
---
 gcc/cp/constexpr.cc                           | 21 ++++++++++++++++++++-
 gcc/testsuite/g++.dg/cpp0x/constexpr-nsdmi4.C | 19 +++++++++++++++++++
 gcc/testsuite/g++.dg/cpp0x/constexpr-nsdmi5.C | 15 +++++++++++++++
 3 files changed, 54 insertions(+), 1 deletion(-)

diff --git a/gcc/cp/constexpr.cc b/gcc/cp/constexpr.cc
index 97c227d57a67..aa2fa44613a0 100644
--- a/gcc/cp/constexpr.cc
+++ b/gcc/cp/constexpr.cc
@@ -2707,7 +2707,26 @@ replace_decl_r (tree *tp, int *walk_subtrees, void *data)
 {
   replace_decl_data *d = (replace_decl_data *) data;
 
-  if (*tp == d->decl)
+  /* We could be replacing
+       &<retval>.bar -> &foo.bar
+     where foo is a static VAR_DECL, so we need to recompute TREE_CONSTANT
+     on the ADDR_EXPR around it.  */
+  if (TREE_CODE (*tp) == ADDR_EXPR)
+    {
+      d->pset->add (*tp);
+      auto save_changed = d->changed;
+      d->changed = false;
+      cp_walk_tree (&TREE_OPERAND (*tp, 0), replace_decl_r, d, nullptr);
+      if (d->changed)
+       {
+         cxx_mark_addressable (*tp);
+         recompute_tree_invariant_for_addr_expr (*tp);
+       }
+      else
+       d->changed = save_changed;
+      *walk_subtrees = 0;
+    }
+  else if (*tp == d->decl)
     {
       *tp = unshare_expr (d->replacement);
       d->changed = true;
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 000000000000..360470dbccbf
--- /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 000000000000..0a0acaa9fdff
--- /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);
+}

Reply via email to