aboutsummaryrefslogtreecommitdiff
path: root/gcc/tree-inline.c
diff options
context:
space:
mode:
authorJason Merrill <jason@redhat.com>2014-11-17 13:16:14 -0500
committerJason Merrill <jason@gcc.gnu.org>2014-11-17 13:16:14 -0500
commit60813a463b1e1398cd9786b8c4761283efefb831 (patch)
treeed78ea66194e7a5833092975ccb8f03c0921da3a /gcc/tree-inline.c
parent544009d369ebcdc8208b76ca4f7e3372f5985f5d (diff)
downloadgcc-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.c52
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);
+}