On Thu, Sep 02, 2010 at 07:25:02AM +0200, Julia Lawall wrote:
> > > This time there is a call to foo after the call to bar and before the 
> > > call 
> > > to xxx, and this call to foo is that same as the one that was matched 
> > > before the call to bar.
> > 
> > OK, because we would have to cycle around the loop to match, and the
> > "when" clause would disqualify the only reasonable match.
> 
> Yes.
> 
> > Thank you again!
> > 
> > And yet another question...
> > 
> > spatch does not seem to like the following:
> > 
> >     when != if (p) atomic_inc(&<+...p->f1...+>)
> 
> The branch of an if is a statement.  A function call that is a statement 
> has a ; after it.  I see that the parse error is quite unhelpful, due to 
> the way the yacc-like parsing works.

Ah, got it!

> But here you assume that the if (p) will only have the atomic_inc.  
> Perhaps the following would be better:
> 
> when != if (p) { ... atomic_inc(&<+...p->f1...+>); ... }
> 
> Note that all of the when code has to stay on the same line.  An 
> isomorphism will allow this to match a case where there are no {}.

This does work nicely, thank you!  The isomorphism works in both
directions?

> > The problem I am trying to solve is that it is OK to leak a pointer
> > out of an RCU read-side critical section if you have done something
> > to keep the underlying data structure from going away.  One way of
> > doing this is to increment a reference count in the pointed-to structure,
> > for example:
> > 
> >     rcu_read_lock();
> >     p = rcu_dereference(gp);
> >     if (p && something_bad_happened(p))
> >             p = NULL
> >     if (p)
> >             atomic_inc(&p->refcount);
> >     rcu_read_unlock();
> > 
> >     if (p)
> >             do_something_with(p->a);
> > 
> > My current set of rules will flag the last line as a pointer leak,
> > presumably because there is a code path that skips the atomic_inc().
> > My first reaction was to just put the "if" statement in a when clause
> > as above, but that gives a parse error.
> > 
> > I tried a number of variations, including a separate rule matching the
> > "if" (which worked) and recording the "if"s position (which did not).
> > For your amusement, one attempt follows.
> 
> I don't think when != @guardedref.q works at all, or if it does, then it 
> is being interpreted as something other than what you intended.  When you 
> inherit a metavariable, the name of the rule from which it is inherited 
> only appears in the metavariable declaration.  So guardedref.q is a 
> structure field reference.  And a position variable has to be attached to 
> something.  In this case, it should be an identifier, because that is what 
> the position was attached to in guardedref.  It can be any identifier at 
> all, not necessarily an inherited one, because the position is enough to 
> make it unique.

OK, so the rule inheriting the metavariable must not have another
metavariable with that same name.  Fair enough!

                                                        Thanx, Paul

> julia
> 
> 
> 
> > Thoughts?
> > 
> >                                                     Thanx, Paul
> > 
> > ------------------------------------------------------------------------
> > 
> > @guardedref@
> > position q;
> > identifier p;
> > identifier f1;
> > @@
> >     if (p...@q) {
> >             atomic_inc(&p->f1);
> >     }
> > 
> > @rcupointerleak@
> > identifier p;
> > identifier f1, f2, f3;
> > expression e1, e2, e3;
> > expression c1;
> > @@
> > *   rcu_read_lock();
> > 
> >     ... when any
> > 
> > (
> > *   p = rcu_dereference(e1);
> > |
> > *   p = rcu_dereference_raw(e1);
> > |
> > *   p = rcu_dereference_check(e1,c1);
> > |
> > *   p = rcu_dereference_index_check(e1,c1);
> > |
> > *   list_for_each_entry_rcu(p,e1,f3)
> > |
> > *   list_for_each_entry_continue_rcu(p,e1,f3)
> > |
> > *   hlist_for_each_entry_rcu(p,e1,f3)
> > |
> > *   hlist_for_each_entry_continue_rcu(p,e1,f3)
> > )
> > 
> >     ... when != p = e2
> >         when != atomic_inc_not_zero(&<+...p->f1...+>)
> >         when != atomic_inc_not_zero(&<+...p[e2]...+>)
> >         when != atomic_inc(&<+...p->f1...+>)
> >         when != atomic_inc(&<+...p[e2]...+>)
> >         when != try_module_get(p->owner)
> >         when != @guardedref.q
> > 
> > *   rcu_read_unlock();
> > 
> >     ... when != p = e2
> > 
> > (
> > *   *p
> > |
> > *   p->f2
> > |
> > *   p[e3]
> > )
> > 
_______________________________________________
Cocci mailing list
[email protected]
http://lists.diku.dk/mailman/listinfo/cocci
(Web access from inside DIKUs LAN only)

Reply via email to