[Cocci] Extracting types passed to variadic (varargs) functions
julia at diku.dk
Tue Nov 17 21:21:48 CET 2009
On Tue, 17 Nov 2009, David Malcolm wrote:
> 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):
> > @check_PyArg_ParseTuple@
> > position pos;
> > expression args;
> > expresion fmt;
> > type t; t e;
> > expression list[n] E;
> > @@
> > PyArg_ParseTuple(args at pos, fmt, E, e, ...)
> > @script:python@
> > 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_
> after, thus:
> @ check_PyArg_ParseTuple @
> position pos;
> expression args;
> expression fmt;
> expression list[len_E] E;
> expression list[len_F] F;
> type t;
> t e;
> 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.
> Many thanks!
Great! Although I will have to look into why the ... solution didn't
work. Thanks for reporting the problem.
More information about the Cocci