diff mbox

[genmatch] reject empty c_expr

Message ID CAAgBjMnin_uqmwnku+UW48DTCTEZ=5CTDxXXffYGCyW_0n6Jiw@mail.gmail.com
State New
Headers show

Commit Message

Prathamesh Kulkarni July 15, 2015, 4 p.m. UTC
Hi,
We allow c_expr to be empty which accepts cases like the following:

(simplify
  match-operand
  (if ()
    result-operand))

(simplify
  match-operand
  {})

The attached patch rejects empty c_expr.
Ok for trunk after bootstrap + test ?

Thank you,
Prathamesh
2015-07-15  Prathamesh Kulkarni  <prathamesh.kulkarni@linaro.org>

	* genmatch.c (parse_c_expr): Reject empty c_expr.

Comments

Prathamesh Kulkarni July 16, 2015, 8:19 a.m. UTC | #1
On 16 July 2015 at 12:39, Richard Biener <rguenther@suse.de> wrote:
> On Wed, 15 Jul 2015, Prathamesh Kulkarni wrote:
>
>> Hi,
>> We allow c_expr to be empty which accepts cases like the following:
>>
>> (simplify
>>   match-operand
>>   (if ()
>>     result-operand))
>>
>> (simplify
>>   match-operand
>>   {})
>
> Yes we do.  We also do not reject various other "bad" forms like
>
>  { ( blah! }
>
> so I am not sure treating empty ones specially makes sense.  After
> all a c-expr is just a list of preprocessing tokens we re-inject
> into the generated C code.
Well the empty () causes genmatch to segfault.
(simplify
  (plus @x @y)
    (if ()
      @x)))

segfaults here at genmatch.c:2583
output_line_directive (f, ife->cond->code[0].src_loc);

IIUC, since we bail out early from parse_c_expr on "()", code remains
vNULL and accessing code[0] leads to segfault.

backtrace with gdb:
#0  operator[] (ix=0, this=0x6bb628) at ../../src/gcc/vec.h:1180
#1  dt_simplify::gen_1 (this=this@entry=0x6bac30,
f=f@entry=0x7ffff7dd4400 <_IO_2_1_stdout_>, indent=indent@entry=10,
gimple=gimple@entry=true, result=0x6bb5e0) at
../../src/gcc/genmatch.c:2583
#2  0x0000000000413430 in dt_simplify::gen (this=0x6bac30,
f=0x7ffff7dd4400 <_IO_2_1_stdout_>, indent=10, gimple=<optimized out>)
at ../../src/gcc/genmatch.c:2873
#3  0x000000000040de6f in dt_node::gen_kids_1
(this=this@entry=0x6babc0, f=f@entry=0x7ffff7dd4400 <_IO_2_1_stdout_>,
indent=indent@entry=8, gimple=gimple@entry=true,
gimple_exprs=gimple_exprs@entry=...,
    generic_exprs=generic_exprs@entry=..., fns=fns@entry=...,
generic_fns=generic_fns@entry=..., preds=preds@entry=...,
others=others@entry=...) at ../../src/gcc/genmatch.c:2510
#4  0x000000000040ecf3 in dt_node::gen_kids (this=0x6babc0,
f=0x7ffff7dd4400 <_IO_2_1_stdout_>, indent=8, gimple=true) at
../../src/gcc/genmatch.c:2312
#5  0x000000000040f491 in dt_operand::gen (this=0x6babc0,
f=0x7ffff7dd4400 <_IO_2_1_stdout_>, indent=8, gimple=<optimized out>)
at ../../src/gcc/genmatch.c:2548
#6  0x000000000040e3a2 in dt_node::gen_kids (this=0x6bab80,
f=0x7ffff7dd4400 <_IO_2_1_stdout_>, indent=8, gimple=true) at
../../src/gcc/genmatch.c:2298
#7  0x000000000040f491 in dt_operand::gen (this=0x6bab80,
f=0x7ffff7dd4400 <_IO_2_1_stdout_>, indent=8, gimple=<optimized out>)
at ../../src/gcc/genmatch.c:2548
#8  0x000000000040e3a2 in dt_node::gen_kids (this=0x6bab40,
f=0x7ffff7dd4400 <_IO_2_1_stdout_>, indent=8, gimple=true) at
../../src/gcc/genmatch.c:2298
#9  0x000000000040f667 in decision_tree::gen_gimple
(this=0x7fffffffde00, f=0x7ffff7dd4400 <_IO_2_1_stdout_>) at
../../src/gcc/genmatch.c:2913
#10 0x000000000040835e in main (argc=7056432, argv=0x0) at
../../src/gcc/genmatch.c:4135

Thanks,
Prathamesh
>
>> The attached patch rejects empty c_expr.
>> Ok for trunk after bootstrap + test ?
>>
>> Thank you,
>> Prathamesh
>>
>
> --
> Richard Biener <rguenther@suse.de>
> SUSE LINUX GmbH, GF: Felix Imendoerffer, Jane Smithard, Dilip Upmanyu, Graham Norton, HRB 21284 (AG Nuernberg)
diff mbox

Patch

Index: genmatch.c
===================================================================
--- genmatch.c	(revision 225834)
+++ genmatch.c	(working copy)
@@ -3375,6 +3375,7 @@ 
   unsigned opencnt;
   vec<cpp_token> code = vNULL;
   unsigned nr_stmts = 0;
+  bool empty = true;
   eat_token (start);
   if (start == CPP_OPEN_PAREN)
     end = CPP_CLOSE_PAREN;
@@ -3394,6 +3395,7 @@ 
 	       && --opencnt == 0)
 	break;
 
+      empty = false;
       /* This is a lame way of counting the number of statements.  */
       if (token->type == CPP_SEMICOLON)
 	nr_stmts++;
@@ -3412,6 +3414,10 @@ 
       code.safe_push (*token);
     }
   while (1);
+
+  if (empty)
+    fatal_at (token, "c_expr cannot be empty");
+
   return new c_expr (r, code, nr_stmts, vNULL, capture_ids);
 }