154c05628SNicolas Palix/// Find missing unlocks. This semantic match considers the specific case 254c05628SNicolas Palix/// where the unlock is missing from an if branch, and there is a lock 354c05628SNicolas Palix/// before the if and an unlock after the if. False positives are due to 454c05628SNicolas Palix/// cases where the if branch represents a case where the function is 554c05628SNicolas Palix/// supposed to exit with the lock held, or where there is some preceding 654c05628SNicolas Palix/// function call that releases the lock. 754c05628SNicolas Palix/// 854c05628SNicolas Palix// Confidence: Moderate 9*29a36d4dSJulia Lawall// Copyright: (C) 2010-2012 Nicolas Palix. GPLv2. 10*29a36d4dSJulia Lawall// Copyright: (C) 2010-2012 Julia Lawall, INRIA/LIP6. GPLv2. 11*29a36d4dSJulia Lawall// Copyright: (C) 2010-2012 Gilles Muller, INRIA/LiP6. GPLv2. 1254c05628SNicolas Palix// URL: http://coccinelle.lip6.fr/ 1354c05628SNicolas Palix// Comments: 1454c05628SNicolas Palix// Options: -no_includes -include_headers 1554c05628SNicolas Palix 16*29a36d4dSJulia Lawallvirtual context 1754c05628SNicolas Palixvirtual org 1854c05628SNicolas Palixvirtual report 1954c05628SNicolas Palix 2054c05628SNicolas Palix@prelocked@ 2154c05628SNicolas Palixposition p1,p; 2254c05628SNicolas Palixexpression E1; 2354c05628SNicolas Palix@@ 2454c05628SNicolas Palix 2554c05628SNicolas Palix( 2654c05628SNicolas Palixmutex_lock@p1 2754c05628SNicolas Palix| 2854c05628SNicolas Palixmutex_trylock@p1 2954c05628SNicolas Palix| 3054c05628SNicolas Palixspin_lock@p1 3154c05628SNicolas Palix| 3254c05628SNicolas Palixspin_trylock@p1 3354c05628SNicolas Palix| 3454c05628SNicolas Palixread_lock@p1 3554c05628SNicolas Palix| 3654c05628SNicolas Palixread_trylock@p1 3754c05628SNicolas Palix| 3854c05628SNicolas Palixwrite_lock@p1 3954c05628SNicolas Palix| 4054c05628SNicolas Palixwrite_trylock@p1 4154c05628SNicolas Palix| 4254c05628SNicolas Palixread_lock_irq@p1 4354c05628SNicolas Palix| 4454c05628SNicolas Palixwrite_lock_irq@p1 4554c05628SNicolas Palix| 4654c05628SNicolas Palixread_lock_irqsave@p1 4754c05628SNicolas Palix| 4854c05628SNicolas Palixwrite_lock_irqsave@p1 4954c05628SNicolas Palix| 5054c05628SNicolas Palixspin_lock_irq@p1 5154c05628SNicolas Palix| 5254c05628SNicolas Palixspin_lock_irqsave@p1 5354c05628SNicolas Palix) (E1@p,...); 5454c05628SNicolas Palix 5554c05628SNicolas Palix@looped@ 5654c05628SNicolas Palixposition r; 5754c05628SNicolas Palix@@ 5854c05628SNicolas Palix 5954c05628SNicolas Palixfor(...;...;...) { <+... return@r ...; ...+> } 6054c05628SNicolas Palix 61*29a36d4dSJulia Lawall@err exists@ 6254c05628SNicolas Palixexpression E1; 6354c05628SNicolas Palixposition prelocked.p; 6454c05628SNicolas Palixposition up != prelocked.p1; 6554c05628SNicolas Palixposition r!=looped.r; 6654c05628SNicolas Palixidentifier lock,unlock; 6754c05628SNicolas Palix@@ 6854c05628SNicolas Palix 69*29a36d4dSJulia Lawall*lock(E1@p,...); 7054c05628SNicolas Palix<+... when != E1 7154c05628SNicolas Palixif (...) { 7254c05628SNicolas Palix ... when != E1 73*29a36d4dSJulia Lawall* return@r ...; 7454c05628SNicolas Palix} 7554c05628SNicolas Palix...+> 76*29a36d4dSJulia Lawall*unlock@up(E1,...); 7754c05628SNicolas Palix 7854c05628SNicolas Palix@script:python depends on org@ 7954c05628SNicolas Palixp << prelocked.p1; 8054c05628SNicolas Palixlock << err.lock; 8154c05628SNicolas Palixunlock << err.unlock; 8254c05628SNicolas Palixp2 << err.r; 8354c05628SNicolas Palix@@ 8454c05628SNicolas Palix 8554c05628SNicolas Palixcocci.print_main(lock,p) 8654c05628SNicolas Palixcocci.print_secs(unlock,p2) 8754c05628SNicolas Palix 8854c05628SNicolas Palix@script:python depends on report@ 8954c05628SNicolas Palixp << prelocked.p1; 9054c05628SNicolas Palixlock << err.lock; 9154c05628SNicolas Palixunlock << err.unlock; 9254c05628SNicolas Palixp2 << err.r; 9354c05628SNicolas Palix@@ 9454c05628SNicolas Palix 9554c05628SNicolas Palixmsg = "preceding lock on line %s" % (p[0].line) 9654c05628SNicolas Palixcoccilib.report.print_report(p2[0],msg) 97