+2014-04-04 Richard Biener <rguenther@suse.de>
+
+ 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 <thomas@codesourcery.com>
PR bootstrap/60719
{
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);
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 ----- */
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 *,
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;
continue;
/* Record the variable. */
- add_local_decl (cfun, var);
+ add_local_decl (DECL_STRUCT_FUNCTION (fn), var);
}
-
- if (change_cfun)
- pop_cfun ();
}
{
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;
/* 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)
{
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);
+2014-04-04 Richard Biener <rguenther@suse.de>
+
+ PR ipa/60746
+ * g++.dg/torture/pr60746.C: New testcase.
+
2014-04-04 Fabien ChĂȘne <fabien@gcc.gnu.org>
* g++.old-deja/g++.robertl/eb121.C: Adjust.
--- /dev/null
+// { 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)
+ {
+ }
+}
/* 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