[Cocci] Extracting types passed to variadic (varargs) functions
dmalcolm at redhat.com
Tue Nov 17 20:21:07 CET 2009
On Mon, 2009-11-16 at 23:14 +0100, Julia Lawall wrote:
> On Mon, 16 Nov 2009, David Malcolm wrote:
> > I'm new to Coccinelle/spatch and have been experimenting with using it
> > upon CPython code 
> > I'm attempting to validate a mini-language used in format strings by a
> > variadic API call. My code examines the types of the
> > variables passed as varargs, and attempts to check that they are
> > pointers of the correct types, according to a set of rules .
> > Unfortunately, I couldn't see a way to match a variable-length list of
> > expressions, capturing the type of each expression.
> If you really want to analyze all of the arguments at once, I don't see
> how to do it. But perhaps the following would be acceptable (not tested):
> position pos;
> expression args;
> expresion fmt;
> type t; t e;
> expression list[n] E;
> PyArg_ParseTuple(args at pos, fmt, E, e, ...)
> fmt << check_PyArg_ParseTuple.fmt;
> pos << check_PyArg_ParseTuple.pos;
> t << check_PyArg_ParseTuple.t;
> n << check_PyArg_ParseTuple.n;
> num_errors += validate_types(pos, fmt.expr, n, t)
> (I'm not sure that the .expr is needed on fmt; or in any case I don't know
> what it does).
> Now validate_types takes a position, a format string, the number of
> arguments between the format string and some argument, and that argument.
> The python code will be called on each argument individually.
Thanks. I tried this, but appeared to only match the final argument at
each call site.
However, I reworked it to have an "expression list" both before _and_
@ check_PyArg_ParseTuple @
expression list[len_E] E;
expression list[len_F] F;
PyArg_ParseTuple at pos(args, fmt, E, e, F)
pos << check_PyArg_ParseTuple.pos;
fmt << check_PyArg_ParseTuple.fmt;
len_E << check_PyArg_ParseTuple.len_E;
len_F << check_PyArg_ParseTuple.len_F;
t << check_PyArg_ParseTuple.t;
num_errors += validate_type(pos,
int(len_E) + 1 + int(len_F),
...and it's now successfully matching the rule for each argument, and
supplying the index and the total number of arguments together which
each type, which seems to be everything I needed.
> > Also, I noticed that positions are passed to Python code as a 1-tuple
> > containing a coccilibs.elems.Location, rather than just the Location
> > itself. Is this deliberate (e.g. to support ranges as well as
> > positions)?
> A single position variable can be bound to more than one position when
> using a nest (<... ...> for 0 or more occurrences of the contained pattren
> and <+... ...+> for 1 or more occurrences of the contained pattern). For
> example, if f is a one-argument function, then the following will bind p
> to each occurrence of e in that argument:
> f(<+...e at p...+>)
> Then you can use for to iterate over them.
Thanks for the clarification.
More information about the Cocci