mirror of
git://gcc.gnu.org/git/gcc.git
synced 2025-04-10 18:20:51 +08:00
re PR c/63554 (ice in "execute_todo, at passes.c:1797" with -O3)
2014-10-16 Richard Biener <rguenther@suse.de> PR middle-end/63554 * builtins.c (fold_builtin_4): Do not call fold_builtin_strncat_chk. (fold_builtin_strncat_chk): Move ... * gimple-fold.c (gimple_fold_builtin_strncat_chk): ... here. (gimple_fold_builtin): Call gimple_fold_builtin_strncat_chk. * gcc.dg/torture/pr63554.c: New testcase. From-SVN: r216315
This commit is contained in:
parent
b7359edc20
commit
745583f953
@ -1,3 +1,11 @@
|
||||
2014-10-16 Richard Biener <rguenther@suse.de>
|
||||
|
||||
PR middle-end/63554
|
||||
* builtins.c (fold_builtin_4): Do not call fold_builtin_strncat_chk.
|
||||
(fold_builtin_strncat_chk): Move ...
|
||||
* gimple-fold.c (gimple_fold_builtin_strncat_chk): ... here.
|
||||
(gimple_fold_builtin): Call gimple_fold_builtin_strncat_chk.
|
||||
|
||||
2014-10-16 Oleg Endo <olegendo@gcc.gnu.org>
|
||||
|
||||
PR target/59401
|
||||
|
@ -198,7 +198,6 @@ static void maybe_emit_chk_warning (tree, enum built_in_function);
|
||||
static void maybe_emit_sprintf_chk_warning (tree, enum built_in_function);
|
||||
static void maybe_emit_free_warning (tree);
|
||||
static tree fold_builtin_object_size (tree, tree);
|
||||
static tree fold_builtin_strncat_chk (location_t, tree, tree, tree, tree, tree);
|
||||
static tree fold_builtin_printf (location_t, tree, tree, tree, bool, enum built_in_function);
|
||||
static tree fold_builtin_fprintf (location_t, tree, tree, tree, tree, bool,
|
||||
enum built_in_function);
|
||||
@ -10366,9 +10365,6 @@ fold_builtin_4 (location_t loc, tree fndecl,
|
||||
|
||||
switch (fcode)
|
||||
{
|
||||
case BUILT_IN_STRNCAT_CHK:
|
||||
return fold_builtin_strncat_chk (loc, fndecl, arg0, arg1, arg2, arg3);
|
||||
|
||||
case BUILT_IN_FPRINTF_CHK:
|
||||
case BUILT_IN_VFPRINTF_CHK:
|
||||
if (!validate_arg (arg1, INTEGER_TYPE)
|
||||
@ -11584,58 +11580,6 @@ fold_builtin_object_size (tree ptr, tree ost)
|
||||
return NULL_TREE;
|
||||
}
|
||||
|
||||
/* Fold a call to the __strncat_chk builtin with arguments DEST, SRC,
|
||||
LEN, and SIZE. */
|
||||
|
||||
static tree
|
||||
fold_builtin_strncat_chk (location_t loc, tree fndecl,
|
||||
tree dest, tree src, tree len, tree size)
|
||||
{
|
||||
tree fn;
|
||||
const char *p;
|
||||
|
||||
if (!validate_arg (dest, POINTER_TYPE)
|
||||
|| !validate_arg (src, POINTER_TYPE)
|
||||
|| !validate_arg (size, INTEGER_TYPE)
|
||||
|| !validate_arg (size, INTEGER_TYPE))
|
||||
return NULL_TREE;
|
||||
|
||||
p = c_getstr (src);
|
||||
/* If the SRC parameter is "" or if LEN is 0, return DEST. */
|
||||
if (p && *p == '\0')
|
||||
return omit_one_operand_loc (loc, TREE_TYPE (TREE_TYPE (fndecl)), dest, len);
|
||||
else if (integer_zerop (len))
|
||||
return omit_one_operand_loc (loc, TREE_TYPE (TREE_TYPE (fndecl)), dest, src);
|
||||
|
||||
if (! tree_fits_uhwi_p (size))
|
||||
return NULL_TREE;
|
||||
|
||||
if (! integer_all_onesp (size))
|
||||
{
|
||||
tree src_len = c_strlen (src, 1);
|
||||
if (src_len
|
||||
&& tree_fits_uhwi_p (src_len)
|
||||
&& tree_fits_uhwi_p (len)
|
||||
&& ! tree_int_cst_lt (len, src_len))
|
||||
{
|
||||
/* If LEN >= strlen (SRC), optimize into __strcat_chk. */
|
||||
fn = builtin_decl_explicit (BUILT_IN_STRCAT_CHK);
|
||||
if (!fn)
|
||||
return NULL_TREE;
|
||||
|
||||
return build_call_expr_loc (loc, fn, 3, dest, src, size);
|
||||
}
|
||||
return NULL_TREE;
|
||||
}
|
||||
|
||||
/* If __builtin_strncat_chk is used, assume strncat is available. */
|
||||
fn = builtin_decl_explicit (BUILT_IN_STRNCAT);
|
||||
if (!fn)
|
||||
return NULL_TREE;
|
||||
|
||||
return build_call_expr_loc (loc, fn, 3, dest, src, len);
|
||||
}
|
||||
|
||||
/* Builtins with folding operations that operate on "..." arguments
|
||||
need special handling; we need to store the arguments in a convenient
|
||||
data structure before attempting any folding. Fortunately there are
|
||||
|
@ -1632,6 +1632,62 @@ gimple_fold_builtin_strcat_chk (gimple_stmt_iterator *gsi)
|
||||
return true;
|
||||
}
|
||||
|
||||
/* Fold a call to the __strncat_chk builtin with arguments DEST, SRC,
|
||||
LEN, and SIZE. */
|
||||
|
||||
static bool
|
||||
gimple_fold_builtin_strncat_chk (gimple_stmt_iterator *gsi)
|
||||
{
|
||||
gimple stmt = gsi_stmt (*gsi);
|
||||
tree dest = gimple_call_arg (stmt, 0);
|
||||
tree src = gimple_call_arg (stmt, 1);
|
||||
tree len = gimple_call_arg (stmt, 2);
|
||||
tree size = gimple_call_arg (stmt, 3);
|
||||
tree fn;
|
||||
const char *p;
|
||||
|
||||
p = c_getstr (src);
|
||||
/* If the SRC parameter is "" or if LEN is 0, return DEST. */
|
||||
if ((p && *p == '\0')
|
||||
|| integer_zerop (len))
|
||||
{
|
||||
replace_call_with_value (gsi, dest);
|
||||
return true;
|
||||
}
|
||||
|
||||
if (! tree_fits_uhwi_p (size))
|
||||
return false;
|
||||
|
||||
if (! integer_all_onesp (size))
|
||||
{
|
||||
tree src_len = c_strlen (src, 1);
|
||||
if (src_len
|
||||
&& tree_fits_uhwi_p (src_len)
|
||||
&& tree_fits_uhwi_p (len)
|
||||
&& ! tree_int_cst_lt (len, src_len))
|
||||
{
|
||||
/* If LEN >= strlen (SRC), optimize into __strcat_chk. */
|
||||
fn = builtin_decl_explicit (BUILT_IN_STRCAT_CHK);
|
||||
if (!fn)
|
||||
return false;
|
||||
|
||||
gimple repl = gimple_build_call (fn, 3, dest, src, size);
|
||||
replace_call_with_call_and_fold (gsi, repl);
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/* If __builtin_strncat_chk is used, assume strncat is available. */
|
||||
fn = builtin_decl_explicit (BUILT_IN_STRNCAT);
|
||||
if (!fn)
|
||||
return false;
|
||||
|
||||
gimple repl = gimple_build_call (fn, 3, dest, src, len);
|
||||
replace_call_with_call_and_fold (gsi, repl);
|
||||
return true;
|
||||
}
|
||||
|
||||
/* Fold a call to the fputs builtin. ARG0 and ARG1 are the arguments
|
||||
to the call. IGNORE is true if the value returned
|
||||
by the builtin will be ignored. UNLOCKED is true is true if this
|
||||
@ -2457,6 +2513,8 @@ gimple_fold_builtin (gimple_stmt_iterator *gsi)
|
||||
return gimple_fold_builtin_sprintf_chk (gsi, DECL_FUNCTION_CODE (callee));
|
||||
case BUILT_IN_STRCAT_CHK:
|
||||
return gimple_fold_builtin_strcat_chk (gsi);
|
||||
case BUILT_IN_STRNCAT_CHK:
|
||||
return gimple_fold_builtin_strncat_chk (gsi);
|
||||
case BUILT_IN_STRLEN:
|
||||
return gimple_fold_builtin_strlen (gsi);
|
||||
case BUILT_IN_STRCPY:
|
||||
|
@ -1,3 +1,8 @@
|
||||
2014-10-16 Richard Biener <rguenther@suse.de>
|
||||
|
||||
PR middle-end/63554
|
||||
* gcc.dg/torture/pr63554.c: New testcase.
|
||||
|
||||
2014-10-16 Marek Polacek <polacek@redhat.com>
|
||||
|
||||
* gcc.target/powerpc/pr58673-1.c: Fix defaulting to int.
|
||||
|
9
gcc/testsuite/gcc.dg/torture/pr63554.c
Normal file
9
gcc/testsuite/gcc.dg/torture/pr63554.c
Normal file
@ -0,0 +1,9 @@
|
||||
/* { dg-do compile } */
|
||||
|
||||
char *a;
|
||||
void
|
||||
nssutil_ReadSecmodDB (void)
|
||||
{
|
||||
long b = __builtin_object_size (0, 0);
|
||||
a = __builtin___strncat_chk (a, " ", 1, b);
|
||||
}
|
Loading…
x
Reference in New Issue
Block a user