1/// If list_for_each_entry, etc complete a traversal of the list, the iterator
2/// variable ends up pointing to an address at an offset from the list head,
3/// and not a meaningful structure.  Thus this value should not be used after
4/// the end of the iterator.
5//#False positives arise when there is a goto in the iterator and the
6//#reported reference is at the label of this goto.  Some flag tests
7//#may also cause a report to be a false positive.
8///
9// Confidence: Moderate
10// Copyright: (C) 2012 Julia Lawall, INRIA/LIP6.  GPLv2.
11// Copyright: (C) 2012 Gilles Muller, INRIA/LIP6.  GPLv2.
12// URL: http://coccinelle.lip6.fr/
13// Comments:
14// Options: --no-includes --include-headers
15
16virtual context
17virtual org
18virtual report
19
20@r exists@
21identifier c,member;
22expression E,x;
23iterator name list_for_each_entry;
24iterator name list_for_each_entry_reverse;
25iterator name list_for_each_entry_continue;
26iterator name list_for_each_entry_continue_reverse;
27iterator name list_for_each_entry_from;
28iterator name list_for_each_entry_safe;
29iterator name list_for_each_entry_safe_continue;
30iterator name list_for_each_entry_safe_from;
31iterator name list_for_each_entry_safe_reverse;
32iterator name hlist_for_each_entry;
33iterator name hlist_for_each_entry_continue;
34iterator name hlist_for_each_entry_from;
35iterator name hlist_for_each_entry_safe;
36statement S;
37position p1,p2;
38type T;
39@@
40
41(
42list_for_each_entry@p1(c,...,member) { ... when != break;
43                                 when forall
44                                 when strict
45}
46|
47list_for_each_entry_reverse@p1(c,...,member) { ... when != break;
48                                 when forall
49                                 when strict
50}
51|
52list_for_each_entry_continue@p1(c,...,member) { ... when != break;
53                                 when forall
54                                 when strict
55}
56|
57list_for_each_entry_continue_reverse@p1(c,...,member) { ... when != break;
58                                 when forall
59                                 when strict
60}
61|
62list_for_each_entry_from@p1(c,...,member) { ... when != break;
63                                 when forall
64                                 when strict
65}
66|
67list_for_each_entry_safe@p1(c,...,member) { ... when != break;
68                                 when forall
69                                 when strict
70}
71|
72list_for_each_entry_safe_continue@p1(c,...,member) { ... when != break;
73                                 when forall
74                                 when strict
75}
76|
77list_for_each_entry_safe_from@p1(c,...,member) { ... when != break;
78                                 when forall
79                                 when strict
80}
81|
82list_for_each_entry_safe_reverse@p1(c,...,member) { ... when != break;
83                                 when forall
84                                 when strict
85}
86)
87...
88(
89list_for_each_entry(c,...) S
90|
91list_for_each_entry_reverse(c,...) S
92|
93list_for_each_entry_continue(c,...) S
94|
95list_for_each_entry_continue_reverse(c,...) S
96|
97list_for_each_entry_from(c,...) S
98|
99list_for_each_entry_safe(c,...) S
100|
101list_for_each_entry_safe(x,c,...) S
102|
103list_for_each_entry_safe_continue(c,...) S
104|
105list_for_each_entry_safe_continue(x,c,...) S
106|
107list_for_each_entry_safe_from(c,...) S
108|
109list_for_each_entry_safe_from(x,c,...) S
110|
111list_for_each_entry_safe_reverse(c,...) S
112|
113list_for_each_entry_safe_reverse(x,c,...) S
114|
115hlist_for_each_entry(c,...) S
116|
117hlist_for_each_entry_continue(c,...) S
118|
119hlist_for_each_entry_from(c,...) S
120|
121hlist_for_each_entry_safe(c,...) S
122|
123list_remove_head(x,c,...)
124|
125sizeof(<+...c...+>)
126|
127 &c->member
128|
129T c;
130|
131c = E
132|
133*c@p2
134)
135
136@script:python depends on org@
137p1 << r.p1;
138p2 << r.p2;
139@@
140
141cocci.print_main("invalid iterator index reference",p2)
142cocci.print_secs("iterator",p1)
143
144@script:python depends on report@
145p1 << r.p1;
146p2 << r.p2;
147@@
148
149msg = "ERROR: invalid reference to the index variable of the iterator on line %s" % (p1[0].line)
150coccilib.report.print_report(p2[0], msg)
151