1 /// list_for_each_entry uses its first argument to get from one element of 2 /// the list to the next, so it is usually not a good idea to reassign it. 3 /// The first rule finds such a reassignment and the second rule checks 4 /// that there is a path from the reassignment back to the top of the loop. 5 /// 6 // Confidence: High 7 // Copyright: (C) 2010 Nicolas Palix, DIKU. GPLv2. 8 // Copyright: (C) 2010 Julia Lawall, DIKU. GPLv2. 9 // Copyright: (C) 2010 Gilles Muller, INRIA/LiP6. GPLv2. 10 // URL: http://coccinelle.lip6.fr/ 11 // Comments: 12 // Options: --no-includes --include-headers 13 14 virtual context 15 virtual org 16 virtual report 17 18 @r@ 19 iterator name list_for_each_entry; 20 expression x,E; 21 position p1,p2; 22 @@ 23 24 list_for_each_entry@p1(x,...) { <... x =@p2 E ...> } 25 26 @depends on context && !org && !report@ 27 expression x,E; 28 position r.p1,r.p2; 29 statement S; 30 @@ 31 32 *x =@p2 E 33 ... 34 list_for_each_entry@p1(x,...) S 35 36 // ------------------------------------------------------------------------ 37 38 @back depends on (org || report) && !context exists@ 39 expression x,E; 40 position r.p1,r.p2; 41 statement S; 42 @@ 43 44 x =@p2 E 45 ... 46 list_for_each_entry@p1(x,...) S 47 48 @script:python depends on back && org@ 49 p1 << r.p1; 50 p2 << r.p2; 51 @@ 52 53 cocci.print_main("iterator",p1) 54 cocci.print_secs("update",p2) 55 56 @script:python depends on back && report@ 57 p1 << r.p1; 58 p2 << r.p2; 59 @@ 60 61 msg = "iterator with update on line %s" % (p2[0].line) 62 coccilib.report.print_report(p1[0],msg) 63