r352473 - [analyzer] Toning down invalidation a bit

Gabor Horvath via cfe-commits cfe-commits at lists.llvm.org
Tue Jan 29 02:27:14 PST 2019


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);




More information about the cfe-commits mailing list