Backported from trunk:

PR middle-end/100732 - ICE on sprintf %s with integer argument

gcc/ChangeLog:

	PR middle-end/100732
	* gimple-fold.c (gimple_fold_builtin_sprintf): Avoid folding calls
	with either source or destination argument of invalid type.
	* tree-ssa-uninit.c (maybe_warn_pass_by_reference): Avoid checking
	calls with arguments of invalid type.

gcc/testsuite/ChangeLog:

	PR middle-end/100732
	* gcc.dg/tree-ssa/builtin-snprintf-11.c: New test.
	* gcc.dg/tree-ssa/builtin-snprintf-12.c: New test.
	* gcc.dg/tree-ssa/builtin-sprintf-28.c: New test.
	* gcc.dg/tree-ssa/builtin-sprintf-29.c: New test.
	* gcc.dg/uninit-pr100732.c: New test.
This commit is contained in:
Martin Sebor 2021-06-17 12:08:15 -06:00
parent ca0bc92710
commit b9edb8fb82
7 changed files with 176 additions and 16 deletions

View File

@ -3318,10 +3318,6 @@ bool
gimple_fold_builtin_sprintf (gimple_stmt_iterator *gsi)
{
gimple *stmt = gsi_stmt (*gsi);
tree dest = gimple_call_arg (stmt, 0);
tree fmt = gimple_call_arg (stmt, 1);
tree orig = NULL_TREE;
const char *fmt_str = NULL;
/* Verify the required arguments in the original call. We deal with two
types of sprintf() calls: 'sprintf (str, fmt)' and
@ -3329,25 +3325,28 @@ gimple_fold_builtin_sprintf (gimple_stmt_iterator *gsi)
if (gimple_call_num_args (stmt) > 3)
return false;
tree orig = NULL_TREE;
if (gimple_call_num_args (stmt) == 3)
orig = gimple_call_arg (stmt, 2);
/* Check whether the format is a literal string constant. */
fmt_str = c_getstr (fmt);
tree fmt = gimple_call_arg (stmt, 1);
const char *fmt_str = c_getstr (fmt);
if (fmt_str == NULL)
return false;
tree dest = gimple_call_arg (stmt, 0);
if (!init_target_chars ())
return false;
tree fn = builtin_decl_implicit (BUILT_IN_STRCPY);
if (!fn)
return false;
/* If the format doesn't contain % args or %%, use strcpy. */
if (strchr (fmt_str, target_percent) == NULL)
{
tree fn = builtin_decl_implicit (BUILT_IN_STRCPY);
if (!fn)
return false;
/* Don't optimize sprintf (buf, "abc", ptr++). */
if (orig)
return false;
@ -3388,16 +3387,15 @@ gimple_fold_builtin_sprintf (gimple_stmt_iterator *gsi)
/* If the format is "%s", use strcpy if the result isn't used. */
else if (fmt_str && strcmp (fmt_str, target_percent_s) == 0)
{
tree fn;
fn = builtin_decl_implicit (BUILT_IN_STRCPY);
if (!fn)
return false;
/* Don't crash on sprintf (str1, "%s"). */
if (!orig)
return false;
/* Don't fold calls with source arguments of invalid (nonpointer)
types. */
if (!POINTER_TYPE_P (TREE_TYPE (orig)))
return false;
tree orig_len = NULL_TREE;
if (gimple_call_lhs (stmt))
{

View File

@ -0,0 +1,32 @@
/* PR middle-end/100732 - ICE on sprintf %s with integer argument
{ dg-do compile }
{ dg-options "-O2 -Wall -fdump-tree-optimized" } */
char d[32];
void gb (_Bool b)
{
__builtin_snprintf (d, 32, "%s", b); // { dg-warning "\\\[-Wformat" }
}
void gi (int i)
{
__builtin_snprintf (d, 32, "%s", i); // { dg-warning "\\\[-Wformat" }
}
void gd (char *d, double x)
{
__builtin_snprintf (d, 32, "%s", x); // { dg-warning "\\\[-Wformat" }
}
struct X { int i; };
void gx (char *d, struct X x)
{
__builtin_snprintf (d, 32, "%s", x); // { dg-warning "\\\[-Wformat" }
}
/* Also verify that the invalid sprintf call isn't folded to strcpy.
{ dg-final { scan-tree-dump-times "snprintf" 4 "optimized" } }
{ dg-final { scan-tree-dump-not "strcpy" "optimized" } } */

View File

@ -0,0 +1,36 @@
/* PR middle-end/100732 - ICE on sprintf %s with integer argument
{ dg-do compile }
{ dg-options "-O2 -Wall -fdump-tree-optimized" } */
#define snprintf(d, n, f, ...) \
__builtin___snprintf_chk (d, n, 0, 32, f, __VA_ARGS__)
int n;
void gb (char *d, _Bool b)
{
snprintf (d, n, "%s", b); // { dg-warning "\\\[-Wformat" }
}
void gi (char *d, int i)
{
snprintf (d, n, "%s", i); // { dg-warning "\\\[-Wformat" }
}
void gd (char *d, double x)
{
snprintf (d, n, "%s", x); // { dg-warning "\\\[-Wformat" }
}
struct X { int i; };
void gx (char *d, struct X x)
{
snprintf (d, n, "%s", x); // { dg-warning "\\\[-Wformat" }
}
/* Also verify that the invalid sprintf call isn't folded to strcpy.
{ dg-final { scan-tree-dump-times "snprintf_chk" 4 "optimized" } }
{ dg-final { scan-tree-dump-not "strcpy" "optimized" } } */

View File

@ -0,0 +1,30 @@
/* PR middle-end/100732 - ICE on sprintf %s with integer argument
{ dg-do compile }
{ dg-options "-O2 -Wall -fdump-tree-optimized" } */
void gb (char *d, _Bool b)
{
__builtin_sprintf (d, "%s", b); // { dg-warning "\\\[-Wformat" }
}
void gi (char *d, int i)
{
__builtin_sprintf (d, "%s", i); // { dg-warning "\\\[-Wformat" }
}
void gd (char *d, double x)
{
__builtin_sprintf (d, "%s", x); // { dg-warning "\\\[-Wformat" }
}
struct X { int i; };
void gx (char *d, struct X x)
{
__builtin_sprintf (d, "%s", x); // { dg-warning "\\\[-Wformat" }
}
/* Also verify that the invalid sprintf call isn't folded to strcpy.
{ dg-final { scan-tree-dump-times "sprintf" 4 "optimized" } }
{ dg-final { scan-tree-dump-not "strcpy" "optimized" } } */

View File

@ -0,0 +1,40 @@
/* PR middle-end/100732 - ICE on sprintf %s with integer argument
{ dg-do compile }
{ dg-options "-O2 -Wall -fdump-tree-optimized" } */
#define sprintf(d, f, ...) \
__builtin___sprintf_chk (d, 0, 32, f, __VA_ARGS__)
void fi (int i, const char *s)
{
sprintf (i, "%s", s); // { dg-warning "\\\[-Wint-conversion" }
}
void gb (char *d, _Bool b)
{
sprintf (d, "%s", b); // { dg-warning "\\\[-Wformat" }
}
void gi (char *d, int i)
{
sprintf (d, "%s", i); // { dg-warning "\\\[-Wformat" }
}
void gd (char *d, double x)
{
sprintf (d, "%s", x); // { dg-warning "\\\[-Wformat" }
}
struct X { int i; };
void gx (char *d, struct X x)
{
sprintf (d, "%s", x); // { dg-warning "\\\[-Wformat" }
}
/* Also verify that the invalid sprintf call isn't folded to strcpy.
{ dg-final { scan-tree-dump-times "sprintf_chk" 5 "optimized" } }
{ dg-final { scan-tree-dump-not "strcpy" "optimized" } } */

View File

@ -0,0 +1,21 @@
/* PR middle-end/100732 - ICE on sprintf %s with integer argument
{ dg-do compile }
{ dg-options "-O2 -Wall -fdump-tree-optimized" } */
void nowarn_s_i (char *d, int i)
{
__builtin_sprintf (d, "%s", i); // { dg-warning "\\\[-Wformat" }
}
void warn_s_i (char *d)
{
int i;
__builtin_sprintf (d, "%s", i); // { dg-warning "\\\[-Wformat" }
// { dg-warning "\\\[-Wuninitialized" "" { target *-*-* } .-1 }
}
void warn_i_i (char *d)
{
int i;
__builtin_sprintf (d, "%i", i); // { dg-warning "\\\[-Wuninitialized" }
}

View File

@ -529,6 +529,9 @@ maybe_warn_pass_by_reference (gcall *stmt, wlimits &wlims)
continue;
tree arg = gimple_call_arg (stmt, argno - 1);
if (!POINTER_TYPE_P (TREE_TYPE (arg)))
/* Avoid actual arguments with invalid types. */
continue;
ao_ref ref;
ao_ref_init_from_ptr_and_size (&ref, arg, access_size);