martong updated this revision to Diff 435152.
martong added a comment.

- Rebase to llvm/main


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D117229/new/

https://reviews.llvm.org/D117229

Files:
  clang/include/clang/StaticAnalyzer/Core/PathSensitive/SValBuilder.h
  clang/lib/StaticAnalyzer/Core/SValBuilder.cpp
  clang/test/Analysis/produce-ptr-to-integer-symbolcast.cpp
  clang/test/Analysis/symbol-simplification-mem-region-to-int-cast.cpp

Index: clang/test/Analysis/symbol-simplification-mem-region-to-int-cast.cpp
===================================================================
--- /dev/null
+++ clang/test/Analysis/symbol-simplification-mem-region-to-int-cast.cpp
@@ -0,0 +1,44 @@
+// RUN: %clang_analyze_cc1 %s \
+// RUN:   -analyzer-checker=core \
+// RUN:   -analyzer-checker=debug.ExprInspection \
+// RUN:   -analyzer-config eagerly-assume=false \
+// RUN:   -analyzer-config support-symbolic-integer-casts=true \
+// RUN:   -verify
+
+template <class T>
+void clang_analyzer_dump(T);
+
+void clang_analyzer_eval(bool);
+
+void test_memory_region_to_integer_cast_and_symbol_simplification1(int *p) {
+  long p_as_integer = (long)p;
+  clang_analyzer_dump(p_as_integer);      // expected-warning{{(long) (reg_$0<int * p>)}}
+  if (42 - p_as_integer < 42)
+    return;
+  // 42 - p_as_integer >= 42
+  // p_as_integer <= 0
+
+  if (p)
+    return;
+  clang_analyzer_eval(p == 0);            // expected-warning{{TRUE}}
+  clang_analyzer_eval(p_as_integer == 0); // expected-warning{{TRUE}}
+
+  (void)p_as_integer;
+  (void)p;
+}
+
+void test_memory_region_to_integer_cast_and_symbol_simplification2(int *p) {
+  long p_as_integer = (long)p;
+  if (42 - p_as_integer < 42)
+    return;
+  // 42 - p_as_integer >= 42
+  // p_as_integer <= 0
+
+  if (p_as_integer)
+    return;
+  clang_analyzer_eval(p == 0);            // expected-warning{{UNKNOWN}}
+  clang_analyzer_eval(p_as_integer == 0); // expected-warning{{TRUE}}
+
+  (void)p_as_integer;
+  (void)p;
+}
Index: clang/test/Analysis/produce-ptr-to-integer-symbolcast.cpp
===================================================================
--- /dev/null
+++ clang/test/Analysis/produce-ptr-to-integer-symbolcast.cpp
@@ -0,0 +1,31 @@
+// RUN: %clang_analyze_cc1 %s \
+// RUN:   -analyzer-checker=core \
+// RUN:   -analyzer-checker=debug.ExprInspection \
+// RUN:   -analyzer-config eagerly-assume=false \
+// RUN:   -analyzer-config support-symbolic-integer-casts=true \
+// RUN:   -triple x86_64-pc-linux-gnu \
+// RUN:   -verify
+
+template <class T>
+void clang_analyzer_dump(T);
+
+void test_memory_region_to_integer_cast(int *p) {
+  long p_int = (long)p;
+  clang_analyzer_dump(p);     // expected-warning{{&SymRegion{reg_$0<int * p>}}}
+  clang_analyzer_dump(p_int); // expected-warning{{(long) (reg_$0<int * p>)}}
+}
+
+void test_label_to_integer_cast(bool coin) {
+  int x = 0;
+p: ++x;
+  if (coin)
+    goto p;
+
+  // FIXME, below we should produce a SymbolCast instead of the LocAsInteger.
+  // However, for that we'd need to be able to store a loc::GotoLabel SVal
+  // inside the SymbolCast. But currently we can put only another SymExpr
+  // inside a SymbolCast.
+
+  // Use of GNU address-of-label extension.
+  clang_analyzer_dump((long)&&p); // expected-warning{{&&p [as 64 bit integer]}}
+}
Index: clang/lib/StaticAnalyzer/Core/SValBuilder.cpp
===================================================================
--- clang/lib/StaticAnalyzer/Core/SValBuilder.cpp
+++ clang/lib/StaticAnalyzer/Core/SValBuilder.cpp
@@ -795,6 +795,16 @@
       //    QualType elemTy = cast<ArrayType>(originalTy)->getElementType();
       //    QualType pointerTy = C.getPointerType(elemTy);
     }
