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