This is the mail archive of the gcc@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

Re: preview of the tree-check pass (Re: gcc project)


On Wed, 2006-04-05 at 09:12, Zack Weinberg wrote:
> It's an interesting system.  I wonder if it's powerful enough to express
> the rather complicated constraints on objects of type va_list.  Warnings
> for violations of those constraints would be valuable - there are common
> portability errors that could be caught - but it's never been important
> enough to write a custom check pass for it.  If your system can handle
> it, we could consider (assuming it's included) providing the check file
> that defines them with GCC as a worked example, maybe even including it
> in -Wall (which would ensure that your pass got exercised and therefore
> didn't break through disuse).  
> 
> I describe the constraints in
> http://gcc.gnu.org/ml/gcc-patches/2002-06/msg01293.html
> and can explain further if they don't make sense.  (I don't swear that
> I have them perfectly accurate, but I'm pretty sure.)

Very interesting problem! The short answer is: 
1. you can solve 1/3 of your problem with the current tree-check pass
2. by hacking a bit the pass, we could easily solve a second third
3. the third third :°) is a bit trickier, actually you cannot express it
in the framework without extending it more seriously.

Here are the details.
Looking at your specification of the va_arg check, it is formulated as
two automata: one for the caller function, and one for the called
("mangling") function. There are three error cases (corresponding to the
3 thirds above):
1. (in the caller:) exiting the function after a va_start() without an
va_end().
This can be expressed directly today as:

  from "va_start(%X,%_)"
  to "return" or "return(%_)"
  avoid "va_end(%X)"

Actually, because the check is performed on the preprocessed form, the
names of the calls have to be a bit different:

  from "__builtin_va_start(%X,%_,%_)"
  to "return" or "return(%_)"
  avoid "__builtin_va_end(%X)"


2. (in the mangler:) calling va_start() or va_end() on a va_list
parameter.
In principle, this can be expressed simply as:

from "va_list %X;" 
to "return" or "return(%_)"

The problem is that currently the pass scans only statements in the CFG,
not declarations, so the "from" expression will never match. Moreover,
the declaration of %X should be a formal parameter, not a local
variable.
The first problem could be handled by simply scanning declarations as an
entry block for the CFG. 
The second problem could be handled by complementing the "from" pattern
with a call to the gcc API (as Diego intended to define one), e.g.:

from "va_list %X;" | PARM_DECL_P(X)
to "return" or "return(%_)"


3. (in the caller:) exiting the function after a va_start() then a call
to the mangler without an va_end().
This one involves more than a from/to/avoid; it is of the form
from/then/to/avoid. In other words, the corresponding automaton has more
than three states, which is the limit of my current framework. The
reason why I chose this limitation in the first place is to ensure taht
checking is linear in time and space. I'm not sure this should be
re-considered.

Cheers,
Nic.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]