{
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;
--- /dev/null
+// 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; }
--- /dev/null
+// 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);
+}