re PR c/12085 (Internal compiler error in convert_move, at expr.c:504 with -O3 flag)
PR c/12085 * c-typeck.c (build_function_call): Issue a warning if a function is called through an incompatible prototype and replace the call by a trap in this case. From-SVN: r74874
This commit is contained in:
parent
bcd11e5e45
commit
c96f4f736a
|
@ -1,3 +1,10 @@
|
|||
2003-12-20 Eric Botcazou <ebotcazou@libertysurf.fr>
|
||||
|
||||
PR c/12085
|
||||
* c-typeck.c (build_function_call): Issue a warning if a
|
||||
function is called through an incompatible prototype and
|
||||
replace the call by a trap in this case.
|
||||
|
||||
2003-12-19 James E Wilson <wilson@specifixinc.com>
|
||||
|
||||
* install.texi (ia64-*-linux): Document minimum libunwind version
|
||||
|
|
|
@ -1645,6 +1645,7 @@ build_function_call (tree function, tree params)
|
|||
tree fntype, fundecl = 0;
|
||||
tree coerced_params;
|
||||
tree name = NULL_TREE, result;
|
||||
tree tem;
|
||||
|
||||
/* Strip NON_LVALUE_EXPRs, etc., since we aren't using as an lvalue. */
|
||||
STRIP_TYPE_NOPS (function);
|
||||
|
@ -1684,6 +1685,47 @@ build_function_call (tree function, tree params)
|
|||
/* fntype now gets the type of function pointed to. */
|
||||
fntype = TREE_TYPE (fntype);
|
||||
|
||||
/* 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.
|
||||
|
||||
??? This doesn't work for Objective-C because objc_comptypes
|
||||
refuses to compare function prototypes, yet the compiler appears
|
||||
to build calls that are flagged as invalid by C's comptypes. */
|
||||
if (! c_dialect_objc ()
|
||||
&& TREE_CODE (function) == NOP_EXPR
|
||||
&& TREE_CODE (tem = TREE_OPERAND (function, 0)) == ADDR_EXPR
|
||||
&& TREE_CODE (tem = TREE_OPERAND (tem, 0)) == FUNCTION_DECL
|
||||
&& ! comptypes (fntype, TREE_TYPE (tem), COMPARE_STRICT))
|
||||
{
|
||||
tree return_type = TREE_TYPE (fntype);
|
||||
tree trap = build_function_call (built_in_decls[BUILT_IN_TRAP],
|
||||
NULL_TREE);
|
||||
|
||||
/* 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. */
|
||||
warning ("function called through a non-compatible type");
|
||||
|
||||
if (VOID_TYPE_P (return_type))
|
||||
return trap;
|
||||
else
|
||||
{
|
||||
tree rhs;
|
||||
|
||||
if (AGGREGATE_TYPE_P (return_type))
|
||||
rhs = build_compound_literal (return_type,
|
||||
build_constructor (return_type,
|
||||
NULL_TREE));
|
||||
else
|
||||
rhs = fold (build1 (NOP_EXPR, return_type, integer_zero_node));
|
||||
|
||||
return build (COMPOUND_EXPR, return_type, trap, rhs);
|
||||
}
|
||||
}
|
||||
|
||||
/* Convert the parameters to the types declared in the
|
||||
function prototype, or apply default promotions. */
|
||||
|
||||
|
|
|
@ -1,3 +1,7 @@
|
|||
2003-12-20 Eric Botcazou <ebotcazou@libertysurf.fr>
|
||||
|
||||
* gcc.dg/cast-function-1.c: New test.
|
||||
|
||||
2003-12-19 Joseph S. Myers <jsm@polyomino.org.uk>
|
||||
|
||||
* gcc.dg/format/ext-1.c: Allow 'I' flag on floating point decimal
|
||||
|
|
|
@ -0,0 +1,49 @@
|
|||
/* PR c/12085 */
|
||||
/* Origin: David Hollenberg <dhollen@mosis.org> */
|
||||
|
||||
/* Verify that the compiler doesn't inline a function at
|
||||
a calling point where it is viewed with a different
|
||||
prototype than the actual one. */
|
||||
|
||||
/* { dg-do compile } */
|
||||
/* { dg-options "-O3" } */
|
||||
|
||||
int foo1(int);
|
||||
int foo2();
|
||||
|
||||
typedef struct {
|
||||
double d;
|
||||
int a;
|
||||
} str_t;
|
||||
|
||||
void bar(void)
|
||||
{
|
||||
double d;
|
||||
int i;
|
||||
str_t s;
|
||||
|
||||
d = ((double (*) (int)) foo1) (i); /* { dg-warning "non-compatible" } */
|
||||
i = ((int (*) (double)) foo1) (d); /* { dg-warning "non-compatible" } */
|
||||
s = ((str_t (*) (int)) foo1) (i); /* { dg-warning "non-compatible" } */
|
||||
((void (*) (int)) foo1) (d); /* { dg-warning "non-compatible" } */
|
||||
i = ((int (*) (int)) foo1) (i); /* { dg-bogus "non-compatible" } */
|
||||
(void) foo1 (i); /* { dg-bogus "non-compatible" } */
|
||||
|
||||
d = ((double (*) (int)) foo2) (i); /* { dg-warning "non-compatible" } */
|
||||
i = ((int (*) (double)) foo2) (d); /* { dg-bogus "non-compatible" } */
|
||||
s = ((str_t (*) (int)) foo2) (i); /* { dg-warning "non-compatible" } */
|
||||
((void (*) (int)) foo2) (d); /* { dg-warning "non-compatible" } */
|
||||
i = ((int (*) (int)) foo2) (i); /* { dg-bogus "non-compatible" } */
|
||||
(void) foo2 (i); /* { dg-bogus "non-compatible" } */
|
||||
}
|
||||
|
||||
int foo1(int arg)
|
||||
{
|
||||
return arg;
|
||||
}
|
||||
|
||||
int foo2(arg)
|
||||
int arg;
|
||||
{
|
||||
return arg;
|
||||
}
|
Loading…
Reference in New Issue