aboutsummaryrefslogtreecommitdiff
path: root/gcc/cp/constexpr.c
diff options
context:
space:
mode:
Diffstat (limited to 'gcc/cp/constexpr.c')
-rw-r--r--gcc/cp/constexpr.c42
1 files changed, 31 insertions, 11 deletions
diff --git a/gcc/cp/constexpr.c b/gcc/cp/constexpr.c
index 1b35bc1..192ba56 100644
--- a/gcc/cp/constexpr.c
+++ b/gcc/cp/constexpr.c
@@ -1074,13 +1074,18 @@ struct constexpr_ctx {
/* If inside SWITCH_EXPR. */
constexpr_switch_state *css_state;
- /* Whether we should error on a non-constant expression or fail quietly. */
+ /* Whether we should error on a non-constant expression or fail quietly.
+ This flag needs to be here, but some of the others could move to global
+ if they get larger than a word. */
bool quiet;
/* Whether we are strictly conforming to constant expression rules or
trying harder to get a constant value. */
bool strict;
/* Whether __builtin_is_constant_evaluated () should be true. */
bool manifestly_const_eval;
+ /* Whether we want to avoid doing anything that will cause extra DECL_UID
+ generation. */
+ bool uid_sensitive;
};
/* A table of all constexpr calls that have been evaluated by the
@@ -1145,7 +1150,7 @@ static GTY(()) hash_map<tree, tree> *fundef_copies_table;
is parms, TYPE is result. */
static tree
-get_fundef_copy (constexpr_fundef *fundef)
+get_fundef_copy (const constexpr_ctx *ctx, constexpr_fundef *fundef)
{
tree copy;
bool existed;
@@ -1162,6 +1167,9 @@ get_fundef_copy (constexpr_fundef *fundef)
}
else if (*slot == NULL_TREE)
{
+ if (ctx->uid_sensitive)
+ return NULL_TREE;
+
/* We've already used the function itself, so make a copy. */
copy = build_tree_list (NULL, NULL);
tree saved_body = DECL_SAVED_TREE (fundef->decl);
@@ -2232,6 +2240,7 @@ cxx_eval_call_expression (const constexpr_ctx *ctx, tree t,
/* We can't defer instantiating the function any longer. */
if (!DECL_INITIAL (fun)
+ && !ctx->uid_sensitive
&& DECL_TEMPLOID_INSTANTIATION (fun))
{
location_t save_loc = input_location;
@@ -2378,13 +2387,12 @@ cxx_eval_call_expression (const constexpr_ctx *ctx, tree t,
gcc_assert (at_eof >= 2 && ctx->quiet);
*non_constant_p = true;
}
- else
+ else if (tree copy = get_fundef_copy (ctx, new_call.fundef))
{
tree body, parms, res;
releasing_vec ctors;
/* Reuse or create a new unshared copy of this function's body. */
- tree copy = get_fundef_copy (new_call.fundef);
body = TREE_PURPOSE (copy);
parms = TREE_VALUE (copy);
res = TREE_TYPE (copy);
@@ -2522,6 +2530,9 @@ cxx_eval_call_expression (const constexpr_ctx *ctx, tree t,
}
}
}
+ else
+ /* Couldn't get a function copy to evaluate. */
+ *non_constant_p = true;
if (result == error_mark_node)
*non_constant_p = true;
@@ -6275,7 +6286,8 @@ cxx_eval_outermost_constant_expr (tree t, bool allow_non_constant,
bool strict = true,
bool manifestly_const_eval = false,
bool constexpr_dtor = false,
- tree object = NULL_TREE)
+ tree object = NULL_TREE,
+ bool uid_sensitive = false)
{
auto_timevar time (TV_CONSTEXPR);
@@ -6285,7 +6297,8 @@ cxx_eval_outermost_constant_expr (tree t, bool allow_non_constant,
constexpr_global_ctx global_ctx;
constexpr_ctx ctx = { &global_ctx, NULL, NULL, NULL, NULL, NULL,
allow_non_constant, strict,
- manifestly_const_eval || !allow_non_constant };
+ manifestly_const_eval || !allow_non_constant,
+ uid_sensitive };
tree type = initialized_type (t);
tree r = t;
@@ -6375,7 +6388,8 @@ cxx_eval_outermost_constant_expr (tree t, bool allow_non_constant,
auto_vec<tree, 16> cleanups;
global_ctx.cleanups = &cleanups;
- instantiate_constexpr_fns (r);
+ if (!uid_sensitive)
+ instantiate_constexpr_fns (r);
r = cxx_eval_constant_expression (&ctx, r,
false, &non_constant_p, &overflow_p);
@@ -6623,12 +6637,14 @@ fold_simple (tree t)
Otherwise, if T does not have TREE_CONSTANT set, returns T.
Otherwise, returns a version of T without TREE_CONSTANT.
MANIFESTLY_CONST_EVAL is true if T is manifestly const-evaluated
- as per P0595. */
+ as per P0595. UID_SENSITIVE is true if we can't do anything that
+ would affect DECL_UID ordering. */
static GTY((deletable)) hash_map<tree, tree> *cv_cache;
tree
-maybe_constant_value (tree t, tree decl, bool manifestly_const_eval)
+maybe_constant_value (tree t, tree decl, bool manifestly_const_eval,
+ bool uid_sensitive)
{
tree r;
@@ -6646,7 +6662,8 @@ maybe_constant_value (tree t, tree decl, bool manifestly_const_eval)
return t;
if (manifestly_const_eval)
- return cxx_eval_outermost_constant_expr (t, true, true, true, false, decl);
+ return cxx_eval_outermost_constant_expr (t, true, true, true, false,
+ decl, uid_sensitive);
if (cv_cache == NULL)
cv_cache = hash_map<tree, tree>::create_ggc (101);
@@ -6658,7 +6675,10 @@ maybe_constant_value (tree t, tree decl, bool manifestly_const_eval)
r = unshare_expr_without_location (r);
protected_set_expr_location (r, EXPR_LOCATION (t));
}
- return r;
+ if (r != t || TREE_CONSTANT (t) || !manifestly_const_eval)
+ return r;
+ /* If we cached this as non-constant and we need a constant value, try
+ again; we might have failed before due to UID_SENSITIVE. */
}
r = cxx_eval_outermost_constant_expr (t, true, true, false, false, decl);