+
+    AnalyzerOptions &Opts =
+        StateMgr.getOwningEngine().getAnalysisManager().getAnalyzerOptions();
+    if (Opts.ShouldSupportSymbolicIntegerCasts) {
+      const MemRegion *R = V.getRegion();
+      if (R && !OriginalTy.isNull())
+        if (const auto *SR = dyn_cast<SymbolicRegion>(R))
+          return simplifySymbolCast(SR->getSymbol(), CastTy);
+    }
+
     const unsigned BitWidth = Context.getIntWidth(CastTy);
     return makeLocAsInteger(Val.castAs<Loc>(), BitWidth);
   }
@@ -1031,8 +1041,12 @@
   return V;
 }
 
-nonloc::SymbolVal SValBuilder::simplifySymbolCast(nonloc::SymbolVal V,
+nonloc::SymbolVal SValBuilder::simplifySymbolCast(SymbolRef SE,
                                                   QualType CastTy) {
+  QualType T = Context.getCanonicalType(SE->getType());
+  if (!isa<SymbolCast>(SE))
+    return makeNonLoc(SE, T, CastTy);
+
   // We use seven conditions to recognize a simplification case.
   // For the clarity let `CastTy` be `C`, SE->getType() - `T`, root type - `R`,
   // prefix `u` for unsigned, `s` for signed, no prefix - any sign:
@@ -1066,15 +1080,6 @@
   //  (uint)(ushort)(ushort x) -> (uint)(ushort x)
   //  (llong)(ulong)(uint x) -> (llong)(uint x) (sizeof(ulong) == sizeof(uint))
 
-  SymbolRef SE = V.getSymbol();
-  QualType T = Context.getCanonicalType(SE->getType());
-
-  if (T == CastTy)
-    return V;
-
-  if (!isa<SymbolCast>(SE))
-    return makeNonLoc(SE, T, CastTy);
-
   SymbolRef RootSym = cast<SymbolCast>(SE)->getOperand();
   QualType RT = RootSym->getType().getCanonicalType();
 
@@ -1102,3 +1107,14 @@
 
   return makeNonLoc(SE, T, CastTy);
 }
+
+nonloc::SymbolVal SValBuilder::simplifySymbolCast(nonloc::SymbolVal V,
+                                                  QualType CastTy) {
+  assert(CastTy == Context.getCanonicalType(CastTy) &&
+         "The CastTy shall be canonical!");
+  SymbolRef SE = V.getSymbol();
+  QualType T = Context.getCanonicalType(SE->getType());
+  if (T == CastTy)
+    return V;
+  return simplifySymbolCast(SE, CastTy);
+}
Index: clang/include/clang/StaticAnalyzer/Core/PathSensitive/SValBuilder.h
===================================================================
--- clang/include/clang/StaticAnalyzer/Core/PathSensitive/SValBuilder.h
+++ clang/include/clang/StaticAnalyzer/Core/PathSensitive/SValBuilder.h
@@ -108,6 +108,8 @@
   /// \note: Currently only support integral casts.
   nonloc::SymbolVal simplifySymbolCast(nonloc::SymbolVal V, QualType CastTy);
 
+  nonloc::SymbolVal simplifySymbolCast(SymbolRef SE, QualType CastTy);
+
 public:
   SValBuilder(llvm::BumpPtrAllocator &alloc, ASTContext &context,
               ProgramStateManager &stateMgr);
_______________________________________________
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to