diff --git a/gcc/c/ChangeLog b/gcc/c/ChangeLog index 228a93be42d..c6ca4b41a33 100644 --- a/gcc/c/ChangeLog +++ b/gcc/c/ChangeLog @@ -1,3 +1,9 @@ +2014-01-30 Richard Biener + + 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 * c-parser.c (c_parser_declaration_or_fndef): Replaced diff --git a/gcc/c/c-typeck.c b/gcc/c/c-typeck.c index 8477dd43fbf..59bd6df21df 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); + warning_at (loc, 0, "function called through a non-compatible type"); - 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); - - 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 62bcc3131ca..77953e9b395 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,11 @@ +2014-01-30 Richard Biener + + 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 PR c++/58561 diff --git a/gcc/testsuite/gcc.dg/call-diag-2.c b/gcc/testsuite/gcc.dg/call-diag-2.c index 0d87e52e973..c34252cd729 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 781d0e22191..5eb412595fc 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 31f66b92668..7a2f6a07bb3 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 } */ }