Commit 0567dcd2 by Marek Polacek Committed by Marek Polacek

constexpr.c (use_new_call): Remove #define.

	* constexpr.c (use_new_call): Remove #define.
	(lookup_parameter_binding): Remove function.
	(cxx_bind_parameters_in_call): Remove unused code.
	(cxx_eval_call_expression): Likewise.
	(cxx_eval_constant_expression): Likewise.

From-SVN: r222126
parent 5141ed42
2015-04-15 Marek Polacek <polacek@redhat.com>
* constexpr.c (use_new_call): Remove #define.
(lookup_parameter_binding): Remove function.
(cxx_bind_parameters_in_call): Remove unused code.
(cxx_eval_call_expression): Likewise.
(cxx_eval_constant_expression): Likewise.
2015-04-14 Mikhail Maltsev <maltsevm@gmail.com> 2015-04-14 Mikhail Maltsev <maltsevm@gmail.com>
* tree.c (replace_placeholders_t): Remove unused type. * tree.c (replace_placeholders_t): Remove unused type.
......
...@@ -1000,16 +1000,6 @@ get_nth_callarg (tree t, int n) ...@@ -1000,16 +1000,6 @@ get_nth_callarg (tree t, int n)
} }
} }
/* Look up the binding of the function parameter T in a constexpr
function call context CALL. */
static tree
lookup_parameter_binding (const constexpr_call *call, tree t)
{
tree b = purpose_member (t, call->bindings);
return TREE_VALUE (b);
}
/* Attempt to evaluate T which represents a call to a builtin function. /* Attempt to evaluate T which represents a call to a builtin function.
We assume here that all builtin functions evaluate to scalar types We assume here that all builtin functions evaluate to scalar types
represented by _CST nodes. */ represented by _CST nodes. */
...@@ -1054,10 +1044,6 @@ adjust_temp_type (tree type, tree temp) ...@@ -1054,10 +1044,6 @@ adjust_temp_type (tree type, tree temp)
return cp_fold_convert (type, temp); return cp_fold_convert (type, temp);
} }
/* True if we want to use the new handling of constexpr calls based on
DECL_SAVED_TREE. */
#define use_new_call true
/* Subroutine of cxx_eval_call_expression. /* Subroutine of cxx_eval_call_expression.
We are processing a call expression (either CALL_EXPR or We are processing a call expression (either CALL_EXPR or
AGGR_INIT_EXPR) in the context of CTX. Evaluate AGGR_INIT_EXPR) in the context of CTX. Evaluate
...@@ -1090,18 +1076,6 @@ cxx_bind_parameters_in_call (const constexpr_ctx *ctx, tree t, ...@@ -1090,18 +1076,6 @@ cxx_bind_parameters_in_call (const constexpr_ctx *ctx, tree t,
x = cp_build_addr_expr (x, tf_warning_or_error); x = cp_build_addr_expr (x, tf_warning_or_error);
} }
bool lval = false; bool lval = false;
if (parms && DECL_BY_REFERENCE (parms) && !use_new_call)
{
/* cp_genericize made this a reference for argument passing, but
we don't want to treat it like one for C++11 constexpr
evaluation. C++14 constexpr evaluation uses the genericized
DECL_SAVED_TREE. */
gcc_assert (TREE_CODE (type) == REFERENCE_TYPE);
gcc_assert (TREE_CODE (TREE_TYPE (x)) == REFERENCE_TYPE);
type = TREE_TYPE (type);
x = convert_from_reference (x);
lval = true;
}
arg = cxx_eval_constant_expression (ctx, x, lval, arg = cxx_eval_constant_expression (ctx, x, lval,
non_constant_p, overflow_p); non_constant_p, overflow_p);
/* Don't VERIFY_CONSTANT here. */ /* Don't VERIFY_CONSTANT here. */
...@@ -1336,113 +1310,88 @@ cxx_eval_call_expression (const constexpr_ctx *ctx, tree t, ...@@ -1336,113 +1310,88 @@ cxx_eval_call_expression (const constexpr_ctx *ctx, tree t,
{ {
if (!result || result == error_mark_node) if (!result || result == error_mark_node)
{ {
if (!use_new_call) if (DECL_SAVED_TREE (fun) == NULL_TREE
&& (DECL_CONSTRUCTOR_P (fun) || DECL_DESTRUCTOR_P (fun)))
/* The maybe-in-charge 'tor had its DECL_SAVED_TREE
cleared, try a clone. */
for (fun = DECL_CHAIN (fun);
fun && DECL_CLONED_FUNCTION_P (fun);
fun = DECL_CHAIN (fun))
if (DECL_SAVED_TREE (fun))
break;
gcc_assert (DECL_SAVED_TREE (fun));
tree parms, res;
/* Unshare the whole function body. */
tree body = copy_fn (fun, parms, res);
/* Associate the bindings with the remapped parms. */
tree bound = new_call.bindings;
tree remapped = parms;
while (bound)
{ {
new_ctx.call = &new_call; tree oparm = TREE_PURPOSE (bound);
result = (cxx_eval_constant_expression tree arg = TREE_VALUE (bound);
(&new_ctx, new_call.fundef->body, gcc_assert (DECL_NAME (remapped) == DECL_NAME (oparm));
lval, ctx->values->put (remapped, arg);
non_constant_p, overflow_p)); bound = TREE_CHAIN (bound);
remapped = DECL_CHAIN (remapped);
} }
else /* Add the RESULT_DECL to the values map, too. */
tree slot = NULL_TREE;
if (DECL_BY_REFERENCE (res))
{ {
if (DECL_SAVED_TREE (fun) == NULL_TREE slot = AGGR_INIT_EXPR_SLOT (t);
&& (DECL_CONSTRUCTOR_P (fun) || DECL_DESTRUCTOR_P (fun))) tree addr = build_address (slot);
/* The maybe-in-charge 'tor had its DECL_SAVED_TREE addr = build_nop (TREE_TYPE (res), addr);
cleared, try a clone. */ ctx->values->put (res, addr);
for (fun = DECL_CHAIN (fun); ctx->values->put (slot, NULL_TREE);
fun && DECL_CLONED_FUNCTION_P (fun); }
fun = DECL_CHAIN (fun)) else
if (DECL_SAVED_TREE (fun)) ctx->values->put (res, NULL_TREE);
break;
gcc_assert (DECL_SAVED_TREE (fun));
tree parms, res;
/* Unshare the whole function body. */ tree jump_target = NULL_TREE;
tree body = copy_fn (fun, parms, res); cxx_eval_constant_expression (ctx, body,
lval, non_constant_p, overflow_p,
&jump_target);
/* Associate the bindings with the remapped parms. */ if (DECL_CONSTRUCTOR_P (fun))
tree bound = new_call.bindings; /* This can be null for a subobject constructor call, in
tree remapped = parms; which case what we care about is the initialization
while (bound) side-effects rather than the value. We could get at the
{ value by evaluating *this, but we don't bother; there's
tree oparm = TREE_PURPOSE (bound); no need to put such a call in the hash table. */
tree arg = TREE_VALUE (bound); result = lval ? ctx->object : ctx->ctor;
gcc_assert (DECL_NAME (remapped) == DECL_NAME (oparm)); else if (VOID_TYPE_P (TREE_TYPE (res)))
ctx->values->put (remapped, arg); result = void_node;
bound = TREE_CHAIN (bound); else
remapped = DECL_CHAIN (remapped); {
} result = *ctx->values->get (slot ? slot : res);
/* Add the RESULT_DECL to the values map, too. */ if (result == NULL_TREE && !*non_constant_p)
tree slot = NULL_TREE;
if (DECL_BY_REFERENCE (res))
{
slot = AGGR_INIT_EXPR_SLOT (t);
tree addr = build_address (slot);
addr = build_nop (TREE_TYPE (res), addr);
ctx->values->put (res, addr);
ctx->values->put (slot, NULL_TREE);
}
else
ctx->values->put (res, NULL_TREE);
tree jump_target = NULL_TREE;
cxx_eval_constant_expression (ctx, body,
lval, non_constant_p, overflow_p,
&jump_target);
if (DECL_CONSTRUCTOR_P (fun))
/* This can be null for a subobject constructor call, in
which case what we care about is the initialization
side-effects rather than the value. We could get at the
value by evaluating *this, but we don't bother; there's
no need to put such a call in the hash table. */
result = lval ? ctx->object : ctx->ctor;
else if (VOID_TYPE_P (TREE_TYPE (res)))
result = void_node;
else
{ {
result = *ctx->values->get (slot ? slot : res); if (!ctx->quiet)
if (result == NULL_TREE && !*non_constant_p) error ("constexpr call flows off the end "
{ "of the function");
if (!ctx->quiet) *non_constant_p = true;
error ("constexpr call flows off the end "
"of the function");
*non_constant_p = true;
}
} }
/* Remove the parms/result from the values map. Is it worth
bothering to do this when the map itself is only live for
one constexpr evaluation? If so, maybe also clear out
other vars from call, maybe in BIND_EXPR handling? */
ctx->values->remove (res);
if (slot)
ctx->values->remove (slot);
for (tree parm = parms; parm; parm = TREE_CHAIN (parm))
ctx->values->remove (parm);
} }
/* Remove the parms/result from the values map. Is it worth
bothering to do this when the map itself is only live for
one constexpr evaluation? If so, maybe also clear out
other vars from call, maybe in BIND_EXPR handling? */
ctx->values->remove (res);
if (slot)
ctx->values->remove (slot);
for (tree parm = parms; parm; parm = TREE_CHAIN (parm))
ctx->values->remove (parm);
} }
if (result == error_mark_node) if (result == error_mark_node)
*non_constant_p = true; *non_constant_p = true;
if (*non_constant_p) if (*non_constant_p)
result = error_mark_node; result = error_mark_node;
else if (result) else if (!result)
{
/* If this was a call to initialize an object, set the type of
the CONSTRUCTOR to the type of that object. */
if (DECL_CONSTRUCTOR_P (fun) && !use_new_call)
{
tree ob_arg = get_nth_callarg (t, 0);
STRIP_NOPS (ob_arg);
gcc_assert (TYPE_PTR_P (TREE_TYPE (ob_arg))
&& CLASS_TYPE_P (TREE_TYPE (TREE_TYPE (ob_arg))));
result = adjust_temp_type (TREE_TYPE (TREE_TYPE (ob_arg)),
result);
}
}
else
result = void_node; result = void_node;
if (entry) if (entry)
entry->result = result; entry->result = result;
...@@ -3048,10 +2997,7 @@ cxx_eval_constant_expression (const constexpr_ctx *ctx, tree t, ...@@ -3048,10 +2997,7 @@ cxx_eval_constant_expression (const constexpr_ctx *ctx, tree t,
return t; return t;
case PARM_DECL: case PARM_DECL:
if (!use_new_call && ctx if (lval && TREE_CODE (TREE_TYPE (t)) != REFERENCE_TYPE)
&& ctx->call && DECL_CONTEXT (t) == ctx->call->fundef->decl)
r = lookup_parameter_binding (ctx->call, t);
else if (lval && TREE_CODE (TREE_TYPE (t)) != REFERENCE_TYPE)
/* glvalue use. */; /* glvalue use. */;
else if (tree *p = ctx->values->get (r)) else if (tree *p = ctx->values->get (r))
r = *p; r = *p;
...@@ -3148,16 +3094,6 @@ cxx_eval_constant_expression (const constexpr_ctx *ctx, tree t, ...@@ -3148,16 +3094,6 @@ cxx_eval_constant_expression (const constexpr_ctx *ctx, tree t,
break; break;
case INIT_EXPR: case INIT_EXPR:
if (!use_new_call)
{
/* In C++11 constexpr evaluation we are looking for the value,
not the side-effect of the initialization. */
r = cxx_eval_constant_expression (ctx, TREE_OPERAND (t, 1),
false,
non_constant_p, overflow_p);
break;
}
/* else fall through */
case MODIFY_EXPR: case MODIFY_EXPR:
r = cxx_eval_store_expression (ctx, t, lval, r = cxx_eval_store_expression (ctx, t, lval,
non_constant_p, overflow_p); non_constant_p, overflow_p);
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment