Skip to content

Commit 9816f50

Browse files
author
Martin Sebor
committed
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.
1 parent c6503fa commit 9816f50

File tree

7 files changed

+176
-16
lines changed

7 files changed

+176
-16
lines changed

gcc/gimple-fold.c

Lines changed: 14 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -3514,36 +3514,35 @@ bool
35143514
gimple_fold_builtin_sprintf (gimple_stmt_iterator *gsi)
35153515
{
35163516
gimple *stmt = gsi_stmt (*gsi);
3517-
tree dest = gimple_call_arg (stmt, 0);
3518-
tree fmt = gimple_call_arg (stmt, 1);
3519-
tree orig = NULL_TREE;
3520-
const char *fmt_str = NULL;
35213517

35223518
/* Verify the required arguments in the original call. We deal with two
35233519
types of sprintf() calls: 'sprintf (str, fmt)' and
35243520
'sprintf (dest, "%s", orig)'. */
35253521
if (gimple_call_num_args (stmt) > 3)
35263522
return false;
35273523

3524+
tree orig = NULL_TREE;
35283525
if (gimple_call_num_args (stmt) == 3)
35293526
orig = gimple_call_arg (stmt, 2);
35303527

35313528
/* Check whether the format is a literal string constant. */
3532-
fmt_str = c_getstr (fmt);
3529+
tree fmt = gimple_call_arg (stmt, 1);
3530+
const char *fmt_str = c_getstr (fmt);
35333531
if (fmt_str == NULL)
35343532
return false;
35353533

3534+
tree dest = gimple_call_arg (stmt, 0);
3535+
35363536
if (!init_target_chars ())
35373537
return false;
35383538

3539+
tree fn = builtin_decl_implicit (BUILT_IN_STRCPY);
3540+
if (!fn)
3541+
return false;
3542+
35393543
/* If the format doesn't contain % args or %%, use strcpy. */
35403544
if (strchr (fmt_str, target_percent) == NULL)
35413545
{
3542-
tree fn = builtin_decl_implicit (BUILT_IN_STRCPY);
3543-
3544-
if (!fn)
3545-
return false;
3546-
35473546
/* Don't optimize sprintf (buf, "abc", ptr++). */
35483547
if (orig)
35493548
return false;
@@ -3584,16 +3583,15 @@ gimple_fold_builtin_sprintf (gimple_stmt_iterator *gsi)
35843583
/* If the format is "%s", use strcpy if the result isn't used. */
35853584
else if (fmt_str && strcmp (fmt_str, target_percent_s) == 0)
35863585
{
3587-
tree fn;
3588-
fn = builtin_decl_implicit (BUILT_IN_STRCPY);
3589-
3590-
if (!fn)
3591-
return false;
3592-
35933586
/* Don't crash on sprintf (str1, "%s"). */
35943587
if (!orig)
35953588
return false;
35963589

3590+
/* Don't fold calls with source arguments of invalid (nonpointer)
3591+
types. */
3592+
if (!POINTER_TYPE_P (TREE_TYPE (orig)))
3593+
return false;
3594+
35973595
tree orig_len = NULL_TREE;
35983596
if (gimple_call_lhs (stmt))
35993597
{
Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
/* PR middle-end/100732 - ICE on sprintf %s with integer argument
2+
{ dg-do compile }
3+
{ dg-options "-O2 -Wall -fdump-tree-optimized" } */
4+
5+
char d[32];
6+
7+
void gb (_Bool b)
8+
{
9+
__builtin_snprintf (d, 32, "%s", b); // { dg-warning "\\\[-Wformat" }
10+
}
11+
12+
void gi (int i)
13+
{
14+
__builtin_snprintf (d, 32, "%s", i); // { dg-warning "\\\[-Wformat" }
15+
}
16+
17+
void gd (char *d, double x)
18+
{
19+
__builtin_snprintf (d, 32, "%s", x); // { dg-warning "\\\[-Wformat" }
20+
}
21+
22+
23+
struct X { int i; };
24+
25+
void gx (char *d, struct X x)
26+
{
27+
__builtin_snprintf (d, 32, "%s", x); // { dg-warning "\\\[-Wformat" }
28+
}
29+
30+
/* Also verify that the invalid sprintf call isn't folded to strcpy.
31+
{ dg-final { scan-tree-dump-times "snprintf" 4 "optimized" } }
32+
{ dg-final { scan-tree-dump-not "strcpy" "optimized" } } */
Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
/* PR middle-end/100732 - ICE on sprintf %s with integer argument
2+
{ dg-do compile }
3+
{ dg-options "-O2 -Wall -fdump-tree-optimized" } */
4+
5+
#define snprintf(d, n, f, ...) \
6+
__builtin___snprintf_chk (d, n, 0, 32, f, __VA_ARGS__)
7+
8+
int n;
9+
10+
void gb (char *d, _Bool b)
11+
{
12+
snprintf (d, n, "%s", b); // { dg-warning "\\\[-Wformat" }
13+
}
14+
15+
void gi (char *d, int i)
16+
{
17+
snprintf (d, n, "%s", i); // { dg-warning "\\\[-Wformat" }
18+
}
19+
20+
void gd (char *d, double x)
21+
{
22+
snprintf (d, n, "%s", x); // { dg-warning "\\\[-Wformat" }
23+
}
24+
25+
26+
struct X { int i; };
27+
28+
void gx (char *d, struct X x)
29+
{
30+
snprintf (d, n, "%s", x); // { dg-warning "\\\[-Wformat" }
31+
}
32+
33+
34+
/* Also verify that the invalid sprintf call isn't folded to strcpy.
35+
{ dg-final { scan-tree-dump-times "snprintf_chk" 4 "optimized" } }
36+
{ dg-final { scan-tree-dump-not "strcpy" "optimized" } } */
Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
/* PR middle-end/100732 - ICE on sprintf %s with integer argument
2+
{ dg-do compile }
3+
{ dg-options "-O2 -Wall -fdump-tree-optimized" } */
4+
5+
void gb (char *d, _Bool b)
6+
{
7+
__builtin_sprintf (d, "%s", b); // { dg-warning "\\\[-Wformat" }
8+
}
9+
10+
void gi (char *d, int i)
11+
{
12+
__builtin_sprintf (d, "%s", i); // { dg-warning "\\\[-Wformat" }
13+
}
14+
15+
void gd (char *d, double x)
16+
{
17+
__builtin_sprintf (d, "%s", x); // { dg-warning "\\\[-Wformat" }
18+
}
19+
20+
21+
struct X { int i; };
22+
23+
void gx (char *d, struct X x)
24+
{
25+
__builtin_sprintf (d, "%s", x); // { dg-warning "\\\[-Wformat" }
26+
}
27+
28+
/* Also verify that the invalid sprintf call isn't folded to strcpy.
29+
{ dg-final { scan-tree-dump-times "sprintf" 4 "optimized" } }
30+
{ dg-final { scan-tree-dump-not "strcpy" "optimized" } } */
Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,40 @@
1+
/* PR middle-end/100732 - ICE on sprintf %s with integer argument
2+
{ dg-do compile }
3+
{ dg-options "-O2 -Wall -fdump-tree-optimized" } */
4+
5+
#define sprintf(d, f, ...) \
6+
__builtin___sprintf_chk (d, 0, 32, f, __VA_ARGS__)
7+
8+
9+
void fi (int i, const char *s)
10+
{
11+
sprintf (i, "%s", s); // { dg-warning "\\\[-Wint-conversion" }
12+
}
13+
14+
void gb (char *d, _Bool b)
15+
{
16+
sprintf (d, "%s", b); // { dg-warning "\\\[-Wformat" }
17+
}
18+
19+
void gi (char *d, int i)
20+
{
21+
sprintf (d, "%s", i); // { dg-warning "\\\[-Wformat" }
22+
}
23+
24+
void gd (char *d, double x)
25+
{
26+
sprintf (d, "%s", x); // { dg-warning "\\\[-Wformat" }
27+
}
28+
29+
30+
struct X { int i; };
31+
32+
void gx (char *d, struct X x)
33+
{
34+
sprintf (d, "%s", x); // { dg-warning "\\\[-Wformat" }
35+
}
36+
37+
38+
/* Also verify that the invalid sprintf call isn't folded to strcpy.
39+
{ dg-final { scan-tree-dump-times "sprintf_chk" 5 "optimized" } }
40+
{ dg-final { scan-tree-dump-not "strcpy" "optimized" } } */
Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
/* PR middle-end/100732 - ICE on sprintf %s with integer argument
2+
{ dg-do compile }
3+
{ dg-options "-O2 -Wall -fdump-tree-optimized" } */
4+
5+
void nowarn_s_i (char *d, int i)
6+
{
7+
__builtin_sprintf (d, "%s", i); // { dg-warning "\\\[-Wformat" }
8+
}
9+
10+
void warn_s_i (char *d)
11+
{
12+
int i;
13+
__builtin_sprintf (d, "%s", i); // { dg-warning "\\\[-Wformat" }
14+
// { dg-warning "\\\[-Wuninitialized" "" { target *-*-* } .-1 }
15+
}
16+
17+
void warn_i_i (char *d)
18+
{
19+
int i;
20+
__builtin_sprintf (d, "%i", i); // { dg-warning "\\\[-Wuninitialized" }
21+
}

gcc/tree-ssa-uninit.c

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -541,6 +541,9 @@ maybe_warn_pass_by_reference (gcall *stmt, wlimits &wlims)
541541
continue;
542542

543543
tree arg = gimple_call_arg (stmt, argno - 1);
544+
if (!POINTER_TYPE_P (TREE_TYPE (arg)))
545+
/* Avoid actual arguments with invalid types. */
546+
continue;
544547

545548
ao_ref ref;
546549
ao_ref_init_from_ptr_and_size (&ref, arg, access_size);

0 commit comments

Comments
 (0)