ASDenysPetrov updated this revision to Diff 326651.
ASDenysPetrov added a comment.

A bit improved.


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

https://reviews.llvm.org/D97388

Files:
  clang/include/clang/StaticAnalyzer/Core/PathSensitive/SValBuilder.h
  clang/lib/StaticAnalyzer/Core/ExprEngineC.cpp
  clang/lib/StaticAnalyzer/Core/SValBuilder.cpp

Index: clang/lib/StaticAnalyzer/Core/SValBuilder.cpp
===================================================================
--- clang/lib/StaticAnalyzer/Core/SValBuilder.cpp
+++ clang/lib/StaticAnalyzer/Core/SValBuilder.cpp
@@ -493,44 +493,6 @@
   return true;
 }
 
-// Handles casts of type CK_IntegralCast.
-// At the moment, this function will redirect to evalCast, except when the range
-// of the original value is known to be greater than the max of the target type.
-SVal SValBuilder::evalIntegralCast(ProgramStateRef state, SVal val,
-                                   QualType castTy, QualType originalTy) {
-  // No truncations if target type is big enough.
-  if (getContext().getTypeSize(castTy) >= getContext().getTypeSize(originalTy))
-    return evalCast(state, val, castTy, originalTy);
-
-  SymbolRef se = val.getAsSymbol();
-  if (!se) // Let evalCast handle non symbolic expressions.
-    return evalCast(state, val, castTy, originalTy);
-
-  // Find the maximum value of the target type.
-  APSIntType ToType(getContext().getTypeSize(castTy),
-                    castTy->isUnsignedIntegerType());
-  llvm::APSInt ToTypeMax = ToType.getMaxValue();
-  NonLoc ToTypeMaxVal =
-      makeIntVal(ToTypeMax.isUnsigned() ? ToTypeMax.getZExtValue()
-                                        : ToTypeMax.getSExtValue(),
-                 castTy)
-          .castAs<NonLoc>();
-  // Check the range of the symbol being casted against the maximum value of the
-  // target type.
-  NonLoc FromVal = val.castAs<NonLoc>();
-  QualType CmpTy = getConditionType();
-  NonLoc CompVal =
-      evalBinOpNN(state, BO_LE, FromVal, ToTypeMaxVal, CmpTy).castAs<NonLoc>();
-  ProgramStateRef IsNotTruncated, IsTruncated;
-  std::tie(IsNotTruncated, IsTruncated) = state->assume(CompVal);
-  if (!IsNotTruncated && IsTruncated) {
-    // Symbol is truncated so we evaluate it as a cast.
-    NonLoc CastVal = makeNonLoc(se, originalTy, castTy);
-    return CastVal;
-  }
-  return evalCast(state, val, castTy, originalTy);
-}
-
 //===----------------------------------------------------------------------===//
 // Cast methods.
 // `evalCast` is the main method
@@ -915,6 +877,37 @@
       return makeNonLoc(SE, BO_NE, BVF.getValue(0, SE->getType()), CastTy);
     }
   } else {
+    // Symbol to integer.
+    if (!OriginalTy.isNull() && CastTy->isIntegralOrEnumerationType()) {
+      // Symbolic integer to integer.
+      if (OriginalTy->isIntegralOrEnumerationType()) {
+        // Truncation.
+        if (getContext().getTypeSize(CastTy) <
+            getContext().getTypeSize(OriginalTy)) {
+          // Find the maximum value of the target type.
+          llvm::APSInt ToTypeMax =
+              llvm::APSInt::getMaxValue(getContext().getTypeSize(CastTy),
+                                        CastTy->isUnsignedIntegerType());
+          NonLoc ToTypeMaxVal =
+              makeIntVal(ToTypeMax.getExtValue(), CastTy).castAs<NonLoc>();
+          // Check the range of the symbol being casted against the maximum
+          // value of the target type.
+          NonLoc FromVal = V.castAs<NonLoc>();
+          QualType CmpTy = getConditionType();
+          NonLoc CompVal =
+              evalBinOpNN(State, BO_LE, FromVal, ToTypeMaxVal, CmpTy)
+                  .castAs<NonLoc>();
+          ProgramStateRef IsNotTruncated, IsTruncated;
+          std::tie(IsNotTruncated, IsTruncated) = State->assume(CompVal);
+          if (!IsNotTruncated && IsTruncated) {
+            // Symbol is truncated so we evaluate it as a cast.
+            NonLoc CastVal = makeNonLoc(SE, OriginalTy, CastTy);
+            return CastVal;
+          }
+        }
+      }
+    }
+
     // Symbol to integer, float.
     QualType T = Context.getCanonicalType(SE->getType());
     // If types are the same or both are integers, ignore the cast.
Index: clang/lib/StaticAnalyzer/Core/ExprEngineC.cpp
===================================================================
--- clang/lib/StaticAnalyzer/Core/ExprEngineC.cpp
+++ clang/lib/StaticAnalyzer/Core/ExprEngineC.cpp
@@ -431,7 +431,7 @@
       case CK_IntegralCast: {
         // Delegate to SValBuilder to process.
         SVal V = state->getSVal(Ex, LCtx);
-        V = svalBuilder.evalIntegralCast(state, V, T, ExTy);
+        V = svalBuilder.evalCast(state, V, T, ExTy);
         state = state->BindExpr(CastE, LCtx, V);
         Bldr.generateNode(CastE, Pred, state);
         continue;
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
@@ -124,10 +124,6 @@
   SVal evalCast(ProgramStateRef State, SVal V, QualType CastTy,
                 QualType OriginalTy = QualType{});
 
-  // Handles casts of type CK_IntegralCast.
-  SVal evalIntegralCast(ProgramStateRef state, SVal val, QualType castTy,
-                        QualType originalType);
-
   virtual SVal evalMinus(NonLoc val) = 0;
 
   virtual SVal evalComplement(NonLoc val) = 0;
_______________________________________________
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to