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 14virtual context 15virtual org 16virtual report 17 18@r exists@ 19iterator name list_for_each_entry; 20expression x,E; 21position p1,p2; 22@@ 23 24list_for_each_entry@p1(x,...) { <... x =@p2 E ...> } 25 26@depends on context && !org && !report@ 27expression x,E; 28position r.p1,r.p2; 29statement S; 30@@ 31 32*x =@p2 E 33... 34list_for_each_entry@p1(x,...) S 35 36// ------------------------------------------------------------------------ 37 38@back depends on (org || report) && !context exists@ 39expression x,E; 40position r.p1,r.p2; 41statement S; 42@@ 43 44x =@p2 E 45... 46list_for_each_entry@p1(x,...) S 47 48@script:python depends on back && org@ 49p1 << r.p1; 50p2 << r.p2; 51@@ 52 53cocci.print_main("iterator",p1) 54cocci.print_secs("update",p2) 55 56@script:python depends on back && report@ 57p1 << r.p1; 58p2 << r.p2; 59@@ 60 61msg = "iterator with update on line %s" % (p2[0].line) 62coccilib.report.print_report(p1[0],msg) 63