From: Jordy Rose Date: Thu, 5 Aug 2010 23:11:30 +0000 (+0000) Subject: When checking if a buffer access is valid, first make sure the buffer has a valid... X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=b6a4026de13909c2b145166ae0b7d96cf1948f64;p=clang When checking if a buffer access is valid, first make sure the buffer has a valid Loc. Fixes PR7830. git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@110390 91177308-0d34-0410-b5e6-96231b3b80d8 --- diff --git a/lib/Checker/CStringChecker.cpp b/lib/Checker/CStringChecker.cpp index a883c32d92..bb40b04bb1 100644 --- a/lib/Checker/CStringChecker.cpp +++ b/lib/Checker/CStringChecker.cpp @@ -221,14 +221,16 @@ const GRState *CStringChecker::CheckBufferAccess(CheckerContext &C, *Length, One, SizeTy)); // Check that the first buffer is sufficently long. - Loc BufStart = cast(SV.EvalCast(BufVal, PtrTy, FirstBuf->getType())); - SVal BufEnd - = SV.EvalBinOpLN(state, BinaryOperator::Add, BufStart, LastOffset, PtrTy); - state = CheckLocation(C, state, FirstBuf, BufEnd); + SVal BufStart = SV.EvalCast(BufVal, PtrTy, FirstBuf->getType()); + if (Loc *BufLoc = dyn_cast(&BufStart)) { + SVal BufEnd = SV.EvalBinOpLN(state, BinaryOperator::Add, *BufLoc, + LastOffset, PtrTy); + state = CheckLocation(C, state, FirstBuf, BufEnd); - // If the buffer isn't large enough, abort. - if (!state) - return NULL; + // If the buffer isn't large enough, abort. + if (!state) + return NULL; + } // If there's a second buffer, check it as well. if (SecondBuf) { @@ -237,10 +239,12 @@ const GRState *CStringChecker::CheckBufferAccess(CheckerContext &C, if (!state) return NULL; - BufStart = cast(SV.EvalCast(BufVal, PtrTy, SecondBuf->getType())); - BufEnd - = SV.EvalBinOpLN(state, BinaryOperator::Add, BufStart, LastOffset, PtrTy); - state = CheckLocation(C, state, SecondBuf, BufEnd); + BufStart = SV.EvalCast(BufVal, PtrTy, SecondBuf->getType()); + if (Loc *BufLoc = dyn_cast(&BufStart)) { + SVal BufEnd = SV.EvalBinOpLN(state, BinaryOperator::Add, *BufLoc, + LastOffset, PtrTy); + state = CheckLocation(C, state, SecondBuf, BufEnd); + } } // Large enough or not, return this state! diff --git a/test/Analysis/bstring.c b/test/Analysis/bstring.c index 418b323300..ae9ba4f973 100644 --- a/test/Analysis/bstring.c +++ b/test/Analysis/bstring.c @@ -246,6 +246,12 @@ void memcmp6 (char *a, char *b, size_t n) { (void)*(char*)0; // expected-warning{{null}} } +int memcmp7 (char *a, size_t x, size_t y, size_t n) { + // We used to crash when either of the arguments was unknown. + return memcmp(a, &a[x*y], n) + + memcmp(&a[x*y], a, n); +} + //===----------------------------------------------------------------------=== // bcopy() //===----------------------------------------------------------------------===