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-Tag: releases/gcc-9.3.0~125 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=b8c42b4d0a2595fb6806473f816b94cc1b222cb1;p=thirdparty%2Fgcc.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 68eebc0d9e61..2e633ce881ad 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,12 @@ +2020-02-14 Richard Biener + + Backport from mainline + 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-14 Richard Biener Backport from mainline diff --git a/gcc/genmatch.c b/gcc/genmatch.c index 7b9b09c7d8bb..345e21dac400 100644 --- a/gcc/genmatch.c +++ b/gcc/genmatch.c @@ -3035,10 +3035,15 @@ dt_node::gen_kids_1 (FILE *f, int indent, bool gimple, { 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); - 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"); diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index 2aa91dae4919..838f82322540 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,11 @@ +2020-02-14 Richard Biener + + Backport from mainline + 2020-02-05 Richard Biener + + PR middle-end/90648 + * gcc.dg/pr90648.c: New testcase. + 2020-02-14 Richard Biener Backport from mainline diff --git a/gcc/testsuite/gcc.dg/pr90648.c b/gcc/testsuite/gcc.dg/pr90648.c new file mode 100644 index 000000000000..bf1fa9894782 --- /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" } */ +}