aboutsummaryrefslogtreecommitdiff
path: root/gcc/cp/constexpr.cc
diff options
context:
space:
mode:
Diffstat (limited to 'gcc/cp/constexpr.cc')
-rw-r--r--gcc/cp/constexpr.cc21
1 files changed, 20 insertions, 1 deletions
diff --git a/gcc/cp/constexpr.cc b/gcc/cp/constexpr.cc
index 97c227d..aa2fa44 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;