From: Anna Zaks Date: Fri, 15 Mar 2013 23:34:29 +0000 (+0000) Subject: [analyzer] Use isLiveRegion to determine when SymbolRegionValue is dead. X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=74c0d6988462c2cb882e7a8b8050fe119a5af56f;p=clang [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 --- 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(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}} +}