On Wednesday 23 June 2010 15:16:41 Pierre Habouzit wrote:
> No it doesn't work on:
> 
> void broken(void)
> {
>     t_foo();
>     t_foo();
>     t_push();
>     t_pop();
>     t_foo();
>     t_foo();
> }


The attached SmPL file works on that case too.

> 
> And I've absolutely no clue why. Coccinelle documentation is rather terse on
> how regexp constraints work, so I really was expecting what I wrote to work. I
> mean when I write:

It is not a problem with regexp. It is the use of "..." inside a function
and the way coccinelle determines the paths that match the given pattern.

The idea is to split the rule in two pieces:
 - the first one looks for use of a "g" function
 - the second identifies the function "f" where it occurs.


> 
> @r@
> type t;
> position p;
> identifier f !~= "^t_.*$";
> identifier g  ~= "^t_.*$";
> @@
> t f...@p(...) {
> ... when != t_push()
> *g(...)
> ...
> }
> 
> I /think/ I wrote: if you find out about an identifier starting with t_
> before any call to t_push() (or withouth any call to t_push actually),
> then report this.
> 
> I understand that t_push() itself matches the wildcard, but it doesn't
> seem to be the problem.

My cocci file discard t_push too using position.

> 
> So what is broken in my assumption since coccinelle definitely seems not
> to behave how I expect it to ?

Julia can explain later better than me but using "..." implies a shortest
path constraint which does not allow to match as you expect.

You can see that effect by comparing the following two rule on e.g. one of your 
functions.

@@
type t;
identifier f;
identifier g;
@@
t f(...) {
<+...
*g(...)
...+>
}

@@
type t;
identifier f;
identifier g;
@@
t f(...) {
...
*g(...)
...
}

> 
> 
> On Wed, Jun 23, 2010 at 03:00:54PM +0200, Nicolas Palix wrote:
> > Hi Pierre,
> > 
> > Does these examples suit you ?
> > 
> > t.cocci seems to highlight what you want.
> > 
> > I expect t2 to do the same thing in a simpler way,
> > but t_pop calls are not filtered out properly.
> > 
> > Julia, can you check I am doing it right ?
> > 
> > Excerpt of t2:
> > 
> > @r_push@
> > position p_push;
> > @@
> > t_p...@p_push();
> > 
> > @r_pop@
> > position p_pop;
> > @@
> > t_...@p_pop();
> > 
> > @r1@
> > type t;
> > position p;
> > position p2 != {r_push.p_push, r_pop.p_pop};
> > identifier f !~= "^t_.*$";
> > identifier g  ~= "^t_.*$";
> > @@
> > t f...@p(...) {
> > ... when != t_push();
> > *...@p2(...);
> > ...
> > }
> > 
> > 
> > On Wednesday 23 June 2010 13:15:52 Pierre Habouzit wrote:
> > > 
> > > Hi, I'm trying to write a rule that checks a syntaxic coding rule we
> > > have at work. We have this stacked allocator, that has two functions:
> > > t_push()/t_pop() placing marks on an allocation mark.
> > > 
> > > Any t_* allocation performed since a given t_push() is deallocated after
> > > the next t_pop().
> > > 
> > > Some of our functions use this stack to do their stuff, some leave it
> > > untouched, some return results allocated on it (for example we have a
> > > t_sprintf).
> > > 
> > > Our coding rule is that any function that allocates on the stack without
> > > guarding the allocation by t_push()/t_pop() should have a name starting
> > > with t_.
> > > 
> > > I've written the attached .cocci. Though run on the following test:
> > > 
> > >     void f1(void)
> > >     {
> > >   t_push();
> > >   t_foo();
> > >   t_pop();
> > >     }
> > > 
> > >     void f2(void)
> > >     {
> > >   t_foo();
> > >     }
> > > 
> > >     void f3(void)
> > >     {
> > >   t_bar();
> > >   t_push();
> > >   t_foo();
> > >   t_pop();
> > >     }
> > > 
> > > 
> > >     void f4(void)
> > >     {
> > >   t_push();
> > >   t_foo();
> > >   t_pop();
> > >   t_bar();
> > >     }
> > > 
> > > I expected it to yield errors for f2-f4, but it only does for f2.
> > > Further investigation shows that it doesn't even report:
> > > 
> > > void f(void) {
> > >     t_something();
> > >     t_somethingelse();
> > > }
> > > 
> > > Any idea if I'm doing something wrong or if that's a coccinelle bug ?
> > > 
> > 
> 
> > @r_pop@
> > position p_pop;
> > @@
> > t_...@p_pop();
> > 
> > @r1@
> > type t;
> > position p;
> > position p2 != r_pop.p_pop;
> > identifier f !~= "^t_.*$";
> > identifier g  ~= "^t_.*$";
> > @@
> > t f...@p(...) {
> > ... when != t_push();
> > *...@p2(...);
> > ...
> > t_push();
> > ...
> > }
> > 
> > @script:python@
> > x << r1.p;
> > f << r1.f;
> > g << r1.g;
> > @@
> > print "%s:%s:%s:%s should be named t_%s" % (x[0].file, x[0].line, 
> > x[0].column, f, f)
> > 
> > @r2@
> > type t;
> > position p;
> > position p2 != r_pop.p_pop;
> > identifier f !~= "^t_.*$";
> > identifier g  ~= "^t_.*$";
> > @@
> > t f...@p(...) {
> > ...
> > t_pop();
> > ...
> > *...@p2(...);
> > ... when != t_pop();
> > }
> > 
> > @script:python@
> > x << r2.p;
> > f << r2.f;
> > g << r2.g;
> > @@
> > print "%s:%s:%s:%s should be named t_%s" % (x[0].file, x[0].line, 
> > x[0].column, f, f)
> > 
> > @r3@
> > type t;
> > position p;
> > identifier f !~= "^t_.*$";
> > identifier g  ~= "^t_.*$";
> > @@
> > t f...@p(...) {
> > ... when != t_push();
> > *g(...);
> > ... when != t_pop();
> > }
> > 
> > @script:python@
> > x << r3.p;
> > f << r3.f;
> > g << r3.g;
> > @@
> > print "%s:%s:%s:%s should be named t_%s" % (x[0].file, x[0].line, 
> > x[0].column, f, f)
> 
> > @r_push@
> > position p_push;
> > @@
> > t_p...@p_push();
> > 
> > @r_pop@
> > position p_pop;
> > @@
> > t_...@p_pop();
> > 
> > @r1@
> > type t;
> > position p;
> > position p2 != {r_push.p_push, r_pop.p_pop};
> > identifier f !~= "^t_.*$";
> > identifier g  ~= "^t_.*$";
> > @@
> > t f...@p(...) {
> > ... when != t_push();
> > *...@p2(...);
> > ...
> > }
> > 
> > @script:python@
> > x << r1.p;
> > f << r1.f;
> > g << r1.g;
> > @@
> > print "%s:%s:%s:%s should be named t_%s" % (x[0].file, x[0].line, 
> > x[0].column, f, f)
> > 
> > @r2@
> > type t;
> > position p;
> > position p2 != {r_push.p_push, r_pop.p_pop};
> > identifier f !~= "^t_.*$";
> > identifier g  ~= "^t_.*$";
> > @@
> > t f...@p(...) {
> > ...
> > *...@p2(...);
> > ... when != t_pop();
> > }
> > 
> > @script:python@
> > x << r2.p;
> > f << r2.f;
> > g << r2.g;
> > @@
> > print "%s:%s:%s:%s should be named t_%s" % (x[0].file, x[0].line, 
> > x[0].column, f, f)
> 
> 
> 

