Author: xazax Date: Tue Jan 29 02:27:14 2019 New Revision: 352473 URL: http://llvm.org/viewvc/llvm-project?rev=352473&view=rev Log: [analyzer] Toning down invalidation a bit
When a function takes the address of a field the analyzer will no longer assume that the function will change other fields of the enclosing structs. Differential Revision: https://reviews.llvm.org/D57230 Modified: cfe/trunk/lib/StaticAnalyzer/Core/CallEvent.cpp cfe/trunk/test/Analysis/call-invalidation.cpp cfe/trunk/test/Analysis/cxx-uninitialized-object.cpp cfe/trunk/test/Analysis/malloc.c cfe/trunk/test/Analysis/taint-generic.c cfe/trunk/test/Analysis/taint-tester.c Modified: cfe/trunk/lib/StaticAnalyzer/Core/CallEvent.cpp URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/StaticAnalyzer/Core/CallEvent.cpp?rev=352473&r1=352472&r2=352473&view=diff ============================================================================== --- cfe/trunk/lib/StaticAnalyzer/Core/CallEvent.cpp (original) +++ cfe/trunk/lib/StaticAnalyzer/Core/CallEvent.cpp Tue Jan 29 02:27:14 2019 @@ -303,11 +303,23 @@ ProgramStateRef CallEvent::invalidateReg for (unsigned Idx = 0, Count = getNumArgs(); Idx != Count; ++Idx) { // Mark this region for invalidation. We batch invalidate regions // below for efficiency. - if (PreserveArgs.count(Idx)) - if (const MemRegion *MR = getArgSVal(Idx).getAsRegion()) - ETraits.setTrait(MR->getBaseRegion(), - RegionAndSymbolInvalidationTraits::TK_PreserveContents); - // TODO: Factor this out + handle the lower level const pointers. + if (const MemRegion *MR = getArgSVal(Idx).getAsRegion()) { + bool UseBaseRegion = true; + if (const auto *FR = MR->getAs<FieldRegion>()) { + if (const auto *TVR = FR->getSuperRegion()->getAs<TypedValueRegion>()) { + if (!TVR->getValueType()->isUnionType()) { + ETraits.setTrait(MR, RegionAndSymbolInvalidationTraits:: + TK_DoNotInvalidateSuperRegion); + UseBaseRegion = false; + } + } + } + // todo: factor this out + handle the lower level const pointers. + if (PreserveArgs.count(Idx)) + ETraits.setTrait( + UseBaseRegion ? MR->getBaseRegion() : MR, + RegionAndSymbolInvalidationTraits::TK_PreserveContents); + } ValuesToInvalidate.push_back(getArgSVal(Idx)); Modified: cfe/trunk/test/Analysis/call-invalidation.cpp URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Analysis/call-invalidation.cpp?rev=352473&r1=352472&r2=352473&view=diff ============================================================================== --- cfe/trunk/test/Analysis/call-invalidation.cpp (original) +++ cfe/trunk/test/Analysis/call-invalidation.cpp Tue Jan 29 02:27:14 2019 @@ -132,18 +132,21 @@ void testInvalidationThroughBaseRegionPo PlainStruct s1; s1.x = 1; s1.z = 1; + s1.y = 1; clang_analyzer_eval(s1.x == 1); // expected-warning{{TRUE}} clang_analyzer_eval(s1.z == 1); // expected-warning{{TRUE}} // Not only passing a structure pointer through const pointer parameter, // but also passing a field pointer through const pointer parameter // should preserve the contents of the structure. useAnythingConst(&(s1.y)); + clang_analyzer_eval(s1.y == 1); // expected-warning{{TRUE}} clang_analyzer_eval(s1.x == 1); // expected-warning{{TRUE}} // FIXME: Should say "UNKNOWN", because it is not uncommon to // modify a mutable member variable through const pointer. clang_analyzer_eval(s1.z == 1); // expected-warning{{TRUE}} useAnything(&(s1.y)); - clang_analyzer_eval(s1.x == 1); // expected-warning{{UNKNOWN}} + clang_analyzer_eval(s1.x == 1); // expected-warning{{TRUE}} + clang_analyzer_eval(s1.y == 1); // expected-warning{{UNKNOWN}} } Modified: cfe/trunk/test/Analysis/cxx-uninitialized-object.cpp URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Analysis/cxx-uninitialized-object.cpp?rev=352473&r1=352472&r2=352473&view=diff ============================================================================== --- cfe/trunk/test/Analysis/cxx-uninitialized-object.cpp (original) +++ cfe/trunk/test/Analysis/cxx-uninitialized-object.cpp Tue Jan 29 02:27:14 2019 @@ -358,7 +358,7 @@ template <class T> void wontInitialize(const T &); class PassingToUnknownFunctionTest1 { - int a, b; + int a, b; // expected-note{{uninitialized field 'this->b'}} public: PassingToUnknownFunctionTest1() { @@ -368,8 +368,7 @@ public: } PassingToUnknownFunctionTest1(int) { - mayInitialize(a); - // All good! + mayInitialize(a); // expected-warning{{1 uninitialized field at the end of the constructor call}} } PassingToUnknownFunctionTest1(int, int) { Modified: cfe/trunk/test/Analysis/malloc.c URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Analysis/malloc.c?rev=352473&r1=352472&r2=352473&view=diff ============================================================================== --- cfe/trunk/test/Analysis/malloc.c (original) +++ cfe/trunk/test/Analysis/malloc.c Tue Jan 29 02:27:14 2019 @@ -1758,8 +1758,8 @@ void constEscape(const void *ptr); void testConstEscapeThroughAnotherField() { struct IntAndPtr s; s.p = malloc(sizeof(int)); - constEscape(&(s.x)); // could free s->p! -} // no-warning + constEscape(&(s.x)); +} // expected-warning {{Potential leak of memory pointed to by 's.p'}} // PR15623 int testNoCheckerDataPropogationFromLogicalOpOperandToOpResult(void) { Modified: cfe/trunk/test/Analysis/taint-generic.c URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Analysis/taint-generic.c?rev=352473&r1=352472&r2=352473&view=diff ============================================================================== --- cfe/trunk/test/Analysis/taint-generic.c (original) +++ cfe/trunk/test/Analysis/taint-generic.c Tue Jan 29 02:27:14 2019 @@ -231,6 +231,7 @@ void testUnion() { int sock = socket(AF_INET, SOCK_STREAM, 0); read(sock, &tainted.y, sizeof(tainted.y)); + tainted.x = 0; // FIXME: overlapping regions aren't detected by isTainted yet __builtin_memcpy(buffer, tainted.y, tainted.x); } Modified: cfe/trunk/test/Analysis/taint-tester.c URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Analysis/taint-tester.c?rev=352473&r1=352472&r2=352473&view=diff ============================================================================== --- cfe/trunk/test/Analysis/taint-tester.c (original) +++ cfe/trunk/test/Analysis/taint-tester.c Tue Jan 29 02:27:14 2019 @@ -51,7 +51,7 @@ void taintTracking(int x) { scanf("%d", &xy.y); scanf("%d", &xy.x); int tx = xy.x; // expected-warning + {{tainted}} - int ty = xy.y; // FIXME: This should be tainted as well. + int ty = xy.y; // expected-warning + {{tainted}} char ntz = xy.z;// no warning // Now, scanf scans both. scanf("%d %d", &xy.y, &xy.x); _______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits