]> git.ipfire.org Git - thirdparty/gcc.git/commitdiff
re PR c/41163 (verify_gimple fails)
authorRichard Guenther <rguenther@suse.de>
Wed, 26 Aug 2009 13:23:04 +0000 (13:23 +0000)
committerRichard Biener <rguenth@gcc.gnu.org>
Wed, 26 Aug 2009 13:23:04 +0000 (13:23 +0000)
2009-08-26  Richard Guenther  <rguenther@suse.de>

PR middle-end/41163
* gimplify.c (gimplify_addr_expr): Canonicalize ADDR_EXPRs if
the types to not match.
* tree-cfg.c (verify_gimple_assign_single): Adjust ADDR_EXPR
verification.
* tree-ssa.c (useless_type_conversion_p): Conversions to
pointers to unprototyped functions are useless.

* gcc.c-torture/compile/pr41163.c: New testcase.
* gcc.dg/pr35899.c: Adjust.

From-SVN: r151122

gcc/ChangeLog
gcc/gimplify.c
gcc/testsuite/ChangeLog
gcc/testsuite/gcc.c-torture/compile/pr41163.c [new file with mode: 0644]
gcc/testsuite/gcc.dg/pr35899.c
gcc/tree-cfg.c
gcc/tree-ssa.c

index 85f1015f7b99f40c0a041b97e01773625c1039dc..f50b14c18ade886405e4d00f0e522af17cdb9f8e 100644 (file)
@@ -1,3 +1,13 @@
+2009-08-26  Richard Guenther  <rguenther@suse.de>
+
+       PR middle-end/41163
+       * gimplify.c (gimplify_addr_expr): Canonicalize ADDR_EXPRs if
+       the types to not match.
+       * tree-cfg.c (verify_gimple_assign_single): Adjust ADDR_EXPR
+       verification.
+       * tree-ssa.c (useless_type_conversion_p): Conversions to
+       pointers to unprototyped functions are useless.
+
 2009-08-26  Richard Guenther  <rguenther@suse.de>
 
        * tree-ssa-structalias.c (create_variable_info_for): Remove
index bdb64ea88c892543a7e639a41859b86810d20ba9..7f1dc4ae94bd861215bea72cdc54c2689d794b2b 100644 (file)
@@ -4725,10 +4725,22 @@ gimplify_addr_expr (tree *expr_p, gimple_seq *pre_p, gimple_seq *post_p)
       if (TREE_CODE (op0) == INDIRECT_REF)
        goto do_indirect_ref;
 
+      mark_addressable (TREE_OPERAND (expr, 0));
+
+      /* The FEs may end up building ADDR_EXPRs early on a decl with
+        an incomplete type.  Re-build ADDR_EXPRs in canonical form
+        here.  */
+      if (!types_compatible_p (TREE_TYPE (op0), TREE_TYPE (TREE_TYPE (expr))))
+       *expr_p = build_fold_addr_expr (op0);
+
       /* Make sure TREE_CONSTANT and TREE_SIDE_EFFECTS are set properly.  */
-      recompute_tree_invariant_for_addr_expr (expr);
+      recompute_tree_invariant_for_addr_expr (*expr_p);
+
+      /* If we re-built the ADDR_EXPR add a conversion to the original type
+         if required.  */
+      if (!useless_type_conversion_p (TREE_TYPE (expr), TREE_TYPE (*expr_p)))
+       *expr_p = fold_convert (TREE_TYPE (expr), *expr_p);
 
-      mark_addressable (TREE_OPERAND (expr, 0));
       break;
     }
 
index e11a926dda955b9afda330d8d6b7ab0d758daaed..9ed0d6dde851dfcbf86ac82c425e4064ad51d4a2 100644 (file)
@@ -1,3 +1,9 @@
+2009-08-26  Richard Guenther  <rguenther@suse.de>
+
+       PR middle-end/41163
+       * gcc.c-torture/compile/pr41163.c: New testcase.
+       * gcc.dg/pr35899.c: Adjust.
+
 2009-08-26  Richard Guenther  <rguenther@suse.de>
 
        * gcc.dg/tree-ssa/restrict-4.c: New testcase.
