NoQ created this revision.
NoQ added reviewers: dcoughlin, xazax.hun, a.sidorin, george.karpenkov, szepet, 
rnkovacs, mikhail.ramalho.
Herald added subscribers: cfe-commits, baloghadamsoftware.

Add one more defensive check to prevent crashes on trying to simplify a 
`SymSymExpr` with different `Loc`-ness of operands. This fix is similar to 
https://reviews.llvm.org/D49703 and addresses a regression caused by 
https://reviews.llvm.org/D48650.

When an operation between a `nonloc::LocAsInteger` and a non-pointer symbol is 
performed, the `LocAsInteger`-specific part of information is lost. When the 
non-pointer symbol is collapsing into a constant, we cannot easily re-evaluate 
the result, because we need to recover the missing g`LocAsInteger`-specific 
information (eg., integer type, or the very fact that this pointer was at some 
point converted to an integer).


Repository:
  rC Clang

https://reviews.llvm.org/D49749

Files:
  lib/StaticAnalyzer/Core/SimpleSValBuilder.cpp
  test/Analysis/casts.c


Index: test/Analysis/casts.c
===================================================================
--- test/Analysis/casts.c
+++ test/Analysis/casts.c
@@ -175,3 +175,10 @@
 void testLocNonLocSymbolAssume(int a, int *b) {
   if ((int)b < a) {}
 }
+
+void testLocNonLocSymbolRemainder(int a, int *b) {
+  int c = ((int)b) % a;
+  if (a == 1) {
+    c += 1;
+  }
+}
Index: lib/StaticAnalyzer/Core/SimpleSValBuilder.cpp
===================================================================
--- lib/StaticAnalyzer/Core/SimpleSValBuilder.cpp
+++ lib/StaticAnalyzer/Core/SimpleSValBuilder.cpp
@@ -1291,6 +1291,17 @@
       if (I != Cached.end())
         return I->second;
 
+      // For now don't try to simplify mixed Loc/NonLoc expressions
+      // because they often appear from LocAsInteger operations
+      // and we don't know how to combine a LocAsInteger
+      // with a concrete value.
+      if (Loc::isLocType(S->getLHS()->getType()) !=
+          Loc::isLocType(S->getRHS()->getType())) {
+        SVal V = SVB.makeSymbolVal(S);
+        Cached[S] = V;
+        return V;
+      }
+
       SVal LHS = Visit(S->getLHS());
       SVal RHS = Visit(S->getRHS());
       if (isUnchanged(S->getLHS(), LHS) && isUnchanged(S->getRHS(), RHS)) {


Index: test/Analysis/casts.c
===================================================================
--- test/Analysis/casts.c
+++ test/Analysis/casts.c
@@ -175,3 +175,10 @@
 void testLocNonLocSymbolAssume(int a, int *b) {
   if ((int)b < a) {}
 }
+
+void testLocNonLocSymbolRemainder(int a, int *b) {
+  int c = ((int)b) % a;
+  if (a == 1) {
+    c += 1;
+  }
+}
Index: lib/StaticAnalyzer/Core/SimpleSValBuilder.cpp
===================================================================
--- lib/StaticAnalyzer/Core/SimpleSValBuilder.cpp
+++ lib/StaticAnalyzer/Core/SimpleSValBuilder.cpp
@@ -1291,6 +1291,17 @@
       if (I != Cached.end())
         return I->second;
 
+      // For now don't try to simplify mixed Loc/NonLoc expressions
+      // because they often appear from LocAsInteger operations
+      // and we don't know how to combine a LocAsInteger
+      // with a concrete value.
+      if (Loc::isLocType(S->getLHS()->getType()) !=
+          Loc::isLocType(S->getRHS()->getType())) {
+        SVal V = SVB.makeSymbolVal(S);
+        Cached[S] = V;
+        return V;
+      }
+
       SVal LHS = Visit(S->getLHS());
       SVal RHS = Visit(S->getRHS());
       if (isUnchanged(S->getLHS(), LHS) && isUnchanged(S->getRHS(), RHS)) {
_______________________________________________
cfe-commits mailing list
cfe-commits@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to