// An ALLOC is not matched by an FREE before an error return.
//
// Confidence: Moderate
// Copyright: (C) Gilles Muller, Julia Lawall, EMN, INRIA, DIKU.  GPLv2.
// URL: https://coccinelle.gitlabpages.inria.fr/website/rules/alloc_free.html
// Options:

@r exists@
local idexpression n;
statement S1,S2;
expression E;
expression *ptr != NULL;
type T;
position p1,p2;
@@

(
if ((n = ALLOC@p1(...)) == NULL) S1
|
n = ALLOC@p1(...)
)
... when != FREE((T)n)
    when != if (...) { <+... FREE((T)n) ...+> } else S2
    when != true n == NULL  || ...
    when != n = (T)E
    when != E = (T)n
(
  return \(0\|<+...n...+>\|ptr\);
|
return@p2 ...;
)

@script:python@
p1 << r.p1;
p2 << r.p2;
@@

cocci.print_main("",p1)
cocci.print_sec("return",p2)