The complate semantic patch that finds this problem is as follows: (http://coccinelle.lip6.fr/)
// <smpl> @ok exists@ identifier f,ret,i; expression e; constant c; @@ // identify a function that returns a negative return value at least once. f(...) { ... when any ( return -c@i; | ret = -c@i; ... when != ret = e return ret; | if (ret < 0) { ... return ret; } ) ... when any } @r exists@ identifier ret,ok.f,fn; expression e1,e2,e3,e4,e5,e6,x; statement S,S1; position p1,p2,p3; @@ // identify a case where the return variable is set to a non-negative value // and then returned in error-handling code f(...) { ... when any ( if@p1 (\(ret < 0\|ret != 0\)) { ... return ret; } | ret@p1 = 0 ) ... when != \(ret = e1\|ret++\|ret--\|ret+=e1\|ret-=e1\) when != &ret when any ( if (<+... ret = e5 ...+>) S1 | if (<+... &ret ...+>) S1 | if@p2(<+...x = fn(...)...+>) { ... when != ret = e6 when forall return@p3 ret; } | break; | x = fn(...) ... when != \(ret = e4\|ret++\|ret--\|ret+=e4\|ret-=e4\) when != &ret ( if (<+... ret = e3 ...+>) S | if (<+... &ret ...+>) S | if@p2(<+...\(x != 0\|x < 0\|x == NULL\|IS_ERR(x)\)...+>) { ... when != ret = e2 when forall return@p3 ret; } ) ) ... when any } @printer depends on r@ position p; identifier ok.f,pr; constant char [] c; @@ f(...) { <...pr@p(...,c,...)...> } @bad0 exists@ identifier r.ret,ok.f,g != {ERR_PTR,IS_ERR}; position p != printer.p; @@ f(...) { ... when any g@p(...,ret,...) ... when any } @bad depends on !bad0 exists@ position r.p1,r.p2; statement S1,S2; identifier r.ret; expression e1; @@ // ignore the above if there is some path where the variable is set to // something else ( if@p1 (\(ret < 0\|ret != 0\)) S1 | ret@p1 = 0 ) ... when any \(ret = e1\|ret++\|ret--\|ret+=e1\|ret-=e1\|&ret\) ... when any if@p2(...) S2 @bad1 depends on !bad0 && !bad exists@ position r.p2; statement S2; identifier r.ret; expression e1; constant c; @@ ret = -c ... when != \(ret = e1\|ret++\|ret--\|ret+=e1\|ret-=e1\) when != &ret when any if@p2(...) S2 @bad2 depends on !bad0 && !bad && !bad1 exists@ position r.p1,r.p2; identifier r.ret; expression e1; statement S2; constant c; @@ // likewise ignore it if there has been an intervening return ret@p1 = 0 ... when != if (...) { ... ret = e1 ... return ret; } when != if (...) { ... return -c; } when any if@p2(...) S2 @script:python depends on !bad0 && !bad && !bad1 && !bad2@ p1 << r.p1; p2 << r.p2; p3 << r.p3; @@ cocci.print_main("",p1) cocci.print_secs("",p2) cocci.print_secs("",p3) // </smpl> -- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/