aboutsummaryrefslogtreecommitdiff
path: root/gcc
diff options
context:
space:
mode:
authorRichard Biener <rguenther@suse.de>2014-01-30 14:17:02 +0000
committerRichard Biener <rguenth@gcc.gnu.org>2014-01-30 14:17:02 +0000
commitfa337f3ae5fb8c4c3631345e65ec8c75cb40ab69 (patch)
treee34fbb86afbceba8a29f011b72b2cdeb158c3fcf /gcc
parentf30a0ba57a9a407601afd871d6bf49038b258c94 (diff)
downloadgcc-fa337f3ae5fb8c4c3631345e65ec8c75cb40ab69.zip
gcc-fa337f3ae5fb8c4c3631345e65ec8c75cb40ab69.tar.gz
gcc-fa337f3ae5fb8c4c3631345e65ec8c75cb40ab69.tar.bz2
re PR c/59905 (Unfriendly abort when calling a fucntion via a function pointer cast)
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
Diffstat (limited to 'gcc')
-rw-r--r--gcc/c/ChangeLog6
-rw-r--r--gcc/c/c-typeck.c46
-rw-r--r--gcc/testsuite/ChangeLog8
-rw-r--r--gcc/testsuite/gcc.dg/call-diag-2.c4
-rw-r--r--gcc/testsuite/gcc.dg/cast-function-1.c10
-rw-r--r--gcc/testsuite/gcc.dg/invalid-call-1.c1
6 files changed, 27 insertions, 48 deletions
diff --git a/gcc/c/ChangeLog b/gcc/c/ChangeLog
index 228a93b..c6ca4b4 100644
--- a/gcc/c/ChangeLog
+++ b/gcc/c/ChangeLog
@@ -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
diff --git a/gcc/c/c-typeck.c b/gcc/c/c-typeck.c
index 8477dd4..59bd6df 100644
--- a/gcc/c/c-typeck.c
+++ b/gcc/c/c-typeck.c
@@ -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);
diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog
index 62bcc31..77953e9 100644
--- a/gcc/testsuite/ChangeLog
+++ b/gcc/testsuite/ChangeLog
@@ -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
diff --git a/gcc/testsuite/gcc.dg/call-diag-2.c b/gcc/testsuite/gcc.dg/call-diag-2.c
index 0d87e52..c34252c 100644
--- a/gcc/testsuite/gcc.dg/call-diag-2.c
+++ b/gcc/testsuite/gcc.dg/call-diag-2.c
@@ -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 } */
diff --git a/gcc/testsuite/gcc.dg/cast-function-1.c b/gcc/testsuite/gcc.dg/cast-function-1.c
index 781d0e2..5eb4125 100644
--- a/gcc/testsuite/gcc.dg/cast-function-1.c
+++ b/gcc/testsuite/gcc.dg/cast-function-1.c
@@ -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;
}
diff --git a/gcc/testsuite/gcc.dg/invalid-call-1.c b/gcc/testsuite/gcc.dg/invalid-call-1.c
index 31f66b9..7a2f6a0 100644
--- a/gcc/testsuite/gcc.dg/invalid-call-1.c
+++ b/gcc/testsuite/gcc.dg/invalid-call-1.c
@@ -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 } */
}