[PR 91853] Prevent IPA-SRA ICEs on type-mismatched calls
authorMartin Jambor <mjambor@suse.cz>
Mon, 30 Sep 2019 08:18:59 +0000 (10:18 +0200)
committerMartin Jambor <jamborm@gcc.gnu.org>
Mon, 30 Sep 2019 08:18:59 +0000 (10:18 +0200)
2019-09-30  Martin Jambor  <mjambor@suse.cz>

PR ipa/91853
* tree-inline.c (force_value_to_type): New function.
(setup_one_parameter): Use force_value_to_type to convert type.
* tree-inline.c (force_value_to_type): Declare.
* ipa-param-manipulation.c (ipa_param_adjustments::modify_call): Deal
with register type mismatches.

testsuite/
* gcc.dg/ipa/pr91853.c: New test.

From-SVN: r276296

gcc/ChangeLog
gcc/ipa-param-manipulation.c
gcc/testsuite/ChangeLog
gcc/testsuite/gcc.dg/ipa/pr91853.c [new file with mode: 0644]
gcc/tree-inline.c
gcc/tree-inline.h

index 099d1b9a89fbcf6c62db7ee2addfda7ae4b50e6f..4a76e2f41008fb057c5f681cf895e72fef6749f3 100644 (file)
@@ -1,3 +1,12 @@
+2019-09-30  Martin Jambor  <mjambor@suse.cz>
+
+       PR ipa/91853
+       * tree-inline.c (force_value_to_type): New function.
+       (setup_one_parameter): Use force_value_to_type to convert type.
+       * tree-inline.c (force_value_to_type): Declare.
+       * ipa-param-manipulation.c (ipa_param_adjustments::modify_call): Deal
+       with register type mismatches.
+
 2019-09-30  Andreas Tobler  <andreast@gcc.gnu.org>
 
        * config.gcc: Use the secure-plt on FreeBSD 13 and upwards for
index 913b96fefa434f0d8ac7a58de8d37a85b953974f..bbf646726e230d32c749a0790fd2c35333e38583 100644 (file)
@@ -651,8 +651,15 @@ ipa_param_adjustments::modify_call (gcall *stmt,
       bool deref_base = false;
       unsigned int deref_align = 0;
       if (TREE_CODE (base) != ADDR_EXPR
-         && POINTER_TYPE_P (TREE_TYPE (base)))
-       off = build_int_cst (apm->alias_ptr_type, apm->unit_offset);
+         && is_gimple_reg_type (TREE_TYPE (base)))
+       {
+         /* Detect type mismatches in calls in invalid programs and make a
+            poor attempt to gracefully convert them so that we don't ICE.  */
+         if (!POINTER_TYPE_P (TREE_TYPE (base)))
+           base = force_value_to_type (ptr_type_node, base);
+
+         off = build_int_cst (apm->alias_ptr_type, apm->unit_offset);
+       }
       else
        {
          bool addrof;
index 85e718ebe66e6dc8f3060951306d8326138a9da5..84139ef0fb0943f64e9e5269f89a7686a6ca68aa 100644 (file)
@@ -1,3 +1,8 @@
+2019-09-30  Martin Jambor  <mjambor@suse.cz>
+
+       PR ipa/91853
+       * gcc.dg/ipa/pr91853.c: New test.
+
 2019-09-30  Jakub Jelinek  <jakub@redhat.com>
 
        PR target/91931
diff --git a/gcc/testsuite/gcc.dg/ipa/pr91853.c b/gcc/testsuite/gcc.dg/ipa/pr91853.c
new file mode 100644 (file)
index 0000000..4bad780
--- /dev/null
@@ -0,0 +1,30 @@
+/* { dg-do compile } */
+/* { dg-options "--param ipa-cp-value-list-size=0 -Os -fno-inline" } */
+
+struct _wincore
+{
+  int y;
+  int width;
+};
+int a;
+void fn2 (void);
+static int fn1 (dpy, winInfo) struct _XDisplay *dpy;
+struct _wincore *winInfo;
+{
+  a = winInfo->width;
+  fn2 ();
+}
+
+void fn4 (int, int, int);
+static int fn3 (dpy, winInfo, visrgn) struct _XDisplay *dpy;
+int winInfo, visrgn;
+{
+  int b = fn1 (0, winInfo);
+  fn4 (0, 0, visrgn);
+}
+
+int
+fn5 (event) struct _XEvent *event;
+{
+  fn3 (0, 0, 0);
+}
index 500037c9f3f3023b620ca645bc49366af7a4e91e..d6920f48693d3551b630583bd623056077e93dd5 100644 (file)
@@ -3333,6 +3333,29 @@ insert_init_stmt (copy_body_data *id, basic_block bb, gimple *init_stmt)
     }
 }
 
