]> git.ipfire.org Git - thirdparty/gcc.git/commitdiff
Backported from trunk:
authorMartin Sebor <msebor@redhat.com>
Thu, 17 Jun 2021 18:08:15 +0000 (12:08 -0600)
committerMartin Sebor <msebor@redhat.com>
Thu, 17 Jun 2021 20:07:15 +0000 (14:07 -0600)
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.

gcc/gimple-fold.c
gcc/testsuite/gcc.dg/tree-ssa/builtin-snprintf-11.c [new file with mode: 0644]
gcc/testsuite/gcc.dg/tree-ssa/builtin-snprintf-12.c [new file with mode: 0644]
gcc/testsuite/gcc.dg/tree-ssa/builtin-sprintf-28.c [new file with mode: 0644]
gcc/testsuite/gcc.dg/tree-ssa/builtin-sprintf-29.c [new file with mode: 0644]
gcc/testsuite/gcc.dg/uninit-pr100732.c [new file with mode: 0644]
gcc/tree-ssa-uninit.c

index 39356eaf66f2064e0992e20c3c71449911a8e768..6079f88163f0c8c9fa841fb88e6d81cd0bd7c028 100644 (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))
        {
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 (file)
index 0000000..73117c4
--- /dev/null
@@ -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 (file)
index 0000000..9e26356
--- /dev/null
@@ -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 (file)
index 0000000..c1d0083
--- /dev/null
@@ -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 (file)
index 0000000..d0f7db2
--- /dev/null
@@ -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 (file)
index 0000000..9c847ce
--- /dev/null
@@ -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" }
+}
index 0800f596ab1a55889aaaa031bb912f262ecafa74..0c04136ed1ef82146154096aebadd351359f482a 100644 (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);