diff options
author | Jason Merrill <jason@redhat.com> | 2014-11-17 13:16:14 -0500 |
---|---|---|
committer | Jason Merrill <jason@gcc.gnu.org> | 2014-11-17 13:16:14 -0500 |
commit | 60813a463b1e1398cd9786b8c4761283efefb831 (patch) | |
tree | ed78ea66194e7a5833092975ccb8f03c0921da3a /gcc/tree-inline.c | |
parent | 544009d369ebcdc8208b76ca4f7e3372f5985f5d (diff) | |
download | gcc-60813a463b1e1398cd9786b8c4761283efefb831.zip gcc-60813a463b1e1398cd9786b8c4761283efefb831.tar.gz gcc-60813a463b1e1398cd9786b8c4761283efefb831.tar.bz2 |
C++14 constexpr support (minus loops and multiple returns)
C++14 constexpr support (minus loops and multiple returns)
gcc/
* tree-inline.c (copy_fn): New.
* tree-inline.h: Declare it.
gcc/cp/
* constexpr.c (use_new_call): New macro.
(build_data_member_initialization): Ignore non-mem-inits.
(check_constexpr_bind_expr_vars): Remove C++14 checks.
(constexpr_fn_retval): Likewise.
(check_constexpr_ctor_body): Do nothing in C++14.
(massage_constexpr_body): In C++14 only collect mem-inits.
(get_function_named_in_call): Handle null CALL_EXPR_FN.
(cxx_bind_parameters_in_call): Build bindings in same order as
parameters. Don't treat iniviref parms specially in new call mode.
(cxx_eval_call_expression): If use_new_call, do constexpr expansion
based on DECL_SAVED_TREE rather than the massaged constexpr body.
Set up ctx->object from AGGR_INIT_EXPR_SLOT if we don't have one.
(is_sub_constant_expr): Don't mess with ctx.ctor here.
(cxx_eval_component_reference): A null element means we're mid-
initialization.
(cxx_eval_store_expression, cxx_eval_increment_expression): New.
(cxx_eval_constant_expression): Handle RESULT_DECL, DECL_EXPR,
MODIFY_EXPR, STATEMENT_LIST, BIND_EXPR, USING_STMT,
PREINCREMENT_EXPR, POSTINCREMENT_EXPR, PREDECREMENT_EXPR,
POSTDECREMENT_EXPR. Don't look into DECL_INITIAL of variables in
constexpr functions. In new-call mode find parms in the values table.
(potential_constant_expression_1): Handle null CALL_EXPR_FN.
Handle STATEMENT_LIST, MODIFY_EXPR, MODOP_EXPR, IF_STMT,
PREINCREMENT_EXPR, POSTINCREMENT_EXPR, PREDECREMENT_EXPR,
POSTDECREMENT_EXPR, BIND_EXPR, WITH_CLEANUP_EXPR,
CLEANUP_POINT_EXPR, MUST_NOT_THROW_EXPR, TRY_CATCH_EXPR,
EH_SPEC_BLOCK, EXPR_STMT, DECL_EXPR, CASE_LABEL_EXPR, BREAK_STMT,
CONTINUE_STMT, USING_STMT, IF_STMT, DO_STMT, FOR_STMT, WHILE_STMT,
SWITCH_STMT, ASM_EXPR.
(cxx_eval_vec_init_1): Call build_aggr_init_expr.
(cxx_eval_indirect_ref): Don't return a CONSTRUCTOR when the
caller wants an lvalue.
(cxx_eval_outermost_constant_expr): Pull object out of AGGR_INIT_EXPR.
(maybe_constant_init): Look through INIT_EXPR.
(ensure_literal_type_for_constexpr_object): Set
cp_function_chain->invalid_constexpr.
* cp-tree.h (struct language_function): Add invalid_constexpr bitfield.
* decl.c (start_decl): Set cp_function_chain->invalid_constexpr.
(check_for_uninitialized_const_var): Likewise.
(maybe_save_function_definition): Check it.
* parser.c (cp_parser_jump_statement): Set
cp_function_chain->invalid_constexpr.
(cp_parser_asm_definition): Likewise.
From-SVN: r217663
Diffstat (limited to 'gcc/tree-inline.c')
-rw-r--r-- | gcc/tree-inline.c | 52 |
1 files changed, 52 insertions, 0 deletions
diff --git a/gcc/tree-inline.c b/gcc/tree-inline.c index 510b53e..4b937ca 100644 --- a/gcc/tree-inline.c +++ b/gcc/tree-inline.c @@ -5817,3 +5817,55 @@ build_duplicate_type (tree type) return type; } + +/* Unshare the entire DECL_SAVED_TREE of FN and return the remapped + parameters and RESULT_DECL in PARMS and RESULT. Used by C++ constexpr + evaluation. */ + +tree +copy_fn (tree fn, tree& parms, tree& result) +{ + copy_body_data id; + tree param; + hash_map<tree, tree> decl_map; + + tree *p = &parms; + *p = NULL_TREE; + + memset (&id, 0, sizeof (id)); + id.src_fn = fn; + id.dst_fn = current_function_decl; + id.src_cfun = DECL_STRUCT_FUNCTION (fn); + id.decl_map = &decl_map; + + id.copy_decl = copy_decl_no_change; + id.transform_call_graph_edges = CB_CGE_DUPLICATE; + id.transform_new_cfg = false; + id.transform_return_to_modify = false; + id.transform_parameter = true; + id.transform_lang_insert_block = NULL; + + /* Make sure not to unshare trees behind the front-end's back + since front-end specific mechanisms may rely on sharing. */ + id.regimplify = false; + id.do_not_unshare = true; + + /* We're not inside any EH region. */ + id.eh_lp_nr = 0; + + /* Remap the parameters and result and return them to the caller. */ + for (param = DECL_ARGUMENTS (fn); + param; + param = DECL_CHAIN (param)) + { + *p = remap_decl (param, &id); + p = &DECL_CHAIN (*p); + } + + if (DECL_RESULT (fn)) + result = remap_decl (DECL_RESULT (fn), &id); + else + result = NULL_TREE; + + return copy_tree_body (&id); +} |