aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--lib/StaticAnalyzer/Checkers/CStringChecker.cpp3
-rw-r--r--test/Analysis/bstring.c10
2 files changed, 12 insertions, 1 deletions
diff --git a/lib/StaticAnalyzer/Checkers/CStringChecker.cpp b/lib/StaticAnalyzer/Checkers/CStringChecker.cpp
index 9eb7edffe6..bd1a56a1aa 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 833c917613..87c91613a5 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;
+}