1 // ****************************************************************************
3 // ****************************************************************************
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:
11 // - optional_qualifier
13 // See parse_cocci.ml, pattern.ml, transformation.ml.
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
20 // iso2 = i++ <=> i=i+1;
24 // in C we have i=1+i;
26 // Does the SP matches the C ?
27 // - Yes if iso2 precedes iso1 in this file,
31 // ****************************************************************************
32 // Standard C isomorphisms
33 // ****************************************************************************
35 // ---------------------------------------------------------------------------
36 // Spacing (include comments) isomorphisms
37 // ---------------------------------------------------------------------------
38 // They are handled at lex time.
40 // ---------------------------------------------------------------------------
41 // Dataflow isomorphisms (copy propagation, assignments)
42 // ---------------------------------------------------------------------------
43 // They are handled in engine (TODO).
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.
53 // chip = (ak4117_t *)snd_magic_kcalloc(ak4117_t, 0, GFP_KERNEL);
55 // X = snd_magic_kcalloc(T, 0, C)
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)
66 // in the following, the space at the beginning of the line is very important!
77 unsigned => unsigned int
85 // ---------------------------------------------------------------------------
87 // ---------------------------------------------------------------------------
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.
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
127 // ---------------------------------------------------------------------------
128 // Typedef isomorphisms
129 // ---------------------------------------------------------------------------
130 // They are handled in engine.
133 // ---------------------------------------------------------------------------
134 // Boolean isomorphisms for int and pointer types
135 // ---------------------------------------------------------------------------
137 // the space at the beginning of the line is very important!
150 // the space at the beginning of the line is very important!
163 // ---------------------------------------------------------------------------
164 // Boolean isomorphisms
165 // ---------------------------------------------------------------------------
189 // X should be a test expression, but X!=0 doesn't have to be one
190 // not nice at all... ToTestExpression sets everything after the first
191 // pattern in the iso rule to be TestExpression
210 // ---------------------------------------------------------------------------
212 // ---------------------------------------------------------------------------
226 // only if side effect free in theory, perhaps makes no sense
240 // ---------------------------------------------------------------------------
241 // Arithmetic isomorphisms
242 // ---------------------------------------------------------------------------
243 //todo: require check side-effect free expression
252 // needed in kcalloc CE, where have a -kzalloc(c * sizeof(T), E)
263 // note space before (
264 (X + Y) + Z <=> X + Y + Z
271 (X - Y) - Z <=> X - Y - Z
274 @ plus_minus_assoc1 @
278 (X + Y) - Z <=> X + Y - Z
281 @ plus_minus_assoc2 @
285 (X - Y) + Z <=> X - Y + Z
292 (X * Y) * Z <=> X * Y * Z
299 (X / Y) / Z <=> X / Y / Z
306 (X * Y) / Z <=> X * Y / Z
313 (X / Y) * Z <=> X / Y * Z
315 // ---------------------------------------------------------------------------
316 // Relational isomorphisms
317 // ---------------------------------------------------------------------------
331 // ---------------------------------------------------------------------------
332 // Increment isomorphisms
333 // ---------------------------------------------------------------------------
335 // equivalences between i++, +=1, etc.
336 // note: there is an addition in this SP.
341 i++; <=> ++i; <=> i+=1; <=> i=i+1;
343 // I would like to avoid the following rule, but we cant transform a ++i
344 // in i++ everywhere. We can do it only when the instruction is alone,
345 // such as when there is not stuff around it (not as in x = i++) That's why in
346 // the previous iso, we have explicitely force the i++ do be alone with
347 // the ';'. But unfortunately in the last expression of the for there is
348 // no ';' so the previous rule cannot be applied, hence this special
357 for(X;Y;i++) S <=> for(X;Y;++i) S
360 // ****************************************************************************
361 // gcc specific isomorphisms
362 // ****************************************************************************
364 // likely and unlikely are used to give hints to gcc to improve performance.
371 unlikely(E) <=> likely(E) => E
373 // ---------------------------------------------------------------------------
374 // Parenthesis isomorphisms
375 // ---------------------------------------------------------------------------
377 //@@ expression E; @@
381 // todo: isomorphism avec les () around ? cf sizeof 3.
382 // (E) => E with some conditions.
391 // ---------------------------------------------------------------------------
392 // Statement isomorphisms
393 // ---------------------------------------------------------------------------
395 // ---------------------------------------------------------------------------
396 // Value isomorphisms
397 // ---------------------------------------------------------------------------
399 // There is also equal_c_int in cocci_vs_c to dealing with other
400 // integer decimal/hexadecimal isomorphisms.
401 // an argexpression applies only at top level, in the argument of a
402 // function call, or on the right-hand side of an assignment
404 @ zero_multiple_format @
412 // ****************************************************************************
413 // if structure isomorphisms
414 // ****************************************************************************
416 // these are after the above so that the introduced negation will distribute
417 // properly over the argument to likely/unlikely
424 if (X) S1 else S2 => if (!X) S2 else S1
431 if (E1 != E2) S1 else S2 => if (E1 == E2) S2 else S1
440 if (E) S1 else S2 => if (E) S1
444 expression E1, E2, E3;
447 E1 ? E2 : E3 => !E1 ? E3 : E2
450 // if (X) Y else Z <=> X ? Y : Z sometimes.
456 // ---------------------------------------------------------------------------
457 // Optional initializers
458 // ---------------------------------------------------------------------------
459 // this is not safe when the declaration is replaced
460 // attempt to indicate that by requiring that Z is context
461 // no optional static/extern for isos
465 context identifier Z;
480 context identifier Z;
482 extern T Z; => extern T Z = ...;
485 @ const_extern_decl_init @
490 extern T Z; => extern T Z = C;
495 context identifier Z;
497 static T Z; => static T Z = ...;
500 @ const_static_decl_init @
505 static T Z; => static T Z = C;
507 // ---------------------------------------------------------------------------
508 // Branch (or compound) isomorphisms
509 // ---------------------------------------------------------------------------
510 // maybe a cocci patch should require something that looks like what is on
511 // the left above to occur in a if or while
513 // could worry that this has to be a simple statement, but this should work
514 // better as it allows + code on S
542 return ...; => return;
545 // ---------------------------------------------------------------------------
546 // Declaration isomorphisms
547 // ---------------------------------------------------------------------------
548 // They are handled in engine (TODO)
550 // int i,j,k; <=> int i; int j; int k;
553 // ---------------------------------------------------------------------------
554 // Affectation/initialisation isomorphism
555 // ---------------------------------------------------------------------------
556 // They are handled in engine.
557 // 'X = Y' should also match 'type X = Y';
559 // ---------------------------------------------------------------------------
560 // Pointer/Array isomorphisms
561 // ---------------------------------------------------------------------------
563 // pointer arithmetic equivalences
566 // ---------------------------------------------------------------------------
567 // Pointer/Field isomorphisms
568 // ---------------------------------------------------------------------------
572 expression E1, E2; // was pure, not sure why that's needed, not good for rule27
576 E1->fld => E1[E2].fld
589 E.fld = E1; => T I = { .fld = E1, };
591 // ---------------------------------------------------------------------------
592 // more pointer field iso
593 // ---------------------------------------------------------------------------
595 // pure means that either the whole field reference expression is dropped,
596 // or E is context code and has no attached + code
597 // not really... pure means matches a unitary unplussed metavariable
598 // but this rule doesn't work anyway
611 // ---------------------------------------------------------------------------
612 // sizeof isomorphisms
613 // ---------------------------------------------------------------------------
615 // The following is made redundant by the paren isomorphism
621 // sizeof(E) => sizeof E
626 pure type T; // pure because we drop a metavar
630 sizeof(T) => sizeof(E)
634 // expression list ES;
638 // E.fld(ES) <=> (*E.fld)(ES)
641 // ****************************************************************************
642 // Linux specific isomorphisms
643 // ****************************************************************************
645 // Examples: many functions are equivalent/related, and one SP modifying
646 // such a function should also modify the equivalent/related one.
649 // ---------------------------------------------------------------------------
650 // in rule18, needed ?
651 // ---------------------------------------------------------------------------
653 // - test_and_set_bit(ev, &bcs->event);
655 // - set_bit(ev, &bcs->event);
657 // - bcs->event |= 1 << ev; // the only case that is used
660 // ****************************************************************************
661 // Everything that is required to be in last position, for ugly reasons ...
662 // ****************************************************************************