diff options
-rw-r--r-- | gcc/cp/ChangeLog | 8 | ||||
-rw-r--r-- | gcc/cp/constexpr.c | 202 |
2 files changed, 77 insertions, 133 deletions
diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog index d91b614..15a1b8b 100644 --- a/gcc/cp/ChangeLog +++ b/gcc/cp/ChangeLog @@ -1,3 +1,11 @@ +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> * tree.c (replace_placeholders_t): Remove unused type. diff --git a/gcc/cp/constexpr.c b/gcc/cp/constexpr.c index 2952cbe..60f0a79 100644 --- a/gcc/cp/constexpr.c +++ b/gcc/cp/constexpr.c @@ -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. We assume here that all builtin functions evaluate to scalar types represented by _CST nodes. */ @@ -1054,10 +1044,6 @@ adjust_temp_type (tree type, tree 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. We are processing a call expression (either CALL_EXPR or AGGR_INIT_EXPR) in the context of CTX. Evaluate @@ -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); } 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, non_constant_p, overflow_p); /* Don't VERIFY_CONSTANT here. */ @@ -1336,113 +1310,88 @@ cxx_eval_call_expression (const constexpr_ctx *ctx, tree t, { 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; - result = (cxx_eval_constant_expression - (&new_ctx, new_call.fundef->body, - lval, - non_constant_p, overflow_p)); + tree oparm = TREE_PURPOSE (bound); + tree arg = TREE_VALUE (bound); + gcc_assert (DECL_NAME (remapped) == DECL_NAME (oparm)); + ctx->values->put (remapped, arg); + 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 - && (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; + 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); - /* Unshare the whole function body. */ - tree body = copy_fn (fun, parms, res); + tree jump_target = NULL_TREE; + cxx_eval_constant_expression (ctx, body, + lval, non_constant_p, overflow_p, + &jump_target); - /* Associate the bindings with the remapped parms. */ - tree bound = new_call.bindings; - tree remapped = parms; - while (bound) - { - tree oparm = TREE_PURPOSE (bound); - tree arg = TREE_VALUE (bound); - gcc_assert (DECL_NAME (remapped) == DECL_NAME (oparm)); - ctx->values->put (remapped, arg); - bound = TREE_CHAIN (bound); - remapped = DECL_CHAIN (remapped); - } - /* Add the RESULT_DECL to the values map, too. */ - 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 + 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 (result == NULL_TREE && !*non_constant_p) { - result = *ctx->values->get (slot ? slot : res); - if (result == NULL_TREE && !*non_constant_p) - { - if (!ctx->quiet) - error ("constexpr call flows off the end " - "of the function"); - *non_constant_p = true; - } + if (!ctx->quiet) + 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) *non_constant_p = true; if (*non_constant_p) result = error_mark_node; - 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 + else if (!result) result = void_node; if (entry) entry->result = result; @@ -3048,10 +2997,7 @@ cxx_eval_constant_expression (const constexpr_ctx *ctx, tree t, return t; case PARM_DECL: - if (!use_new_call && ctx - && 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) + if (lval && TREE_CODE (TREE_TYPE (t)) != REFERENCE_TYPE) /* glvalue use. */; else if (tree *p = ctx->values->get (r)) r = *p; @@ -3148,16 +3094,6 @@ cxx_eval_constant_expression (const constexpr_ctx *ctx, tree t, break; 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: r = cxx_eval_store_expression (ctx, t, lval, non_constant_p, overflow_p); |