From 1105cf8163f635ac4e4a3357d8b16a73fb6aced5 Mon Sep 17 00:00:00 2001 From: Richard Biener Date: Wed, 5 Feb 2020 14:04:29 +0100 Subject: [PATCH] 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. --- gcc/ChangeLog | 6 ++++++ gcc/genmatch.c | 22 ++++++++++++++-------- gcc/testsuite/ChangeLog | 6 ++++++ gcc/testsuite/gcc.dg/pr90648.c | 8 ++++++++ 4 files changed, 34 insertions(+), 8 deletions(-) create mode 100644 gcc/testsuite/gcc.dg/pr90648.c 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" } */ +} -- 2.30.2