+/* Deal with mismatched formal/actual parameters, in a rather brute-force way
+   if need be (which should only be necessary for invalid programs).  Attempt
+   to convert VAL to TYPE and return the result if it is possible, just return
+   a zero constant of the given type if it fails.  */
+
+tree
+force_value_to_type (tree type, tree value)
+{
+  /* If we can match up types by promotion/demotion do so.  */
+  if (fold_convertible_p (type, value))
+    return fold_convert (type, value);
+
+  /* ???  For valid programs we should not end up here.
+     Still if we end up with truly mismatched types here, fall back
+     to using a VIEW_CONVERT_EXPR or a literal zero to not leak invalid
+     GIMPLE to the following passes.  */
+  if (!is_gimple_reg_type (TREE_TYPE (value))
+          || TYPE_SIZE (type) == TYPE_SIZE (TREE_TYPE (value)))
+    return fold_build1 (VIEW_CONVERT_EXPR, type, value);
+  else
+    return build_zero_cst (type);
+}
+
 /* Initialize parameter P with VALUE.  If needed, produce init statement
    at the end of BB.  When BB is NULL, we return init statement to be
    output later.  */
@@ -3349,23 +3372,7 @@ setup_one_parameter (copy_body_data *id, tree p, tree value, tree fn,
   if (value
       && value != error_mark_node
       && !useless_type_conversion_p (TREE_TYPE (p), TREE_TYPE (value)))
-    {
-      /* If we can match up types by promotion/demotion do so.  */
-      if (fold_convertible_p (TREE_TYPE (p), value))
-       rhs = fold_convert (TREE_TYPE (p), value);
-      else
-       {
-         /* ???  For valid programs we should not end up here.
-            Still if we end up with truly mismatched types here, fall back
-            to using a VIEW_CONVERT_EXPR or a literal zero to not leak invalid
-            GIMPLE to the following passes.  */
-         if (!is_gimple_reg_type (TREE_TYPE (value))
-             || TYPE_SIZE (TREE_TYPE (p)) == TYPE_SIZE (TREE_TYPE (value)))
-           rhs = fold_build1 (VIEW_CONVERT_EXPR, TREE_TYPE (p), value);
-         else
-           rhs = build_zero_cst (TREE_TYPE (p));
-       }
-    }
+    rhs = force_value_to_type (TREE_TYPE (p), value);
 
   /* Make an equivalent VAR_DECL.  Note that we must NOT remap the type
      here since the type of this decl must be visible to the calling
index 87a149c357bb603c3cd4aba3a327a2a4f01e295a..b226dc03833512513a55417bfc2289d71dc8a09d 100644 (file)
@@ -250,6 +250,7 @@ extern tree copy_fn (tree, tree&, tree&);
 extern const char *copy_forbidden (struct function *fun);
 extern tree copy_decl_for_dup_finish (copy_body_data *id, tree decl, tree copy);
 extern tree copy_decl_to_var (tree, copy_body_data *);
+extern tree force_value_to_type (tree type, tree value);
 
 /* This is in tree-inline.c since the routine uses
    data structures from the inliner.  */