diff --git a/lib/StaticAnalyzer/Checkers/CStringChecker.cpp b/lib/StaticAnalyzer/Checkers/CStringChecker.cpp index 9eb7edffe6df301abb2af4cb9d0158d3b072ab26..bd1a56a1aa05811f3f999e8f11ab19d8b2418376 100644 --- a/lib/StaticAnalyzer/Checkers/CStringChecker.cpp +++ b/lib/StaticAnalyzer/Checkers/CStringChecker.cpp @@ -901,9 +901,10 @@ void CStringChecker::evalCopyCommon(CheckerContext &C, // If the size is zero, there won't be any actual memory access, so // just bind the return value to the destination buffer and return. - if (stateZeroSize) { + if (stateZeroSize && !stateNonZeroSize) { stateZeroSize = stateZeroSize->BindExpr(CE, LCtx, destVal); C.addTransition(stateZeroSize); + return; } // If the size can be nonzero, we have to check the other arguments. diff --git a/test/Analysis/bstring.c b/test/Analysis/bstring.c index 833c917613ed5e6b8d8c0664fcfe87027707169e..87c91613a5d559de16592425d0d609c41fa8fa85 100644 --- a/test/Analysis/bstring.c +++ b/test/Analysis/bstring.c @@ -428,3 +428,13 @@ void bcopy2 () { bcopy(src, dst, 4); // expected-warning{{overflow}} } + +void *malloc(size_t); +void free(void *); +char radar_11125445_memcopythenlogfirstbyte(const char *input, size_t length) { + char *bytes = malloc(sizeof(char) * (length + 1)); + memcpy(bytes, input, length); + char x = bytes[0]; // no warning + free(bytes); + return x; +}