Bootstrapped/regtested on x86_64-pc-linux-gnu, ok for trunk/16?

-- >8 --
Like in PR110822, the attached test produces an ICE in verify_address:

      error: constant not recomputed when 'ADDR_EXPR' changed

since r10-7718, but it wasn't fixed by r15-7762.  The reason is that
here we have:

  {.D.3013={.D.3006={.a={.ptr=&<retval>.D.3013.D.3006.a}},
            .D.3007={.b={.ptr=&<retval>.D.3013.D.3007.b}}}}

and we replace '<retval>' with 'names', but we only call
recompute_tree_invariant_expr for the first ADDR_EXPR, not the latter.
For the second ADDR_EXPR d->changed will be false: the first replacement
changed the shared tree <retval>.D.3013.  So I'm afraid we have to
recompute the flags unconditionally.  It may be a bit slower, but it's
correct.

        PR c++/126215

gcc/cp/ChangeLog:

        * constexpr.cc (replace_decl_r): Recompute the flags
        unconditionally.

gcc/testsuite/ChangeLog:

        * g++.dg/cpp1z/constexpr-nsdmi1.C: New test.
---
 gcc/cp/constexpr.cc                           | 11 ++---------
 gcc/testsuite/g++.dg/cpp1z/constexpr-nsdmi1.C | 13 +++++++++++++
 2 files changed, 15 insertions(+), 9 deletions(-)
 create mode 100644 gcc/testsuite/g++.dg/cpp1z/constexpr-nsdmi1.C

diff --git a/gcc/cp/constexpr.cc b/gcc/cp/constexpr.cc
index 868925012e5..6e14e7c4de6 100644
--- a/gcc/cp/constexpr.cc
+++ b/gcc/cp/constexpr.cc
@@ -3810,16 +3810,9 @@ replace_decl_r (tree *tp, int *walk_subtrees, void *data)
   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;
+      cxx_mark_addressable (*tp);
+      recompute_tree_invariant_for_addr_expr (*tp);
       *walk_subtrees = 0;
     }
   else if (*tp == d->decl)
diff --git a/gcc/testsuite/g++.dg/cpp1z/constexpr-nsdmi1.C 
b/gcc/testsuite/g++.dg/cpp1z/constexpr-nsdmi1.C
new file mode 100644
index 00000000000..a7f29e56a5d
--- /dev/null
+++ b/gcc/testsuite/g++.dg/cpp1z/constexpr-nsdmi1.C
@@ -0,0 +1,13 @@
+// PR c++/126215
+// { dg-do compile { target c++17 } }
+
+struct bug{ bug *ptr = this; };
+
+struct base0 { bug a; };
+struct base1 { bug b; };
+struct tuple_: base0, base1 {};
+struct tuple : tuple_ {};
+
+constexpr tuple gen() { return {}; }
+constexpr tuple names = gen();
+int main() { bug *x = names.b.ptr; }

base-commit: 97a43fc4dbc5cfb1174a13313dda7637c838d110
-- 
2.55.0

Reply via email to