05c2107b88bad130d5863041dfbca38bf31ece53
[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 Expression
275 @ gtr_lss_eq @
276 expression X, Y;
277 @@
278 X <= Y <=> Y >= X
279
280 // ---------------------------------------------------------------------------
281 // Increment isomorphisms
282 // ---------------------------------------------------------------------------
283
284 // equivalences between i++, +=1, etc.
285 // note: there is an addition in this SP.
286 Statement
287 @ inc @
288 identifier i;
289 @@
290 i++; <=> ++i; <=> i+=1; <=> i=i+1;
291
292 // I would like to avoid the following rule, but we cant transform a ++i
293 // in i++ everywhere. We can do it only when the instruction is alone,
294 // such as when there is not stuff around it (not as in x = i++) That's why in
295 // the previous iso, we have explicitely force the i++ do be alone with
296 // the ';'. But unfortunately in the last expression of the for there is
297 // no ';' so the previous rule cannot be applied, hence this special
298 // case.
299
300 Statement
301 @ for_inc @
302 expression X, Y;
303 statement S;
304 identifier i;
305 @@
306 for(X;Y;i++) S <=> for(X;Y;++i) S
307
308
309 // ---------------------------------------------------------------------------
310 // Pointer isomorphisms
311 // ---------------------------------------------------------------------------
312
313 // the space at the beginning of the line is very important!
314 Expression
315 @ not_ptr1 @
316 expression *X;
317 @@
318 !X => NULL == X
319
320 // the space at the beginning of the line is very important!
321 Expression
322 @ not_ptr2 @
323 expression *X;
324 @@
325 !X => X == NULL
326
327 Expression
328 @ is_null @
329 expression X;
330 @@
331 X == NULL <=> NULL == X => !X
332
333 Expression
334 @ isnt_null1 @
335 expression X;
336 @@
337 X != NULL <=> NULL != X
338
339 TestExpression
340 @ isnt_null1 @
341 expression X;
342 @@
343 NULL != X => X
344
345 // pointer arithmetic equivalences
346
347 // ---------------------------------------------------------------------------
348 // Statement isomorphisms
349 // ---------------------------------------------------------------------------
350
351 // ----------------
352 // If
353 // ----------------
354
355 Statement
356 @ int_if_test1 @
357 int X;
358 statement S1, S2;
359 @@
360 if (X) S1 else S2 => if (X != 0) S1 else S2 <=> if (0 != X) S1 else S2
361
362 Statement
363 @ int_if_test2 @
364 int X;
365 statement S;
366 @@
367 if (X) S => if (X != 0) S <=> if (0 != X) S
368
369 Statement
370 @ ptr_if_test1 @
371 expression *X;
372 statement S1, S2;
373 @@
374 if (X) S1 else S2 => if (X != NULL) S1 else S2 => if (NULL != X) S1 else S2
375
376 Statement
377 @ ptr_if_test2 @
378 expression *X;
379 statement S;
380 @@
381 if (X) S => if (X != NULL) S <=> if (NULL != X) S
382
383 // ---------------------------------------------------------------------------
384 // Value isomorphisms
385 // ---------------------------------------------------------------------------
386
387 // There is also equal_c_int in cocci_vs_c to dealing with other
388 // integer decimal/hexadecimal isomorphisms.
389 // an argexpression applies only at top level, in the argument of a
390 // function call, or on the right-hand side of an assignment
391 ArgExpression
392 @ zero_multiple_format @
393 @@
394 0 => '\0'
395
396 // ****************************************************************************
397 // gcc specific isomorphisms
398 // ****************************************************************************
399
400 // likely and unlikely are used to give hints to gcc to improve performance.
401
402 Expression
403 @ unlikely @
404 expression E;
405 @@
406
407 unlikely(E) => E
408
409 Expression
410 @ likely @
411 expression E;
412 @@
413
414 likely(E) => E
415
416 // ****************************************************************************
417 // if structure isomorphisms
418 // ****************************************************************************
419
420 // these after after the above so that the introduced negation will distribute
421 // properly over the argument to likely/unlikely
422
423 Statement
424 @ neg_if @
425 expression X;
426 statement S1, S2;
427 @@
428 if (X) S1 else S2 => if (!X) S2 else S1
429
430 Statement
431 @ ne_if @
432 expression E1, E2;
433 statement S1, S2;
434 @@
435 if (E1 != E2) S1 else S2 => if (E1 == E2) S2 else S1
436
437 Statement
438 @ drop_else @
439 expression E;
440 statement S1;
441 pure statement S2;
442 @@
443
444 if (E) S1 else S2 => if (E) S1
445
446 Expression
447 @ neg_if_exp @
448 expression E1, E2, E3;
449 @@
450
451 E1 ? E2 : E3 => !E1 ? E3 : E2
452
453
454 // if (X) Y else Z <=> X ? Y : Z sometimes.
455
456 // ----------------
457 // Loops
458 // ----------------
459
460 // ---------------------------------------------------------------------------
461 // Optional initializers
462 // ---------------------------------------------------------------------------
463 // this is not safe when the declaration is replaced
464 // attempt to indicate that by requiring that Z is context
465 // no optional static/extern for isos
466 Declaration
467 @ decl_init @
468 type T;
469 context identifier Z;
470 @@
471 T Z; => T Z = ...;
472
473 Declaration
474 @ const_decl_init @
475 type T;
476 identifier Z;
477 constant C;
478 @@
479 T Z; => T Z = C;
480
481 Declaration
482 @ extern_decl_init @
483 type T;
484 context identifier Z;
485 @@
486 extern T Z; => extern T Z = ...;
487
488 Declaration
489 @ const_extern_decl_init @
490 type T;
491 identifier Z;
492 constant C;
493 @@
494 extern T Z; => extern T Z = C;
495
496 Declaration
497 @ static_decl_init @
498 type T;
499 context identifier Z;
500 @@
501 static T Z; => static T Z = ...;
502
503 Declaration
504 @ const_static_decl_init @
505 type T;
506 identifier Z;
507 constant C;
508 @@
509 static T Z; => static T Z = C;
510
511 // ---------------------------------------------------------------------------
512 // Branch (or compound) isomorphisms
513 // ---------------------------------------------------------------------------
514 // maybe a cocci patch should require something that looks like what is on
515 // the left above to occur in a if or while
516
517 // could worry that this has to be a simple statement, but this should work
518 // better as it allows + code on S
519 Statement
520 @ braces1 @
521 statement S;
522 @@
523 { ... S } => S
524
525 Statement
526 @ braces2 @
527 statement S;
528 @@
529 { ... S ... } => S
530
531 Statement
532 @ braces3 @
533 statement S;
534 @@
535 { S ... } => S
536
537 Statement
538 @ braces4 @
539 statement S;
540 @@
541 { S } => S
542
543 Statement
544 @ ret @
545 @@
546 return ...; => return;
547
548
549 // ---------------------------------------------------------------------------
550 // Declaration isomorphisms
551 // ---------------------------------------------------------------------------
552 // They are handled in engine (TODO)
553
554 // int i,j,k; <=> int i; int j; int k;
555
556
557 // ---------------------------------------------------------------------------
558 // Affectation/initialisation isomorphism
559 // ---------------------------------------------------------------------------
560 // They are handled in engine.
561 // 'X = Y' should also match 'type X = Y';
562
563 // ---------------------------------------------------------------------------
564 // Parenthesis isomorphisms
565 // ---------------------------------------------------------------------------
566 //Expression
567 //@@ expression E; @@
568 // E => (E)
569 //// E => ((E))
570
571 // todo: isomorphism avec les () around ? cf sizeof 3.
572 // (E) => E with some conditions.
573
574 Expression
575 @ paren @
576 expression E;
577 @@
578
579 (E) => E
580
581 // ---------------------------------------------------------------------------
582 // Pointer/Array isomorphisms
583 // ---------------------------------------------------------------------------
584
585 // pointer arithmetic equivalences
586 // a + x <=> a[x]
587
588 // ---------------------------------------------------------------------------
589 // Pointer/Field isomorphisms
590 // ---------------------------------------------------------------------------
591
592 Expression
593 @ ptr_to_array @
594 expression E1, E2; // was pure, not sure why that's needed, not good for rule27
595 identifier fld;
596 @@
597
598 E1->fld => E1[E2].fld
599
600
601
602 TopLevel
603 @ mkinit @
604 type T;
605 pure context T E;
606 identifier I;
607 identifier fld;
608 expression E1;
609 @@
610
611 E.fld = E1; => T I = { .fld = E1, };
612
613 // ---------------------------------------------------------------------------
614 // more pointer field iso
615 // ---------------------------------------------------------------------------
616
617 // pure means that either the whole field reference expression is dropped,
618 // or E is context code and has no attached + code
619 // not really... pure means matches a unitary unplussed metavariable
620 // but this rule doesn't work anyway
621
622 Expression
623 @ fld_to_ptr @
624 type T;
625 pure T E;
626 pure T *E1;
627 identifier fld;
628 @@
629
630 E.fld => E1->fld
631
632
633 // ---------------------------------------------------------------------------
634 // sizeof isomorphisms
635 // ---------------------------------------------------------------------------
636
637 // The following is made redundant by the paren isomorphism
638 // Expression
639 // @ sizeof_parens @
640 // expression E;
641 // @@
642
643 // sizeof(E) => sizeof E
644
645
646 Expression
647 @ sizeof_type_expr @
648 pure type T; // pure because we drop a metavar
649 T E;
650 @@
651
652 sizeof(T) => sizeof(E)
653
654 // Expression
655 // @ fld_func_call @
656 // expression list ES;
657 // identifier fld;
658 // expression E;
659 // @@
660 // E.fld(ES) <=> (*E.fld)(ES)
661
662
663 // ****************************************************************************
664 // Linux specific isomorphisms
665 // ****************************************************************************
666
667 // Examples: many functions are equivalent/related, and one SP modifying
668 // such a function should also modify the equivalent/related one.
669
670
671 // ---------------------------------------------------------------------------
672 // in rule18, needed ?
673 // ---------------------------------------------------------------------------
674 // (
675 // - test_and_set_bit(ev, &bcs->event);
676 // |
677 // - set_bit(ev, &bcs->event);
678 // |
679 // - bcs->event |= 1 << ev; // the only case that is used
680
681
682 // ****************************************************************************
683 // Everything that is required to be in last position, for ugly reasons ...
684 // ****************************************************************************