r331563 - [analyzer] Invalidate union regions properly. Don't hesitate to load later.

Artem Dergachev via cfe-commits cfe-commits at lists.llvm.org
Fri May 4 15:19:32 PDT 2018


Author: dergachev
Date: Fri May  4 15:19:32 2018
New Revision: 331563

URL: http://llvm.org/viewvc/llvm-project?rev=331563&view=rev
Log:
[analyzer] Invalidate union regions properly. Don't hesitate to load later.

We weren't invalidating our unions correctly. The previous behavior in
invalidateRegionsWorker::VisitCluster() was to direct-bind an UnknownVal
to the union (at offset 0).

For that reason we were never actually loading default bindings from our unions,
because there never was any default binding to load, and the value
that is presumed when there's no default binding to load
is usually completely incorrect (eg. UndefinedVal for stack unions).

The new behavior is to default-bind a conjured symbol (of irrelevant type)
to the union that's being invalidated, similarly to what we do for structures
and classes. Then it becomes safe to load the value properly.

Differential Revision: https://reviews.llvm.org/D45241

Modified:
    cfe/trunk/lib/StaticAnalyzer/Core/RegionStore.cpp
    cfe/trunk/test/Analysis/unions.cpp

Modified: cfe/trunk/lib/StaticAnalyzer/Core/RegionStore.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/StaticAnalyzer/Core/RegionStore.cpp?rev=331563&r1=331562&r2=331563&view=diff
==============================================================================
--- cfe/trunk/lib/StaticAnalyzer/Core/RegionStore.cpp (original)
+++ cfe/trunk/lib/StaticAnalyzer/Core/RegionStore.cpp Fri May  4 15:19:32 2018
@@ -230,11 +230,6 @@ Optional<SVal> RegionBindingsRef::getDir
 }
 
 Optional<SVal> RegionBindingsRef::getDefaultBinding(const MemRegion *R) const {
-  if (R->isBoundable())
-    if (const TypedValueRegion *TR = dyn_cast<TypedValueRegion>(R))
-      if (TR->getValueType()->isUnionType())
-        return UnknownVal();
-
   return Optional<SVal>::create(lookup(R, BindingKey::Default));
 }
 
@@ -1099,7 +1094,7 @@ void invalidateRegionsWorker::VisitClust
     return;
   }
 
-  if (T->isStructureOrClassType()) {
+  if (T->isRecordType()) {
     // Invalidate the region by setting its default value to
     // conjured symbol. The type of the symbol is irrelevant.
     DefinedOrUnknownSVal V = svalBuilder.conjureSymbolVal(baseR, Ex, LCtx,

Modified: cfe/trunk/test/Analysis/unions.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Analysis/unions.cpp?rev=331563&r1=331562&r2=331563&view=diff
==============================================================================
--- cfe/trunk/test/Analysis/unions.cpp (original)
+++ cfe/trunk/test/Analysis/unions.cpp Fri May  4 15:19:32 2018
@@ -79,8 +79,7 @@ namespace PR17596 {
     IntOrString vv;
     vv.i = 5;
     uu = vv;
-    // FIXME: Should be true.
-    clang_analyzer_eval(uu.i == 5); // expected-warning{{UNKNOWN}}
+    clang_analyzer_eval(uu.i == 5); // expected-warning{{TRUE}}
   }
 
   void testInvalidation() {
@@ -106,3 +105,20 @@ namespace PR17596 {
     clang_analyzer_eval(uu.s[0] == 'a'); // expected-warning{{UNKNOWN}}
   }
 }
+
+namespace assume_union_contents {
+union U {
+  int x;
+};
+
+U get();
+
+void test() {
+  U u = get();
+  int y = 0;
+  if (u.x)
+    y = 1;
+  if (u.x)
+    y = 1 / y; // no-warning
+}
+} // end namespace assume_union_contents




More information about the cfe-commits mailing list