diff --git a/gcc/testsuite/gcc.c-torture/compile/pr41163.c b/gcc/testsuite/gcc.c-torture/compile/pr41163.c
new file mode 100644 (file)
index 0000000..c224837
--- /dev/null
@@ -0,0 +1,10 @@
+struct option {
+    void *value;
+};
+void parse_options (struct option *);
+void cmd_grep(void)
+{
+  struct option options[] = { { &options } };
+  parse_options(options);
+}
+
index 0dc4ffaa31716a6180a3bf06dcdb96401f0b1890..fca3a3d8621707259d2117288339e31b6cd8a31c 100644 (file)
@@ -5,7 +5,7 @@
 int
 foo (void)
 {
-  int a = bar ();      /* { dg-error "returning 'void'" } */
+  int a = bar ();
   return a;
 }
 
index 3b99d6c5a3093fb1c019b1fc116c3da5c7b8cef4..639c4ec710cf46ff62eba769346709718a3e67d6 100644 (file)
@@ -3889,12 +3889,13 @@ verify_gimple_assign_single (gimple stmt)
            return true;
          }
 
-       if (!one_pointer_to_useless_type_conversion_p (lhs_type,
-                                                      TREE_TYPE (op)))
+       if (!types_compatible_p (TREE_TYPE (op), TREE_TYPE (TREE_TYPE (rhs1)))
+           && !one_pointer_to_useless_type_conversion_p (TREE_TYPE (rhs1),
+                                                         TREE_TYPE (op)))
          {
            error ("type mismatch in address expression");
-           debug_generic_stmt (lhs_type);
-           debug_generic_stmt (TYPE_POINTER_TO (TREE_TYPE (op)));
+           debug_generic_stmt (TREE_TYPE (rhs1));
+           debug_generic_stmt (TREE_TYPE (op));
            return true;
          }
 
index 76e4e8b7f1b3c0ae0e18eae355cb424ac4b92828..51b1689912115fb07297b28cc91ca70461ff36c7 100644 (file)
@@ -875,13 +875,21 @@ useless_type_conversion_p (tree outer_type, tree inner_type)
       && POINTER_TYPE_P (outer_type))
     {
       /* If the outer type is (void *) or a pointer to an incomplete
-        record type, then the conversion is not necessary.  */
+        record type or a pointer to an unprototyped function,
+        then the conversion is not necessary.  */
       if (VOID_TYPE_P (TREE_TYPE (outer_type))
          || (AGGREGATE_TYPE_P (TREE_TYPE (outer_type))
              && TREE_CODE (TREE_TYPE (outer_type)) != ARRAY_TYPE
              && (TREE_CODE (TREE_TYPE (outer_type))
                  == TREE_CODE (TREE_TYPE (inner_type)))
-             && !COMPLETE_TYPE_P (TREE_TYPE (outer_type))))
+             && !COMPLETE_TYPE_P (TREE_TYPE (outer_type)))
+         || ((TREE_CODE (TREE_TYPE (outer_type)) == FUNCTION_TYPE
+              || TREE_CODE (TREE_TYPE (outer_type)) == METHOD_TYPE)
+             && (TREE_CODE (TREE_TYPE (outer_type))
+                 == TREE_CODE (TREE_TYPE (inner_type)))
+             && !TYPE_ARG_TYPES (TREE_TYPE (outer_type))
+             && useless_type_conversion_p (TREE_TYPE (TREE_TYPE (outer_type)),
+                                           TREE_TYPE (TREE_TYPE (inner_type)))))
        return true;
 
       /* Do not lose casts to restrict qualified pointers.  */