Release coccinelle-0.2.2-rc1
[bpt/coccinelle.git] / standard.iso
CommitLineData
34e49164
C
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
60Expression
61@ drop_cast @
62expression E;
63pure type T;
64@@
65
66// in the following, the space at the beginning of the line is very important!
67 (T)E => E
68
69Type
70@ add_signed @
71@@
72int => signed int
73
74Type
75@ add_int1 @
76@@
77unsigned => unsigned int
78
79Type
80@ add_int2 @
81@@
82signed => 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// ---------------------------------------------------------------------------
c3e37e97 134// Boolean isomorphisms for int and pointer types
34e49164
C
135// ---------------------------------------------------------------------------
136
137// the space at the beginning of the line is very important!
138Expression
c3e37e97
C
139@ not_int1 @
140int X;
141@@
142 !X => X == 0
143
144TestExpression
145@ not_int2 @
34e49164
C
146int X;
147@@
c3e37e97 148 X => X != 0
34e49164
C
149
150// the space at the beginning of the line is very important!
151Expression
c3e37e97
C
152@ not_ptr1 @
153expression *X;
154@@
155 !X => X == NULL
156
157TestExpression
158@ not_ptr2 @
159expression *X;
160@@
161 X => X != NULL
162
163// ---------------------------------------------------------------------------
164// Boolean isomorphisms
165// ---------------------------------------------------------------------------
166
167Expression
168@commeq@
169expression E;
170constant C;
171@@
172
173E == C <=> C == E
174
175Expression
176@commneq@
177expression E;
178constant C;
34e49164 179@@
c3e37e97
C
180
181E != C <=> C != E
34e49164
C
182
183Expression
184@ is_zero @
185expression X;
186@@
c3e37e97 187X == 0 => !X
34e49164 188
c3e37e97
C
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
192ToTestExpression
34e49164
C
193@ isnt_zero @
194expression X;
195@@
c3e37e97
C
196X != 0 => X
197
198Expression
199@ is_null @
200expression X;
201@@
202X == NULL => !X
203
204ToTestExpression
205@ isnt_null1 @
206expression X;
207@@
208X != NULL => X
209
210// ---------------------------------------------------------------------------
211// Bit operations
212// ---------------------------------------------------------------------------
34e49164
C
213
214Expression
215@ bitor_comm @
216expression X,Y;
217@@
218X | Y => Y | X
219
220Expression
221@ bitand_comm @
222expression X,Y;
223@@
224X & Y => Y & X
225
faf9a90c
C
226// only if side effect free in theory, perhaps makes no sense
227// Expression
228// @ and_comm @
229// expression X,Y;
230// @@
231// X && Y => Y && X
34e49164 232
faf9a90c
C
233// Expression
234// @ or_comm @
235// expression X,Y;
236// @@
237// X || Y => Y || X
34e49164
C
238
239
240// ---------------------------------------------------------------------------
241// Arithmetic isomorphisms
242// ---------------------------------------------------------------------------
243//todo: require check side-effect free expression
244
245Expression
246@ plus_comm @
247expression X, Y;
248@@
249X + Y => Y + X
250
251
252// needed in kcalloc CE, where have a -kzalloc(c * sizeof(T), E)
253Expression
254@ mult_comm @
255expression X, Y;
256@@
257X * Y => Y * X
258
259Expression
260@ plus_assoc @
261expression X, Y, Z;
262@@
263 // note space before (
264 (X + Y) + Z <=> X + Y + Z
265
266Expression
267@ minus_assoc @
268expression X, Y, Z;
269@@
270
271 (X - Y) - Z <=> X - Y - Z
272
273Expression
274@ plus_minus_assoc1 @
275expression X, Y, Z;
276@@
277
278 (X + Y) - Z <=> X + Y - Z
279
280Expression
281@ plus_minus_assoc2 @
282expression X, Y, Z;
283@@
284
285 (X - Y) + Z <=> X - Y + Z
286
287Expression
288@ times_assoc @
289expression X, Y, Z;
290@@
291
292 (X * Y) * Z <=> X * Y * Z
293
294Expression
295@ div_assoc @
296expression X, Y, Z;
297@@
298
299 (X / Y) / Z <=> X / Y / Z
300
301Expression
302@ times_div_assoc1 @
303expression X, Y, Z;
304@@
305
306 (X * Y) / Z <=> X * Y / Z
307
308Expression
309@ times_div_assoc2 @
310expression X, Y, Z;
311@@
312
313 (X / Y) * Z <=> X / Y * Z
314
315// ---------------------------------------------------------------------------
316// Relational isomorphisms
317// ---------------------------------------------------------------------------
318
319Expression
320@ gtr_lss @
321expression X, Y;
322@@
323X < Y <=> Y > X
324
708f4980
C
325Expression
326@ gtr_lss_eq @
327expression X, Y;
328@@
329X <= Y <=> Y >= X
330
34e49164
C
331// ---------------------------------------------------------------------------
332// Increment isomorphisms
333// ---------------------------------------------------------------------------
334
335// equivalences between i++, +=1, etc.
336// note: there is an addition in this SP.
337Statement
338@ inc @
339identifier i;
340@@
341i++; <=> ++i; <=> i+=1; <=> i=i+1;
342
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
349// case.
350
351Statement
352@ for_inc @
353expression X, Y;
354statement S;
355identifier i;
356@@
357for(X;Y;i++) S <=> for(X;Y;++i) S
358
359
7f004419
C
360// ****************************************************************************
361// gcc specific isomorphisms
362// ****************************************************************************
363
364// likely and unlikely are used to give hints to gcc to improve performance.
365
366Expression
9f8e26f4 367@ unlikely @
7f004419
C
368expression E;
369@@
370
371unlikely(E) <=> likely(E) => E
372
373// ---------------------------------------------------------------------------
374// Parenthesis isomorphisms
375// ---------------------------------------------------------------------------
376//Expression
377//@@ expression E; @@
378// E => (E)
379//// E => ((E))
380
381// todo: isomorphism avec les () around ? cf sizeof 3.
382// (E) => E with some conditions.
383
384Expression
385@ paren @
386expression E;
387@@
388
389 (E) => E
390
34e49164
C
391// ---------------------------------------------------------------------------
392// Statement isomorphisms
393// ---------------------------------------------------------------------------
394
34e49164
C
395// ---------------------------------------------------------------------------
396// Value isomorphisms
397// ---------------------------------------------------------------------------
398
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
403ArgExpression
404@ zero_multiple_format @
405@@
406 0 => '\0'
407
c3e37e97
C
408// ----------------
409// If
410// ----------------
411
34e49164
C
412// ****************************************************************************
413// if structure isomorphisms
414// ****************************************************************************
415
c3e37e97 416// these are after the above so that the introduced negation will distribute
34e49164
C
417// properly over the argument to likely/unlikely
418
419Statement
420@ neg_if @
421expression X;
422statement S1, S2;
423@@
424if (X) S1 else S2 => if (!X) S2 else S1
425
002099fc
C
426Statement
427@ ne_if @
428expression E1, E2;
429statement S1, S2;
430@@
431if (E1 != E2) S1 else S2 => if (E1 == E2) S2 else S1
432
34e49164
C
433Statement
434@ drop_else @
435expression E;
436statement S1;
437pure statement S2;
438@@
439
440if (E) S1 else S2 => if (E) S1
441
442Expression
443@ neg_if_exp @
444expression E1, E2, E3;
445@@
446
447E1 ? E2 : E3 => !E1 ? E3 : E2
448
449
450// if (X) Y else Z <=> X ? Y : Z sometimes.
451
452// ----------------
453// Loops
454// ----------------
455
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
462Declaration
463@ decl_init @
464type T;
465context identifier Z;
466@@
467T Z; => T Z = ...;
468
469Declaration
470@ const_decl_init @
471type T;
472identifier Z;
473constant C;
474@@
475T Z; => T Z = C;
476
477Declaration
478@ extern_decl_init @
479type T;
480context identifier Z;
481@@
482extern T Z; => extern T Z = ...;
483
484Declaration
485@ const_extern_decl_init @
486type T;
487identifier Z;
488constant C;
489@@
490extern T Z; => extern T Z = C;
491
492Declaration
493@ static_decl_init @
494type T;
495context identifier Z;
496@@
497static T Z; => static T Z = ...;
498
499Declaration
500@ const_static_decl_init @
501type T;
502identifier Z;
503constant C;
504@@
505static T Z; => static T Z = C;
506
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
512
513// could worry that this has to be a simple statement, but this should work
514// better as it allows + code on S
515Statement
516@ braces1 @
517statement S;
518@@
519{ ... S } => S
520
521Statement
522@ braces2 @
523statement S;
524@@
525{ ... S ... } => S
526
527Statement
528@ braces3 @
529statement S;
530@@
531{ S ... } => S
532
533Statement
534@ braces4 @
535statement S;
536@@
537{ S } => S
538
539Statement
540@ ret @
541@@
542return ...; => return;
543
544
545// ---------------------------------------------------------------------------
546// Declaration isomorphisms
547// ---------------------------------------------------------------------------
548// They are handled in engine (TODO)
549
550// int i,j,k; <=> int i; int j; int k;
551
552
553// ---------------------------------------------------------------------------
554// Affectation/initialisation isomorphism
555// ---------------------------------------------------------------------------
556// They are handled in engine.
557// 'X = Y' should also match 'type X = Y';
558
34e49164
C
559// ---------------------------------------------------------------------------
560// Pointer/Array isomorphisms
561// ---------------------------------------------------------------------------
562
563// pointer arithmetic equivalences
564// a + x <=> a[x]
565
566// ---------------------------------------------------------------------------
567// Pointer/Field isomorphisms
568// ---------------------------------------------------------------------------
569
570Expression
571@ ptr_to_array @
572expression E1, E2; // was pure, not sure why that's needed, not good for rule27
573identifier fld;
574@@
575
576E1->fld => E1[E2].fld
577
578
579
580TopLevel
581@ mkinit @
582type T;
583pure context T E;
584identifier I;
585identifier fld;
586expression E1;
587@@
588
589E.fld = E1; => T I = { .fld = E1, };
590
591// ---------------------------------------------------------------------------
592// more pointer field iso
593// ---------------------------------------------------------------------------
594
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
599
600Expression
601@ fld_to_ptr @
602type T;
603pure T E;
604pure T *E1;
605identifier fld;
606@@
607
608E.fld => E1->fld
609
610
611// ---------------------------------------------------------------------------
612// sizeof isomorphisms
613// ---------------------------------------------------------------------------
614
faf9a90c
C
615// The following is made redundant by the paren isomorphism
616// Expression
617// @ sizeof_parens @
618// expression E;
619// @@
34e49164 620
faf9a90c 621// sizeof(E) => sizeof E
34e49164
C
622
623
624Expression
625@ sizeof_type_expr @
626pure type T; // pure because we drop a metavar
627T E;
628@@
629
630sizeof(T) => sizeof(E)
631
485bce71
C
632// Expression
633// @ fld_func_call @
634// expression list ES;
635// identifier fld;
636// expression E;
637// @@
638// E.fld(ES) <=> (*E.fld)(ES)
639
34e49164
C
640
641// ****************************************************************************
642// Linux specific isomorphisms
643// ****************************************************************************
644
645// Examples: many functions are equivalent/related, and one SP modifying
646// such a function should also modify the equivalent/related one.
647
648
649// ---------------------------------------------------------------------------
650// in rule18, needed ?
651// ---------------------------------------------------------------------------
652// (
653// - test_and_set_bit(ev, &bcs->event);
654// |
655// - set_bit(ev, &bcs->event);
656// |
657// - bcs->event |= 1 << ev; // the only case that is used
658
659
660// ****************************************************************************
661// Everything that is required to be in last position, for ugly reasons ...
662// ****************************************************************************