re PR middle-end/59630 (ICE converting the return type of a builtin function)
2014-01-08 Richard Biener <rguenther@suse.de> PR middle-end/59630 * gimple.h (is_gimple_builtin_call): Remove. (gimple_builtin_call_types_compatible_p): New. (gimple_call_builtin_p): New overload. * gimple.c (is_gimple_builtin_call): Remove. (validate_call): Rename to ... (gimple_builtin_call_types_compatible_p): ... this and export. Also check return types. (validate_type): New static function. (gimple_call_builtin_p): New overload and adjust. * gimple-fold.c (gimple_fold_builtin): Fold the return value. (gimple_fold_call): Likewise. Use gimple_call_builtin_p. (gimple_fold_stmt_to_constant_1): Likewise. * tsan.c (instrument_gimple): Use gimple_call_builtin_p. * gcc.dg/pr59630.c: New testcase. From-SVN: r206421
This commit is contained in:
parent
0bd34ae421
commit
5c944c6cb8
@ -1,3 +1,20 @@
|
|||||||
|
2014-01-08 Richard Biener <rguenther@suse.de>
|
||||||
|
|
||||||
|
PR middle-end/59630
|
||||||
|
* gimple.h (is_gimple_builtin_call): Remove.
|
||||||
|
(gimple_builtin_call_types_compatible_p): New.
|
||||||
|
(gimple_call_builtin_p): New overload.
|
||||||
|
* gimple.c (is_gimple_builtin_call): Remove.
|
||||||
|
(validate_call): Rename to ...
|
||||||
|
(gimple_builtin_call_types_compatible_p): ... this and export. Also
|
||||||
|
check return types.
|
||||||
|
(validate_type): New static function.
|
||||||
|
(gimple_call_builtin_p): New overload and adjust.
|
||||||
|
* gimple-fold.c (gimple_fold_builtin): Fold the return value.
|
||||||
|
(gimple_fold_call): Likewise. Use gimple_call_builtin_p.
|
||||||
|
(gimple_fold_stmt_to_constant_1): Likewise.
|
||||||
|
* tsan.c (instrument_gimple): Use gimple_call_builtin_p.
|
||||||
|
|
||||||
2014-01-08 Richard Biener <rguenther@suse.de>
|
2014-01-08 Richard Biener <rguenther@suse.de>
|
||||||
|
|
||||||
PR middle-end/59471
|
PR middle-end/59471
|
||||||
|
@ -879,8 +879,6 @@ gimple_fold_builtin (gimple stmt)
|
|||||||
int nargs;
|
int nargs;
|
||||||
location_t loc = gimple_location (stmt);
|
location_t loc = gimple_location (stmt);
|
||||||
|
|
||||||
gcc_assert (is_gimple_call (stmt));
|
|
||||||
|
|
||||||
ignore = (gimple_call_lhs (stmt) == NULL);
|
ignore = (gimple_call_lhs (stmt) == NULL);
|
||||||
|
|
||||||
/* First try the generic builtin folder. If that succeeds, return the
|
/* First try the generic builtin folder. If that succeeds, return the
|
||||||
@ -890,6 +888,8 @@ gimple_fold_builtin (gimple stmt)
|
|||||||
{
|
{
|
||||||
if (ignore)
|
if (ignore)
|
||||||
STRIP_NOPS (result);
|
STRIP_NOPS (result);
|
||||||
|
else
|
||||||
|
result = fold_convert (gimple_call_return_type (stmt), result);
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1206,8 +1206,7 @@ gimple_fold_call (gimple_stmt_iterator *gsi, bool inplace)
|
|||||||
|
|
||||||
/* Check for builtins that CCP can handle using information not
|
/* Check for builtins that CCP can handle using information not
|
||||||
available in the generic fold routines. */
|
available in the generic fold routines. */
|
||||||
callee = gimple_call_fndecl (stmt);
|
if (gimple_call_builtin_p (stmt))
|
||||||
if (callee && DECL_BUILT_IN (callee))
|
|
||||||
{
|
{
|
||||||
tree result = gimple_fold_builtin (stmt);
|
tree result = gimple_fold_builtin (stmt);
|
||||||
if (result)
|
if (result)
|
||||||
@ -1216,7 +1215,7 @@ gimple_fold_call (gimple_stmt_iterator *gsi, bool inplace)
|
|||||||
gimplify_and_update_call_from_tree (gsi, result);
|
gimplify_and_update_call_from_tree (gsi, result);
|
||||||
changed = true;
|
changed = true;
|
||||||
}
|
}
|
||||||
else if (DECL_BUILT_IN_CLASS (callee) == BUILT_IN_MD)
|
else if (gimple_call_builtin_p (stmt, BUILT_IN_MD))
|
||||||
changed |= targetm.gimple_fold_builtin (gsi);
|
changed |= targetm.gimple_fold_builtin (gsi);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -2726,7 +2725,9 @@ gimple_fold_stmt_to_constant_1 (gimple stmt, tree (*valueize) (tree))
|
|||||||
fn = (*valueize) (gimple_call_fn (stmt));
|
fn = (*valueize) (gimple_call_fn (stmt));
|
||||||
if (TREE_CODE (fn) == ADDR_EXPR
|
if (TREE_CODE (fn) == ADDR_EXPR
|
||||||
&& TREE_CODE (TREE_OPERAND (fn, 0)) == FUNCTION_DECL
|
&& TREE_CODE (TREE_OPERAND (fn, 0)) == FUNCTION_DECL
|
||||||
&& DECL_BUILT_IN (TREE_OPERAND (fn, 0)))
|
&& DECL_BUILT_IN (TREE_OPERAND (fn, 0))
|
||||||
|
&& gimple_builtin_call_types_compatible_p (stmt,
|
||||||
|
TREE_OPERAND (fn, 0)))
|
||||||
{
|
{
|
||||||
tree *args = XALLOCAVEC (tree, gimple_call_num_args (stmt));
|
tree *args = XALLOCAVEC (tree, gimple_call_num_args (stmt));
|
||||||
tree call, retval;
|
tree call, retval;
|
||||||
@ -2738,8 +2739,11 @@ gimple_fold_stmt_to_constant_1 (gimple stmt, tree (*valueize) (tree))
|
|||||||
fn, gimple_call_num_args (stmt), args);
|
fn, gimple_call_num_args (stmt), args);
|
||||||
retval = fold_call_expr (EXPR_LOCATION (call), call, false);
|
retval = fold_call_expr (EXPR_LOCATION (call), call, false);
|
||||||
if (retval)
|
if (retval)
|
||||||
/* fold_call_expr wraps the result inside a NOP_EXPR. */
|
{
|
||||||
STRIP_NOPS (retval);
|
/* fold_call_expr wraps the result inside a NOP_EXPR. */
|
||||||
|
STRIP_NOPS (retval);
|
||||||
|
retval = fold_convert (gimple_call_return_type (stmt), retval);
|
||||||
|
}
|
||||||
return retval;
|
return retval;
|
||||||
}
|
}
|
||||||
return NULL_TREE;
|
return NULL_TREE;
|
||||||
|
72
gcc/gimple.c
72
gcc/gimple.c
@ -2351,27 +2351,37 @@ gimple_ior_addresses_taken (bitmap addresses_taken, gimple stmt)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/* Return TRUE iff stmt is a call to a built-in function. */
|
/* Return true if TYPE1 and TYPE2 are compatible enough for builtin
|
||||||
|
processing. */
|
||||||
bool
|
|
||||||
is_gimple_builtin_call (gimple stmt)
|
|
||||||
{
|
|
||||||
tree callee;
|
|
||||||
|
|
||||||
if (is_gimple_call (stmt)
|
|
||||||
&& (callee = gimple_call_fndecl (stmt))
|
|
||||||
&& is_builtin_fn (callee)
|
|
||||||
&& DECL_BUILT_IN_CLASS (callee) == BUILT_IN_NORMAL)
|
|
||||||
return true;
|
|
||||||
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Return true when STMTs arguments match those of FNDECL. */
|
|
||||||
|
|
||||||
static bool
|
static bool
|
||||||
validate_call (gimple stmt, tree fndecl)
|
validate_type (tree type1, tree type2)
|
||||||
{
|
{
|
||||||
|
if (INTEGRAL_TYPE_P (type1)
|
||||||
|
&& INTEGRAL_TYPE_P (type2))
|
||||||
|
;
|
||||||
|
else if (POINTER_TYPE_P (type1)
|
||||||
|
&& POINTER_TYPE_P (type2))
|
||||||
|
;
|
||||||
|
else if (TREE_CODE (type1)
|
||||||
|
!= TREE_CODE (type2))
|
||||||
|
return false;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Return true when STMTs arguments and return value match those of FNDECL,
|
||||||
|
a decl of a builtin function. */
|
||||||
|
|
||||||
|
bool
|
||||||
|
gimple_builtin_call_types_compatible_p (gimple stmt, tree fndecl)
|
||||||
|
{
|
||||||
|
gcc_checking_assert (DECL_BUILT_IN_CLASS (fndecl) != NOT_BUILT_IN);
|
||||||
|
|
||||||
|
tree ret = gimple_call_lhs (stmt);
|
||||||
|
if (ret
|
||||||
|
&& !validate_type (TREE_TYPE (ret), TREE_TYPE (TREE_TYPE (fndecl))))
|
||||||
|
return false;
|
||||||
|
|
||||||
tree targs = TYPE_ARG_TYPES (TREE_TYPE (fndecl));
|
tree targs = TYPE_ARG_TYPES (TREE_TYPE (fndecl));
|
||||||
unsigned nargs = gimple_call_num_args (stmt);
|
unsigned nargs = gimple_call_num_args (stmt);
|
||||||
for (unsigned i = 0; i < nargs; ++i)
|
for (unsigned i = 0; i < nargs; ++i)
|
||||||
@ -2380,14 +2390,7 @@ validate_call (gimple stmt, tree fndecl)
|
|||||||
if (!targs)
|
if (!targs)
|
||||||
return true;
|
return true;
|
||||||
tree arg = gimple_call_arg (stmt, i);
|
tree arg = gimple_call_arg (stmt, i);
|
||||||
if (INTEGRAL_TYPE_P (TREE_TYPE (arg))
|
if (!validate_type (TREE_TYPE (arg), TREE_VALUE (targs)))
|
||||||
&& INTEGRAL_TYPE_P (TREE_VALUE (targs)))
|
|
||||||
;
|
|
||||||
else if (POINTER_TYPE_P (TREE_TYPE (arg))
|
|
||||||
&& POINTER_TYPE_P (TREE_VALUE (targs)))
|
|
||||||
;
|
|
||||||
else if (TREE_CODE (TREE_TYPE (arg))
|
|
||||||
!= TREE_CODE (TREE_VALUE (targs)))
|
|
||||||
return false;
|
return false;
|
||||||
targs = TREE_CHAIN (targs);
|
targs = TREE_CHAIN (targs);
|
||||||
}
|
}
|
||||||
@ -2396,6 +2399,19 @@ validate_call (gimple stmt, tree fndecl)
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Return true when STMT is builtins call. */
|
||||||
|
|
||||||
|
bool
|
||||||
|
gimple_call_builtin_p (gimple stmt)
|
||||||
|
{
|
||||||
|
tree fndecl;
|
||||||
|
if (is_gimple_call (stmt)
|
||||||
|
&& (fndecl = gimple_call_fndecl (stmt)) != NULL_TREE
|
||||||
|
&& DECL_BUILT_IN_CLASS (fndecl) != NOT_BUILT_IN)
|
||||||
|
return gimple_builtin_call_types_compatible_p (stmt, fndecl);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
/* Return true when STMT is builtins call to CLASS. */
|
/* Return true when STMT is builtins call to CLASS. */
|
||||||
|
|
||||||
bool
|
bool
|
||||||
@ -2405,7 +2421,7 @@ gimple_call_builtin_p (gimple stmt, enum built_in_class klass)
|
|||||||
if (is_gimple_call (stmt)
|
if (is_gimple_call (stmt)
|
||||||
&& (fndecl = gimple_call_fndecl (stmt)) != NULL_TREE
|
&& (fndecl = gimple_call_fndecl (stmt)) != NULL_TREE
|
||||||
&& DECL_BUILT_IN_CLASS (fndecl) == klass)
|
&& DECL_BUILT_IN_CLASS (fndecl) == klass)
|
||||||
return validate_call (stmt, fndecl);
|
return gimple_builtin_call_types_compatible_p (stmt, fndecl);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -2419,7 +2435,7 @@ gimple_call_builtin_p (gimple stmt, enum built_in_function code)
|
|||||||
&& (fndecl = gimple_call_fndecl (stmt)) != NULL_TREE
|
&& (fndecl = gimple_call_fndecl (stmt)) != NULL_TREE
|
||||||
&& DECL_BUILT_IN_CLASS (fndecl) == BUILT_IN_NORMAL
|
&& DECL_BUILT_IN_CLASS (fndecl) == BUILT_IN_NORMAL
|
||||||
&& DECL_FUNCTION_CODE (fndecl) == code)
|
&& DECL_FUNCTION_CODE (fndecl) == code)
|
||||||
return validate_call (stmt, fndecl);
|
return gimple_builtin_call_types_compatible_p (stmt, fndecl);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1253,7 +1253,8 @@ extern tree gimple_unsigned_type (tree);
|
|||||||
extern tree gimple_signed_type (tree);
|
extern tree gimple_signed_type (tree);
|
||||||
extern alias_set_type gimple_get_alias_set (tree);
|
extern alias_set_type gimple_get_alias_set (tree);
|
||||||
extern bool gimple_ior_addresses_taken (bitmap, gimple);
|
extern bool gimple_ior_addresses_taken (bitmap, gimple);
|
||||||
extern bool is_gimple_builtin_call (gimple stmt);
|
extern bool gimple_builtin_call_types_compatible_p (gimple, tree);
|
||||||
|
extern bool gimple_call_builtin_p (gimple);
|
||||||
extern bool gimple_call_builtin_p (gimple, enum built_in_class);
|
extern bool gimple_call_builtin_p (gimple, enum built_in_class);
|
||||||
extern bool gimple_call_builtin_p (gimple, enum built_in_function);
|
extern bool gimple_call_builtin_p (gimple, enum built_in_function);
|
||||||
extern bool gimple_asm_clobbers_memory_p (const_gimple);
|
extern bool gimple_asm_clobbers_memory_p (const_gimple);
|
||||||
|
@ -1,3 +1,8 @@
|
|||||||
|
2014-01-08 Richard Biener <rguenther@suse.de>
|
||||||
|
|
||||||
|
PR middle-end/59630
|
||||||
|
* gcc.dg/pr59630.c: New testcase.
|
||||||
|
|
||||||
2014-01-08 Richard Biener <rguenther@suse.de>
|
2014-01-08 Richard Biener <rguenther@suse.de>
|
||||||
|
|
||||||
PR middle-end/59471
|
PR middle-end/59471
|
||||||
|
8
gcc/testsuite/gcc.dg/pr59630.c
Normal file
8
gcc/testsuite/gcc.dg/pr59630.c
Normal file
@ -0,0 +1,8 @@
|
|||||||
|
/* { dg-do compile } */
|
||||||
|
/* { dg-options "-O" } */
|
||||||
|
|
||||||
|
_Bool foo()
|
||||||
|
{
|
||||||
|
_Bool (*f)(int) = __builtin_abs; /* { dg-warning "" } */
|
||||||
|
return f(0);
|
||||||
|
}
|
@ -609,7 +609,7 @@ instrument_gimple (gimple_stmt_iterator *gsi)
|
|||||||
&& (gimple_call_fndecl (stmt)
|
&& (gimple_call_fndecl (stmt)
|
||||||
!= builtin_decl_implicit (BUILT_IN_TSAN_INIT)))
|
!= builtin_decl_implicit (BUILT_IN_TSAN_INIT)))
|
||||||
{
|
{
|
||||||
if (is_gimple_builtin_call (stmt))
|
if (gimple_call_builtin_p (stmt, BUILT_IN_NORMAL))
|
||||||
instrument_builtin_call (gsi);
|
instrument_builtin_call (gsi);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user