8d6c16102c2c972afffa4c8acde0f472c1bf444e
[bpt/coccinelle.git] / standard.iso
1 // ****************************************************************************
2 // Prelude
3 // ****************************************************************************
4
5 // Note: some isomorphisms are handled in the engine directly because they
6 // require special support. They can not be easily described with a
7 // XX <=> YY. But some of them have names, so they can be disabled, as for
8 // any other isomorphism rule. That also means that those names can not
9 // be used for regular isomorphism rule. Those reserved rule names are:
10 // - optional_storage
11 // - optional_qualifier
12 // - value_format
13 // See parse_cocci.ml, pattern.ml, transformation.ml.
14
15
16 // Note: the order of the rules has some importance. As we don't do a fixpoint,
17 // changing the order may impact the result. For instance, if we have
18 //
19 // iso1 = x+y <=> y+x
20 // iso2 = i++ <=> i=i+1;
21 //
22 // and if
23 // in SP we have i++;
24 // in C we have i=1+i;
25 //
26 // Does the SP matches the C ?
27 // - Yes if iso2 precedes iso1 in this file,
28 // - No otherwise.
29
30
31 // ****************************************************************************
32 // Standard C isomorphisms
33 // ****************************************************************************
34
35 // ---------------------------------------------------------------------------
36 // Spacing (include comments) isomorphisms
37 // ---------------------------------------------------------------------------
38 // They are handled at lex time.
39
40 // ---------------------------------------------------------------------------
41 // Dataflow isomorphisms (copy propagation, assignments)
42 // ---------------------------------------------------------------------------
43 // They are handled in engine (TODO).
44
45
46 // ---------------------------------------------------------------------------
47 // Iso-by-absence (optional qualifier, storage, sign, cast) isomorphisms
48 // ---------------------------------------------------------------------------
49 // Some of them are handled in cocci_vs_c. Some of them handled here.
50
51
52 // We would like that
53 // chip = (ak4117_t *)snd_magic_kcalloc(ak4117_t, 0, GFP_KERNEL);
54 // also matches
55 // X = snd_magic_kcalloc(T, 0, C)
56 //
57 // For the moment because the iso is (T) E => E and not <=>, it forces
58 // us to rewrite the SP as X = (T) snd_magic_kcalloc(T, 0, C)
59
60 Expression
61 @ drop_cast @
62 expression E;
63 pure type T;
64 @@
65
66 // in the following, the space at the beginning of the line is very important!
67 (T)E => E
68
69 Type
70 @ add_signed @
71 @@
72 int => signed int
73
74 Type
75 @ add_int1 @
76 @@
77 unsigned => unsigned int
78
79 Type
80 @ add_int2 @
81 @@
82 signed => signed int
83
84
85 // ---------------------------------------------------------------------------
86 // Field isomorphisms
87 // ---------------------------------------------------------------------------
88 // Dereferences
89
90
91 // Those iso were introduced for the 'generic program matching' paper,
92 // with sgrep. The idea is that when we want to detect bugs,
93 // we want to detect something like free(X) ... *X
94 // meaning that you try to access something that have been freed.
95 // But *X is not the only way to deference X, there is also
96 // X->fld, hence those iso.
97
98 // The following don't see like a good idea, because eg fld could be
99 // instantiated in different ways in different places, meaning that the
100 // two occurrences of "*E" would not refer to the same thing at all.
101 // This could be addressed by making E pure, but then I think it would
102 // have no purpose.
103
104 // Expression
105 // @@
106 // expression E;
107 // identifier fld;
108 // @@
109 //
110 // *E => E->fld
111 //
112 // Expression
113 // @@
114 // expression E;
115 // identifier fld;
116 // @@
117 //
118 // *E => (E)->fld
119 //
120 // Expression
121 // @@
122 // expression E,E1;
123 // @@
124 //
125 // *E => E[E1]
126
127 // ---------------------------------------------------------------------------
128 // Typedef isomorphisms
129 // ---------------------------------------------------------------------------
130 // They are handled in engine.
131
132
133 // ---------------------------------------------------------------------------
134 // Boolean isomorphisms
135 // ---------------------------------------------------------------------------
136
137 // the space at the beginning of the line is very important!
138 Expression
139 @ not_int1 @
140 int X;
141 @@
142 !X => 0 == X
143
144 // the space at the beginning of the line is very important!
145 Expression
146 @ not_int2 @
147 int X;
148 @@
149 !X => X == 0
150
151 Expression
152 @ is_zero @
153 expression X;
154 @@
155 X == 0 <=> 0 == X => !X
156
157 Expression
158 @ isnt_zero @
159 expression X;
160 @@
161 X != 0 <=> 0 != X => X
162
163 Expression
164 @ bitor_comm @
165 expression X,Y;
166 @@
167 X | Y => Y | X
168
169 Expression
170 @ bitand_comm @
171 expression X,Y;
172 @@
173 X & Y => Y & X
174
175 // only if side effect free in theory, perhaps makes no sense
176 // Expression
177 // @ and_comm @
178 // expression X,Y;
179 // @@
180 // X && Y => Y && X
181
182 // Expression
183 // @ or_comm @
184 // expression X,Y;
185 // @@
186 // X || Y => Y || X
187
188
189 // ---------------------------------------------------------------------------
190 // Arithmetic isomorphisms
191 // ---------------------------------------------------------------------------
192 //todo: require check side-effect free expression
193
194 Expression
195 @ plus_comm @
196 expression X, Y;
197 @@
198 X + Y => Y + X
199
200
201 // needed in kcalloc CE, where have a -kzalloc(c * sizeof(T), E)
202 Expression
203 @ mult_comm @
204 expression X, Y;
205 @@
206 X * Y => Y * X
207
208 Expression
209 @ plus_assoc @
210 expression X, Y, Z;
211 @@
212 // note space before (
213 (X + Y) + Z <=> X + Y + Z
214
215 Expression
216 @ minus_assoc @
217 expression X, Y, Z;
218 @@
219
220 (X - Y) - Z <=> X - Y - Z
221
222 Expression
223 @ plus_minus_assoc1 @
224 expression X, Y, Z;
225 @@
226
227 (X + Y) - Z <=> X + Y - Z
228
229 Expression
230 @ plus_minus_assoc2 @
231 expression X, Y, Z;
232 @@
233
234 (X - Y) + Z <=> X - Y + Z
235
236 Expression
237 @ times_assoc @
238 expression X, Y, Z;
239 @@
240
241 (X * Y) * Z <=> X * Y * Z
242
243 Expression
244 @ div_assoc @
245 expression X, Y, Z;
246 @@
247
248 (X / Y) / Z <=> X / Y / Z
249
250 Expression
251 @ times_div_assoc1 @
252 expression X, Y, Z;
253 @@
254
255 (X * Y) / Z <=> X * Y / Z
256
257 Expression
258 @ times_div_assoc2 @
259 expression X, Y, Z;
260 @@
261
262 (X / Y) * Z <=> X / Y * Z
263
264 // ---------------------------------------------------------------------------
265 // Relational isomorphisms
266 // ---------------------------------------------------------------------------
267
268 Expression
269 @ gtr_lss @
270 expression X, Y;
271 @@
272 X < Y <=> Y > X
273
274 // ---------------------------------------------------------------------------
275 // Increment isomorphisms
276 // ---------------------------------------------------------------------------
277
278 // equivalences between i++, +=1, etc.
279 // note: there is an addition in this SP.
280 Statement
281 @ inc @
282 identifier i;
283 @@
284 i++; <=> ++i; <=> i+=1; <=> i=i+1;
285
286 // I would like to avoid the following rule, but we cant transform a ++i
287 // in i++ everywhere. We can do it only when the instruction is alone,
288 // such as when there is not stuff around it (not as in x = i++) That's why in
289 // the previous iso, we have explicitely force the i++ do be alone with
290 // the ';'. But unfortunately in the last expression of the for there is
291 // no ';' so the previous rule cannot be applied, hence this special
292 // case.
293
294 Statement
295 @ for_inc @
296 expression X, Y;
297 statement S;
298 identifier i;
299 @@
300 for(X;Y;i++) S <=> for(X;Y;++i) S
301
302
303 // ---------------------------------------------------------------------------
304 // Pointer isomorphisms
305 // ---------------------------------------------------------------------------
306
307 // the space at the beginning of the line is very important!
308 Expression
309 @ not_ptr1 @
310 expression *X;
311 @@
312 !X => NULL == X
313
314 // the space at the beginning of the line is very important!
315 Expression
316 @ not_ptr2 @
317 expression *X;
318 @@
319 !X => X == NULL
320
321 Expression
322 @ is_null @
323 expression X;
324 @@
325 X == NULL <=> NULL == X => !X
326
327 Expression
328 @ isnt_null1 @
329 expression X;
330 @@
331 X != NULL <=> NULL != X
332
333 TestExpression
334 @ isnt_null1 @
335 expression X;
336 @@
337 NULL != X => X
338
339 // pointer arithmetic equivalences
340
341 // ---------------------------------------------------------------------------
342 // Statement isomorphisms
343 // ---------------------------------------------------------------------------
344
345 // ----------------
346 // If
347 // ----------------
348
349 Statement
350 @ int_if_test1 @
351 int X;
352 statement S1, S2;
353 @@
354 if (X) S1 else S2 => if (X != 0) S1 else S2 <=> if (0 != X) S1 else S2
355
356 Statement
357 @ int_if_test2 @
358 int X;
359 statement S;
360 @@
361 if (X) S => if (X != 0) S <=> if (0 != X) S
362
363 Statement
364 @ ptr_if_test1 @
365 expression *X;
366 statement S1, S2;
367 @@
368 if (X) S1 else S2 => if (X != NULL) S1 else S2 => if (NULL != X) S1 else S2
369
370 Statement
371 @ ptr_if_test2 @
372 expression *X;
373 statement S;
374 @@
375 if (X) S => if (X != NULL) S <=> if (NULL != X) S
376
377 // ---------------------------------------------------------------------------
378 // Value isomorphisms
379 // ---------------------------------------------------------------------------
380
381 // There is also equal_c_int in cocci_vs_c to dealing with other
382 // integer decimal/hexadecimal isomorphisms.
383 // an argexpression applies only at top level, in the argument of a
384 // function call, or on the right-hand side of an assignment
385 ArgExpression
386 @ zero_multiple_format @
387 @@
388 0 => '\0'
389
390 // ****************************************************************************
391 // gcc specific isomorphisms
392 // ****************************************************************************
393
394 // likely and unlikely are used to give hints to gcc to improve performance.
395
396 Expression
397 @ unlikely @
398 expression E;
399 @@
400
401 unlikely(E) => E
402
403 Expression
404 @ likely @
405 expression E;
406 @@
407
408 likely(E) => E
409
410 // ****************************************************************************
411 // if structure isomorphisms
412 // ****************************************************************************
413
414 // these after after the above so that the introduced negation will distribute
415 // properly over the argument to likely/unlikely
416
417 Statement
418 @ neg_if @
419 expression X;
420 statement S1, S2;
421 @@
422 if (X) S1 else S2 => if (!X) S2 else S1
423
424 Statement
425 @ drop_else @
426 expression E;
427 statement S1;
428 pure statement S2;
429 @@
430
431 if (E) S1 else S2 => if (E) S1
432
433 Expression
434 @ neg_if_exp @
435 expression E1, E2, E3;
436 @@
437
438 E1 ? E2 : E3 => !E1 ? E3 : E2
439
440
441 // if (X) Y else Z <=> X ? Y : Z sometimes.
442
443 // ----------------
444 // Loops
445 // ----------------
446
447 // ---------------------------------------------------------------------------
448 // Optional initializers
449 // ---------------------------------------------------------------------------
450 // this is not safe when the declaration is replaced
451 // attempt to indicate that by requiring that Z is context
452 // no optional static/extern for isos
453 Declaration
454 @ decl_init @
455 type T;
456 context identifier Z;
457 @@
458 T Z; => T Z = ...;
459
460 Declaration
461 @ const_decl_init @
462 type T;
463 identifier Z;
464 constant C;
465 @@
466 T Z; => T Z = C;
467
468 Declaration
469 @ extern_decl_init @
470 type T;
471 context identifier Z;
472 @@
473 extern T Z; => extern T Z = ...;
474
475 Declaration
476 @ const_extern_decl_init @
477 type T;
478 identifier Z;
479 constant C;
480 @@
481 extern T Z; => extern T Z = C;
482
483 Declaration
484 @ static_decl_init @
485 type T;
486 context identifier Z;
487 @@
488 static T Z; => static T Z = ...;
489
490 Declaration
491 @ const_static_decl_init @
492 type T;
493 identifier Z;
494 constant C;
495 @@
496 static T Z; => static T Z = C;
497
498 // ---------------------------------------------------------------------------
499 // Branch (or compound) isomorphisms
500 // ---------------------------------------------------------------------------
501 // maybe a cocci patch should require something that looks like what is on
502 // the left above to occur in a if or while
503
504 // could worry that this has to be a simple statement, but this should work
505 // better as it allows + code on S
506 Statement
507 @ braces1 @
508 statement S;
509 @@
510 { ... S } => S
511
512 Statement
513 @ braces2 @
514 statement S;
515 @@
516 { ... S ... } => S
517
518 Statement
519 @ braces3 @
520 statement S;
521 @@
522 { S ... } => S
523
524 Statement
525 @ braces4 @
526 statement S;
527 @@
528 { S } => S
529
530 Statement
531 @ ret @
532 @@
533 return ...; => return;
534
535
536 // ---------------------------------------------------------------------------
537 // Declaration isomorphisms
538 // ---------------------------------------------------------------------------
539 // They are handled in engine (TODO)
540
541 // int i,j,k; <=> int i; int j; int k;
542
543
544 // ---------------------------------------------------------------------------
545 // Affectation/initialisation isomorphism
546 // ---------------------------------------------------------------------------
547 // They are handled in engine.
548 // 'X = Y' should also match 'type X = Y';
549
550 // ---------------------------------------------------------------------------
551 // Parenthesis isomorphisms
552 // ---------------------------------------------------------------------------
553 //Expression
554 //@@ expression E; @@
555 // E => (E)
556 //// E => ((E))
557
558 // todo: isomorphism avec les () around ? cf sizeof 3.
559 // (E) => E with some conditions.
560
561 Expression
562 @ paren @
563 expression E;
564 @@
565
566 (E) => E
567
568 // ---------------------------------------------------------------------------
569 // Pointer/Array isomorphisms
570 // ---------------------------------------------------------------------------
571
572 // pointer arithmetic equivalences
573 // a + x <=> a[x]
574
575 // ---------------------------------------------------------------------------
576 // Pointer/Field isomorphisms
577 // ---------------------------------------------------------------------------
578
579 Expression
580 @ ptr_to_array @
581 expression E1, E2; // was pure, not sure why that's needed, not good for rule27
582 identifier fld;
583 @@
584
585 E1->fld => E1[E2].fld
586
587
588
589 TopLevel
590 @ mkinit @
591 type T;
592 pure context T E;
593 identifier I;
594 identifier fld;
595 expression E1;
596 @@
597
598 E.fld = E1; => T I = { .fld = E1, };
599
600 // ---------------------------------------------------------------------------
601 // more pointer field iso
602 // ---------------------------------------------------------------------------
603
604 // pure means that either the whole field reference expression is dropped,
605 // or E is context code and has no attached + code
606 // not really... pure means matches a unitary unplussed metavariable
607 // but this rule doesn't work anyway
608
609 Expression
610 @ fld_to_ptr @
611 type T;
612 pure T E;
613 pure T *E1;
614 identifier fld;
615 @@
616
617 E.fld => E1->fld
618
619
620 // ---------------------------------------------------------------------------
621 // sizeof isomorphisms
622 // ---------------------------------------------------------------------------
623
624 // The following is made redundant by the paren isomorphism
625 // Expression
626 // @ sizeof_parens @
627 // expression E;
628 // @@
629
630 // sizeof(E) => sizeof E
631
632
633 Expression
634 @ sizeof_type_expr @
635 pure type T; // pure because we drop a metavar
636 T E;
637 @@
638
639 sizeof(T) => sizeof(E)
640
641 // Expression
642 // @ fld_func_call @
643 // expression list ES;
644 // identifier fld;
645 // expression E;
646 // @@
647 // E.fld(ES) <=> (*E.fld)(ES)
648
649
650 // ****************************************************************************
651 // Linux specific isomorphisms
652 // ****************************************************************************
653
654 // Examples: many functions are equivalent/related, and one SP modifying
655 // such a function should also modify the equivalent/related one.
656
657
658 // ---------------------------------------------------------------------------
659 // in rule18, needed ?
660 // ---------------------------------------------------------------------------
661 // (
662 // - test_and_set_bit(ev, &bcs->event);
663 // |
664 // - set_bit(ev, &bcs->event);
665 // |
666 // - bcs->event |= 1 << ev; // the only case that is used
667
668
669 // ****************************************************************************
670 // Everything that is required to be in last position, for ugly reasons ...
671 // ****************************************************************************