David Richard Larochelle
Sat, 29 Jun 2002 06:48:25 -0700
I was able to verify the problem and I'll try to put together a patch for the internal
error in the next few days.
-David
On Thu, Jun 27, 2002 at 06:33:31PM +0200, Enrico Scholz wrote:
> Hello,
>
> while trying to check the following program-fragment which copies the
> content of one list into another one, splint generates bounds-checking
> warnings.
>
> The first one probably appears because 'src->elems[i]->data' may contain
> uninitialized values. The
>
> (maxRead(src->elems[].data)+1) == SIZE
>
> in the @requires@ clause in line 20 does not help. I tried a helper
> function 'getData()' (lines 10-14), but when using it by uncommenting
> line 26, splint fails with an internal error:
>
> | vec.c:33:2: *** Fatal bug: Invalid sRef
> | *** Last code point: exprNode.c:10066
> | *** Previous code point: exprNode.c:10066
> | *** Please report bug to [EMAIL PROTECTED] ***
>
>
> The last two warnings are caused because splint can not derive
>
> maxSet(dst->elems) >= i
>
> from the
>
> (maxRead(dst->elems)+1) >= src->cnt (line 19)
> and
> i<src->cnt (line 24)
>
> relations. I tried to give hints like 'assert(i<=src->cnt-1)' but the
> warnings remain.
>
> How can I write the code so that it can be checked with splint?
>
>
>
> ------
> 1 #include <string.h>
> 2 #define SIZE 1024
>
> 3 struct Data {
> 4 char data[SIZE];
> 5 };
>
> 6 struct Vector {
> 7 /*@owned@*/struct Data *elems;
> 8 unsigned int cnt;
> 9 };
>
> 10 char *getData(/*@returned@*/struct Data *dta)
> 11 /*@ensures (maxRead(result)+1) == SIZE@*/
> 12 {
> 13 return dta->data;
> 14 }
>
> 15 void foo(struct Vector *dst,
> 16 /*@in@*/struct Vector const *src)
> 17 /*@modifies dst->elems@*/
> 18 /*@requires (maxRead(src->elems)+1) == src->cnt
> 19 /\ (maxRead(dst->elems)+1) >= src->cnt
> 20 /\ (maxRead(src->elems[].data)+1) == SIZE
> 21 @*/
> 22 {
> 23 unsigned int i;
>
> 24 for (i=0; i<src->cnt; ++i) {
> 25 memcpy(dst->elems[i].data, src->elems[i].data, SIZE);
> 26 //memcpy(getData(dst->elems+i), getData(src->elems+i), SIZE);
> 27 }
> 28 }
> ------
>
> | $ splint +bounds vec.c
> | Splint 3.0.1.6 --- 17 Jun 2002
> |
> | vec.c: (in function foo)
> | vec.c:30:5: Possible out-of-bounds read:
> | memcpy(dst->elems[i].data, src->elems[i].data, 1024)
> | Unable to resolve constraint:
> | requires <undef> >= 1024
> | needed to satisfy precondition:
> | requires maxRead(src->elems[i].data @ vec.c:30:32) >= 1023
> | derived from memcpy precondition: requires maxRead(<parameter 2>) >=
> | <parameter 3> + -1
> | A memory read references memory beyond the allocated storage. (Use
> | -boundsread to inhibit warning)
> | vec.c:30:12: Possible out-of-bounds read:
> | dst->elems[i]
> | Unable to resolve constraint:
> | requires maxRead(dst->elems @ vec.c:30:12) >= i @ vec.c:30:23
> | needed to satisfy precondition:
> | requires maxRead(dst->elems @ vec.c:30:12) >= i @ vec.c:30:23
> | vec.c:30:32: Possible out-of-bounds read:
> | src->elems[i]
> | Unable to resolve constraint:
> | requires *(<parameter 2>).cnt >= i @ vec.c:30:43 + 1
> | needed to satisfy precondition:
> | requires maxRead(src->elems @ vec.c:30:32) >= i @ vec.c:30:43
> |
> | Finished checking --- 3 code warnings
>
>
>
>
> Enrico
>