On Wed, 19 Feb 2025, Marek Polacek wrote: > I suppose it's safer to leave this for GCC 16, but anyway: > > Bootstrapped/regtested on x86_64-pc-linux-gnu. > > -- >8 -- > 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. > --- > gcc/cp/constexpr.cc | 17 ++++++++++++++++- > gcc/testsuite/g++.dg/cpp0x/constexpr-nsdmi4.C | 19 +++++++++++++++++++ > gcc/testsuite/g++.dg/cpp0x/constexpr-nsdmi5.C | 15 +++++++++++++++ > 3 files changed, 50 insertions(+), 1 deletion(-) > create mode 100644 gcc/testsuite/g++.dg/cpp0x/constexpr-nsdmi4.C > create mode 100644 gcc/testsuite/g++.dg/cpp0x/constexpr-nsdmi5.C > > diff --git a/gcc/cp/constexpr.cc b/gcc/cp/constexpr.cc > index 59dd0668af3..c41454057cb 100644 > --- a/gcc/cp/constexpr.cc > +++ b/gcc/cp/constexpr.cc > @@ -2707,7 +2707,22 @@ 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); > + cp_walk_tree (&TREE_OPERAND (*tp, 0), replace_decl_r, d, nullptr); > + if (d->changed)
d->changed could already be true if something before the ADDR_EXPR was replaced. I think we should clear/restore d->changed around the cp_walk_tree call to accurately track whether anything inside the ADDR_EXPR was replaced. Otherwise LGTM > + { > + cxx_mark_addressable (*tp); > + recompute_tree_invariant_for_addr_expr (*tp); > + } > + *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 00000000000..360470dbccb > --- /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 00000000000..0a0acaa9fdf > --- /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); > +} > > base-commit: 44d4a1086d965fb5280daf65c7c4a253ad6cc8a1 > -- > 2.48.1 > >