Index: lib/StaticAnalyzer/Core/SymbolManager.cpp =================================================================== --- lib/StaticAnalyzer/Core/SymbolManager.cpp +++ lib/StaticAnalyzer/Core/SymbolManager.cpp @@ -459,7 +459,7 @@ KnownLive = isLiveRegion(cast(sym)->getRegion()); break; case SymExpr::MetadataKind: - KnownLive = MetadataInUse.count(sym) && + KnownLive = MetadataInUse.count(sym) || isLiveRegion(cast(sym)->getRegion()); if (KnownLive) MetadataInUse.erase(sym); Index: test/Analysis/string.c =================================================================== --- test/Analysis/string.c +++ test/Analysis/string.c @@ -414,6 +414,12 @@ 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"); @@ -520,6 +526,17 @@ 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 @@ -1079,30 +1096,3 @@ // character. For now, we just model the invalidation. clang_analyzer_eval(str[1] == 'b'); // expected-warning{{UNKNOWN}} } - -//===----------------------------------------------------------------------=== -// 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}} -}