]> git.ipfire.org Git - thirdparty/gcc.git/commitdiff
re PR c/59905 (Unfriendly abort when calling a fucntion via a function pointer cast)
authorRichard Biener <rguenther@suse.de>
Thu, 30 Jan 2014 14:17:02 +0000 (14:17 +0000)
committerRichard Biener <rguenth@gcc.gnu.org>
Thu, 30 Jan 2014 14:17:02 +0000 (14:17 +0000)
2014-01-30  Richard Biener  <rguenther@suse.de>

PR c/59905
* c-typeck.c (build_function_call_vec): Do not replace calls
to a function via an incompatible type with a runtime abort.

* gcc.dg/cast-function-1.c: Adjust to survive DCE.
* gcc.dg/call-diag-2.c: Remove expected warnings about calling
abort.
* gcc.dg/invalid-call-1.c: Likewise.

From-SVN: r207300

gcc/c/ChangeLog
gcc/c/c-typeck.c
gcc/testsuite/ChangeLog
gcc/testsuite/gcc.dg/call-diag-2.c
gcc/testsuite/gcc.dg/cast-function-1.c
gcc/testsuite/gcc.dg/invalid-call-1.c

index 228a93be42dfced1317e0ed6d8b1fe3682beb44d..c6ca4b41a3387a287d94ae2e4a0305a8b6436c6b 100644 (file)
@@ -1,3 +1,9 @@
+2014-01-30  Richard Biener  <rguenther@suse.de>
+
+       PR c/59905
+       * c-typeck.c (build_function_call_vec): Do not replace calls
+       to a function via an incompatible type with a runtime abort.
+
 2014-01-24  Balaji V. Iyer  <balaji.v.iyer@intel.com>
 
        * c-parser.c (c_parser_declaration_or_fndef): Replaced
index 8477dd43fbf1d07fd861cc2218386e806a9653f8..59bd6df21df596e17af777cf4be50a0080d0453d 100644 (file)
@@ -2907,56 +2907,24 @@ build_function_call_vec (location_t loc, tree function,
     return error_mark_node;
 
   /* Check that the function is called through a compatible prototype.
-     If it is not, replace the call by a trap, wrapped up in a compound
-     expression if necessary.  This has the nice side-effect to prevent
-     the tree-inliner from generating invalid assignment trees which may
-     blow up in the RTL expander later.  */
+     If it is not, warn.  */
   if (CONVERT_EXPR_P (function)
       && TREE_CODE (tem = TREE_OPERAND (function, 0)) == ADDR_EXPR
       && TREE_CODE (tem = TREE_OPERAND (tem, 0)) == FUNCTION_DECL
       && !comptypes (fntype, TREE_TYPE (tem)))
     {
       tree return_type = TREE_TYPE (fntype);
-      tree trap = build_function_call (loc,
-                                      builtin_decl_explicit (BUILT_IN_TRAP),
-                                      NULL_TREE);
-      int i;
 
       /* This situation leads to run-time undefined behavior.  We can't,
         therefore, simply error unless we can prove that all possible
         executions of the program must execute the code.  */
-      if (warning_at (loc, 0, "function called through a non-compatible type"))
-       /* We can, however, treat "undefined" any way we please.
-          Call abort to encourage the user to fix the program.  */
-       inform (loc, "if this code is reached, the program will abort");
-      /* Before the abort, allow the function arguments to exit or
-        call longjmp.  */
-      for (i = 0; i < nargs; i++)
-       trap = build2 (COMPOUND_EXPR, void_type_node, (*params)[i], trap);
-
-      if (VOID_TYPE_P (return_type))
-       {
-         if (TYPE_QUALS (return_type) != TYPE_UNQUALIFIED)
-           pedwarn (loc, 0,
-                    "function with qualified void return type called");
-         return trap;
-       }
-      else
-       {
-         tree rhs;
-
-         if (AGGREGATE_TYPE_P (return_type))
-           rhs = build_compound_literal (loc, return_type,
-                                         build_constructor (return_type,
-                                           NULL),
-                                         false);
-         else
-           rhs = build_zero_cst (return_type);
+      warning_at (loc, 0, "function called through a non-compatible type");
 
-         return require_complete_type (build2 (COMPOUND_EXPR, return_type,
-                                               trap, rhs));
-       }
-    }
+      if (VOID_TYPE_P (return_type)
+         && TYPE_QUALS (return_type) != TYPE_UNQUALIFIED)
+       pedwarn (loc, 0,
+                "function with qualified void return type called");
+     }
 
   argarray = vec_safe_address (params);
 
