aboutsummaryrefslogtreecommitdiff
path: root/gcc
diff options
context:
space:
mode:
authorMartin Sebor <msebor@redhat.com>2021-06-04 10:49:06 -0600
committerMartin Sebor <msebor@redhat.com>2021-06-04 10:49:39 -0600
commit9816f509db4966fcb90ed3baab72cc6cd901f06c (patch)
treeabb2a4e7b5c79a640dc41d6d2b413b8963a37b06 /gcc
parentc6503fa93b5565c922f76611a55b0a53cd940a5f (diff)
downloadgcc-9816f509db4966fcb90ed3baab72cc6cd901f06c.zip
gcc-9816f509db4966fcb90ed3baab72cc6cd901f06c.tar.gz
gcc-9816f509db4966fcb90ed3baab72cc6cd901f06c.tar.bz2
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.
Diffstat (limited to 'gcc')
-rw-r--r--gcc/gimple-fold.c30
-rw-r--r--gcc/testsuite/gcc.dg/tree-ssa/builtin-snprintf-11.c32
-rw-r--r--gcc/testsuite/gcc.dg/tree-ssa/builtin-snprintf-12.c36
-rw-r--r--gcc/testsuite/gcc.dg/tree-ssa/builtin-sprintf-28.c30
-rw-r--r--gcc/testsuite/gcc.dg/tree-ssa/builtin-sprintf-29.c40
-rw-r--r--gcc/testsuite/gcc.dg/uninit-pr100732.c21
-rw-r--r--gcc/tree-ssa-uninit.c3
7 files changed, 176 insertions, 16 deletions
diff --git a/gcc/gimple-fold.c b/gcc/gimple-fold.c
index eaf0fb7..1c0e930 100644
--- a/gcc/gimple-fold.c
+++ b/gcc/gimple-fold.c
@@ -3514,10 +3514,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
@@ -3525,25 +3521,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;
@@ -3584,16 +3583,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))
{
diff --git a/gcc/testsuite/gcc.dg/tree-ssa/builtin-snprintf-11.c b/gcc/testsuite/gcc.dg/tree-ssa/builtin-snprintf-11.c
new file mode 100644
index 0000000..73117c4
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/tree-ssa/builtin-snprintf-11.c
@@ -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" } } */
diff --git a/gcc/testsuite/gcc.dg/tree-ssa/builtin-snprintf-12.c b/gcc/testsuite/gcc.dg/tree-ssa/builtin-snprintf-12.c
new file mode 100644
index 0000000..9e26356
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/tree-ssa/builtin-snprintf-12.c
@@ -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" } } */
diff --git a/gcc/testsuite/gcc.dg/tree-ssa/builtin-sprintf-28.c b/gcc/testsuite/gcc.dg/tree-ssa/builtin-sprintf-28.c
new file mode 100644
index 0000000..c1d0083
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/tree-ssa/builtin-sprintf-28.c
@@ -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" } } */
diff --git a/gcc/testsuite/gcc.dg/tree-ssa/builtin-sprintf-29.c b/gcc/testsuite/gcc.dg/tree-ssa/builtin-sprintf-29.c
new file mode 100644
index 0000000..d0f7db2
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/tree-ssa/builtin-sprintf-29.c
@@ -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" } } */
diff --git a/gcc/testsuite/gcc.dg/uninit-pr100732.c b/gcc/testsuite/gcc.dg/uninit-pr100732.c
new file mode 100644
index 0000000..9c847ce
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/uninit-pr100732.c
@@ -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" }
+}
diff --git a/gcc/tree-ssa-uninit.c b/gcc/tree-ssa-uninit.c
index dcfdec9..7c002f8 100644
--- a/gcc/tree-ssa-uninit.c
+++ b/gcc/tree-ssa-uninit.c
@@ -541,6 +541,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);