]> gcc.gnu.org Git - gcc.git/commitdiff
re PR middle-end/60746 (ICE segfault in gimple-expr.c:314)
authorRichard Biener <rguenther@suse.de>
Fri, 4 Apr 2014 11:52:35 +0000 (11:52 +0000)
committerRichard Biener <rguenth@gcc.gnu.org>
Fri, 4 Apr 2014 11:52:35 +0000 (11:52 +0000)
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.

From-SVN: r209079

gcc/ChangeLog
gcc/cgraph.c
gcc/gimple-expr.c
gcc/gimple-expr.h
gcc/gimple-low.c
gcc/gimple.c
gcc/gimplify.c
gcc/gimplify.h
gcc/testsuite/ChangeLog
gcc/testsuite/g++.dg/torture/pr60746.C [new file with mode: 0644]
gcc/tree-ssanames.c

index 5a25f784dd793691696e34c9985ac925fef00aa2..4dc3a9ea7f71cf7447c44d02de99e531728c8019 100644 (file)
@@ -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
index dcab9848307e4db4de1f39d21af9610dd042db46..281ad6326b51559c9be8943c51f02fa7704c971d 100644 (file)
@@ -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);
index 2c4da474eff73fe68891443df46043c0a1b060c8..da663d6fb79908fce3d4d4669a232545712eac7a 100644 (file)
@@ -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 -----  */
 
index ed8e338beca0563718615fb62e32c0c2a67e8451..3b6cda8441b1b124de6656044230e8e0fa4b35a5 100644 (file)
@@ -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 *,
index 80fd786fddeb40f75e4bee1a9802d74b507517fb..da3fb9fb35eb771f420d19a82b47043c15702f4b 100644 (file)
@@ -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 ();
 }
 
 
index e9851ca386a2e75a22104691b1cbf7c244e30a3a..2a278e41e9dff8f5227fd086225123f839c4031c 100644 (file)
@@ -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;
index ad2178dd914c8a8cbe2e333cb6010dca5f975add..744178420ab70242f48b055a2c37825e60ed7b2d 100644 (file)
@@ -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)
 {
index 6bc0057c30e9f7ee8ccfd8dbf6a9e4683d6295ab..47e72130add6f0c3c331ba4f84d401fb68c15899 100644 (file)
@@ -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);
index 0446485dfb88436715f2ca4c0677798c5e4d21dd..3c64a2bf96b858e0a38723d04933117e31319276 100644 (file)
@@ -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 (file)
index 0000000..7ce6ebe
--- /dev/null
@@ -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)
+    {
+    }
+}
index 2fc822081c8db33bd8133d12febcb8c281d75ec3..2b535a1fef0ee974aa51962e567dc76e1f9fb4bf 100644 (file)
@@ -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
This page took 0.193161 seconds and 5 git commands to generate.