-- 
Nicolas Palix
Tel: (+33) 1 44 27 87 25
Tel: (+33) 6 81 07 91 72
Web: http://www.diku.dk/~npalix/
///////////////////////////
//
// Problem before t_push ()
//
///////////////////////////
@r_push@
position p_push;
@@
t_p...@p_push()

@pb_push@
identifier g  ~= "^t_.*$";
position pg;
@@
... when != t_push()
    when any
g...@pg(...)

@filter@
position pg != r_push.p_push;
identifier pb_push.g !~= "^t_push$";
@@
g...@pg(...)

@p_push depends on filter@
type t;
identifier f !~= "^t_.*$";
position p;
position pb_push.pg;
identifier pb_push.g;
@@
t f...@p(...) {
<+...
*...@pg(...)
...+>
}

///////////////////////////
//
// Problem after t_pop ()
//
///////////////////////////

@pb_pop@
identifier g  ~= "^t_.*$";
position p2;
@@
t_pop()
... when != t_pop()
    when any
g...@p2(...)

@p_pop@
type t;
identifier f !~= "^t_.*$";
position p;
position pb_pop.p2;
identifier pb_pop.g;
@@
t f...@p(...) {
<+...
*...@p2(...)
...+>
}


@script:python@
x << p_push.p;
f << p_push.f;
@@
print "%s:%s:%s:%s should be named t_%s" % (x[0].file, x[0].line, x[0].column, f, f)


@script:python@
x << p_pop.p;
f << p_pop.f;
@@
print "%s:%s:%s:%s should be named t_%s" % (x[0].file, x[0].line, x[0].column, f, f)
_______________________________________________
Cocci mailing list
[email protected]
http://lists.diku.dk/mailman/listinfo/cocci
(Web access from inside DIKUs LAN only)

Reply via email to