I'm trying to write a spatch rule that has some inversion logic for a
given struct member, but I'm struggling to express this in SmPL. I'm
also a bit of a coccinelle novice, however. Specifically, I'm trying
to express:

For all structs, for each member `M` of type `struct rwlock`, if there
are calls to `rwlock_wlock(&M)` and `rwlock_wunlock(&M)`, but there
are no calls to `rwlock_rlock(&M)` or `rwlock_runlock(&M)`, then
change `M`'s type from `struct rwlock` to `struct lock` and change
calls to `rwlock_wlock(&M)` and `rwlock_wunlock(&M)` to
`lock_lock(&M)` and `lock_unlock(&M)`, respectively.

In other words, "if I'm not using the reader part of an rwlock, make
it into a normal boring lock."

I realize that tracking whether, in a call to f(&something->M),
something is actually of the type in which rwlock was replaced is kind
of hard (I think?). But I'd be willing to compromise on just assuming
that something->M is always correct, because M always has
unique-enough names. Or maybe that compromise isn't needed due to some
sort of amazing coccinelle type inference, but anyway, I'm willing to

The trickiest part seems to be, however, only doing this in the case
where there aren't calls to `rwlock_rlock(&M)` and
`rwlock_runlock(&M)`. I tried using a virtual rule and a depends
clause, but those dependencies don't seem to work over a given
instance of an identifier.

I could probably hack my way toward that with a ridiculous sed
expression, or do it procedurally after parsing the AST. But it seems
like this would be a good case for where Coccinelle makes things
easier, so I thought I'd commit to getting it done with spatch. Any
pointers would be appreciated.

Cocci mailing list

Reply via email to