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