From: Richard Biener Date: Wed, 5 Feb 2020 13:04:29 +0000 (+0100) Subject: middle-end/90648 fend off builtin calls with not enough arguments from match X-Git-Url: https://git.libre-soc.org/?a=commitdiff_plain;h=1105cf8163f635ac4e4a3357d8b16a73fb6aced5;p=gcc.git middle-end/90648 fend off builtin calls with not enough arguments from match 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 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. --- diff --git a/gcc/ChangeLog b/gcc/ChangeLog index a4005841f60..072c89171ae 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,9 @@ +2020-02-05 Richard Biener + + PR middle-end/90648 + * genmatch.c (dt_node::gen_kids_1): Emit number of argument + checks before matching calls. + 2020-02-05 Jakub Jelinek * tree-ssa-alias.c (aliasing_matching_component_refs_p): Fix up diff --git a/gcc/genmatch.c b/gcc/genmatch.c index d174d4144fd..0a8cba62e0c 100644 --- a/gcc/genmatch.c +++ b/gcc/genmatch.c @@ -3060,10 +3060,15 @@ dt_node::gen_kids_1 (FILE *f, int indent, bool gimple, int depth, { expr *e = as_a (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, depth); - 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 (_c%d) == %d)\n" + " {\n", depth, e->ops.length ()); + fns[i]->gen (f, indent + 6, true, depth); + fprintf_indent (f, indent, + " }\n" + " break;\n"); } fprintf_indent (f, indent, "default:;\n"); @@ -3125,10 +3130,11 @@ dt_node::gen_kids_1 (FILE *f, int indent, bool gimple, int depth, 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, depth); - 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, depth); + fprintf_indent (f, indent, " }\n" + " break;\n"); } fprintf_indent (f, indent, "default:;\n"); diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index 584b111cfd2..873a7c415ae 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,9 @@ +2020-02-05 Richard Biener + + PR middle-end/90648 + * genmatch.c (dt_node::gen_kids_1): Emit number of argument + checks before matching calls. + 2020-02-05 Jakub Jelinek PR middle-end/93555 diff --git a/gcc/testsuite/gcc.dg/pr90648.c b/gcc/testsuite/gcc.dg/pr90648.c new file mode 100644 index 00000000000..bf1fa989478 --- /dev/null +++ b/gcc/testsuite/gcc.dg/pr90648.c @@ -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" } */ +}