[splint-discuss] Annoying False Positives
Tommy Pettersson
ptp at lysator.liu.se
Fri Sep 15 17:46:21 EDT 2006
On Fri, Sep 15, 2006 at 11:10:11AM -0500, Felipe Contreras wrote:
> Well, I'm using splint to get the most warnings I can, so I'm not
> specifying any extra options. My objective is to get zero warnings so
> I can feel my code is better.
Most of the checks are off by default. "splint -strict" turns on
almost all warnings; there are some warnings about index bounds
that have to be explicitly turned on. But it would not be
possible to write a "real" program that has zero splint
warnings. The objective should be to write clear and simple code
that is easy to understand. If splint doesn't understand it,
splint should be shut up or ignored, the code should not be
mutilated!
> If I try with calloc, or manually set test->data = NULL; I get the same
> warning.
calloc does, just like memset(ptr, 0, ...), fill the memory with
a zero bit pattern. So they both assign the pointer with a value
that is not known to be NULL, whereas "ptr = 0;" assigns the
pointer a value that is known to be NULL (but might have the bit
pattern 0x0004 or whatever, although it is usually 0x0).
The following code:
test = malloc (sizeof (test))
test->data = 0;
test->data = malloc (...
does therefore not give the mustfreeonly warning (at least not
on my computer).
> >After a memset (foo, 0, ...) you can put lines like:
> >
> > /*@-mustfreeonly@*/
> > foo->ptr1 = 0;
> > foo->ptr2 = init2;
> > ..
> > /*@=mustfreeonly@*/
>
> Yeah, I could, but my code is already ugly with all the splint comments.
Most of the time annotations like /*@-mustfreeonly@*/ serve as
informative comments for the reader of the code. It says it's ok
to not free the pointer before giving it a new value in this
special case. Good to know if you want to make changes to the
code.
> > /*@null@*/ /*@partial@*/ static MyTest * my_test_new (void) { ...
> >
> >There are also more advanced special annotations to specify in
> >detail what fields of a struct get allocated, freed, initialized
> >and so on by a function.
>
> I see, but what if I consider malloc'ed memory initialized? Somebody
> else is going to use that buffer memory and write stuff to it.
So, the my_test_new function _allocates_ the memory, and the
function that write stuff to it _initializes_ it. In between the
memory is uninitialized.
It is wrong for the writing function (that receive uninitialized
memory) to read from that memory before writing to it (unless it
wants poor random data). How does splint know to check for this?
It doesn't, unless it knows the memory in uninitialized. By
annotating this fact you get more checks that the returned value
from my_test_new is used correctly. Before you added that
annotation splint could not detect such errors, but it _did_
detect my_test_new returned uninitialized memory without saying
so.
--
Tommy Pettersson <ptp at lysator.liu.se>
More information about the splint-discuss
mailing list