aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAnna Zaks <ganna@apple.com>2013-03-15 23:34:29 +0000
committerAnna Zaks <ganna@apple.com>2013-03-15 23:34:29 +0000
commit74c0d6988462c2cb882e7a8b8050fe119a5af56f (patch)
treea376007af6426764510f8d9250dc3611bc22baa4
parentf510f5cd57fa9b7ea6f6e103c65c0df95a55d986 (diff)
[analyzer] Use isLiveRegion to determine when SymbolRegionValue is dead.
Fixes a FIXME, improves dead symbol collection, suppresses a false positive, which resulted from reusing the same symbol twice for simulation of 2 calls to the same function. Fixing this lead to 2 possible false negatives in CString checker. Since the checker is still alpha and the solution will not require revert of this commit, move the tests to a FIXME section. git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@177206 91177308-0d34-0410-b5e6-96231b3b80d8
-rw-r--r--lib/StaticAnalyzer/Core/SymbolManager.cpp4
-rw-r--r--test/Analysis/malloc.c11
-rw-r--r--test/Analysis/string.c44
3 files changed, 39 insertions, 20 deletions
diff --git a/lib/StaticAnalyzer/Core/SymbolManager.cpp b/lib/StaticAnalyzer/Core/SymbolManager.cpp
index 7438ee0160..de2f5bc7b3 100644
--- a/lib/StaticAnalyzer/Core/SymbolManager.cpp
+++ b/lib/StaticAnalyzer/Core/SymbolManager.cpp
@@ -449,9 +449,7 @@ bool SymbolReaper::isLive(SymbolRef sym) {
switch (sym->getKind()) {
case SymExpr::RegionValueKind:
- // FIXME: We should be able to use isLiveRegion here (this behavior
- // predates isLiveRegion), but doing so causes test failures. Investigate.
- KnownLive = true;
+ KnownLive = isLiveRegion(cast<SymbolRegionValue>(sym)->getRegion());
break;
case SymExpr::ConjuredKind:
KnownLive = false;
diff --git a/test/Analysis/malloc.c b/test/Analysis/malloc.c
index 29f5aa69ca..e8b4ad3b4d 100644
--- a/test/Analysis/malloc.c
+++ b/test/Analysis/malloc.c
@@ -1191,3 +1191,14 @@ void testOffsetPassedAsConst() {
free(string); // expected-warning {{Argument to free() is offset by 1 byte from the start of memory allocated by malloc()}}
}
+char **_vectorSegments;
+int _nVectorSegments;
+
+void poolFreeC(void* s) {
+ free(s); // no-warning
+}
+void freeMemory() {
+ while (_nVectorSegments) {
+ poolFreeC(_vectorSegments[_nVectorSegments++]);
+ }
+}
diff --git a/test/Analysis/string.c b/test/Analysis/string.c
index fd836c471b..17a93ec013 100644
--- a/test/Analysis/string.c
+++ b/test/Analysis/string.c
@@ -410,12 +410,6 @@ void strcat_symbolic_dst_length(char *dst) {
clang_analyzer_eval(strlen(dst) >= 4); // expected-warning{{TRUE}}
}
-void strcat_symbolic_src_length(char *src) {
- char dst[8] = "1234";
- strcat(dst, src);
- clang_analyzer_eval(strlen(dst) >= 4); // expected-warning{{TRUE}}
-}
-
void strcat_symbolic_dst_length_taint(char *dst) {
scanf("%s", dst); // Taint data.
strcat(dst, "1234");
@@ -521,17 +515,6 @@ void strncpy_exactly_matching_buffer(char *y) {
clang_analyzer_eval(strlen(x) > 4); // expected-warning{{UNKNOWN}}
}
-void strncpy_exactly_matching_buffer2(char *y) {
- if (strlen(y) >= 4)
- return;
-
- char x[4];
- strncpy(x, y, 4); // no-warning
-
- // This time, we know that y fits in x anyway.
- clang_analyzer_eval(strlen(x) <= 3); // expected-warning{{TRUE}}
-}
-
void strncpy_zero(char *src) {
char dst[] = "123";
strncpy(dst, src, 0); // no-warning
@@ -1039,3 +1022,30 @@ void strncasecmp_diff_length_6() {
void strncasecmp_embedded_null () {
clang_analyzer_eval(strncasecmp("ab\0zz", "ab\0yy", 4) == 0); // expected-warning{{TRUE}}
}
+
+//===----------------------------------------------------------------------===
+// FIXMEs
+//===----------------------------------------------------------------------===
+
+// The analyzer_eval call below should evaluate to true. We are being too
+// aggressive in marking the (length of) src symbol dead. The length of dst
+// depends on src. This could be explicitely specified in the checker or the
+// logic for handling MetadataSymbol in SymbolManager needs to change.
+void strcat_symbolic_src_length(char *src) {
+ char dst[8] = "1234";
+ strcat(dst, src);
+ clang_analyzer_eval(strlen(dst) >= 4); // expected-warning{{UNKNOWN}}
+}
+
+// The analyzer_eval call below should evaluate to true. Most likely the same
+// issue as the test above.
+void strncpy_exactly_matching_buffer2(char *y) {
+ if (strlen(y) >= 4)
+ return;
+
+ char x[4];
+ strncpy(x, y, 4); // no-warning
+
+ // This time, we know that y fits in x anyway.
+ clang_analyzer_eval(strlen(x) <= 3); // expected-warning{{UNKNOWN}}
+}