Release coccinelle-0.1.8
[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 @ drop_else @
432 expression E;
433 statement S1;
434 pure statement S2;
435 @@
436
437 if (E) S1 else S2 => if (E) S1
438
439 Expression
440 @ neg_if_exp @
441 expression E1, E2, E3;
442 @@
443
444 E1 ? E2 : E3 => !E1 ? E3 : E2
445
446
447 // if (X) Y else Z <=> X ? Y : Z sometimes.
448
449 // ----------------
450 // Loops
451 // ----------------
452
453 // ---------------------------------------------------------------------------
454 // Optional initializers
455 // ---------------------------------------------------------------------------
456 // this is not safe when the declaration is replaced
457 // attempt to indicate that by requiring that Z is context
458 // no optional static/extern for isos
459 Declaration
460 @ decl_init @
461 type T;
462 context identifier Z;
463 @@
464 T Z; => T Z = ...;
465
466 Declaration
467 @ const_decl_init @
468 type T;
469 identifier Z;
470 constant C;
471 @@
472 T Z; => T Z = C;
473
474 Declaration
475 @ extern_decl_init @
476 type T;
477 context identifier Z;
478 @@
479 extern T Z; => extern T Z = ...;
480
481 Declaration
482 @ const_extern_decl_init @
483 type T;
484 identifier Z;
485 constant C;
486 @@
487 extern T Z; => extern T Z = C;
488
489 Declaration
490 @ static_decl_init @
491 type T;
492 context identifier Z;
493 @@
494 static T Z; => static T Z = ...;
495
496 Declaration
497 @ const_static_decl_init @
498 type T;
499 identifier Z;
500 constant C;
501 @@
502 static T Z; => static T Z = C;
503
504 // ---------------------------------------------------------------------------
505 // Branch (or compound) isomorphisms
506 // ---------------------------------------------------------------------------
507 // maybe a cocci patch should require something that looks like what is on
508 // the left above to occur in a if or while
509
510 // could worry that this has to be a simple statement, but this should work
511 // better as it allows + code on S
512 Statement
513 @ braces1 @
514 statement S;
515 @@
516 { ... S } => S
517
518 Statement
519 @ braces2 @
520 statement S;
521 @@
522 { ... S ... } => S
523
524 Statement
525 @ braces3 @
526 statement S;
527 @@
528 { S ... } => S
529
530 Statement
531 @ braces4 @
532 statement S;
533 @@
534 { S } => S
535
536 Statement
537 @ ret @
538 @@
539 return ...; => return;
540
541
542 // ---------------------------------------------------------------------------
543 // Declaration isomorphisms
544 // ---------------------------------------------------------------------------
545 // They are handled in engine (TODO)
546
547 // int i,j,k; <=> int i; int j; int k;
548
549
550 // ---------------------------------------------------------------------------
551 // Affectation/initialisation isomorphism
552 // ---------------------------------------------------------------------------
553 // They are handled in engine.
554 // 'X = Y' should also match 'type X = Y';
555
556 // ---------------------------------------------------------------------------
557 // Parenthesis isomorphisms
558 // ---------------------------------------------------------------------------
559 //Expression
560 //@@ expression E; @@
561 // E => (E)
562 //// E => ((E))
563
564 // todo: isomorphism avec les () around ? cf sizeof 3.
565 // (E) => E with some conditions.
566
567 Expression
568 @ paren @
569 expression E;
570 @@
571
572 (E) => E
573
574 // ---------------------------------------------------------------------------
575 // Pointer/Array isomorphisms
576 // ---------------------------------------------------------------------------
577
578 // pointer arithmetic equivalences
579 // a + x <=> a[x]
580
581 // ---------------------------------------------------------------------------
582 // Pointer/Field isomorphisms
583 // ---------------------------------------------------------------------------
584
585 Expression
586 @ ptr_to_array @
587 expression E1, E2; // was pure, not sure why that's needed, not good for rule27
588 identifier fld;
589 @@
590
591 E1->fld => E1[E2].fld
592
593
594
595 TopLevel
596 @ mkinit @
597 type T;
598 pure context T E;
599 identifier I;
600 identifier fld;
601 expression E1;
602 @@
603
604 E.fld = E1; => T I = { .fld = E1, };
605
606 // ---------------------------------------------------------------------------
607 // more pointer field iso
608 // ---------------------------------------------------------------------------
609
610 // pure means that either the whole field reference expression is dropped,
611 // or E is context code and has no attached + code
612 // not really... pure means matches a unitary unplussed metavariable
613 // but this rule doesn't work anyway
614
615 Expression
616 @ fld_to_ptr @
617 type T;
618 pure T E;
619 pure T *E1;
620 identifier fld;
621 @@
622
623 E.fld => E1->fld
624
625
626 // ---------------------------------------------------------------------------
627 // sizeof isomorphisms
628 // ---------------------------------------------------------------------------
629
630 // The following is made redundant by the paren isomorphism
631 // Expression
632 // @ sizeof_parens @
633 // expression E;
634 // @@
635
636 // sizeof(E) => sizeof E
637
638
639 Expression
640 @ sizeof_type_expr @
641 pure type T; // pure because we drop a metavar
642 T E;
643 @@
644
645 sizeof(T) => sizeof(E)
646
647 // Expression
648 // @ fld_func_call @
649 // expression list ES;
650 // identifier fld;
651 // expression E;
652 // @@
653 // E.fld(ES) <=> (*E.fld)(ES)
654
655
656 // ****************************************************************************
657 // Linux specific isomorphisms
658 // ****************************************************************************
659
660 // Examples: many functions are equivalent/related, and one SP modifying
661 // such a function should also modify the equivalent/related one.
662
663
664 // ---------------------------------------------------------------------------
665 // in rule18, needed ?
666 // ---------------------------------------------------------------------------
667 // (
668 // - test_and_set_bit(ev, &bcs->event);
669 // |
670 // - set_bit(ev, &bcs->event);
671 // |
672 // - bcs->event |= 1 << ev; // the only case that is used
673
674
675 // ****************************************************************************
676 // Everything that is required to be in last position, for ugly reasons ...
677 // ****************************************************************************