[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