]> git.ipfire.org Git - thirdparty/gcc.git/commitdiff
middle-end/90648 fend off builtin calls with not enough arguments from match
authorRichard Biener <rguenther@suse.de>
Wed, 5 Feb 2020 13:04:29 +0000 (14:04 +0100)
committerRichard Biener <rguenther@suse.de>
Fri, 14 Feb 2020 13:35:26 +0000 (14:35 +0100)
This adds guards to genmatch generated code before accessing call
expression or stmt arguments that might be out of bounds when
the user provided bogus prototypes for what we consider builtins.

2020-02-05  Richard Biener  <rguenther@suse.de>

PR middle-end/90648
* genmatch.c (dt_node::gen_kids_1): Emit number of argument
checks before matching calls.

* gcc.dg/pr90648.c: New testcase.

gcc/ChangeLog
gcc/genmatch.c
gcc/testsuite/ChangeLog
gcc/testsuite/gcc.dg/pr90648.c [new file with mode: 0644]

index 68eebc0d9e61249fa85ae66da5a6c66328e782ad..2e633ce881adf9e2d4b43d76423db21c1020cb4e 100644 (file)
@@ -1,3 +1,12 @@
+2020-02-14  Richard Biener  <rguenther@suse.de>
+
+       Backport from mainline
+       2020-02-05  Richard Biener  <rguenther@suse.de>
+
+       PR middle-end/90648
+       * genmatch.c (dt_node::gen_kids_1): Emit number of argument
+       checks before matching calls.
+
 2020-02-14  Richard Biener  <rguenther@suse.de>
 
        Backport from mainline
index 7b9b09c7d8bbceb06410b91312d0695874cad96c..345e21dac40085a625dca04fec74a3d14b4a8e95 100644 (file)
@@ -3035,10 +3035,15 @@ dt_node::gen_kids_1 (FILE *f, int indent, bool gimple,
            {
              expr *e = as_a <expr *>(fns[i]->op);
              fprintf_indent (f, indent, "case %s:\n", e->operation->id);
-             fprintf_indent (f, indent, "  {\n");
-             fns[i]->gen (f, indent + 4, true);
-             fprintf_indent (f, indent, "    break;\n");
-             fprintf_indent (f, indent, "  }\n");
+             /* We need to be defensive against bogus prototypes allowing
+                calls with not enough arguments.  */
+             fprintf_indent (f, indent,
+                             "  if (gimple_call_num_args (def) == %d)\n"
+                             "    {\n", e->ops.length ());
+             fns[i]->gen (f, indent + 6, true);
+             fprintf_indent (f, indent,
+                             "    }\n"
+                             "  break;\n");
            }
 
          fprintf_indent (f, indent, "default:;\n");
@@ -3099,10 +3104,11 @@ dt_node::gen_kids_1 (FILE *f, int indent, bool gimple,
          gcc_assert (e->operation->kind == id_base::FN);
 
          fprintf_indent (f, indent, "case %s:\n", e->operation->id);
-         fprintf_indent (f, indent, "  {\n");
-         generic_fns[j]->gen (f, indent + 4, false);
-         fprintf_indent (f, indent, "    break;\n");
-         fprintf_indent (f, indent, "  }\n");
+         fprintf_indent (f, indent, "  if (call_expr_nargs (%s) == %d)\n"
+                                    "    {\n", kid_opname, e->ops.length ());
+         generic_fns[j]->gen (f, indent + 6, false);
+         fprintf_indent (f, indent, "    }\n"
+                                    "  break;\n");
        }
       fprintf_indent (f, indent, "default:;\n");
 
index 2aa91dae49197430255dc4f305e32a713d64d9a6..838f8232254089fa1d108df15d51c0a3440b6156 100644 (file)
@@ -1,3 +1,11 @@
+2020-02-14  Richard Biener  <rguenther@suse.de>
+
+       Backport from mainline
+       2020-02-05  Richard Biener  <rguenther@suse.de>
+
+       PR middle-end/90648
+       * gcc.dg/pr90648.c: New testcase.
+
 2020-02-14  Richard Biener  <rguenther@suse.de>
 
        Backport from mainline
diff --git a/gcc/testsuite/gcc.dg/pr90648.c b/gcc/testsuite/gcc.dg/pr90648.c
new file mode 100644 (file)
index 0000000..bf1fa98
--- /dev/null
@@ -0,0 +1,8 @@
+/* { dg-do compile } */
+/* { dg-options "-O" } */
+
+extern double copysign ();
+double foo (double x)
+{
+  return x * copysign (); /* { dg-warning "too few arguments" } */
+}