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
> 

Reply via email to