summaryrefslogtreecommitdiff
path: root/gcc
diff options
context:
space:
mode:
authorrguenth <rguenth@138bc75d-0d04-0410-961f-82ee72b054a4>2014-04-04 11:52:35 +0000
committerrguenth <rguenth@138bc75d-0d04-0410-961f-82ee72b054a4>2014-04-04 11:52:35 +0000
commit98107def4d92f0f02d34c53e5971c5e68176815a (patch)
tree5d195f2c96f8f418bd1d795709474cd7c6d0007d /gcc
parent23913915572ebc3bee410dc2b1115199865f179e (diff)
downloadgcc-98107def4d92f0f02d34c53e5971c5e68176815a.tar.gz
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. * g++.dg/torture/pr60746.C: New testcase. git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@209079 138bc75d-0d04-0410-961f-82ee72b054a4
Diffstat (limited to 'gcc')
-rw-r--r--gcc/ChangeLog14
-rw-r--r--gcc/cgraph.c13
-rw-r--r--gcc/gimple-expr.c18
-rw-r--r--gcc/gimple-expr.h1
-rw-r--r--gcc/gimple-low.c10
-rw-r--r--gcc/gimple.c5
-rw-r--r--gcc/gimplify.c19
-rw-r--r--gcc/gimplify.h1
-rw-r--r--gcc/testsuite/ChangeLog5
-rw-r--r--gcc/testsuite/g++.dg/torture/pr60746.C23
-rw-r--r--gcc/tree-ssanames.c2
11 files changed, 94 insertions, 17 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index 5a25f784dd7..4dc3a9ea7f7 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -1,3 +1,17 @@
+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
diff --git a/gcc/cgraph.c b/gcc/cgraph.c
index dcab9848307..281ad6326b5 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 2c4da474eff..da663d6fb79 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 ed8e338beca..3b6cda8441b 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 80fd786fdde..da3fb9fb35e 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 e9851ca386a..2a278e41e9d 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 ad2178dd914..744178420ab 100644
--- a/gcc/gimplify.c
+++ b/gcc/gimplify.c
@@ -627,6 +627,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)
{
gcc_assert (!DECL_CHAIN (tmp) && !DECL_SEEN_IN_BIND_EXPR_P (tmp));
diff --git a/gcc/gimplify.h b/gcc/gimplify.h
index 6bc0057c30e..47e72130add 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 0446485dfb8..3c64a2bf96b 100644
--- a/gcc/testsuite/ChangeLog
+++ b/gcc/testsuite/ChangeLog
@@ -1,3 +1,8 @@
+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.
diff --git a/gcc/testsuite/g++.dg/torture/pr60746.C b/gcc/testsuite/g++.dg/torture/pr60746.C
new file mode 100644
index 00000000000..7ce6ebe6bc0
--- /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 2fc822081c8..2b535a1fef0 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