[cfe-commits] r132617 - in /cfe/trunk: lib/StaticAnalyzer/Checkers/CStringChecker.cpp test/Analysis/bstring.c
Jordy Rose
jediknil at belkadan.com
Fri Jun 3 18:47:27 PDT 2011
Author: jrose
Date: Fri Jun 3 20:47:27 2011
New Revision: 132617
URL: http://llvm.org/viewvc/llvm-project?rev=132617&view=rev
Log:
[analyzer] Don't crash when copying an unknown number of bytes with memcpy(). Also handle all memcpy-family return values in evalCopyCommon(), rather than having some outside and some inside.
Modified:
cfe/trunk/lib/StaticAnalyzer/Checkers/CStringChecker.cpp
cfe/trunk/test/Analysis/bstring.c
Modified: cfe/trunk/lib/StaticAnalyzer/Checkers/CStringChecker.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/StaticAnalyzer/Checkers/CStringChecker.cpp?rev=132617&r1=132616&r2=132617&view=diff
==============================================================================
--- cfe/trunk/lib/StaticAnalyzer/Checkers/CStringChecker.cpp (original)
+++ cfe/trunk/lib/StaticAnalyzer/Checkers/CStringChecker.cpp Fri Jun 3 20:47:27 2011
@@ -748,19 +748,33 @@
// bind the expr.
if (IsMempcpy) {
loc::MemRegionVal *destRegVal = dyn_cast<loc::MemRegionVal>(&destVal);
+ assert(destRegVal && "Destination should be a known MemRegionVal here");
// Get the length to copy.
- SVal lenVal = state->getSVal(Size);
- NonLoc *lenValNonLoc = dyn_cast<NonLoc>(&lenVal);
+ NonLoc *lenValNonLoc = dyn_cast<NonLoc>(&sizeVal);
- // Get the byte after the last byte copied.
- SVal lastElement = C.getSValBuilder().evalBinOpLN(state, BO_Add,
- *destRegVal,
- *lenValNonLoc,
- Dest->getType());
+ if (lenValNonLoc) {
+ // Get the byte after the last byte copied.
+ SVal lastElement = C.getSValBuilder().evalBinOpLN(state, BO_Add,
+ *destRegVal,
+ *lenValNonLoc,
+ Dest->getType());
- // The byte after the last byte copied is the return value.
- state = state->BindExpr(CE, lastElement);
+ // The byte after the last byte copied is the return value.
+ state = state->BindExpr(CE, lastElement);
+ } else {
+ // If we don't know how much we copied, we can at least
+ // conjure a return value for later.
+ unsigned Count = C.getNodeBuilder().getCurrentBlockCount();
+ SVal result =
+ C.getSValBuilder().getConjuredSymbolVal(NULL, CE, Count);
+ state = state->BindExpr(CE, result);
+ }
+
+ } else {
+ // All other copies return the destination buffer.
+ // (Well, bcopy() has a void return type, but this won't hurt.)
+ state = state->BindExpr(CE, destVal);
}
// Invalidate the destination.
@@ -780,7 +794,7 @@
// The return value is the address of the destination buffer.
const Expr *Dest = CE->getArg(0);
const GRState *state = C.getState();
- state = state->BindExpr(CE, state->getSVal(Dest));
+
evalCopyCommon(C, CE, state, CE->getArg(2), Dest, CE->getArg(1), true);
}
@@ -798,7 +812,7 @@
// The return value is the address of the destination buffer.
const Expr *Dest = CE->getArg(0);
const GRState *state = C.getState();
- state = state->BindExpr(CE, state->getSVal(Dest));
+
evalCopyCommon(C, CE, state, CE->getArg(2), Dest, CE->getArg(1));
}
Modified: cfe/trunk/test/Analysis/bstring.c
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Analysis/bstring.c?rev=132617&r1=132616&r2=132617&view=diff
==============================================================================
--- cfe/trunk/test/Analysis/bstring.c (original)
+++ cfe/trunk/test/Analysis/bstring.c Fri Jun 3 20:47:27 2011
@@ -264,6 +264,12 @@
(void)*(char*)0; // no-warning
}
+void mempcpy_unknownable_size (char *src, float n) {
+ char a[4];
+ // This used to crash because we don't model floats.
+ mempcpy(a, src, (size_t)n);
+}
+
//===----------------------------------------------------------------------===
// memmove()
//===----------------------------------------------------------------------===
More information about the cfe-commits
mailing list