From: Richard Biener Date: Fri, 4 Apr 2014 11:52:35 +0000 (+0000) Subject: re PR middle-end/60746 (ICE segfault in gimple-expr.c:314) X-Git-Tag: basepoints/gcc-5~85 X-Git-Url: https://gcc.gnu.org/git/?a=commitdiff_plain;h=45b6259486e4a1201c630186338e0845ffeab2f5;p=gcc.git re PR middle-end/60746 (ICE segfault in gimple-expr.c:314) 2014-04-04 Richard Biener PR ipa/60746 * tree-ssanames.c (make_ssa_name_fn): Fix assert. * gimple.c (gimple_set_bb): Avoid ICEing for NULL cfun for non-GIMPLE_LABELs. * gimplify.h (gimple_add_tmp_var_fn): Declare. * gimplify.c (gimple_add_tmp_var_fn): New function. * gimple-expr.h (create_tmp_reg_fn): Declare. * gimple-expr.c (create_tmp_reg_fn): New function. * gimple-low.c (record_vars_into): Don't change cfun. * cgraph.c (cgraph_redirect_edge_call_stmt_to_callee): Fix code generation without cfun. * g++.dg/torture/pr60746.C: New testcase. From-SVN: r209079 --- diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 5a25f784dd79..4dc3a9ea7f71 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,17 @@ +2014-04-04 Richard Biener + + PR ipa/60746 + * tree-ssanames.c (make_ssa_name_fn): Fix assert. + * gimple.c (gimple_set_bb): Avoid ICEing for NULL cfun for + non-GIMPLE_LABELs. + * gimplify.h (gimple_add_tmp_var_fn): Declare. + * gimplify.c (gimple_add_tmp_var_fn): New function. + * gimple-expr.h (create_tmp_reg_fn): Declare. + * gimple-expr.c (create_tmp_reg_fn): New function. + * gimple-low.c (record_vars_into): Don't change cfun. + * cgraph.c (cgraph_redirect_edge_call_stmt_to_callee): Fix + code generation without cfun. + 2014-04-04 Thomas Schwinge PR bootstrap/60719 diff --git a/gcc/cgraph.c b/gcc/cgraph.c index dcab9848307e..281ad6326b51 100644 --- a/gcc/cgraph.c +++ b/gcc/cgraph.c @@ -1479,13 +1479,14 @@ cgraph_redirect_edge_call_stmt_to_callee (struct cgraph_edge *e) { if (TREE_CODE (lhs) == SSA_NAME) { + tree var = create_tmp_reg_fn (DECL_STRUCT_FUNCTION (e->caller->decl), + TREE_TYPE (lhs), NULL); + var = get_or_create_ssa_default_def + (DECL_STRUCT_FUNCTION (e->caller->decl), var); + gimple set_stmt = gimple_build_assign (lhs, var); gsi = gsi_for_stmt (new_stmt); - - tree var = create_tmp_var (TREE_TYPE (lhs), NULL); - tree def = get_or_create_ssa_default_def - (DECL_STRUCT_FUNCTION (e->caller->decl), var); - gimple set_stmt = gimple_build_assign (lhs, def); - gsi_insert_before (&gsi, set_stmt, GSI_SAME_STMT); + gsi_insert_before_without_update (&gsi, set_stmt, GSI_SAME_STMT); + update_stmt_fn (DECL_STRUCT_FUNCTION (e->caller->decl), set_stmt); } gimple_call_set_lhs (new_stmt, NULL_TREE); update_stmt_fn (DECL_STRUCT_FUNCTION (e->caller->decl), new_stmt); diff --git a/gcc/gimple-expr.c b/gcc/gimple-expr.c index 2c4da474eff7..da663d6fb799 100644 --- a/gcc/gimple-expr.c +++ b/gcc/gimple-expr.c @@ -527,6 +527,24 @@ create_tmp_reg (tree type, const char *prefix) return tmp; } +/* Create a new temporary variable declaration of type TYPE by calling + create_tmp_var and if TYPE is a vector or a complex number, mark the new + temporary as gimple register. */ + +tree +create_tmp_reg_fn (struct function *fn, tree type, const char *prefix) +{ + tree tmp; + + tmp = create_tmp_var_raw (type, prefix); + gimple_add_tmp_var_fn (fn, tmp); + if (TREE_CODE (type) == COMPLEX_TYPE + || TREE_CODE (type) == VECTOR_TYPE) + DECL_GIMPLE_REG_P (tmp) = 1; + + return tmp; +} + /* ----- Expression related ----- */ diff --git a/gcc/gimple-expr.h b/gcc/gimple-expr.h index ed8e338beca0..3b6cda8441b1 100644 --- a/gcc/gimple-expr.h +++ b/gcc/gimple-expr.h @@ -33,6 +33,7 @@ extern tree create_tmp_var_name (const char *); extern tree create_tmp_var_raw (tree, const char *); extern tree create_tmp_var (tree, const char *); extern tree create_tmp_reg (tree, const char *); +extern tree create_tmp_reg_fn (struct function *, tree, const char *); extern void extract_ops_from_tree_1 (tree, enum tree_code *, tree *, tree *, diff --git a/gcc/gimple-low.c b/gcc/gimple-low.c index 80fd786fddeb..da3fb9fb35eb 100644 --- a/gcc/gimple-low.c +++ b/gcc/gimple-low.c @@ -841,11 +841,6 @@ lower_builtin_posix_memalign (gimple_stmt_iterator *gsi) void record_vars_into (tree vars, tree fn) { - bool change_cfun = fn != current_function_decl; - - if (change_cfun) - push_cfun (DECL_STRUCT_FUNCTION (fn)); - for (; vars; vars = DECL_CHAIN (vars)) { tree var = vars; @@ -860,11 +855,8 @@ record_vars_into (tree vars, tree fn) continue; /* Record the variable. */ - add_local_decl (cfun, var); + add_local_decl (DECL_STRUCT_FUNCTION (fn), var); } - - if (change_cfun) - pop_cfun (); } diff --git a/gcc/gimple.c b/gcc/gimple.c index e9851ca386a2..2a278e41e9df 100644 --- a/gcc/gimple.c +++ b/gcc/gimple.c @@ -1464,9 +1464,12 @@ gimple_set_bb (gimple stmt, basic_block bb) { stmt->bb = bb; + if (gimple_code (stmt) != GIMPLE_LABEL) + return; + /* If the statement is a label, add the label to block-to-labels map so that we can speed up edge creation for GIMPLE_GOTOs. */ - if (cfun->cfg && gimple_code (stmt) == GIMPLE_LABEL) + if (cfun->cfg) { tree t; int uid; diff --git a/gcc/gimplify.c b/gcc/gimplify.c index ad2178dd914c..744178420ab7 100644 --- a/gcc/gimplify.c +++ b/gcc/gimplify.c @@ -626,6 +626,25 @@ force_constant_size (tree var) /* Push the temporary variable TMP into the current binding. */ +void +gimple_add_tmp_var_fn (struct function *fn, tree tmp) +{ + gcc_assert (!DECL_CHAIN (tmp) && !DECL_SEEN_IN_BIND_EXPR_P (tmp)); + + /* Later processing assumes that the object size is constant, which might + not be true at this point. Force the use of a constant upper bound in + this case. */ + if (!tree_fits_uhwi_p (DECL_SIZE_UNIT (tmp))) + force_constant_size (tmp); + + DECL_CONTEXT (tmp) = fn->decl; + DECL_SEEN_IN_BIND_EXPR_P (tmp) = 1; + + record_vars_into (tmp, fn->decl); +} + +/* Push the temporary variable TMP into the current binding. */ + void gimple_add_tmp_var (tree tmp) { diff --git a/gcc/gimplify.h b/gcc/gimplify.h index 6bc0057c30e9..47e72130add6 100644 --- a/gcc/gimplify.h +++ b/gcc/gimplify.h @@ -60,6 +60,7 @@ extern tree get_formal_tmp_var (tree, gimple_seq *); extern tree get_initialized_tmp_var (tree, gimple_seq *, gimple_seq *); extern void declare_vars (tree, gimple, bool); extern void gimple_add_tmp_var (tree); +extern void gimple_add_tmp_var_fn (struct function *, tree); extern tree unshare_expr (tree); extern tree unshare_expr_without_location (tree); extern tree voidify_wrapper_expr (tree, tree); diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index 0446485dfb88..3c64a2bf96b8 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,8 @@ +2014-04-04 Richard Biener + + PR ipa/60746 + * g++.dg/torture/pr60746.C: New testcase. + 2014-04-04 Fabien Chêne * g++.old-deja/g++.robertl/eb121.C: Adjust. diff --git a/gcc/testsuite/g++.dg/torture/pr60746.C b/gcc/testsuite/g++.dg/torture/pr60746.C new file mode 100644 index 000000000000..7ce6ebe6bc0d --- /dev/null +++ b/gcc/testsuite/g++.dg/torture/pr60746.C @@ -0,0 +1,23 @@ +// { dg-do compile } + +class One +{ +public: + virtual unsigned long getSize () const; +}; + +class Two +{ + virtual int run (); +}; + +int +Two::run () +{ + One list_arry[5][2]; + int orig = 0; + if (list_arry[3][orig].getSize () > 0 + || list_arry[4][orig].getSize () > 0) + { + } +} diff --git a/gcc/tree-ssanames.c b/gcc/tree-ssanames.c index 2fc822081c8d..2b535a1fef0e 100644 --- a/gcc/tree-ssanames.c +++ b/gcc/tree-ssanames.c @@ -144,7 +144,7 @@ make_ssa_name_fn (struct function *fn, tree var, gimple stmt) /* The node was cleared out when we put it on the free list, so there is no need to do so again here. */ - gcc_assert (ssa_name (SSA_NAME_VERSION (t)) == NULL); + gcc_assert ((*SSANAMES (fn))[SSA_NAME_VERSION (t)] == NULL); (*SSANAMES (fn))[SSA_NAME_VERSION (t)] = t; } else