[Cocci] Extracting types passed to variadic (varargs) functions

Julia Lawall 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 [1]
> > > 
> > > 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 [2].
> > > 
> > > 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[0], 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)
> 
> @script:python@
> 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[0], 
>     fmt.expr,
>     int(len_E), 
>     int(len_E) + 1 + int(len_F),
>     t)
> 
> ...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.

julia


More information about the Cocci mailing list