index 62bcc3131ca16b5b19c5db7dc860f3986608677e..77953e9b395a8cb181e4d2faf6ca0f8939eb4a6a 100644 (file)
@@ -1,3 +1,11 @@
+2014-01-30  Richard Biener  <rguenther@suse.de>
+
+       PR c/59905
+       * gcc.dg/cast-function-1.c: Adjust to survive DCE.
+       * gcc.dg/call-diag-2.c: Remove expected warnings about calling
+       abort.
+       * gcc.dg/invalid-call-1.c: Likewise.
+
 2014-01-29  Paolo Carlini  <paolo.carlini@oracle.com>
 
        PR c++/58561
index 0d87e52e973ee9b9266d3b16efd1f0fdff5163fa..c34252cd7294998dd60159ddc3cddb74cf219754 100644 (file)
@@ -11,7 +11,5 @@ void g1 (void) { f_cv (); } /* { dg-error "qualified void" } */
 void g2 (void) { f_s (); } /* { dg-error "invalid use of undefined type" } */
 void g3 (void) { ((const void (*) (void)) f_v) (); } /* { dg-error "qualified void" } */
 /* { dg-warning "function called through a non-compatible type" "cast" { target *-*-* } 12 } */
-/* { dg-message "will abort" "abort" { target *-*-* } 12 } */
 void g4 (void) { ((struct s (*) (void)) f_v) (), (void) 0; } /* { dg-error "invalid use of undefined type" } */
-/* { dg-warning "function called through a non-compatible type" "cast" { target *-*-* } 15 } */
-/* { dg-message "will abort" "abort" { target *-*-* } 15 } */
+/* { dg-warning "function called through a non-compatible type" "cast" { target *-*-* } 14 } */
index 781d0e221911821144794c76f749c747ca46f703..5eb412595fcb13438bb85a1425bc69b2759b94a6 100644 (file)
@@ -16,12 +16,8 @@ typedef struct {
   int a;
 } str_t;
 
-void bar(void)
+void bar(double d, int i, str_t s)
 {
-  double d;
-  int i;
-  str_t s;
-
   d = ((double (*) (int)) foo1) (i);  /* { dg-warning "33:non-compatible|abort" } */
   i = ((int (*) (double)) foo1) (d);  /* { dg-warning "33:non-compatible|abort" } */
   s = ((str_t (*) (int)) foo1) (i);   /* { dg-warning "32:non-compatible|abort" } */
@@ -39,11 +35,15 @@ void bar(void)
 
 int foo1(int arg)
 {
+  /* Prevent the function from becoming const and thus DCEd.  */
+  __asm volatile ("" : "+r" (arg));
   return arg;
 }
 
 int foo2(arg)
   int arg;
 {
+  /* Prevent the function from becoming const and thus DCEd.  */
+  __asm volatile ("" : "+r" (arg));
   return arg;
 }
index 31f66b9266889f3bfaa098fca7bda8aefe1b496f..7a2f6a07bb3729a020fc4a7fc426bf10608f14c3 100644 (file)
@@ -14,5 +14,4 @@ void foo()
 {
   cptr = mar(6);
   ((char *(*)(void *,int (*)(void *,unsigned char **),char**))((fp)bar))(0,0,(void*)(0)); /* { dg-warning "function called through a non-compatible type" "non-compatible type" } */
-  /* { dg-message "note: if this code is reached, the program will abort" "" { target *-*-* } 16 } */
 }