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  <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.
This commit is contained in:
Richard Biener 2020-02-05 14:04:29 +01:00
parent 5f44a4341c
commit 1105cf8163
4 changed files with 34 additions and 8 deletions

View File

@ -1,3 +1,9 @@
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-05 Jakub Jelinek <jakub@redhat.com>
* tree-ssa-alias.c (aliasing_matching_component_refs_p): Fix up

View File

@ -3060,10 +3060,15 @@ dt_node::gen_kids_1 (FILE *f, int indent, bool gimple, int depth,
{
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, 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");

View File

@ -1,3 +1,9 @@
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-05 Jakub Jelinek <jakub@redhat.com>
PR middle-end/93555

View File

@ -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" } */
}