Replace SVal llvm::cast support to be well-defined.
authorDavid Blaikie <dblaikie@gmail.com>
Wed, 20 Feb 2013 05:52:05 +0000 (05:52 +0000)
committerDavid Blaikie <dblaikie@gmail.com>
Wed, 20 Feb 2013 05:52:05 +0000 (05:52 +0000)
See r175462 for another example/more details.

llvm-svn: 175594

44 files changed:
clang/include/clang/StaticAnalyzer/Core/PathSensitive/ExprEngine.h
clang/include/clang/StaticAnalyzer/Core/PathSensitive/MemRegion.h
clang/include/clang/StaticAnalyzer/Core/PathSensitive/ProgramState.h
clang/include/clang/StaticAnalyzer/Core/PathSensitive/SVals.h
clang/lib/StaticAnalyzer/Checkers/ArrayBoundCheckerV2.cpp
clang/lib/StaticAnalyzer/Checkers/AttrNonNullChecker.cpp
clang/lib/StaticAnalyzer/Checkers/BasicObjCFoundationChecks.cpp
clang/lib/StaticAnalyzer/Checkers/BoolAssignmentChecker.cpp
clang/lib/StaticAnalyzer/Checkers/BuiltinFunctionChecker.cpp
clang/lib/StaticAnalyzer/Checkers/CStringChecker.cpp
clang/lib/StaticAnalyzer/Checkers/CallAndMessageChecker.cpp
clang/lib/StaticAnalyzer/Checkers/DereferenceChecker.cpp
clang/lib/StaticAnalyzer/Checkers/DivZeroChecker.cpp
clang/lib/StaticAnalyzer/Checkers/ExprInspectionChecker.cpp
clang/lib/StaticAnalyzer/Checkers/GenericTaintChecker.cpp
clang/lib/StaticAnalyzer/Checkers/IdempotentOperationChecker.cpp
clang/lib/StaticAnalyzer/Checkers/MacOSKeychainAPIChecker.cpp
clang/lib/StaticAnalyzer/Checkers/MallocChecker.cpp
clang/lib/StaticAnalyzer/Checkers/NSErrorChecker.cpp
clang/lib/StaticAnalyzer/Checkers/ObjCAtSyncChecker.cpp
clang/lib/StaticAnalyzer/Checkers/ObjCContainersChecker.cpp
clang/lib/StaticAnalyzer/Checkers/ObjCSelfInitChecker.cpp
clang/lib/StaticAnalyzer/Checkers/PthreadLockChecker.cpp
clang/lib/StaticAnalyzer/Checkers/RetainCountChecker.cpp
clang/lib/StaticAnalyzer/Checkers/StreamChecker.cpp
clang/lib/StaticAnalyzer/Checkers/UnixAPIChecker.cpp
clang/lib/StaticAnalyzer/Checkers/VLASizeChecker.cpp
clang/lib/StaticAnalyzer/Core/BugReporterVisitors.cpp
clang/lib/StaticAnalyzer/Core/CallEvent.cpp
clang/lib/StaticAnalyzer/Core/Environment.cpp
clang/lib/StaticAnalyzer/Core/ExprEngine.cpp
clang/lib/StaticAnalyzer/Core/ExprEngineC.cpp
clang/lib/StaticAnalyzer/Core/ExprEngineCXX.cpp
clang/lib/StaticAnalyzer/Core/ExprEngineCallAndReturn.cpp
clang/lib/StaticAnalyzer/Core/ExprEngineObjC.cpp
clang/lib/StaticAnalyzer/Core/MemRegion.cpp
clang/lib/StaticAnalyzer/Core/PathDiagnostic.cpp
clang/lib/StaticAnalyzer/Core/ProgramState.cpp
clang/lib/StaticAnalyzer/Core/RegionStore.cpp
clang/lib/StaticAnalyzer/Core/SValBuilder.cpp
clang/lib/StaticAnalyzer/Core/SVals.cpp
clang/lib/StaticAnalyzer/Core/SimpleConstraintManager.cpp
clang/lib/StaticAnalyzer/Core/SimpleSValBuilder.cpp
clang/lib/StaticAnalyzer/Core/Store.cpp

index 598a915..959c1dc 100644 (file)
@@ -429,11 +429,11 @@ public:
     geteagerlyAssumeBinOpBifurcationTags();
 
   SVal evalMinus(SVal X) {
-    return X.isValid() ? svalBuilder.evalMinus(cast<NonLoc>(X)) : X;
+    return X.isValid() ? svalBuilder.evalMinus(X.castAs<NonLoc>()) : X;
   }
 
   SVal evalComplement(SVal X) {
-    return X.isValid() ? svalBuilder.evalComplement(cast<NonLoc>(X)) : X;
+    return X.isValid() ? svalBuilder.evalComplement(X.castAs<NonLoc>()) : X;
   }
 
 public:
@@ -445,7 +445,8 @@ public:
 
   SVal evalBinOp(ProgramStateRef state, BinaryOperator::Opcode op,
                  NonLoc L, SVal R, QualType T) {
-    return R.isValid() ? svalBuilder.evalBinOpNN(state,op,L, cast<NonLoc>(R), T) : R;
+    return R.isValid() ? svalBuilder.evalBinOpNN(state, op, L,
+                                                 R.castAs<NonLoc>(), T) : R;
   }
 
   SVal evalBinOp(ProgramStateRef ST, BinaryOperator::Opcode Op,
index 59225cb..a72273f 100644 (file)
@@ -991,8 +991,8 @@ class ElementRegion : public TypedValueRegion {
   ElementRegion(QualType elementType, NonLoc Idx, const MemRegion* sReg)
     : TypedValueRegion(sReg, ElementRegionKind),
       ElementType(elementType), Index(Idx) {
-    assert((!isa<nonloc::ConcreteInt>(&Idx) ||
-           cast<nonloc::ConcreteInt>(&Idx)->getValue().isSigned()) &&
+    assert((!Idx.getAs<nonloc::ConcreteInt>() ||
+            Idx.castAs<nonloc::ConcreteInt>().getValue().isSigned()) &&
            "The index must be signed");
   }
 
index 0985f12..c23cc49 100644 (file)
@@ -620,22 +620,24 @@ inline ProgramStateRef ProgramState::assume(DefinedOrUnknownSVal Cond,
                                       bool Assumption) const {
   if (Cond.isUnknown())
     return this;
-  
-  return getStateManager().ConstraintMgr->assume(this, cast<DefinedSVal>(Cond),
-                                                 Assumption);
+
+  return getStateManager().ConstraintMgr
+      ->assume(this, Cond.castAs<DefinedSVal>(), Assumption);
 }
   
 inline std::pair<ProgramStateRef , ProgramStateRef >
 ProgramState::assume(DefinedOrUnknownSVal Cond) const {
   if (Cond.isUnknown())
     return std::make_pair(this, this);
-  
-  return getStateManager().ConstraintMgr->assumeDual(this,
-                                                     cast<DefinedSVal>(Cond));
+
+  return getStateManager().ConstraintMgr
+      ->assumeDual(this, Cond.castAs<DefinedSVal>());
 }
 
 inline ProgramStateRef ProgramState::bindLoc(SVal LV, SVal V) const {
-  return !isa<Loc>(LV) ? this : bindLoc(cast<Loc>(LV), V);
+  if (llvm::Optional<Loc> L = LV.getAs<Loc>())
+    return bindLoc(*L, V);
+  return this;
 }
 
 inline Loc ProgramState::getLValue(const VarDecl *VD,
@@ -669,7 +671,7 @@ inline SVal ProgramState::getLValue(const IndirectFieldDecl *D,
 }
 
 inline SVal ProgramState::getLValue(QualType ElementType, SVal Idx, SVal Base) const{
-  if (NonLoc *N = dyn_cast<NonLoc>(&Idx))
+  if (llvm::Optional<NonLoc> N = Idx.getAs<NonLoc>())
     return getStateManager().StoreMgr->getLValueElement(ElementType, *N, Base);
   return UnknownVal();
 }
index d77a796..def060f 100644 (file)
@@ -69,6 +69,25 @@ protected:
 public:
   explicit SVal() : Data(0), Kind(0) {}
 
+  template<typename T>
+  T castAs() const {
+    assert(T::isType(*this));
+    T t;
+    SVal& sv = t;
+    sv = *this;
+    return t;
+  }
+
+  template<typename T>
+  llvm::Optional<T> getAs() const {
+    if (!T::isType(*this))
+      return llvm::Optional<T>();
+    T t;
+    SVal& sv = t;
+    sv = *this;
+    return t;
+  }
+
   /// BufferTy - A temporary buffer to hold a set of SVals.
   typedef SmallVector<SVal,5> BufferTy;
 
@@ -161,8 +180,10 @@ class UndefinedVal : public SVal {
 public:
   UndefinedVal() : SVal(UndefinedKind) {}
 
-  static inline bool classof(const SVal* V) {
-    return V->getBaseKind() == UndefinedKind;
+private:
+  friend class SVal;
+  static bool isType(const SVal& V) {
+    return V.getBaseKind() == UndefinedKind;
   }
 };
 
@@ -174,16 +195,17 @@ private:
   bool isValid() const LLVM_DELETED_FUNCTION;
   
 protected:
+  DefinedOrUnknownSVal() {}
   explicit DefinedOrUnknownSVal(const void *d, bool isLoc, unsigned ValKind)
     : SVal(d, isLoc, ValKind) {}
   
   explicit DefinedOrUnknownSVal(BaseKind k, void *D = NULL)
     : SVal(k, D) {}
   
-public:
-    // Implement isa<T> support.
-  static inline bool classof(const SVal *V) {
-    return !V->isUndef();
+private:
+  friend class SVal;
+  static bool isType(const SVal& V) {
+    return !V.isUndef();
   }
 };
   
@@ -191,8 +213,10 @@ class UnknownVal : public DefinedOrUnknownSVal {
 public:
   explicit UnknownVal() : DefinedOrUnknownSVal(UnknownKind) {}
   
-  static inline bool classof(const SVal *V) {
-    return V->getBaseKind() == UnknownKind;
+private:
+  friend class SVal;
+  static bool isType(const SVal& V) {
+    return V.getBaseKind() == UnknownKind;
   }
 };
 
@@ -204,46 +228,51 @@ private:
   bool isUnknownOrUndef() const LLVM_DELETED_FUNCTION;
   bool isValid() const LLVM_DELETED_FUNCTION;
 protected:
+  DefinedSVal() {}
   explicit DefinedSVal(const void *d, bool isLoc, unsigned ValKind)
     : DefinedOrUnknownSVal(d, isLoc, ValKind) {}
-public:
-  // Implement isa<T> support.
-  static inline bool classof(const SVal *V) {
-    return !V->isUnknownOrUndef();
+private:
+  friend class SVal;
+  static bool isType(const SVal& V) {
+    return !V.isUnknownOrUndef();
   }
 };
 
 class NonLoc : public DefinedSVal {
 protected:
+  NonLoc() {}
   explicit NonLoc(unsigned SubKind, const void *d)
     : DefinedSVal(d, false, SubKind) {}
 
 public:
   void dumpToStream(raw_ostream &Out) const;
 
-  // Implement isa<T> support.
-  static inline bool classof(const SVal* V) {
-    return V->getBaseKind() == NonLocKind;
+private:
+  friend class SVal;
+  static bool isType(const SVal& V) {
+    return V.getBaseKind() == NonLocKind;
   }
 };
 
 class Loc : public DefinedSVal {
 protected:
+  Loc() {}
   explicit Loc(unsigned SubKind, const void *D)
   : DefinedSVal(const_cast<void*>(D), true, SubKind) {}
 
 public:
   void dumpToStream(raw_ostream &Out) const;
 
-  // Implement isa<T> support.
-  static inline bool classof(const SVal* V) {
-    return V->getBaseKind() == LocKind;
-  }
-
   static inline bool isLocType(QualType T) {
     return T->isAnyPointerType() || T->isBlockPointerType() || 
            T->isReferenceType();
   }
+
+private:
+  friend class SVal;
+  static bool isType(const SVal& V) {
+    return V.getBaseKind() == LocKind;
+  }
 };
 
 //==------------------------------------------------------------------------==//
@@ -264,17 +293,20 @@ public:
     return (const SymExpr*) Data;
   }
 
-  bool isExpression() {
+  bool isExpression() const {
     return !isa<SymbolData>(getSymbol());
   }
 
-  static inline bool classof(const SVal* V) {
-    return V->getBaseKind() == NonLocKind &&
-           V->getSubKind() == SymbolValKind;
+private:
+  friend class SVal;
+  SymbolVal() {}
+  static bool isType(const SVal& V) {
+    return V.getBaseKind() == NonLocKind &&
+           V.getSubKind() == SymbolValKind;
   }
 
-  static inline bool classof(const NonLoc* V) {
-    return V->getSubKind() == SymbolValKind;
+  static bool isType(const NonLoc& V) {
+    return V.getSubKind() == SymbolValKind;
   }
 };
 
@@ -295,38 +327,40 @@ public:
 
   ConcreteInt evalMinus(SValBuilder &svalBuilder) const;
 
-  // Implement isa<T> support.
-  static inline bool classof(const SVal* V) {
-    return V->getBaseKind() == NonLocKind &&
-           V->getSubKind() == ConcreteIntKind;
+private:
+  friend class SVal;
+  ConcreteInt() {}
+  static bool isType(const SVal& V) {
+    return V.getBaseKind() == NonLocKind &&
+           V.getSubKind() == ConcreteIntKind;
   }
 
-  static inline bool classof(const NonLoc* V) {
-    return V->getSubKind() == ConcreteIntKind;
+  static bool isType(const NonLoc& V) {
+    return V.getSubKind() == ConcreteIntKind;
   }
 };
 
 class LocAsInteger : public NonLoc {
   friend class ento::SValBuilder;
 
-  explicit LocAsInteger(const std::pair<SVal, uintptr_t>& data) :
-    NonLoc(LocAsIntegerKind, &data) {
-      assert (isa<Loc>(data.first));
-    }
+  explicit LocAsInteger(const std::pair<SVal, uintptr_t> &data)
+      : NonLoc(LocAsIntegerKind, &data) {
+    assert (data.first.getAs<Loc>());
+  }
 
 public:
 
   Loc getLoc() const {
     const std::pair<SVal, uintptr_t> *D =
       static_cast<const std::pair<SVal, uintptr_t> *>(Data);
-    return cast<Loc>(D->first);
+    return D->first.castAs<Loc>();
   }
 
-  const Loc& getPersistentLoc() const {
+  Loc getPersistentLoc() const {
     const std::pair<SVal, uintptr_t> *D =
       static_cast<const std::pair<SVal, uintptr_t> *>(Data);
     const SVal& V = D->first;
-    return cast<Loc>(V);
+    return V.castAs<Loc>();
   }
 
   unsigned getNumBits() const {
@@ -335,14 +369,16 @@ public:
     return D->second;
   }
 
-  // Implement isa<T> support.
-  static inline bool classof(const SVal* V) {
-    return V->getBaseKind() == NonLocKind &&
-           V->getSubKind() == LocAsIntegerKind;
+private:
+  friend class SVal;
+  LocAsInteger() {}
+  static bool isType(const SVal& V) {
+    return V.getBaseKind() == NonLocKind &&
+           V.getSubKind() == LocAsIntegerKind;
   }
 
-  static inline bool classof(const NonLoc* V) {
-    return V->getSubKind() == LocAsIntegerKind;
+  static bool isType(const NonLoc& V) {
+    return V.getSubKind() == LocAsIntegerKind;
   }
 };
 
@@ -360,12 +396,15 @@ public:
   iterator begin() const;
   iterator end() const;
 
-  static bool classof(const SVal* V) {
-    return V->getBaseKind() == NonLocKind && V->getSubKind() == CompoundValKind;
+private:
+  friend class SVal;
+  CompoundVal() {}
+  static bool isType(const SVal& V) {
+    return V.getBaseKind() == NonLocKind && V.getSubKind() == CompoundValKind;
   }
 
-  static bool classof(const NonLoc* V) {
-    return V->getSubKind() == CompoundValKind;
+  static bool isType(const NonLoc& V) {
+    return V.getSubKind() == CompoundValKind;
   }
 };
 
@@ -381,12 +420,15 @@ public:
   const void *getStore() const;
   const TypedValueRegion *getRegion() const;
 
-  static bool classof(const SVal *V) {
-    return V->getBaseKind() == NonLocKind &&
-           V->getSubKind() == LazyCompoundValKind;
+private:
+  friend class SVal;
+  LazyCompoundVal() {}
+  static bool isType(const SVal& V) {
+    return V.getBaseKind() == NonLocKind &&
+           V.getSubKind() == LazyCompoundValKind;
   }
-  static bool classof(const NonLoc *V) {
-    return V->getSubKind() == LazyCompoundValKind;
+  static bool isType(const NonLoc& V) {
+    return V.getSubKind() == LazyCompoundValKind;
   }
 };
 
@@ -408,12 +450,15 @@ public:
     return static_cast<const LabelDecl*>(Data);
   }
 
-  static inline bool classof(const SVal* V) {
-    return V->getBaseKind() == LocKind && V->getSubKind() == GotoLabelKind;
+private:
+  friend class SVal;
+  GotoLabel() {}
+  static bool isType(const SVal& V) {
+    return V.getBaseKind() == LocKind && V.getSubKind() == GotoLabelKind;
   }
 
-  static inline bool classof(const Loc* V) {
-    return V->getSubKind() == GotoLabelKind;
+  static bool isType(const Loc& V) {
+    return V.getSubKind() == GotoLabelKind;
   }
 };
 
@@ -443,14 +488,16 @@ public:
     return getRegion() != R.getRegion();
   }
 
-  // Implement isa<T> support.
-  static inline bool classof(const SVal* V) {
-    return V->getBaseKind() == LocKind &&
-           V->getSubKind() == MemRegionKind;
+private:
+  friend class SVal;
+  MemRegionVal() {}
+  static bool isType(const SVal& V) {
+    return V.getBaseKind() == LocKind &&
+           V.getSubKind() == MemRegionKind;
   }
 
-  static inline bool classof(const Loc* V) {
-    return V->getSubKind() == MemRegionKind;
+  static bool isType(const Loc& V) {
+    return V.getSubKind() == MemRegionKind;
   }
 };
 
@@ -466,14 +513,16 @@ public:
   SVal evalBinOp(BasicValueFactory& BasicVals, BinaryOperator::Opcode Op,
                  const ConcreteInt& R) const;
 
-  // Implement isa<T> support.
-  static inline bool classof(const SVal* V) {
-    return V->getBaseKind() == LocKind &&
-           V->getSubKind() == ConcreteIntKind;
+private:
+  friend class SVal;
+  ConcreteInt() {}
+  static bool isType(const SVal& V) {
+    return V.getBaseKind() == LocKind &&
+           V.getSubKind() == ConcreteIntKind;
   }
 
-  static inline bool classof(const Loc* V) {
-    return V->getSubKind() == ConcreteIntKind;
+  static bool isType(const Loc& V) {
+    return V.getSubKind() == ConcreteIntKind;
   }
 };
 
index f60b7d7..27692fe 100644 (file)
@@ -53,7 +53,7 @@ public:
   RegionRawOffsetV2(const SubRegion* base, SVal offset)
     : baseRegion(base), byteOffset(offset) {}
 
-  NonLoc getByteOffset() const { return cast<NonLoc>(byteOffset); }
+  NonLoc getByteOffset() const { return byteOffset.castAs<NonLoc>(); }
   const SubRegion *getRegion() const { return baseRegion; }
   
   static RegionRawOffsetV2 computeOffset(ProgramStateRef state,
@@ -110,13 +110,12 @@ void ArrayBoundCheckerV2::checkLocation(SVal location, bool isLoad,
 
   SVal extentBegin = computeExtentBegin(svalBuilder, rawOffset.getRegion());
   
-  if (isa<NonLoc>(extentBegin)) {
-    SVal lowerBound
-      = svalBuilder.evalBinOpNN(state, BO_LT, rawOffset.getByteOffset(),
-                                cast<NonLoc>(extentBegin),
+  if (llvm::Optional<NonLoc> NV = extentBegin.getAs<NonLoc>()) {
+    SVal lowerBound =
+        svalBuilder.evalBinOpNN(state, BO_LT, rawOffset.getByteOffset(), *NV,
                                 svalBuilder.getConditionType());
 
-    NonLoc *lowerBoundToCheck = dyn_cast<NonLoc>(&lowerBound);
+    llvm::Optional<NonLoc> lowerBoundToCheck = lowerBound.getAs<NonLoc>();
     if (!lowerBoundToCheck)
       return;
     
@@ -140,15 +139,15 @@ void ArrayBoundCheckerV2::checkLocation(SVal location, bool isLoad,
     // we are doing a load/store after the last valid offset.
     DefinedOrUnknownSVal extentVal =
       rawOffset.getRegion()->getExtent(svalBuilder);
-    if (!isa<NonLoc>(extentVal))
+    if (!extentVal.getAs<NonLoc>())
       break;
 
     SVal upperbound
       = svalBuilder.evalBinOpNN(state, BO_GE, rawOffset.getByteOffset(),
-                                cast<NonLoc>(extentVal),
+                                extentVal.castAs<NonLoc>(),
                                 svalBuilder.getConditionType());
   
-    NonLoc *upperboundToCheck = dyn_cast<NonLoc>(&upperbound);
+    llvm::Optional<NonLoc> upperboundToCheck = upperbound.getAs<NonLoc>();
     if (!upperboundToCheck)
       break;
   
@@ -235,7 +234,7 @@ static bool IsCompleteType(ASTContext &Ctx, QualType Ty) {
 // is unknown or undefined, we lazily substitute '0'.  Otherwise,
 // return 'val'.
 static inline SVal getValue(SVal val, SValBuilder &svalBuilder) {
-  return isa<UndefinedVal>(val) ? svalBuilder.makeArrayIndex(0) : val;
+  return val.getAs<UndefinedVal>() ? svalBuilder.makeArrayIndex(0) : val;
 }
 
 // Scale a base value by a scaling factor, and return the scaled
@@ -256,9 +255,9 @@ static SVal addValue(ProgramStateRef state, SVal x, SVal y,
   // only care about computing offsets.
   if (x.isUnknownOrUndef() || y.isUnknownOrUndef())
     return UnknownVal();
-  
-  return svalBuilder.evalBinOpNN(state, BO_Add,                                 
-                                 cast<NonLoc>(x), cast<NonLoc>(y),
+
+  return svalBuilder.evalBinOpNN(state, BO_Add, x.castAs<NonLoc>(),
+                                 y.castAs<NonLoc>(),
                                  svalBuilder.getArrayIndexType());
 }
 
@@ -284,7 +283,7 @@ RegionRawOffsetV2 RegionRawOffsetV2::computeOffset(ProgramStateRef state,
       case MemRegion::ElementRegionKind: {
         const ElementRegion *elemReg = cast<ElementRegion>(region);
         SVal index = elemReg->getIndex();
-        if (!isa<NonLoc>(index))
+        if (!index.getAs<NonLoc>())
           return RegionRawOffsetV2();
         QualType elemType = elemReg->getElementType();
         // If the element is an incomplete type, go no further.
@@ -296,7 +295,7 @@ RegionRawOffsetV2 RegionRawOffsetV2::computeOffset(ProgramStateRef state,
         offset = addValue(state,
                           getValue(offset, svalBuilder),
                           scaleValue(state,
-                          cast<NonLoc>(index),
+                          index.castAs<NonLoc>(),
                           astContext.getTypeSizeInChars(elemType),
                           svalBuilder),
                           svalBuilder);
index 3af793c..6185a8e 100644 (file)
@@ -51,13 +51,13 @@ void AttrNonNullChecker::checkPreCall(const CallEvent &Call,
       continue;
 
     SVal V = Call.getArgSVal(idx);
-    DefinedSVal *DV = dyn_cast<DefinedSVal>(&V);
+    llvm::Optional<DefinedSVal> DV = V.getAs<DefinedSVal>();
 
     // If the value is unknown or undefined, we can't perform this check.
     if (!DV)
       continue;
 
-    if (!isa<Loc>(*DV)) {
+    if (!DV->getAs<Loc>()) {
       // If the argument is a union type, we want to handle a potential
       // transparent_union GCC extension.
       const Expr *ArgE = Call.getArgExpr(idx);
@@ -69,11 +69,12 @@ void AttrNonNullChecker::checkPreCall(const CallEvent &Call,
       if (!UT || !UT->getDecl()->hasAttr<TransparentUnionAttr>())
         continue;
 
-      if (nonloc::CompoundVal *CSV = dyn_cast<nonloc::CompoundVal>(DV)) {
+      if (llvm::Optional<nonloc::CompoundVal> CSV =
+              DV->getAs<nonloc::CompoundVal>()) {
         nonloc::CompoundVal::iterator CSV_I = CSV->begin();
         assert(CSV_I != CSV->end());
         V = *CSV_I;
-        DV = dyn_cast<DefinedSVal>(&V);
+        DV = V.getAs<DefinedSVal>();
         assert(++CSV_I == CSV->end());
         if (!DV)
           continue;        
index 12e7527..313778c 100644 (file)
@@ -84,7 +84,7 @@ static FoundationClass findKnownClass(const ObjCInterfaceDecl *ID) {
 }
 
 static inline bool isNil(SVal X) {
-  return isa<loc::ConcreteInt>(X);
+  return X.getAs<loc::ConcreteInt>();
 }
 
 //===----------------------------------------------------------------------===//
@@ -290,7 +290,8 @@ void CFNumberCreateChecker::checkPreStmt(const CallExpr *CE,
 
   // FIXME: We really should allow ranges of valid theType values, and
   //   bifurcate the state appropriately.
-  nonloc::ConcreteInt* V = dyn_cast<nonloc::ConcreteInt>(&TheTypeVal);
+  llvm::Optional<nonloc::ConcreteInt> V =
+      TheTypeVal.getAs<nonloc::ConcreteInt>();
   if (!V)
     return;
 
@@ -308,7 +309,8 @@ void CFNumberCreateChecker::checkPreStmt(const CallExpr *CE,
 
   // FIXME: Eventually we should handle arbitrary locations.  We can do this
   //  by having an enhanced memory model that does low-level typing.
-  loc::MemRegionVal* LV = dyn_cast<loc::MemRegionVal>(&TheValueExpr);
+  llvm::Optional<loc::MemRegionVal> LV =
+      TheValueExpr.getAs<loc::MemRegionVal>();
   if (!LV)
     return;
 
@@ -409,13 +411,14 @@ void CFRetainReleaseChecker::checkPreStmt(const CallExpr *CE,
   // Get the argument's value.
   const Expr *Arg = CE->getArg(0);
   SVal ArgVal = state->getSVal(Arg, C.getLocationContext());
-  DefinedSVal *DefArgVal = dyn_cast<DefinedSVal>(&ArgVal);
+  llvm::Optional<DefinedSVal> DefArgVal = ArgVal.getAs<DefinedSVal>();
   if (!DefArgVal)
     return;
 
   // Get a NULL value.
   SValBuilder &svalBuilder = C.getSValBuilder();
-  DefinedSVal zero = cast<DefinedSVal>(svalBuilder.makeZeroVal(Arg->getType()));
+  DefinedSVal zero =
+      svalBuilder.makeZeroVal(Arg->getType()).castAs<DefinedSVal>();
 
   // Make an expression asserting that they're equal.
   DefinedOrUnknownSVal ArgIsNull = svalBuilder.evalEQ(state, zero, *DefArgVal);
@@ -619,7 +622,7 @@ void VariadicMethodTypeChecker::checkPreObjCMessage(const ObjCMethodCall &msg,
       continue;
 
     // Ignore pointer constants.
-    if (isa<loc::ConcreteInt>(msg.getArgSVal(I)))
+    if (msg.getArgSVal(I).getAs<loc::ConcreteInt>())
       continue;
     
     // Ignore pointer types annotated with 'NSObject' attribute.
@@ -716,12 +719,12 @@ void ObjCLoopChecker::checkPostStmt(const ObjCForCollectionStmt *FCS,
     ElementVar = State->getSVal(Element, C.getLocationContext());
   }
 
-  if (!isa<Loc>(ElementVar))
+  if (!ElementVar.getAs<Loc>())
     return;
 
   // Go ahead and assume the value is non-nil.
-  SVal Val = State->getSVal(cast<Loc>(ElementVar));
-  State = State->assume(cast<DefinedOrUnknownSVal>(Val), true);
+  SVal Val = State->getSVal(ElementVar.castAs<Loc>());
+  State = State->assume(Val.castAs<DefinedOrUnknownSVal>(), true);
   C.addTransition(State);
 }
 
@@ -745,7 +748,8 @@ static ProgramStateRef assumeExprIsNonNull(const Expr *NonNullExpr,
                                            ProgramStateRef State,
                                            CheckerContext &C) {
   SVal Val = State->getSVal(NonNullExpr, C.getLocationContext());
-  if (DefinedOrUnknownSVal *DV = dyn_cast<DefinedOrUnknownSVal>(&Val))
+  if (llvm::Optional<DefinedOrUnknownSVal> DV =
+          Val.getAs<DefinedOrUnknownSVal>())
     return State->assume(*DV, true);
   return State;
 }
index 36fe092..3ceb8c4 100644 (file)
@@ -69,7 +69,7 @@ void BoolAssignmentChecker::checkBind(SVal loc, SVal val, const Stmt *S,
   // Get the value of the right-hand side.  We only care about values
   // that are defined (UnknownVals and UndefinedVals are handled by other
   // checkers).
-  const DefinedSVal *DV = dyn_cast<DefinedSVal>(&val);
+  llvm::Optional<DefinedSVal> DV = val.getAs<DefinedSVal>();
   if (!DV)
     return;
     
@@ -85,10 +85,10 @@ void BoolAssignmentChecker::checkBind(SVal loc, SVal val, const Stmt *S,
   SVal greaterThanOrEqualToZeroVal =
     svalBuilder.evalBinOp(state, BO_GE, *DV, zeroVal,
                           svalBuilder.getConditionType());
-  
-  DefinedSVal *greaterThanEqualToZero =
-    dyn_cast<DefinedSVal>(&greaterThanOrEqualToZeroVal);
-  
+
+  llvm::Optional<DefinedSVal> greaterThanEqualToZero =
+      greaterThanOrEqualToZeroVal.getAs<DefinedSVal>();
+
   if (!greaterThanEqualToZero) {
     // The SValBuilder cannot construct a valid SVal for this condition.
     // This means we cannot properly reason about it.    
@@ -121,10 +121,10 @@ void BoolAssignmentChecker::checkBind(SVal loc, SVal val, const Stmt *S,
   SVal lessThanEqToOneVal =
     svalBuilder.evalBinOp(state, BO_LE, *DV, OneVal,
                           svalBuilder.getConditionType());
-  
-  DefinedSVal *lessThanEqToOne =
-    dyn_cast<DefinedSVal>(&lessThanEqToOneVal);
-  
+
+  llvm::Optional<DefinedSVal> lessThanEqToOne =
+      lessThanEqToOneVal.getAs<DefinedSVal>();
+
   if (!lessThanEqToOne) {
     // The SValBuilder cannot construct a valid SVal for this condition.
     // This means we cannot properly reason about it.    
index e89a4bd..a3327d8 100644 (file)
@@ -61,7 +61,7 @@ bool BuiltinFunctionChecker::evalCall(const CallExpr *CE,
     // SVal of the argument directly. If we save the extent in bits, we
     // cannot represent values like symbol*8.
     DefinedOrUnknownSVal Size =
-      cast<DefinedOrUnknownSVal>(state->getSVal(*(CE->arg_begin()), LCtx));
+        state->getSVal(*(CE->arg_begin()), LCtx).castAs<DefinedOrUnknownSVal>();
 
     SValBuilder& svalBuilder = C.getSValBuilder();
     DefinedOrUnknownSVal Extent = R->getExtent(svalBuilder);
index 0a94747..1c99567 100644 (file)
@@ -201,7 +201,7 @@ REGISTER_MAP_WITH_PROGRAMSTATE(CStringLength, const MemRegion *, SVal)
 std::pair<ProgramStateRef , ProgramStateRef >
 CStringChecker::assumeZero(CheckerContext &C, ProgramStateRef state, SVal V,
                            QualType Ty) {
-  DefinedSVal *val = dyn_cast<DefinedSVal>(&V);
+  llvm::Optional<DefinedSVal> val = V.getAs<DefinedSVal>();
   if (!val)
     return std::pair<ProgramStateRef , ProgramStateRef >(state, state);
 
@@ -278,7 +278,7 @@ ProgramStateRef CStringChecker::CheckLocation(CheckerContext &C,
   SValBuilder &svalBuilder = C.getSValBuilder();
   SVal Extent = 
     svalBuilder.convertToArrayIndex(superReg->getExtent(svalBuilder));
-  DefinedOrUnknownSVal Size = cast<DefinedOrUnknownSVal>(Extent);
+  DefinedOrUnknownSVal Size = Extent.castAs<DefinedOrUnknownSVal>();
 
   // Get the index of the accessed element.
   DefinedOrUnknownSVal Idx = cast<DefinedOrUnknownSVal>(ER->getIndex());
@@ -359,18 +359,18 @@ ProgramStateRef CStringChecker::CheckBufferAccess(CheckerContext &C,
   // FIXME: This assumes the caller has already checked that the access length
   // is positive. And that it's unsigned.
   SVal LengthVal = state->getSVal(Size, LCtx);
-  NonLoc *Length = dyn_cast<NonLoc>(&LengthVal);
+  llvm::Optional<NonLoc> Length = LengthVal.getAs<NonLoc>();
   if (!Length)
     return state;
 
   // Compute the offset of the last element to be accessed: size-1.
-  NonLoc One = cast<NonLoc>(svalBuilder.makeIntVal(1, sizeTy));
-  NonLoc LastOffset = cast<NonLoc>(svalBuilder.evalBinOpNN(state, BO_Sub,
-                                                    *Length, One, sizeTy));
+  NonLoc One = svalBuilder.makeIntVal(1, sizeTy).castAs<NonLoc>();
+  NonLoc LastOffset = svalBuilder
+      .evalBinOpNN(state, BO_Sub, *Length, One, sizeTy).castAs<NonLoc>();
 
   // Check that the first buffer is sufficiently long.
   SVal BufStart = svalBuilder.evalCast(BufVal, PtrTy, FirstBuf->getType());
-  if (Loc *BufLoc = dyn_cast<Loc>(&BufStart)) {
+  if (llvm::Optional<Loc> BufLoc = BufStart.getAs<Loc>()) {
     const Expr *warningExpr = (WarnAboutSize ? Size : FirstBuf);
 
     SVal BufEnd = svalBuilder.evalBinOpLN(state, BO_Add, *BufLoc,
@@ -390,7 +390,7 @@ ProgramStateRef CStringChecker::CheckBufferAccess(CheckerContext &C,
       return NULL;
 
     BufStart = svalBuilder.evalCast(BufVal, PtrTy, SecondBuf->getType());
-    if (Loc *BufLoc = dyn_cast<Loc>(&BufStart)) {
+    if (llvm::Optional<Loc> BufLoc = BufStart.getAs<Loc>()) {
       const Expr *warningExpr = (WarnAboutSize ? Size : SecondBuf);
 
       SVal BufEnd = svalBuilder.evalBinOpLN(state, BO_Add, *BufLoc,
@@ -426,11 +426,11 @@ ProgramStateRef CStringChecker::CheckOverlap(CheckerContext &C,
   SVal firstVal = state->getSVal(First, LCtx);
   SVal secondVal = state->getSVal(Second, LCtx);
 
-  Loc *firstLoc = dyn_cast<Loc>(&firstVal);
+  llvm::Optional<Loc> firstLoc = firstVal.getAs<Loc>();
   if (!firstLoc)
     return state;
 
-  Loc *secondLoc = dyn_cast<Loc>(&secondVal);
+  llvm::Optional<Loc> secondLoc = secondVal.getAs<Loc>();
   if (!secondLoc)
     return state;
 
@@ -453,7 +453,8 @@ ProgramStateRef CStringChecker::CheckOverlap(CheckerContext &C,
   QualType cmpTy = svalBuilder.getConditionType();
   SVal reverse = svalBuilder.evalBinOpLL(state, BO_GT,
                                          *firstLoc, *secondLoc, cmpTy);
-  DefinedOrUnknownSVal *reverseTest = dyn_cast<DefinedOrUnknownSVal>(&reverse);
+  llvm::Optional<DefinedOrUnknownSVal> reverseTest =
+      reverse.getAs<DefinedOrUnknownSVal>();
   if (!reverseTest)
     return state;
 
@@ -464,20 +465,16 @@ ProgramStateRef CStringChecker::CheckOverlap(CheckerContext &C,
       return state;
     } else {
       // Switch the values so that firstVal is before secondVal.
-      Loc *tmpLoc = firstLoc;
-      firstLoc = secondLoc;
-      secondLoc = tmpLoc;
+      std::swap(firstLoc, secondLoc);
 
       // Switch the Exprs as well, so that they still correspond.
-      const Expr *tmpExpr = First;
-      First = Second;
-      Second = tmpExpr;
+      std::swap(First, Second);
     }
   }
 
   // Get the length, and make sure it too is known.
   SVal LengthVal = state->getSVal(Size, LCtx);
-  NonLoc *Length = dyn_cast<NonLoc>(&LengthVal);
+  llvm::Optional<NonLoc> Length = LengthVal.getAs<NonLoc>();
   if (!Length)
     return state;
 
@@ -487,21 +484,22 @@ ProgramStateRef CStringChecker::CheckOverlap(CheckerContext &C,
   QualType CharPtrTy = Ctx.getPointerType(Ctx.CharTy);
   SVal FirstStart = svalBuilder.evalCast(*firstLoc, CharPtrTy, 
                                          First->getType());
-  Loc *FirstStartLoc = dyn_cast<Loc>(&FirstStart);
+  llvm::Optional<Loc> FirstStartLoc = FirstStart.getAs<Loc>();
   if (!FirstStartLoc)
     return state;
 
   // Compute the end of the first buffer. Bail out if THAT fails.
   SVal FirstEnd = svalBuilder.evalBinOpLN(state, BO_Add,
                                  *FirstStartLoc, *Length, CharPtrTy);
-  Loc *FirstEndLoc = dyn_cast<Loc>(&FirstEnd);
+  llvm::Optional<Loc> FirstEndLoc = FirstEnd.getAs<Loc>();
   if (!FirstEndLoc)
     return state;
 
   // Is the end of the first buffer past the start of the second buffer?
   SVal Overlap = svalBuilder.evalBinOpLL(state, BO_GT,
                                 *FirstEndLoc, *secondLoc, cmpTy);
-  DefinedOrUnknownSVal *OverlapTest = dyn_cast<DefinedOrUnknownSVal>(&Overlap);
+  llvm::Optional<DefinedOrUnknownSVal> OverlapTest =
+      Overlap.getAs<DefinedOrUnknownSVal>();
   if (!OverlapTest)
     return state;
 
@@ -557,7 +555,7 @@ ProgramStateRef CStringChecker::checkAdditionOverflow(CheckerContext &C,
   NonLoc maxVal = svalBuilder.makeIntVal(maxValInt);
 
   SVal maxMinusRight;
-  if (isa<nonloc::ConcreteInt>(right)) {
+  if (right.getAs<nonloc::ConcreteInt>()) {
     maxMinusRight = svalBuilder.evalBinOpNN(state, BO_Sub, maxVal, right,
                                                  sizeTy);
   } else {
@@ -568,7 +566,7 @@ ProgramStateRef CStringChecker::checkAdditionOverflow(CheckerContext &C,
     left = right;
   }
 
-  if (NonLoc *maxMinusRightNL = dyn_cast<NonLoc>(&maxMinusRight)) {
+  if (llvm::Optional<NonLoc> maxMinusRightNL = maxMinusRight.getAs<NonLoc>()) {
     QualType cmpTy = svalBuilder.getConditionType();
     // If left > max - right, we have an overflow.
     SVal willOverflow = svalBuilder.evalBinOpNN(state, BO_GT, left,
@@ -576,7 +574,7 @@ ProgramStateRef CStringChecker::checkAdditionOverflow(CheckerContext &C,
 
     ProgramStateRef stateOverflow, stateOkay;
     llvm::tie(stateOverflow, stateOkay) =
-      state->assume(cast<DefinedOrUnknownSVal>(willOverflow));
+      state->assume(willOverflow.castAs<DefinedOrUnknownSVal>());
 
     if (stateOverflow && !stateOkay) {
       // We have an overflow. Emit a bug report.
@@ -683,7 +681,7 @@ SVal CStringChecker::getCStringLength(CheckerContext &C, ProgramStateRef &state,
     // If we can't get a region, see if it's something we /know/ isn't a
     // C string. In the context of locations, the only time we can issue such
     // a warning is for labels.
-    if (loc::GotoLabel *Label = dyn_cast<loc::GotoLabel>(&Buf)) {
+    if (llvm::Optional<loc::GotoLabel> Label = Buf.getAs<loc::GotoLabel>()) {
       if (!Filter.CheckCStringNotNullTerm)
         return UndefinedVal();
 
@@ -798,14 +796,14 @@ const StringLiteral *CStringChecker::getCStringLiteral(CheckerContext &C,
 ProgramStateRef CStringChecker::InvalidateBuffer(CheckerContext &C,
                                                 ProgramStateRef state,
                                                 const Expr *E, SVal V) {
-  Loc *L = dyn_cast<Loc>(&V);
+  llvm::Optional<Loc> L = V.getAs<Loc>();
   if (!L)
     return state;
 
   // FIXME: This is a simplified version of what's in CFRefCount.cpp -- it makes
   // some assumptions about the value that CFRefCount can't. Even so, it should
   // probably be refactored.
-  if (loc::MemRegionVal* MR = dyn_cast<loc::MemRegionVal>(L)) {
+  if (llvm::Optional<loc::MemRegionVal> MR = L->getAs<loc::MemRegionVal>()) {
     const MemRegion *R = MR->getRegion()->StripCasts();
 
     // Are we dealing with an ElementRegion?  If so, we should be invalidating
@@ -929,16 +927,13 @@ void CStringChecker::evalCopyCommon(CheckerContext &C,
     // If this is mempcpy, get the byte after the last byte copied and 
     // bind the expr.
     if (IsMempcpy) {
-      loc::MemRegionVal *destRegVal = dyn_cast<loc::MemRegionVal>(&destVal);
-      assert(destRegVal && "Destination should be a known MemRegionVal here");
+      loc::MemRegionVal destRegVal = destVal.castAs<loc::MemRegionVal>();
       
       // Get the length to copy.
-      NonLoc *lenValNonLoc = dyn_cast<NonLoc>(&sizeVal);
-      
-      if (lenValNonLoc) {
+      if (llvm::Optional<NonLoc> lenValNonLoc = sizeVal.getAs<NonLoc>()) {
         // Get the byte after the last byte copied.
         SVal lastElement = C.getSValBuilder().evalBinOpLN(state, BO_Add, 
-                                                          *destRegVal,
+                                                          destRegVal,
                                                           *lenValNonLoc, 
                                                           Dest->getType());
       
@@ -1054,9 +1049,9 @@ void CStringChecker::evalMemcmp(CheckerContext &C, const CallExpr *CE) const {
     // First, get the two buffers' addresses. Another checker will have already
     // made sure they're not undefined.
     DefinedOrUnknownSVal LV =
-      cast<DefinedOrUnknownSVal>(state->getSVal(Left, LCtx));
+        state->getSVal(Left, LCtx).castAs<DefinedOrUnknownSVal>();
     DefinedOrUnknownSVal RV =
-      cast<DefinedOrUnknownSVal>(state->getSVal(Right, LCtx));
+        state->getSVal(Right, LCtx).castAs<DefinedOrUnknownSVal>();
 
     // See if they are the same.
     DefinedOrUnknownSVal SameBuf = svalBuilder.evalEQ(state, LV, RV);
@@ -1166,19 +1161,17 @@ void CStringChecker::evalstrLengthCommon(CheckerContext &C, const CallExpr *CE,
     const Expr *maxlenExpr = CE->getArg(1);
     SVal maxlenVal = state->getSVal(maxlenExpr, LCtx);
 
-    NonLoc *strLengthNL = dyn_cast<NonLoc>(&strLength);
-    NonLoc *maxlenValNL = dyn_cast<NonLoc>(&maxlenVal);
+    llvm::Optional<NonLoc> strLengthNL = strLength.getAs<NonLoc>();
+    llvm::Optional<NonLoc> maxlenValNL = maxlenVal.getAs<NonLoc>();
 
     if (strLengthNL && maxlenValNL) {
       ProgramStateRef stateStringTooLong, stateStringNotTooLong;
 
       // Check if the strLength is greater than the maxlen.
       llvm::tie(stateStringTooLong, stateStringNotTooLong) =
-        state->assume(cast<DefinedOrUnknownSVal>
-                      (C.getSValBuilder().evalBinOpNN(state, BO_GT, 
-                                                      *strLengthNL,
-                                                      *maxlenValNL,
-                                                      cmpTy)));
+          state->assume(C.getSValBuilder().evalBinOpNN(
+              state, BO_GT, *strLengthNL, *maxlenValNL, cmpTy)
+                            .castAs<DefinedOrUnknownSVal>());
 
       if (stateStringTooLong && !stateStringNotTooLong) {
         // If the string is longer than maxlen, return maxlen.
@@ -1195,28 +1188,24 @@ void CStringChecker::evalstrLengthCommon(CheckerContext &C, const CallExpr *CE,
       // All we know is the return value is the min of the string length
       // and the limit. This is better than nothing.
       result = C.getSValBuilder().conjureSymbolVal(0, CE, LCtx, C.blockCount());
-      NonLoc *resultNL = cast<NonLoc>(&result);
+      NonLoc resultNL = result.castAs<NonLoc>();
 
       if (strLengthNL) {
-        state = state->assume(cast<DefinedOrUnknownSVal>
-                              (C.getSValBuilder().evalBinOpNN(state, BO_LE, 
-                                                              *resultNL,
-                                                              *strLengthNL,
-                                                              cmpTy)), true);
+        state = state->assume(C.getSValBuilder().evalBinOpNN(
+                                  state, BO_LE, resultNL, *strLengthNL, cmpTy)
+                                  .castAs<DefinedOrUnknownSVal>(), true);
       }
       
       if (maxlenValNL) {
-        state = state->assume(cast<DefinedOrUnknownSVal>
-                              (C.getSValBuilder().evalBinOpNN(state, BO_LE, 
-                                                              *resultNL,
-                                                              *maxlenValNL,
-                                                              cmpTy)), true);
+        state = state->assume(C.getSValBuilder().evalBinOpNN(
+                                  state, BO_LE, resultNL, *maxlenValNL, cmpTy)
+                                  .castAs<DefinedOrUnknownSVal>(), true);
       }
     }
 
   } else {
     // This is a plain strlen(), not strnlen().
-    result = cast<DefinedOrUnknownSVal>(strLength);
+    result = strLength.castAs<DefinedOrUnknownSVal>();
 
     // If we don't know the length of the string, conjure a return
     // value, so it can be used in constraints, at least.
@@ -1335,8 +1324,8 @@ void CStringChecker::evalStrcpyCommon(CheckerContext &C, const CallExpr *CE,
     // Protect against misdeclared strncpy().
     lenVal = svalBuilder.evalCast(lenVal, sizeTy, lenExpr->getType());
 
-    NonLoc *strLengthNL = dyn_cast<NonLoc>(&strLength);
-    NonLoc *lenValNL = dyn_cast<NonLoc>(&lenVal);
+    llvm::Optional<NonLoc> strLengthNL = strLength.getAs<NonLoc>();
+    llvm::Optional<NonLoc> lenValNL = lenVal.getAs<NonLoc>();
 
     // If we know both values, we might be able to figure out how much
     // we're copying.
@@ -1346,10 +1335,9 @@ void CStringChecker::evalStrcpyCommon(CheckerContext &C, const CallExpr *CE,
       // Check if the max number to copy is less than the length of the src.
       // If the bound is equal to the source length, strncpy won't null-
       // terminate the result!
-      llvm::tie(stateSourceTooLong, stateSourceNotTooLong) =
-        state->assume(cast<DefinedOrUnknownSVal>
-                      (svalBuilder.evalBinOpNN(state, BO_GE, *strLengthNL,
-                                               *lenValNL, cmpTy)));
+      llvm::tie(stateSourceTooLong, stateSourceNotTooLong) = state->assume(
+          svalBuilder.evalBinOpNN(state, BO_GE, *strLengthNL, *lenValNL, cmpTy)
+              .castAs<DefinedOrUnknownSVal>());
 
       if (stateSourceTooLong && !stateSourceNotTooLong) {
         // Max number to copy is less than the length of the src, so the actual
@@ -1376,7 +1364,8 @@ void CStringChecker::evalStrcpyCommon(CheckerContext &C, const CallExpr *CE,
         if (dstStrLength.isUndef())
           return;
 
-        if (NonLoc *dstStrLengthNL = dyn_cast<NonLoc>(&dstStrLength)) {
+        if (llvm::Optional<NonLoc> dstStrLengthNL =
+                dstStrLength.getAs<NonLoc>()) {
           maxLastElementIndex = svalBuilder.evalBinOpNN(state, BO_Add,
                                                         *lenValNL,
                                                         *dstStrLengthNL,
@@ -1407,7 +1396,7 @@ void CStringChecker::evalStrcpyCommon(CheckerContext &C, const CallExpr *CE,
         // Otherwise, go ahead and figure out the last element we'll touch.
         // We don't record the non-zero assumption here because we can't
         // be sure. We won't warn on a possible zero.
-        NonLoc one = cast<NonLoc>(svalBuilder.makeIntVal(1, sizeTy));
+        NonLoc one = svalBuilder.makeIntVal(1, sizeTy).castAs<NonLoc>();
         maxLastElementIndex = svalBuilder.evalBinOpNN(state, BO_Sub, *lenValNL,
                                                       one, sizeTy);
         boundWarning = "Size argument is greater than the length of the "
@@ -1425,15 +1414,16 @@ void CStringChecker::evalStrcpyCommon(CheckerContext &C, const CallExpr *CE,
       amountCopied = getCStringLength(C, state, lenExpr, srcVal, true);
       assert(!amountCopied.isUndef());
 
-      if (NonLoc *amountCopiedNL = dyn_cast<NonLoc>(&amountCopied)) {
+      if (llvm::Optional<NonLoc> amountCopiedNL =
+              amountCopied.getAs<NonLoc>()) {
         if (lenValNL) {
           // amountCopied <= lenVal
           SVal copiedLessThanBound = svalBuilder.evalBinOpNN(state, BO_LE,
                                                              *amountCopiedNL,
                                                              *lenValNL,
                                                              cmpTy);
-          state = state->assume(cast<DefinedOrUnknownSVal>(copiedLessThanBound),
-                                true);
+          state = state->assume(
+              copiedLessThanBound.castAs<DefinedOrUnknownSVal>(), true);
           if (!state)
             return;
         }
@@ -1444,8 +1434,8 @@ void CStringChecker::evalStrcpyCommon(CheckerContext &C, const CallExpr *CE,
                                                            *amountCopiedNL,
                                                            *strLengthNL,
                                                            cmpTy);
-          state = state->assume(cast<DefinedOrUnknownSVal>(copiedLessThanSrc),
-                                true);
+          state = state->assume(
+              copiedLessThanSrc.castAs<DefinedOrUnknownSVal>(), true);
           if (!state)
             return;
         }
@@ -1475,8 +1465,8 @@ void CStringChecker::evalStrcpyCommon(CheckerContext &C, const CallExpr *CE,
     if (dstStrLength.isUndef())
       return;
 
-    NonLoc *srcStrLengthNL = dyn_cast<NonLoc>(&amountCopied);
-    NonLoc *dstStrLengthNL = dyn_cast<NonLoc>(&dstStrLength);
+    llvm::Optional<NonLoc> srcStrLengthNL = amountCopied.getAs<NonLoc>();
+    llvm::Optional<NonLoc> dstStrLengthNL = dstStrLength.getAs<NonLoc>();
     
     // If we know both string lengths, we might know the final string length.
     if (srcStrLengthNL && dstStrLengthNL) {
@@ -1497,14 +1487,15 @@ void CStringChecker::evalStrcpyCommon(CheckerContext &C, const CallExpr *CE,
       finalStrLength = getCStringLength(C, state, CE, DstVal, true);
       assert(!finalStrLength.isUndef());
 
-      if (NonLoc *finalStrLengthNL = dyn_cast<NonLoc>(&finalStrLength)) {
+      if (llvm::Optional<NonLoc> finalStrLengthNL =
+              finalStrLength.getAs<NonLoc>()) {
         if (srcStrLengthNL) {
           // finalStrLength >= srcStrLength
           SVal sourceInResult = svalBuilder.evalBinOpNN(state, BO_GE,
                                                         *finalStrLengthNL,
                                                         *srcStrLengthNL,
                                                         cmpTy);
-          state = state->assume(cast<DefinedOrUnknownSVal>(sourceInResult),
+          state = state->assume(sourceInResult.castAs<DefinedOrUnknownSVal>(),
                                 true);
           if (!state)
             return;
@@ -1516,8 +1507,8 @@ void CStringChecker::evalStrcpyCommon(CheckerContext &C, const CallExpr *CE,
                                                       *finalStrLengthNL,
                                                       *dstStrLengthNL,
                                                       cmpTy);
-          state = state->assume(cast<DefinedOrUnknownSVal>(destInResult),
-                                true);
+          state =
+              state->assume(destInResult.castAs<DefinedOrUnknownSVal>(), true);
           if (!state)
             return;
         }
@@ -1538,13 +1529,15 @@ void CStringChecker::evalStrcpyCommon(CheckerContext &C, const CallExpr *CE,
 
   // If the destination is a MemRegion, try to check for a buffer overflow and
   // record the new string length.
-  if (loc::MemRegionVal *dstRegVal = dyn_cast<loc::MemRegionVal>(&DstVal)) {
+  if (llvm::Optional<loc::MemRegionVal> dstRegVal =
+          DstVal.getAs<loc::MemRegionVal>()) {
     QualType ptrTy = Dst->getType();
 
     // If we have an exact value on a bounded copy, use that to check for
     // overflows, rather than our estimate about how much is actually copied.
     if (boundWarning) {
-      if (NonLoc *maxLastNL = dyn_cast<NonLoc>(&maxLastElementIndex)) {
+      if (llvm::Optional<NonLoc> maxLastNL =
+              maxLastElementIndex.getAs<NonLoc>()) {
         SVal maxLastElement = svalBuilder.evalBinOpLN(state, BO_Add, *dstRegVal,
                                                       *maxLastNL, ptrTy);
         state = CheckLocation(C, state, CE->getArg(2), maxLastElement, 
@@ -1555,7 +1548,8 @@ void CStringChecker::evalStrcpyCommon(CheckerContext &C, const CallExpr *CE,
     }
 
     // Then, if the final length is known...
-    if (NonLoc *knownStrLength = dyn_cast<NonLoc>(&finalStrLength)) {
+    if (llvm::Optional<NonLoc> knownStrLength =
+            finalStrLength.getAs<NonLoc>()) {
       SVal lastElement = svalBuilder.evalBinOpLN(state, BO_Add, *dstRegVal,
                                                  *knownStrLength, ptrTy);
 
@@ -1673,8 +1667,8 @@ void CStringChecker::evalStrcmpCommon(CheckerContext &C, const CallExpr *CE,
   // If we know the two buffers are the same, we know the result is 0.
   // First, get the two buffers' addresses. Another checker will have already
   // made sure they're not undefined.
-  DefinedOrUnknownSVal LV = cast<DefinedOrUnknownSVal>(s1Val);
-  DefinedOrUnknownSVal RV = cast<DefinedOrUnknownSVal>(s2Val);
+  DefinedOrUnknownSVal LV = s1Val.castAs<DefinedOrUnknownSVal>();
+  DefinedOrUnknownSVal RV = s2Val.castAs<DefinedOrUnknownSVal>();
 
   // See if they are the same.
   SValBuilder &svalBuilder = C.getSValBuilder();
@@ -1859,8 +1853,8 @@ void CStringChecker::checkPreStmt(const DeclStmt *DS, CheckerContext &C) const {
 
     SVal StrVal = state->getSVal(Init, C.getLocationContext());
     assert(StrVal.isValid() && "Initializer string is unknown or undefined");
-    DefinedOrUnknownSVal strLength
-      = cast<DefinedOrUnknownSVal>(getCStringLength(C, state, Init, StrVal));
+    DefinedOrUnknownSVal strLength =
+        getCStringLength(C, state, Init, StrVal).castAs<DefinedOrUnknownSVal>();
 
     state = state->set<CStringLength>(MR, strLength);
   }
index e32091e..d5203a8 100644 (file)
@@ -133,9 +133,9 @@ bool CallAndMessageChecker::PreVisitProcessArg(CheckerContext &C,
 
   if (!checkUninitFields)
     return false;
-  
-  if (const nonloc::LazyCompoundVal *LV =
-        dyn_cast<nonloc::LazyCompoundVal>(&V)) {
+
+  if (llvm::Optional<nonloc::LazyCompoundVal> LV =
+          V.getAs<nonloc::LazyCompoundVal>()) {
 
     class FindUninitializedField {
     public:
@@ -236,7 +236,8 @@ void CallAndMessageChecker::checkPreStmt(const CallExpr *CE,
   }
 
   ProgramStateRef StNonNull, StNull;
-  llvm::tie(StNonNull, StNull) = State->assume(cast<DefinedOrUnknownSVal>(L));
+  llvm::tie(StNonNull, StNull) =
+      State->assume(L.castAs<DefinedOrUnknownSVal>());
 
   if (StNull && !StNonNull) {
     if (!BT_call_null)
@@ -265,7 +266,8 @@ void CallAndMessageChecker::checkPreCall(const CallEvent &Call,
     }
 
     ProgramStateRef StNonNull, StNull;
-    llvm::tie(StNonNull, StNull) = State->assume(cast<DefinedOrUnknownSVal>(V));
+    llvm::tie(StNonNull, StNull) =
+        State->assume(V.castAs<DefinedOrUnknownSVal>());
 
     if (StNull && !StNonNull) {
       if (!BT_cxx_call_null)
@@ -344,7 +346,7 @@ void CallAndMessageChecker::checkPreObjCMessage(const ObjCMethodCall &msg,
     return;
   } else {
     // Bifurcate the state into nil and non-nil ones.
-    DefinedOrUnknownSVal receiverVal = cast<DefinedOrUnknownSVal>(recVal);
+    DefinedOrUnknownSVal receiverVal = recVal.castAs<DefinedOrUnknownSVal>();
 
     ProgramStateRef state = C.getState();
     ProgramStateRef notNilState, nilState;
index c77e2e3..3aa8aaa 100644 (file)
@@ -183,10 +183,10 @@ void DereferenceChecker::checkLocation(SVal l, bool isLoad, const Stmt* S,
     return;
   }
 
-  DefinedOrUnknownSVal location = cast<DefinedOrUnknownSVal>(l);
+  DefinedOrUnknownSVal location = l.castAs<DefinedOrUnknownSVal>();
 
   // Check for null dereferences.
-  if (!isa<Loc>(location))
+  if (!location.getAs<Loc>())
     return;
 
   ProgramStateRef state = C.getState();
@@ -231,7 +231,8 @@ void DereferenceChecker::checkBind(SVal L, SVal V, const Stmt *S,
   ProgramStateRef State = C.getState();
 
   ProgramStateRef StNonNull, StNull;
-  llvm::tie(StNonNull, StNull) = State->assume(cast<DefinedOrUnknownSVal>(V));
+  llvm::tie(StNonNull, StNull) =
+      State->assume(V.castAs<DefinedOrUnknownSVal>());
 
   if (StNull) {
     if (!StNonNull) {
index 228f5cc..3c14e7e 100644 (file)
@@ -58,7 +58,7 @@ void DivZeroChecker::checkPreStmt(const BinaryOperator *B,
     return;
 
   SVal Denom = C.getState()->getSVal(B->getRHS(), C.getLocationContext());
-  const DefinedSVal *DV = dyn_cast<DefinedSVal>(&Denom);
+  llvm::Optional<DefinedSVal> DV = Denom.getAs<DefinedSVal>();
 
   // Divide-by-undefined handled in the generic checking for uses of
   // undefined values.
index fec29d7..810473f 100644 (file)
@@ -65,7 +65,7 @@ static const char *getArgumentValueString(const CallExpr *CE,
 
   ProgramStateRef StTrue, StFalse;
   llvm::tie(StTrue, StFalse) =
-    State->assume(cast<DefinedOrUnknownSVal>(AssertionVal));
+    State->assume(AssertionVal.castAs<DefinedOrUnknownSVal>());
 
   if (StTrue) {
     if (StFalse)
index 2f4b9e9..00ef1f6 100644 (file)
@@ -431,7 +431,7 @@ SymbolRef GenericTaintChecker::getPointedToSymbol(CheckerContext &C,
   if (AddrVal.isUnknownOrUndef())
     return 0;
 
-  Loc *AddrLoc = dyn_cast<Loc>(&AddrVal);
+  llvm::Optional<Loc> AddrLoc = AddrVal.getAs<Loc>();
   if (!AddrLoc)
     return 0;
 
index a42a54b..54c32f8 100644 (file)
@@ -173,11 +173,11 @@ void IdempotentOperationChecker::checkPreStmt(const BinaryOperator *B,
   case BO_ShrAssign:
   case BO_Assign:
   // Assign statements have one extra level of indirection
-    if (!isa<Loc>(LHSVal)) {
+    if (!LHSVal.getAs<Loc>()) {
       A = Impossible;
       return;
     }
-    LHSVal = state->getSVal(cast<Loc>(LHSVal), LHS->getType());
+    LHSVal = state->getSVal(LHSVal.castAs<Loc>(), LHS->getType());
   }
 
 
index b11553c..50114e9 100644 (file)
@@ -217,7 +217,7 @@ static SymbolRef getAsPointeeSymbol(const Expr *Expr,
   ProgramStateRef State = C.getState();
   SVal ArgV = State->getSVal(Expr, C.getLocationContext());
 
-  if (const loc::MemRegionVal *X = dyn_cast<loc::MemRegionVal>(&ArgV)) {
+  if (llvm::Optional<loc::MemRegionVal> X = ArgV.getAs<loc::MemRegionVal>()) {
     StoreManager& SM = C.getStoreManager();
     SymbolRef sym = SM.getBinding(State->getStore(), *X).getAsLocSymbol();
     if (sym)
@@ -421,7 +421,7 @@ void MacOSKeychainAPIChecker::checkPreStmt(const CallExpr *CE,
 
   // If the buffer can be null and the return status can be an error,
   // report a bad call to free.
-  if (State->assume(cast<DefinedSVal>(ArgSVal), false) &&
+  if (State->assume(ArgSVal.castAs<DefinedSVal>(), false) &&
       !definitelyDidnotReturnError(AS->Region, State, C.getSValBuilder())) {
     ExplodedNode *N = C.addTransition(State);
     if (!N)
index 2242b21..aaaafeb 100644 (file)
@@ -555,12 +555,12 @@ ProgramStateRef MallocChecker::MallocMemAux(CheckerContext &C,
   unsigned Count = C.blockCount();
   SValBuilder &svalBuilder = C.getSValBuilder();
   const LocationContext *LCtx = C.getPredecessor()->getLocationContext();
-  DefinedSVal RetVal =
-    cast<DefinedSVal>(svalBuilder.getConjuredHeapSymbolVal(CE, LCtx, Count));
+  DefinedSVal RetVal = svalBuilder.getConjuredHeapSymbolVal(CE, LCtx, Count)
+      .castAs<DefinedSVal>();
   state = state->BindExpr(CE, C.getLocationContext(), RetVal);
 
   // We expect the malloc functions to return a pointer.
-  if (!isa<Loc>(RetVal))
+  if (!RetVal.getAs<Loc>())
     return 0;
 
   // Fill the region with the initialization value.
@@ -571,12 +571,12 @@ ProgramStateRef MallocChecker::MallocMemAux(CheckerContext &C,
       dyn_cast_or_null<SymbolicRegion>(RetVal.getAsRegion());
   if (!R)
     return 0;
-  if (isa<DefinedOrUnknownSVal>(Size)) {
+  if (llvm::Optional<DefinedOrUnknownSVal> DefinedSize =
+          Size.getAs<DefinedOrUnknownSVal>()) {
     SValBuilder &svalBuilder = C.getSValBuilder();
     DefinedOrUnknownSVal Extent = R->getExtent(svalBuilder);
-    DefinedOrUnknownSVal DefinedSize = cast<DefinedOrUnknownSVal>(Size);
     DefinedOrUnknownSVal extentMatchesSize =
-        svalBuilder.evalEQ(state, Extent, DefinedSize);
+        svalBuilder.evalEQ(state, Extent, *DefinedSize);
 
     state = state->assume(extentMatchesSize, true);
     assert(state);
@@ -592,7 +592,7 @@ ProgramStateRef MallocChecker::MallocUpdateRefState(CheckerContext &C,
   SVal retVal = state->getSVal(CE, C.getLocationContext());
 
   // We expect the malloc functions to return a pointer.
-  if (!isa<Loc>(retVal))
+  if (!retVal.getAs<Loc>())
     return 0;
 
   SymbolRef Sym = retVal.getAsLocSymbol();
@@ -661,12 +661,12 @@ ProgramStateRef MallocChecker::FreeMemAux(CheckerContext &C,
                                           bool ReturnsNullOnFailure) const {
 
   SVal ArgVal = State->getSVal(ArgExpr, C.getLocationContext());
-  if (!isa<DefinedOrUnknownSVal>(ArgVal))
+  if (!ArgVal.getAs<DefinedOrUnknownSVal>())
     return 0;
-  DefinedOrUnknownSVal location = cast<DefinedOrUnknownSVal>(ArgVal);
+  DefinedOrUnknownSVal location = ArgVal.castAs<DefinedOrUnknownSVal>();
 
   // Check for null dereferences.
-  if (!isa<Loc>(location))
+  if (!location.getAs<Loc>())
     return 0;
 
   // The explicit NULL case, no operation is performed.
@@ -782,11 +782,13 @@ ProgramStateRef MallocChecker::FreeMemAux(CheckerContext &C,
 }
 
 bool MallocChecker::SummarizeValue(raw_ostream &os, SVal V) {
-  if (nonloc::ConcreteInt *IntVal = dyn_cast<nonloc::ConcreteInt>(&V))
+  if (llvm::Optional<nonloc::ConcreteInt> IntVal =
+          V.getAs<nonloc::ConcreteInt>())
     os << "an integer (" << IntVal->getValue() << ")";
-  else if (loc::ConcreteInt *ConstAddr = dyn_cast<loc::ConcreteInt>(&V))
+  else if (llvm::Optional<loc::ConcreteInt> ConstAddr =
+               V.getAs<loc::ConcreteInt>())
     os << "a constant address (" << ConstAddr->getValue() << ")";
-  else if (loc::GotoLabel *Label = dyn_cast<loc::GotoLabel>(&V))
+  else if (llvm::Optional<loc::GotoLabel> Label = V.getAs<loc::GotoLabel>())
     os << "the address of the label '" << Label->getLabel()->getName() << "'";
   else
     return false;
@@ -952,9 +954,9 @@ ProgramStateRef MallocChecker::ReallocMem(CheckerContext &C,
   const Expr *arg0Expr = CE->getArg(0);
   const LocationContext *LCtx = C.getLocationContext();
   SVal Arg0Val = state->getSVal(arg0Expr, LCtx);
-  if (!isa<DefinedOrUnknownSVal>(Arg0Val))
+  if (!Arg0Val.getAs<DefinedOrUnknownSVal>())
     return 0;
-  DefinedOrUnknownSVal arg0Val = cast<DefinedOrUnknownSVal>(Arg0Val);
+  DefinedOrUnknownSVal arg0Val = Arg0Val.castAs<DefinedOrUnknownSVal>();
 
   SValBuilder &svalBuilder = C.getSValBuilder();
 
@@ -968,9 +970,9 @@ ProgramStateRef MallocChecker::ReallocMem(CheckerContext &C,
 
   // Get the value of the size argument.
   SVal Arg1ValG = state->getSVal(Arg1, LCtx);
-  if (!isa<DefinedOrUnknownSVal>(Arg1ValG))
+  if (!Arg1ValG.getAs<DefinedOrUnknownSVal>())
     return 0;
-  DefinedOrUnknownSVal Arg1Val = cast<DefinedOrUnknownSVal>(Arg1ValG);
+  DefinedOrUnknownSVal Arg1Val = Arg1ValG.castAs<DefinedOrUnknownSVal>();
 
   // Compare the size argument to 0.
   DefinedOrUnknownSVal SizeZero =
index 19f79fa..9e2202b 100644 (file)
@@ -186,7 +186,7 @@ static void setFlag(ProgramStateRef state, SVal val, CheckerContext &C) {
 static QualType parameterTypeFromSVal(SVal val, CheckerContext &C) {
   const StackFrameContext *
     SFC = C.getLocationContext()->getCurrentStackFrame();
-  if (const loc::MemRegionVal* X = dyn_cast<loc::MemRegionVal>(&val)) {
+  if (llvm::Optional<loc::MemRegionVal> X = val.getAs<loc::MemRegionVal>()) {
     const MemRegion* R = X->getRegion();
     if (const VarRegion *VR = R->getAs<VarRegion>())
       if (const StackArgumentsSpaceRegion *
@@ -203,7 +203,7 @@ void NSOrCFErrorDerefChecker::checkLocation(SVal loc, bool isLoad,
                                             CheckerContext &C) const {
   if (!isLoad)
     return;
-  if (loc.isUndef() || !isa<Loc>(loc))
+  if (loc.isUndef() || !loc.getAs<Loc>())
     return;
 
   ASTContext &Ctx = C.getASTContext();
@@ -225,12 +225,12 @@ void NSOrCFErrorDerefChecker::checkLocation(SVal loc, bool isLoad,
     CFErrorII = &Ctx.Idents.get("CFErrorRef");
 
   if (ShouldCheckNSError && IsNSError(parmT, NSErrorII)) {
-    setFlag<NSErrorOut>(state, state->getSVal(cast<Loc>(loc)), C);
+    setFlag<NSErrorOut>(state, state->getSVal(loc.castAs<Loc>()), C);
     return;
   }
 
   if (ShouldCheckCFError && IsCFError(parmT, CFErrorII)) {
-    setFlag<CFErrorOut>(state, state->getSVal(cast<Loc>(loc)), C);
+    setFlag<CFErrorOut>(state, state->getSVal(loc.castAs<Loc>()), C);
     return;
   }
 }
index 62a20a7..4018a66 100644 (file)
@@ -42,7 +42,7 @@ void ObjCAtSyncChecker::checkPreStmt(const ObjCAtSynchronizedStmt *S,
   SVal V = state->getSVal(Ex, C.getLocationContext());
 
   // Uninitialized value used for the mutex?
-  if (isa<UndefinedVal>(V)) {
+  if (V.getAs<UndefinedVal>()) {
     if (ExplodedNode *N = C.generateSink()) {
       if (!BT_undef)
         BT_undef.reset(new BuiltinBug("Uninitialized value used as mutex "
@@ -60,7 +60,7 @@ void ObjCAtSyncChecker::checkPreStmt(const ObjCAtSynchronizedStmt *S,
 
   // Check for null mutexes.
   ProgramStateRef notNullState, nullState;
-  llvm::tie(notNullState, nullState) = state->assume(cast<DefinedSVal>(V));
+  llvm::tie(notNullState, nullState) = state->assume(V.castAs<DefinedSVal>());
 
   if (nullState) {
     if (!notNullState) {
index 747c9c9..b9e96ee 100644 (file)
@@ -72,7 +72,8 @@ void ObjCContainersChecker::addSizeInfo(const Expr *Array, const Expr *Size,
   if (!ArraySym)
     return;
 
-  C.addTransition(State->set<ArraySizeMap>(ArraySym, cast<DefinedSVal>(SizeV)));
+  C.addTransition(
+      State->set<ArraySizeMap>(ArraySym, SizeV.castAs<DefinedSVal>()));
   return;
 }
 
@@ -125,7 +126,7 @@ void ObjCContainersChecker::checkPreStmt(const CallExpr *CE,
     SVal IdxVal = State->getSVal(IdxExpr, C.getLocationContext());
     if (IdxVal.isUnknownOrUndef())
       return;
-    DefinedSVal Idx = cast<DefinedSVal>(IdxVal);
+    DefinedSVal Idx = IdxVal.castAs<DefinedSVal>();
     
     // Now, check if 'Idx in [0, Size-1]'.
     const QualType T = IdxExpr->getType();
index 485ae77..8506e08 100644 (file)
@@ -255,7 +255,7 @@ void ObjCSelfInitChecker::checkPreCall(const CallEvent &CE,
   for (unsigned i = 0; i < NumArgs; ++i) {
     SVal argV = CE.getArgSVal(i);
     if (isSelfVar(argV, C)) {
-      unsigned selfFlags = getSelfFlags(state->getSVal(cast<Loc>(argV)), C);
+      unsigned selfFlags = getSelfFlags(state->getSVal(argV.castAs<Loc>()), C);
       C.addTransition(state->set<PreCallSelfFlags>(selfFlags));
       return;
     } else if (hasSelfFlag(argV, SelfFlag_Self, C)) {
@@ -286,7 +286,7 @@ void ObjCSelfInitChecker::checkPostCall(const CallEvent &CE,
       // If the address of 'self' is being passed to the call, assume that the
       // 'self' after the call will have the same flags.
       // EX: log(&self)
-      addSelfFlag(state, state->getSVal(cast<Loc>(argV)), prevFlags, C);
+      addSelfFlag(state, state->getSVal(argV.castAs<Loc>()), prevFlags, C);
       return;
     } else if (hasSelfFlag(argV, SelfFlag_Self, C)) {
       // If 'self' is passed to the call by value, assume that the function
@@ -312,7 +312,8 @@ void ObjCSelfInitChecker::checkLocation(SVal location, bool isLoad,
   // value is the object that 'self' points to.
   ProgramStateRef state = C.getState();
   if (isSelfVar(location, C))
-    addSelfFlag(state, state->getSVal(cast<Loc>(location)), SelfFlag_Self, C);
+    addSelfFlag(state, state->getSVal(location.castAs<Loc>()), SelfFlag_Self,
+                C);
 }
 
 
@@ -417,10 +418,10 @@ static bool isSelfVar(SVal location, CheckerContext &C) {
   AnalysisDeclContext *analCtx = C.getCurrentAnalysisDeclContext(); 
   if (!analCtx->getSelfDecl())
     return false;
-  if (!isa<loc::MemRegionVal>(location))
+  if (!location.getAs<loc::MemRegionVal>())
     return false;
 
-  loc::MemRegionVal MRV = cast<loc::MemRegionVal>(location);
+  loc::MemRegionVal MRV = location.castAs<loc::MemRegionVal>();
   if (const DeclRegion *DR = dyn_cast<DeclRegion>(MRV.stripCasts()))
     return (DR->getDecl() == analCtx->getSelfDecl());
 
index 8407ea4..ffb8cf2 100644 (file)
@@ -98,7 +98,7 @@ void PthreadLockChecker::AcquireLock(CheckerContext &C, const CallExpr *CE,
   if (X.isUnknownOrUndef())
     return;
   
-  DefinedSVal retVal = cast<DefinedSVal>(X);
+  DefinedSVal retVal = X.castAs<DefinedSVal>();
 
   if (state->contains<LockSet>(lockR)) {
     if (!BT_doublelock)
index 533d0b8..cb731fc 100644 (file)
@@ -3361,7 +3361,8 @@ void RetainCountChecker::checkBind(SVal loc, SVal val, const Stmt *S,
   //     does not understand.
   ProgramStateRef state = C.getState();
 
-  if (loc::MemRegionVal *regionLoc = dyn_cast<loc::MemRegionVal>(&loc)) {
+  if (llvm::Optional<loc::MemRegionVal> regionLoc =
+          loc.getAs<loc::MemRegionVal>()) {
     escapes = !regionLoc->getRegion()->hasStackStorage();
 
     if (!escapes) {
index a39f282..2a6c217 100644 (file)
@@ -210,9 +210,8 @@ void StreamChecker::OpenFileAux(CheckerContext &C, const CallExpr *CE) const {
   ProgramStateRef state = C.getState();
   SValBuilder &svalBuilder = C.getSValBuilder();
   const LocationContext *LCtx = C.getPredecessor()->getLocationContext();
-  DefinedSVal RetVal =
-    cast<DefinedSVal>(svalBuilder.conjureSymbolVal(0, CE, LCtx,
-                                                   C.blockCount()));
+  DefinedSVal RetVal = svalBuilder.conjureSymbolVal(0, CE, LCtx, C.blockCount())
+      .castAs<DefinedSVal>();
   state = state->BindExpr(CE, C.getLocationContext(), RetVal);
   
   ConstraintManager &CM = C.getConstraintManager();
@@ -260,7 +259,7 @@ void StreamChecker::Fseek(CheckerContext &C, const CallExpr *CE) const {
     return;
   // Check the legality of the 'whence' argument of 'fseek'.
   SVal Whence = state->getSVal(CE->getArg(2), C.getLocationContext());
-  const nonloc::ConcreteInt *CI = dyn_cast<nonloc::ConcreteInt>(&Whence);
+  llvm::Optional<nonloc::ConcreteInt> CI = Whence.getAs<nonloc::ConcreteInt>();
 
   if (!CI)
     return;
@@ -338,7 +337,7 @@ void StreamChecker::Fileno(CheckerContext &C, const CallExpr *CE) const {
 
 ProgramStateRef StreamChecker::CheckNullStream(SVal SV, ProgramStateRef state,
                                     CheckerContext &C) const {
-  const DefinedSVal *DV = dyn_cast<DefinedSVal>(&SV);
+  llvm::Optional<DefinedSVal> DV = SV.getAs<DefinedSVal>();
   if (!DV)
     return 0;
 
index c6ea328..3e11fd8 100644 (file)
@@ -103,21 +103,20 @@ void UnixAPIChecker::CheckOpen(CheckerContext &C, const CallExpr *CE) const {
   // Now check if oflags has O_CREAT set.
   const Expr *oflagsEx = CE->getArg(1);
   const SVal V = state->getSVal(oflagsEx, C.getLocationContext());
-  if (!isa<NonLoc>(V)) {
+  if (!V.getAs<NonLoc>()) {
     // The case where 'V' can be a location can only be due to a bad header,
     // so in this case bail out.
     return;
   }
-  NonLoc oflags = cast<NonLoc>(V);
-  NonLoc ocreateFlag =
-    cast<NonLoc>(C.getSValBuilder().makeIntVal(Val_O_CREAT.getValue(),
-                                                oflagsEx->getType()));
+  NonLoc oflags = V.castAs<NonLoc>();
+  NonLoc ocreateFlag = C.getSValBuilder()
+      .makeIntVal(Val_O_CREAT.getValue(), oflagsEx->getType()).castAs<NonLoc>();
   SVal maskedFlagsUC = C.getSValBuilder().evalBinOpNN(state, BO_And,
                                                       oflags, ocreateFlag,
                                                       oflagsEx->getType());
   if (maskedFlagsUC.isUnknownOrUndef())
     return;
-  DefinedSVal maskedFlags = cast<DefinedSVal>(maskedFlagsUC);
+  DefinedSVal maskedFlags = maskedFlagsUC.castAs<DefinedSVal>();
 
   // Check if maskedFlags is non-zero.
   ProgramStateRef trueState, falseState;
@@ -202,7 +201,7 @@ static bool IsZeroByteAllocation(ProgramStateRef state,
                                 ProgramStateRef *trueState,
                                 ProgramStateRef *falseState) {
   llvm::tie(*trueState, *falseState) =
-    state->assume(cast<DefinedSVal>(argVal));
+    state->assume(argVal.castAs<DefinedSVal>());
   
   return (*falseState && !*trueState);
 }
index 6ca9a35..30aef06 100644 (file)
@@ -110,7 +110,7 @@ void VLASizeChecker::checkPreStmt(const DeclStmt *DS, CheckerContext &C) const {
   }
 
   // Check if the size is zero.
-  DefinedSVal sizeD = cast<DefinedSVal>(sizeV);
+  DefinedSVal sizeD = sizeV.castAs<DefinedSVal>();
 
   ProgramStateRef stateNotZero, stateZero;
   llvm::tie(stateNotZero, stateZero) = state->assume(sizeD);
@@ -130,22 +130,22 @@ void VLASizeChecker::checkPreStmt(const DeclStmt *DS, CheckerContext &C) const {
   // Convert the array length to size_t.
   SValBuilder &svalBuilder = C.getSValBuilder();
   QualType SizeTy = Ctx.getSizeType();
-  NonLoc ArrayLength = cast<NonLoc>(svalBuilder.evalCast(sizeD, SizeTy, 
-                                                         SE->getType()));
+  NonLoc ArrayLength =
+      svalBuilder.evalCast(sizeD, SizeTy, SE->getType()).castAs<NonLoc>();
 
   // Get the element size.
   CharUnits EleSize = Ctx.getTypeSizeInChars(VLA->getElementType());
   SVal EleSizeVal = svalBuilder.makeIntVal(EleSize.getQuantity(), SizeTy);
 
   // Multiply the array length by the element size.
-  SVal ArraySizeVal = svalBuilder.evalBinOpNN(state, BO_Mul, ArrayLength,
-                                              cast<NonLoc>(EleSizeVal), SizeTy);
+  SVal ArraySizeVal = svalBuilder.evalBinOpNN(
+      state, BO_Mul, ArrayLength, EleSizeVal.castAs<NonLoc>(), SizeTy);
 
   // Finally, assume that the array's extent matches the given size.
   const LocationContext *LC = C.getLocationContext();
   DefinedOrUnknownSVal Extent =
     state->getRegion(VD, LC)->getExtent(svalBuilder);
-  DefinedOrUnknownSVal ArraySize = cast<DefinedOrUnknownSVal>(ArraySizeVal);
+  DefinedOrUnknownSVal ArraySize = ArraySizeVal.castAs<DefinedOrUnknownSVal>();
   DefinedOrUnknownSVal sizeIsKnown =
     svalBuilder.evalEQ(state, Extent, ArraySize);
   state = state->assume(sizeIsKnown, true);
index 17dd772..8afd488 100644 (file)
@@ -228,7 +228,7 @@ public:
 
     // If we can't prove the return value is 0, just mark it interesting, and
     // make sure to track it into any further inner functions.
-    if (State->assume(cast<DefinedSVal>(V), true)) {
+    if (State->assume(V.castAs<DefinedSVal>(), true)) {
       BR.markInteresting(V);
       ReturnVisitor::addVisitorIfNecessary(N, RetE, BR);
       return 0;
@@ -241,7 +241,7 @@ public:
     SmallString<64> Msg;
     llvm::raw_svector_ostream Out(Msg);
 
-    if (isa<Loc>(V)) {
+    if (V.getAs<Loc>()) {
       // If we are pruning null-return paths as unlikely error paths, mark the
       // report invalid. We still want to emit a path note, however, in case
       // the report is resurrected as valid later on.
@@ -298,7 +298,7 @@ public:
       CallEventRef<> Call = CallMgr.getCaller(StackFrame, State);
       for (unsigned I = 0, E = Call->getNumArgs(); I != E; ++I) {
         SVal ArgV = Call->getArgSVal(I);
-        if (!isa<Loc>(ArgV))
+        if (!ArgV.getAs<Loc>())
           continue;
 
         const Expr *ArgE = Call->getArgExpr(I);
@@ -306,7 +306,7 @@ public:
           continue;
 
         // Is it possible for this argument to be non-null?
-        if (State->assume(cast<Loc>(ArgV), true))
+        if (State->assume(ArgV.castAs<Loc>(), true))
           continue;
 
         if (bugreporter::trackNullOrUndefValue(N, ArgE, BR, /*IsArg=*/true))
@@ -415,7 +415,7 @@ PathDiagnosticPiece *FindLastStoreBRVisitor::VisitNode(const ExplodedNode *Succ,
   // If we have an expression that provided the value, try to track where it
   // came from.
   if (InitE) {
-    if (V.isUndef() || isa<loc::ConcreteInt>(V)) {
+    if (V.isUndef() || V.getAs<loc::ConcreteInt>()) {
       if (!IsParam)
         InitE = InitE->IgnoreParenCasts();
       bugreporter::trackNullOrUndefValue(StoreSite, InitE, BR, IsParam);
@@ -462,7 +462,7 @@ PathDiagnosticPiece *FindLastStoreBRVisitor::VisitNode(const ExplodedNode *Succ,
 
       os << "Variable '" << *VR->getDecl() << "' ";
 
-      if (isa<loc::ConcreteInt>(V)) {
+      if (V.getAs<loc::ConcreteInt>()) {
         bool b = false;
         if (R->isBoundable()) {
           if (const TypedValueRegion *TR = dyn_cast<TypedValueRegion>(R)) {
@@ -475,9 +475,9 @@ PathDiagnosticPiece *FindLastStoreBRVisitor::VisitNode(const ExplodedNode *Succ,
 
         if (!b)
           os << action << "a null pointer value";
-      }
-      else if (isa<nonloc::ConcreteInt>(V)) {
-        os << action << cast<nonloc::ConcreteInt>(V).getValue();
+      } else if (llvm::Optional<nonloc::ConcreteInt> CVal =
+                     V.getAs<nonloc::ConcreteInt>()) {
+        os << action << CVal->getValue();
       }
       else if (DS) {
         if (V.isUndef()) {
@@ -499,15 +499,16 @@ PathDiagnosticPiece *FindLastStoreBRVisitor::VisitNode(const ExplodedNode *Succ,
 
     os << "Passing ";
 
-    if (isa<loc::ConcreteInt>(V)) {
+    if (V.getAs<loc::ConcreteInt>()) {
       if (Param->getType()->isObjCObjectPointerType())
         os << "nil object reference";
       else
         os << "null pointer value";
     } else if (V.isUndef()) {
       os << "uninitialized value";
-    } else if (isa<nonloc::ConcreteInt>(V)) {
-      os << "the value " << cast<nonloc::ConcreteInt>(V).getValue();
+    } else if (llvm::Optional<nonloc::ConcreteInt> CI =
+                   V.getAs<nonloc::ConcreteInt>()) {
+      os << "the value " << CI->getValue();
     } else {
       os << "value";
     }
@@ -521,7 +522,7 @@ PathDiagnosticPiece *FindLastStoreBRVisitor::VisitNode(const ExplodedNode *Succ,
   }
 
   if (os.str().empty()) {
-    if (isa<loc::ConcreteInt>(V)) {
+    if (V.getAs<loc::ConcreteInt>()) {
       bool b = false;
       if (R->isBoundable()) {
         if (const TypedValueRegion *TR = dyn_cast<TypedValueRegion>(R)) {
@@ -537,10 +538,9 @@ PathDiagnosticPiece *FindLastStoreBRVisitor::VisitNode(const ExplodedNode *Succ,
     }
     else if (V.isUndef()) {
       os << "Uninitialized value stored to ";
-    }
-    else if (isa<nonloc::ConcreteInt>(V)) {
-      os << "The value " << cast<nonloc::ConcreteInt>(V).getValue()
-               << " is assigned to ";
+    } else if (llvm::Optional<nonloc::ConcreteInt> CV =
+                   V.getAs<nonloc::ConcreteInt>()) {
+      os << "The value " << CV->getValue() << " is assigned to ";
     }
     else
       os << "Value assigned to ";
@@ -601,7 +601,7 @@ TrackConstraintBRVisitor::VisitNode(const ExplodedNode *N,
     std::string sbuf;
     llvm::raw_string_ostream os(sbuf);
 
-    if (isa<Loc>(Constraint)) {
+    if (Constraint.getAs<Loc>()) {
       os << "Assuming pointer value is ";
       os << (Assumption ? "non-null" : "null");
     }
@@ -693,8 +693,8 @@ bool bugreporter::trackNullOrUndefValue(const ExplodedNode *N, const Stmt *S,
 
         // If the contents are symbolic, find out when they became null.
         if (V.getAsLocSymbol()) {
-          BugReporterVisitor *ConstraintTracker
-            = new TrackConstraintBRVisitor(cast<DefinedSVal>(V), false);
+          BugReporterVisitor *ConstraintTracker =
+              new TrackConstraintBRVisitor(V.castAs<DefinedSVal>(), false);
           report.addVisitor(ConstraintTracker);
         }
 
@@ -713,7 +713,7 @@ bool bugreporter::trackNullOrUndefValue(const ExplodedNode *N, const Stmt *S,
   // assert(!V.isUnknownOrUndef());
 
   // Is it a symbolic value?
-  if (loc::MemRegionVal *L = dyn_cast<loc::MemRegionVal>(&V)) {
+  if (llvm::Optional<loc::MemRegionVal> L = V.getAs<loc::MemRegionVal>()) {
     // At this point we are dealing with the region's LValue.
     // However, if the rvalue is a symbolic region, we should track it as well.
     SVal RVal = state->getSVal(L->getRegion());
@@ -766,7 +766,7 @@ PathDiagnosticPiece *NilReceiverBRVisitor::VisitNode(const ExplodedNode *N,
     return 0;
   ProgramStateRef state = N->getState();
   const SVal &V = state->getSVal(Receiver, N->getLocationContext());
-  const DefinedOrUnknownSVal *DV = dyn_cast<DefinedOrUnknownSVal>(&V);
+  llvm::Optional<DefinedOrUnknownSVal> DV = V.getAs<DefinedOrUnknownSVal>();
   if (!DV)
     return 0;
   state = state->assume(*DV, true);
@@ -806,7 +806,7 @@ void FindLastStoreBRVisitor::registerStatementVarDecls(BugReport &BR,
         // What did we load?
         SVal V = state->getSVal(S, N->getLocationContext());
 
-        if (isa<loc::ConcreteInt>(V) || isa<nonloc::ConcreteInt>(V)) {
+        if (V.getAs<loc::ConcreteInt>() || V.getAs<nonloc::ConcreteInt>()) {
           // Register a new visitor with the BugReport.
           BR.addVisitor(new FindLastStoreBRVisitor(V, R));
         }
index a75efc6..a09d483 100644 (file)
@@ -156,9 +156,10 @@ ProgramStateRef CallEvent::invalidateRegions(unsigned BlockCount,
 
     // If we are passing a location wrapped as an integer, unwrap it and
     // invalidate the values referred by the location.
-    if (nonloc::LocAsInteger *Wrapped = dyn_cast<nonloc::LocAsInteger>(&V))
+    if (llvm::Optional<nonloc::LocAsInteger> Wrapped =
+            V.getAs<nonloc::LocAsInteger>())
       V = Wrapped->getLoc();
-    else if (!isa<Loc>(V))
+    else if (!V.getAs<Loc>())
       continue;
 
     if (const MemRegion *R = V.getAsRegion()) {
@@ -419,7 +420,7 @@ SVal CXXInstanceCall::getCXXThisVal() const {
     return UnknownVal();
 
   SVal ThisVal = getSVal(Base);
-  assert(ThisVal.isUnknownOrUndef() || isa<Loc>(ThisVal));
+  assert(ThisVal.isUnknownOrUndef() || ThisVal.getAs<Loc>());
   return ThisVal;
 }
 
index 2b069a0..481e1bf 100644 (file)
@@ -198,10 +198,8 @@ EnvironmentManager::removeDeadBindings(Environment Env,
       EBMapRef = EBMapRef.add(BlkExpr, X);
 
       // If the block expr's value is a memory region, then mark that region.
-      if (isa<loc::MemRegionVal>(X)) {
-        const MemRegion *R = cast<loc::MemRegionVal>(X).getRegion();
-        SymReaper.markLive(R);
-      }
+      if (llvm::Optional<loc::MemRegionVal> R = X.getAs<loc::MemRegionVal>())
+        SymReaper.markLive(R->getRegion());
 
       // Mark all symbols in the block expr's value live.
       RSScaner.scan(X);
index 18ac096..a077056 100644 (file)
@@ -118,8 +118,8 @@ ProgramStateRef ExprEngine::getInitialState(const LocationContext *InitLoc) {
                                            svalBuilder.makeZeroVal(T),
                                            getContext().IntTy);
 
-      DefinedOrUnknownSVal *Constraint =
-        dyn_cast<DefinedOrUnknownSVal>(&Constraint_untested);
+      llvm::Optional<DefinedOrUnknownSVal> Constraint =
+        Constraint_untested.getAs<DefinedOrUnknownSVal>();
 
       if (!Constraint)
         break;
@@ -138,7 +138,7 @@ ProgramStateRef ExprEngine::getInitialState(const LocationContext *InitLoc) {
     const MemRegion *R = state->getRegion(SelfD, InitLoc);
     SVal V = state->getSVal(loc::MemRegionVal(R));
 
-    if (const Loc *LV = dyn_cast<Loc>(&V)) {
+    if (llvm::Optional<Loc> LV = V.getAs<Loc>()) {
       // Assume that the pointer value in 'self' is non-null.
       state = state->assume(*LV, true);
       assert(state && "'self' cannot be null");
@@ -154,7 +154,7 @@ ProgramStateRef ExprEngine::getInitialState(const LocationContext *InitLoc) {
       if (SFC->getParent() == 0) {
         loc::MemRegionVal L = svalBuilder.getCXXThis(MD, SFC);
         SVal V = state->getSVal(L);
-        if (const Loc *LV = dyn_cast<Loc>(&V)) {
+        if (llvm::Optional<Loc> LV = V.getAs<Loc>()) {
           state = state->assume(*LV, true);
           assert(state && "'this' cannot be null");
         }
@@ -172,7 +172,7 @@ static ProgramStateRef createTemporaryRegionIfNeeded(ProgramStateRef State,
                                                      const Expr *E) {
   SVal V = State->getSVal(E, LC);
 
-  if (isa<NonLoc>(V)) {
+  if (V.getAs<NonLoc>()) {
     MemRegionManager &MRMgr = State->getStateManager().getRegionManager();
     const MemRegion *R  = MRMgr.getCXXTempObjectRegion(E, LC);
     State = State->bindLoc(loc::MemRegionVal(R), V);
@@ -472,8 +472,8 @@ void ExprEngine::ProcessAutomaticObjDtor(const CFGAutomaticObjDtor Dtor,
 
   Loc dest = state->getLValue(varDecl, Pred->getLocationContext());
 
-  VisitCXXDestructor(varType, cast<loc::MemRegionVal>(dest).getRegion(),
-                     Dtor.getTriggerStmt(), /*IsBase=*/false, Pred, Dst);
+  VisitCXXDestructor(varType, dest.castAs<loc::MemRegionVal>().getRegion(),
+                     Dtor.getTriggerStmt(), /*IsBase=*/ false, Pred, Dst);
 }
 
 void ExprEngine::ProcessBaseDtor(const CFGBaseDtor D,
@@ -490,8 +490,8 @@ void ExprEngine::ProcessBaseDtor(const CFGBaseDtor D,
   QualType BaseTy = D.getBaseSpecifier()->getType();
   SVal BaseVal = getStoreManager().evalDerivedToBase(ThisVal, BaseTy);
 
-  VisitCXXDestructor(BaseTy, cast<loc::MemRegionVal>(BaseVal).getRegion(),
-                     CurDtor->getBody(), /*IsBase=*/true, Pred, Dst);
+  VisitCXXDestructor(BaseTy, BaseVal.castAs<loc::MemRegionVal>().getRegion(),
+                     CurDtor->getBody(), /*IsBase=*/ true, Pred, Dst);
 }
 
 void ExprEngine::ProcessMemberDtor(const CFGMemberDtor D,
@@ -503,10 +503,11 @@ void ExprEngine::ProcessMemberDtor(const CFGMemberDtor D,
   const CXXDestructorDecl *CurDtor = cast<CXXDestructorDecl>(LCtx->getDecl());
   Loc ThisVal = getSValBuilder().getCXXThis(CurDtor,
                                             LCtx->getCurrentStackFrame());
-  SVal FieldVal = State->getLValue(Member, cast<Loc>(State->getSVal(ThisVal)));
+  SVal FieldVal =
+      State->getLValue(Member, State->getSVal(ThisVal).castAs<Loc>());
 
   VisitCXXDestructor(Member->getType(),
-                     cast<loc::MemRegionVal>(FieldVal).getRegion(),
+                     FieldVal.castAs<loc::MemRegionVal>().getRegion(),
                      CurDtor->getBody(), /*IsBase=*/false, Pred, Dst);
 }
 
@@ -1287,7 +1288,7 @@ void ExprEngine::processBranch(const Stmt *Condition, const Stmt *Term,
       continue;
     }
 
-    DefinedSVal V = cast<DefinedSVal>(X);
+    DefinedSVal V = X.castAs<DefinedSVal>();
 
     ProgramStateRef StTrue, StFalse;
     tie(StTrue, StFalse) = PrevState->assume(V);
@@ -1327,8 +1328,8 @@ void ExprEngine::processIndirectGoto(IndirectGotoNodeBuilder &builder) {
 
   typedef IndirectGotoNodeBuilder::iterator iterator;
 
-  if (isa<loc::GotoLabel>(V)) {
-    const LabelDecl *L = cast<loc::GotoLabel>(V).getLabel();
+  if (llvm::Optional<loc::GotoLabel> LV = V.getAs<loc::GotoLabel>()) {
+    const LabelDecl *L = LV->getLabel();
 
     for (iterator I = builder.begin(), E = builder.end(); I != E; ++I) {
       if (I.getLabel() == L) {
@@ -1340,7 +1341,7 @@ void ExprEngine::processIndirectGoto(IndirectGotoNodeBuilder &builder) {
     llvm_unreachable("No block with label.");
   }
 
-  if (isa<loc::ConcreteInt>(V) || isa<UndefinedVal>(V)) {
+  if (V.getAs<loc::ConcreteInt>() || V.getAs<UndefinedVal>()) {
     // Dispatch to the first target and mark it as a sink.
     //ExplodedNode* N = builder.generateNode(builder.begin(), state, true);
     // FIXME: add checker visit.
@@ -1394,7 +1395,7 @@ void ExprEngine::processSwitch(SwitchNodeBuilder& builder) {
 
     return;
   }
-  DefinedOrUnknownSVal CondV = cast<DefinedOrUnknownSVal>(CondV_untested);
+  DefinedOrUnknownSVal CondV = CondV_untested.castAs<DefinedOrUnknownSVal>();
 
   ProgramStateRef DefaultSt = state;
   
@@ -1435,7 +1436,7 @@ void ExprEngine::processSwitch(SwitchNodeBuilder& builder) {
         // If CondV evaluates to a constant, then we know that this
         // is the *only* case that we can take, so stop evaluating the
         // others.
-        if (isa<nonloc::ConcreteInt>(CondV))
+        if (CondV.getAs<nonloc::ConcreteInt>())
           return;
       }
 
@@ -1529,7 +1530,7 @@ void ExprEngine::VisitCommonDeclRefExpr(const Expr *Ex, const NamedDecl *D,
     // results in boolean contexts.
     SVal V = svalBuilder.conjureSymbolVal(Ex, LCtx, getContext().VoidPtrTy,
                                           currBldrCtx->blockCount());
-    state = state->assume(cast<DefinedOrUnknownSVal>(V), true);
+    state = state->assume(V.castAs<DefinedOrUnknownSVal>(), true);
     Bldr.generateNode(Ex, Pred, state->BindExpr(Ex, LCtx, V), 0,
                      ProgramPoint::PostLValueKind);
     return;
@@ -1646,7 +1647,8 @@ ProgramStateRef ExprEngine::processPointerEscapedOnBind(ProgramStateRef State,
   bool escapes = true;
 
   // TODO: Move to StoreManager.
-  if (loc::MemRegionVal *regionLoc = dyn_cast<loc::MemRegionVal>(&Loc)) {
+  if (llvm::Optional<loc::MemRegionVal> regionLoc =
+          Loc.getAs<loc::MemRegionVal>()) {
     escapes = !regionLoc->getRegion()->hasStackStorage();
 
     if (!escapes) {
@@ -1754,7 +1756,7 @@ void ExprEngine::evalBind(ExplodedNodeSet &Dst, const Stmt *StoreE,
 
   // If the location is not a 'Loc', it will already be handled by
   // the checkers.  There is nothing left to do.
-  if (!isa<Loc>(location)) {
+  if (!location.getAs<Loc>()) {
     const ProgramPoint L = PostStore(StoreE, LC, /*Loc*/0, /*tag*/0);
     ProgramStateRef state = Pred->getState();
     state = processPointerEscapedOnBind(state, location, Val);
@@ -1773,11 +1775,12 @@ void ExprEngine::evalBind(ExplodedNodeSet &Dst, const Stmt *StoreE,
     // When binding the value, pass on the hint that this is a initialization.
     // For initializations, we do not need to inform clients of region
     // changes.
-    state = state->bindLoc(cast<Loc>(location),
+    state = state->bindLoc(location.castAs<Loc>(),
                            Val, /* notifyChanges = */ !atDeclInit);
 
     const MemRegion *LocReg = 0;
-    if (loc::MemRegionVal *LocRegVal = dyn_cast<loc::MemRegionVal>(&location)) {
+    if (llvm::Optional<loc::MemRegionVal> LocRegVal =
+            location.getAs<loc::MemRegionVal>()) {
       LocReg = LocRegVal->getRegion();
     }
     
@@ -1826,7 +1829,7 @@ void ExprEngine::evalLoad(ExplodedNodeSet &Dst,
                           const ProgramPointTag *tag,
                           QualType LoadTy)
 {
-  assert(!isa<NonLoc>(location) && "location cannot be a NonLoc.");
+  assert(!location.getAs<NonLoc>() && "location cannot be a NonLoc.");
 
   // Are we loading from a region?  This actually results in two loads; one
   // to fetch the address of the referenced value and one to fetch the
@@ -1885,7 +1888,7 @@ void ExprEngine::evalLoadCommon(ExplodedNodeSet &Dst,
     if (location.isValid()) {
       if (LoadTy.isNull())
         LoadTy = BoundEx->getType();
-      V = state->getSVal(cast<Loc>(location), LoadTy);
+      V = state->getSVal(location.castAs<Loc>(), LoadTy);
     }
 
     Bldr.generateNode(NodeEx, *NI, state->BindExpr(BoundEx, LCtx, V), tag,
@@ -1955,7 +1958,7 @@ void ExprEngine::evalEagerlyAssumeBinOpBifurcation(ExplodedNodeSet &Dst,
 
     ProgramStateRef state = Pred->getState();
     SVal V = state->getSVal(Ex, Pred->getLocationContext());
-    nonloc::SymbolVal *SEV = dyn_cast<nonloc::SymbolVal>(&V);
+    llvm::Optional<nonloc::SymbolVal> SEV = V.getAs<nonloc::SymbolVal>();
     if (SEV && SEV->isExpression()) {
       const std::pair<const ProgramPointTag *, const ProgramPointTag*> &tags =
         geteagerlyAssumeBinOpBifurcationTags();
@@ -1995,10 +1998,10 @@ void ExprEngine::VisitGCCAsmStmt(const GCCAsmStmt *A, ExplodedNode *Pred,
   for (GCCAsmStmt::const_outputs_iterator OI = A->begin_outputs(),
        OE = A->end_outputs(); OI != OE; ++OI) {
     SVal X = state->getSVal(*OI, Pred->getLocationContext());
-    assert (!isa<NonLoc>(X));  // Should be an Lval, or unknown, undef.
+    assert (!X.getAs<NonLoc>());  // Should be an Lval, or unknown, undef.
 
-    if (isa<Loc>(X))
-      state = state->bindLoc(cast<Loc>(X), UnknownVal());
+    if (llvm::Optional<Loc> LV = X.getAs<Loc>())
+      state = state->bindLoc(*LV, UnknownVal());
   }
 
   Bldr.generateNode(A, Pred, state);
index f33f561..fe132df 100644 (file)
@@ -67,12 +67,12 @@ void ExprEngine::VisitBinaryOperator(const BinaryOperator* B,
         // TODO: This can be removed after we enable history tracking with
         // SymSymExpr.
         unsigned Count = currBldrCtx->blockCount();
-        if (isa<Loc>(LeftV) &&
+        if (LeftV.getAs<Loc>() &&
             RHS->getType()->isIntegerType() && RightV.isUnknown()) {
           RightV = svalBuilder.conjureSymbolVal(RHS, LCtx, RHS->getType(),
                                                 Count);
         }
-        if (isa<Loc>(RightV) &&
+        if (RightV.getAs<Loc>() &&
             LHS->getType()->isIntegerType() && LeftV.isUnknown()) {
           LeftV = svalBuilder.conjureSymbolVal(LHS, LCtx, LHS->getType(),
                                                Count);
@@ -480,10 +480,13 @@ void ExprEngine::VisitDeclStmt(const DeclStmt *DS, ExplodedNode *Pred,
       } else {
         // We bound the temp obj region to the CXXConstructExpr. Now recover
         // the lazy compound value when the variable is not a reference.
-        if (AMgr.getLangOpts().CPlusPlus && VD->getType()->isRecordType() && 
-            !VD->getType()->isReferenceType() && isa<loc::MemRegionVal>(InitVal)){
-          InitVal = state->getSVal(cast<loc::MemRegionVal>(InitVal).getRegion());
-          assert(isa<nonloc::LazyCompoundVal>(InitVal));
+        if (AMgr.getLangOpts().CPlusPlus && VD->getType()->isRecordType() &&
+            !VD->getType()->isReferenceType()) {
+          if (llvm::Optional<loc::MemRegionVal> M =
+                  InitVal.getAs<loc::MemRegionVal>()) {
+            InitVal = state->getSVal(M->getRegion());
+            assert(InitVal.getAs<nonloc::LazyCompoundVal>());
+          }
         }
         
         // Recover some path-sensitivity if a scalar value evaluated to
@@ -558,7 +561,7 @@ void ExprEngine::VisitLogicalExpr(const BinaryOperator* B, ExplodedNode *Pred,
     if (RHSVal.isUndef()) {
       X = RHSVal;
     } else {
-      DefinedOrUnknownSVal DefinedRHS = cast<DefinedOrUnknownSVal>(RHSVal);
+      DefinedOrUnknownSVal DefinedRHS = RHSVal.castAs<DefinedOrUnknownSVal>();
       ProgramStateRef StTrue, StFalse;
       llvm::tie(StTrue, StFalse) = N->getState()->assume(DefinedRHS);
       if (StTrue) {
@@ -810,11 +813,11 @@ void ExprEngine::VisitUnaryOperator(const UnaryOperator* U,
           llvm_unreachable("Invalid Opcode.");
         case UO_Not:
           // FIXME: Do we need to handle promotions?
-          state = state->BindExpr(U, LCtx, evalComplement(cast<NonLoc>(V)));
+          state = state->BindExpr(U, LCtx, evalComplement(V.castAs<NonLoc>()));
           break;
         case UO_Minus:
           // FIXME: Do we need to handle promotions?
-          state = state->BindExpr(U, LCtx, evalMinus(cast<NonLoc>(V)));
+          state = state->BindExpr(U, LCtx, evalMinus(V.castAs<NonLoc>()));
           break;
         case UO_LNot:
           // C99 6.5.3.3: "The expression !E is equivalent to (0==E)."
@@ -822,17 +825,16 @@ void ExprEngine::VisitUnaryOperator(const UnaryOperator* U,
           //  Note: technically we do "E == 0", but this is the same in the
           //    transfer functions as "0 == E".
           SVal Result;          
-          if (isa<Loc>(V)) {
+          if (llvm::Optional<Loc> LV = V.getAs<Loc>()) {
             Loc X = svalBuilder.makeNull();
-            Result = evalBinOp(state, BO_EQ, cast<Loc>(V), X,
-                               U->getType());
+            Result = evalBinOp(state, BO_EQ, *LV, X, U->getType());
           }
           else if (Ex->getType()->isFloatingType()) {
             // FIXME: handle floating point types.
             Result = UnknownVal();
           } else {
             nonloc::ConcreteInt X(getBasicVals().getValue(0, Ex->getType()));
-            Result = evalBinOp(state, BO_EQ, cast<NonLoc>(V), X,
+            Result = evalBinOp(state, BO_EQ, V.castAs<NonLoc>(), X,
                                U->getType());
           }
           
@@ -874,7 +876,7 @@ void ExprEngine::VisitIncrementDecrementOperator(const UnaryOperator* U,
       Bldr.generateNode(U, *I, state->BindExpr(U, LCtx, V2_untested));
       continue;
     }
-    DefinedSVal V2 = cast<DefinedSVal>(V2_untested);
+    DefinedSVal V2 = V2_untested.castAs<DefinedSVal>();
     
     // Handle all other values.
     BinaryOperator::Opcode Op = U->isIncrementOp() ? BO_Add : BO_Sub;
index fdd50a6..7e86a56 100644 (file)
@@ -64,7 +64,7 @@ void ExprEngine::performTrivialCopy(NodeBuilder &Bldr, ExplodedNode *Pred,
   SVal V = Call.getArgSVal(0);
 
   // Make sure the value being copied is not unknown.
-  if (const Loc *L = dyn_cast<Loc>(&V))
+  if (llvm::Optional<Loc> L = V.getAs<Loc>())
     V = Pred->getState()->getSVal(*L);
 
   evalBind(Dst, CtorExpr, Pred, ThisVal, V, true);
@@ -287,7 +287,7 @@ void ExprEngine::VisitCXXNewExpr(const CXXNewExpr *CNE, ExplodedNode *Pred,
   if (CNE->isArray()) {
     // FIXME: allocating an array requires simulating the constructors.
     // For now, just return a symbolicated region.
-    const MemRegion *NewReg = cast<loc::MemRegionVal>(symVal).getRegion();
+    const MemRegion *NewReg = symVal.castAs<loc::MemRegionVal>().getRegion();
     QualType ObjTy = CNE->getType()->getAs<PointerType>()->getPointeeType();
     const ElementRegion *EleReg =
       getStoreManager().GetElementZeroRegion(NewReg, ObjTy);
@@ -319,8 +319,8 @@ void ExprEngine::VisitCXXNewExpr(const CXXNewExpr *CNE, ExplodedNode *Pred,
       (void)ObjTy;
       assert(!ObjTy->isRecordType());
       SVal Location = State->getSVal(CNE, LCtx);
-      if (isa<Loc>(Location))
-        State = State->bindLoc(cast<Loc>(Location), State->getSVal(Init, LCtx));
+      if (llvm::Optional<Loc> LV = Location.getAs<Loc>())
+        State = State->bindLoc(*LV, State->getSVal(Init, LCtx));
     }
   }
 
index 1d006b0..0d4673c 100644 (file)
@@ -121,7 +121,7 @@ static std::pair<const Stmt*,
 static SVal adjustReturnValue(SVal V, QualType ExpectedTy, QualType ActualTy,
                               StoreManager &StoreMgr) {
   // For now, the only adjustments we handle apply only to locations.
-  if (!isa<Loc>(V))
+  if (!V.getAs<Loc>())
     return V;
 
   // If the types already match, don't do any unnecessary work.
@@ -266,7 +266,7 @@ void ExprEngine::processCallExit(ExplodedNode *CEBNode) {
 
       // If the constructed object is a temporary prvalue, get its bindings.
       if (isTemporaryPRValue(CCE, ThisV))
-        ThisV = state->getSVal(cast<Loc>(ThisV));
+        ThisV = state->getSVal(ThisV.castAs<Loc>());
 
       state = state->BindExpr(CCE, callerCtx, ThisV);
     }
@@ -709,7 +709,7 @@ ProgramStateRef ExprEngine::bindReturnValue(const CallEvent &Call,
 
     // If the constructed object is a temporary prvalue, get its bindings.
     if (isTemporaryPRValue(cast<CXXConstructExpr>(E), ThisV))
-      ThisV = State->getSVal(cast<Loc>(ThisV));
+      ThisV = State->getSVal(ThisV.castAs<Loc>());
 
     return State->BindExpr(E, LCtx, ThisV);
   }
index de73dd7..69a5052 100644 (file)
@@ -103,8 +103,9 @@ void ExprEngine::VisitObjCForCollectionStmt(const ObjCForCollectionStmt *S,
     // Handle the case where the container has no elements.
     SVal FalseV = svalBuilder.makeTruthVal(0);
     ProgramStateRef noElems = state->BindExpr(S, LCtx, FalseV);
-    
-    if (loc::MemRegionVal *MV = dyn_cast<loc::MemRegionVal>(&elementV))
+
+    if (llvm::Optional<loc::MemRegionVal> MV =
+            elementV.getAs<loc::MemRegionVal>())
       if (const TypedValueRegion *R = 
           dyn_cast<TypedValueRegion>(MV->getRegion())) {
         // FIXME: The proper thing to do is to really iterate over the
@@ -161,8 +162,9 @@ void ExprEngine::VisitObjCMessage(const ObjCMessageExpr *ME,
       SVal recVal = UpdatedMsg->getReceiverSVal();
       if (!recVal.isUndef()) {
         // Bifurcate the state into nil and non-nil ones.
-        DefinedOrUnknownSVal receiverVal = cast<DefinedOrUnknownSVal>(recVal);
-        
+        DefinedOrUnknownSVal receiverVal =
+            recVal.castAs<DefinedOrUnknownSVal>();
+
         ProgramStateRef notNilState, nilState;
         llvm::tie(notNilState, nilState) = State->assume(receiverVal);
         
index a0abe42..c48343a 100644 (file)
@@ -1044,7 +1044,8 @@ RegionRawOffset ElementRegion::getAsArrayOffset() const {
 
     // FIXME: generalize to symbolic offsets.
     SVal index = ER->getIndex();
-    if (nonloc::ConcreteInt *CI = dyn_cast<nonloc::ConcreteInt>(&index)) {
+    if (llvm::Optional<nonloc::ConcreteInt> CI =
+            index.getAs<nonloc::ConcreteInt>()) {
       // Update the offset.
       int64_t i = CI->getValue().getSExtValue();
 
@@ -1171,7 +1172,8 @@ RegionOffset MemRegion::getAsOffset() const {
       }
 
       SVal Index = ER->getIndex();
-      if (const nonloc::ConcreteInt *CI=dyn_cast<nonloc::ConcreteInt>(&Index)) {
+      if (llvm::Optional<nonloc::ConcreteInt> CI =
+              Index.getAs<nonloc::ConcreteInt>()) {
         // Don't bother calculating precise offsets if we already have a
         // symbolic offset somewhere in the chain. 
         if (SymbolicOffsetBase)
index 3c6ff6c..c723bc8 100644 (file)
@@ -1029,7 +1029,7 @@ std::string StackHintGeneratorForSymbol::getMessage(const ExplodedNode *N){
     }
 
     // Check if the parameter is a pointer to the symbol.
-    if (const loc::MemRegionVal *Reg = dyn_cast<loc::MemRegionVal>(&SV)) {
+    if (llvm::Optional<loc::MemRegionVal> Reg = SV.getAs<loc::MemRegionVal>()) {
       SVal PSV = State->getSVal(Reg->getRegion());
       SymbolRef AS = PSV.getAsLocSymbol();
       if (AS == Sym) {
index a3db376..6c76ebf 100644 (file)
@@ -132,7 +132,7 @@ ProgramStateRef ProgramState::bindLoc(Loc LV, SVal V, bool notifyChanges) const
 
 ProgramStateRef ProgramState::bindDefault(SVal loc, SVal V) const {
   ProgramStateManager &Mgr = getStateManager();
-  const MemRegion *R = cast<loc::MemRegionVal>(loc).getRegion();
+  const MemRegion *R = loc.castAs<loc::MemRegionVal>().getRegion();
   const StoreRef &newStore = Mgr.StoreMgr->BindDefault(getStore(), R, V);
   ProgramStateRef new_state = makeWithStore(newStore);
   return Mgr.getOwningEngine() ? 
@@ -189,7 +189,7 @@ ProgramState::invalidateRegionsImpl(ArrayRef<const MemRegion *> Regions,
 }
 
 ProgramStateRef ProgramState::killBinding(Loc LV) const {
-  assert(!isa<loc::MemRegionVal>(LV) && "Use invalidateRegion instead.");
+  assert(!LV.getAs<loc::MemRegionVal>() && "Use invalidateRegion instead.");
 
   Store OldStore = getStore();
   const StoreRef &newStore =
@@ -253,7 +253,7 @@ SVal ProgramState::getSVal(Loc location, QualType T) const {
         //  not unsigned.
         const llvm::APSInt &NewV = getBasicVals().Convert(T, *Int);
         
-        if (isa<Loc>(V))
+        if (V.getAs<Loc>())
           return loc::ConcreteInt(NewV);
         else
           return nonloc::ConcreteInt(NewV);
@@ -301,28 +301,27 @@ ProgramStateRef ProgramState::assumeInBound(DefinedOrUnknownSVal Idx,
 
   // Adjust the index.
   SVal newIdx = svalBuilder.evalBinOpNN(this, BO_Add,
-                                        cast<NonLoc>(Idx), Min, indexTy);
+                                        Idx.castAs<NonLoc>(), Min, indexTy);
   if (newIdx.isUnknownOrUndef())
     return this;
 
   // Adjust the upper bound.
   SVal newBound =
-    svalBuilder.evalBinOpNN(this, BO_Add, cast<NonLoc>(UpperBound),
+    svalBuilder.evalBinOpNN(this, BO_Add, UpperBound.castAs<NonLoc>(),
                             Min, indexTy);
 
   if (newBound.isUnknownOrUndef())
     return this;
 
   // Build the actual comparison.
-  SVal inBound = svalBuilder.evalBinOpNN(this, BO_LT,
-                                cast<NonLoc>(newIdx), cast<NonLoc>(newBound),
-                                Ctx.IntTy);
+  SVal inBound = svalBuilder.evalBinOpNN(this, BO_LT, newIdx.castAs<NonLoc>(),
+                                         newBound.castAs<NonLoc>(), Ctx.IntTy);
   if (inBound.isUnknownOrUndef())
     return this;
 
   // Finally, let the constraint manager take care of it.
   ConstraintManager &CM = SM.getConstraintManager();
-  return CM.assume(this, cast<DefinedSVal>(inBound), Assumption);
+  return CM.assume(this, inBound.castAs<DefinedSVal>(), Assumption);
 }
 
 ProgramStateRef ProgramStateManager::getInitialState(const LocationContext *InitLoc) {
@@ -509,10 +508,11 @@ bool ScanReachableSymbols::scan(const SymExpr *sym) {
 }
 
 bool ScanReachableSymbols::scan(SVal val) {
-  if (loc::MemRegionVal *X = dyn_cast<loc::MemRegionVal>(&val))
+  if (llvm::Optional<loc::MemRegionVal> X = val.getAs<loc::MemRegionVal>())
     return scan(X->getRegion());
 
-  if (nonloc::LazyCompoundVal *X = dyn_cast<nonloc::LazyCompoundVal>(&val)) {
+  if (llvm::Optional<nonloc::LazyCompoundVal> X =
+          val.getAs<nonloc::LazyCompoundVal>()) {
     StoreManager &StoreMgr = state->getStateManager().getStoreManager();
     // FIXME: We don't really want to use getBaseRegion() here because pointer
     // arithmetic doesn't apply, but scanReachableSymbols only accepts base
@@ -523,7 +523,8 @@ bool ScanReachableSymbols::scan(SVal val) {
       return false;
   }
 
-  if (nonloc::LocAsInteger *X = dyn_cast<nonloc::LocAsInteger>(&val))
+  if (llvm::Optional<nonloc::LocAsInteger> X =
+          val.getAs<nonloc::LocAsInteger>())
     return scan(X->getLoc());
 
   if (SymbolRef Sym = val.getAsSymbol())
@@ -532,7 +533,7 @@ bool ScanReachableSymbols::scan(SVal val) {
   if (const SymExpr *Sym = val.getAsSymbolicExpression())
     return scan(Sym);
 
-  if (nonloc::CompoundVal *X = dyn_cast<nonloc::CompoundVal>(&val))
+  if (llvm::Optional<nonloc::CompoundVal> X = val.getAs<nonloc::CompoundVal>())
     return scan(*X);
 
   return true;
index 4d9a313..39417af 100644 (file)
@@ -753,7 +753,8 @@ static void collectSubRegionKeys(SmallVectorImpl<BindingKey> &Keys,
   // be using this function anyway.
   uint64_t Length = UINT64_MAX;
   SVal Extent = Top->getExtent(SVB);
-  if (nonloc::ConcreteInt *ExtentCI = dyn_cast<nonloc::ConcreteInt>(&Extent)) {
+  if (llvm::Optional<nonloc::ConcreteInt> ExtentCI =
+          Extent.getAs<nonloc::ConcreteInt>()) {
     const llvm::APSInt &ExtentInt = ExtentCI->getValue();
     assert(ExtentInt.isNonNegative() || ExtentInt.isUnsigned());
     // Extents are in bytes but region offsets are in bits. Be careful!
@@ -893,8 +894,8 @@ void invalidateRegionsWorker::VisitBinding(SVal V) {
   }
 
   // Is it a LazyCompoundVal?  All references get invalidated as well.
-  if (const nonloc::LazyCompoundVal *LCS =
-        dyn_cast<nonloc::LazyCompoundVal>(&V)) {
+  if (llvm::Optional<nonloc::LazyCompoundVal> LCS =
+          V.getAs<nonloc::LazyCompoundVal>()) {
 
     const RegionStoreManager::SValListTy &Vals = RM.getInterestingValues(*LCS);
 
@@ -938,7 +939,7 @@ void invalidateRegionsWorker::VisitBaseRegion(const MemRegion *baseR) {
         // a pointer value, but the thing pointed by that pointer may
         // get invalidated.
         SVal V = RM.getBinding(B, loc::MemRegionVal(VR));
-        if (const Loc *L = dyn_cast<Loc>(&V)) {
+        if (llvm::Optional<Loc> L = V.getAs<Loc>()) {
           if (const MemRegion *LR = L->getAsRegion())
             AddToWorkList(LR);
         }
@@ -1111,10 +1112,10 @@ RegionStoreManager::getSizeInElements(ProgramStateRef state,
 ///  the array).  This is called by ExprEngine when evaluating casts
 ///  from arrays to pointers.
 SVal RegionStoreManager::ArrayToPointer(Loc Array) {
-  if (!isa<loc::MemRegionVal>(Array))
+  if (!Array.getAs<loc::MemRegionVal>())
     return UnknownVal();
 
-  const MemRegion* R = cast<loc::MemRegionVal>(&Array)->getRegion();
+  const MemRegion* R = Array.castAs<loc::MemRegionVal>().getRegion();
   const TypedValueRegion* ArrayR = dyn_cast<TypedValueRegion>(R);
 
   if (!ArrayR)
@@ -1134,8 +1135,8 @@ SVal RegionStoreManager::ArrayToPointer(Loc Array) {
 //===----------------------------------------------------------------------===//
 
 SVal RegionStoreManager::getBinding(RegionBindingsConstRef B, Loc L, QualType T) {
-  assert(!isa<UnknownVal>(L) && "location unknown");
-  assert(!isa<UndefinedVal>(L) && "location undefined");
+  assert(!L.getAs<UnknownVal>() && "location unknown");
+  assert(!L.getAs<UndefinedVal>() && "location undefined");
 
   // For access to concrete addresses, return UnknownVal.  Checks
   // for null dereferences (and similar errors) are done by checkers, not
@@ -1143,14 +1144,14 @@ SVal RegionStoreManager::getBinding(RegionBindingsConstRef B, Loc L, QualType T)
   // FIXME: We can consider lazily symbolicating such memory, but we really
   // should defer this when we can reason easily about symbolicating arrays
   // of bytes.
-  if (isa<loc::ConcreteInt>(L)) {
+  if (L.getAs<loc::ConcreteInt>()) {
     return UnknownVal();
   }
-  if (!isa<loc::MemRegionVal>(L)) {
+  if (!L.getAs<loc::MemRegionVal>()) {
     return UnknownVal();
   }
 
-  const MemRegion *MR = cast<loc::MemRegionVal>(L).getRegion();
+  const MemRegion *MR = L.castAs<loc::MemRegionVal>().getRegion();
 
   if (isa<AllocaRegion>(MR) ||
       isa<SymbolicRegion>(MR) ||
@@ -1263,8 +1264,8 @@ RegionStoreManager::getLazyBinding(RegionBindingsConstRef B,
 
   if (originalRegion != R) {
     if (Optional<SVal> OV = B.getDefaultBinding(R)) {
-      if (const nonloc::LazyCompoundVal *V =
-            dyn_cast<nonloc::LazyCompoundVal>(OV.getPointer()))
+      if (llvm::Optional<nonloc::LazyCompoundVal> V =
+              OV.getPointer()->getAs<nonloc::LazyCompoundVal>())
         return std::make_pair(V->getStore(), V->getRegion());
     }
   }
@@ -1345,7 +1346,8 @@ SVal RegionStoreManager::getBindingForElement(RegionBindingsConstRef B,
 
     const StringLiteral *Str = StrR->getStringLiteral();
     SVal Idx = R->getIndex();
-    if (nonloc::ConcreteInt *CI = dyn_cast<nonloc::ConcreteInt>(&Idx)) {
+    if (llvm::Optional<nonloc::ConcreteInt> CI =
+            Idx.getAs<nonloc::ConcreteInt>()) {
       int64_t i = CI->getValue().getSExtValue();
       // Abort on string underrun.  This can be possible by arbitrary
       // clients of getBindingForElement().
@@ -1431,7 +1433,7 @@ RegionStoreManager::getBindingForDerivedDefaultValue(RegionBindingsConstRef B,
       return val;
 
     // Lazy bindings are handled later.
-    if (isa<nonloc::LazyCompoundVal>(val))
+    if (val.getAs<nonloc::LazyCompoundVal>())
       return Optional<SVal>();
 
     llvm_unreachable("Unknown default value");
@@ -1650,9 +1652,8 @@ RegionStoreManager::getInterestingValues(nonloc::LazyCompoundVal LCV) {
     if (V.isUnknownOrUndef() || V.isConstant())
       continue;
 
-    const nonloc::LazyCompoundVal *InnerLCV =
-      dyn_cast<nonloc::LazyCompoundVal>(&V);
-    if (InnerLCV) {
+    if (llvm::Optional<nonloc::LazyCompoundVal> InnerLCV =
+            V.getAs<nonloc::LazyCompoundVal>()) {
       const SValListTy &InnerList = getInterestingValues(*InnerLCV);
       List.insert(List.end(), InnerList.begin(), InnerList.end());
       continue;
@@ -1669,9 +1670,8 @@ NonLoc RegionStoreManager::createLazyBinding(RegionBindingsConstRef B,
   // If we already have a lazy binding, and it's for the whole structure,
   // don't create a new lazy binding.
   if (Optional<SVal> V = B.getDefaultBinding(R)) {
-    const nonloc::LazyCompoundVal *LCV =
-      dyn_cast<nonloc::LazyCompoundVal>(V.getPointer());
-    if (LCV) {
+    if (llvm::Optional<nonloc::LazyCompoundVal> LCV =
+            V.getPointer()->getAs<nonloc::LazyCompoundVal>()) {
       QualType RegionTy = R->getValueType();
       QualType SourceRegionTy = LCV->getRegion()->getValueType();
       if (Ctx.hasSameUnqualifiedType(RegionTy, SourceRegionTy))
@@ -1728,8 +1728,8 @@ bool RegionStoreManager::includedInBindings(Store store,
 //===----------------------------------------------------------------------===//
 
 StoreRef RegionStoreManager::killBinding(Store ST, Loc L) {
-  if (isa<loc::MemRegionVal>(L))
-    if (const MemRegion* R = cast<loc::MemRegionVal>(L).getRegion())
+  if (llvm::Optional<loc::MemRegionVal> LV = L.getAs<loc::MemRegionVal>())
+    if (const MemRegion* R = LV->getRegion())
       return StoreRef(getRegionBindings(ST).removeBinding(R)
                                            .asImmutableMap()
                                            .getRootWithoutRetain(),
@@ -1740,11 +1740,11 @@ StoreRef RegionStoreManager::killBinding(Store ST, Loc L) {
 
 RegionBindingsRef
 RegionStoreManager::bind(RegionBindingsConstRef B, Loc L, SVal V) {
-  if (isa<loc::ConcreteInt>(L))
+  if (L.getAs<loc::ConcreteInt>())
     return B;
 
   // If we get here, the location should be a region.
-  const MemRegion *R = cast<loc::MemRegionVal>(L).getRegion();
+  const MemRegion *R = L.castAs<loc::MemRegionVal>().getRegion();
 
   // Check if the region is a struct region.
   if (const TypedValueRegion* TR = dyn_cast<TypedValueRegion>(R)) {
@@ -1820,18 +1820,18 @@ RegionStoreManager::bindArray(RegionBindingsConstRef B,
     Size = CAT->getSize().getZExtValue();
 
   // Check if the init expr is a string literal.
-  if (loc::MemRegionVal *MRV = dyn_cast<loc::MemRegionVal>(&Init)) {
+  if (llvm::Optional<loc::MemRegionVal> MRV = Init.getAs<loc::MemRegionVal>()) {
     const StringRegion *S = cast<StringRegion>(MRV->getRegion());
 
     // Treat the string as a lazy compound value.
     StoreRef store(B.asStore(), *this);
-    nonloc::LazyCompoundVal LCV =
-      cast<nonloc::LazyCompoundVal>(svalBuilder.makeLazyCompoundVal(store, S));
+    nonloc::LazyCompoundVal LCV = svalBuilder.makeLazyCompoundVal(store, S)
+        .castAs<nonloc::LazyCompoundVal>();
     return bindAggregate(B, R, LCV);
   }
 
   // Handle lazy compound values.
-  if (isa<nonloc::LazyCompoundVal>(Init))
+  if (Init.getAs<nonloc::LazyCompoundVal>())
     return bindAggregate(B, R, Init);
 
   // Remaining case: explicit compound values.
@@ -1839,7 +1839,7 @@ RegionStoreManager::bindArray(RegionBindingsConstRef B,
   if (Init.isUnknown())
     return setImplicitDefaultValue(B, R, ElementTy);
 
-  nonloc::CompoundVal& CV = cast<nonloc::CompoundVal>(Init);
+  const nonloc::CompoundVal& CV = Init.castAs<nonloc::CompoundVal>();
   nonloc::CompoundVal::iterator VI = CV.begin(), VE = CV.end();
   uint64_t i = 0;
 
@@ -1877,18 +1877,18 @@ RegionBindingsRef RegionStoreManager::bindVector(RegionBindingsConstRef B,
   const VectorType *VT = T->getAs<VectorType>(); // Use getAs for typedefs.
  
   // Handle lazy compound values and symbolic values.
-  if (isa<nonloc::LazyCompoundVal>(V) || isa<nonloc::SymbolVal>(V))
+  if (V.getAs<nonloc::LazyCompoundVal>() || V.getAs<nonloc::SymbolVal>())
     return bindAggregate(B, R, V);
   
   // We may get non-CompoundVal accidentally due to imprecise cast logic or
   // that we are binding symbolic struct value. Kill the field values, and if
   // the value is symbolic go and bind it as a "default" binding.
-  if (!isa<nonloc::CompoundVal>(V)) {
+  if (!V.getAs<nonloc::CompoundVal>()) {
     return bindAggregate(B, R, UnknownVal());
   }
 
   QualType ElemType = VT->getElementType();
-  nonloc::CompoundVal& CV = cast<nonloc::CompoundVal>(V);
+  nonloc::CompoundVal CV = V.castAs<nonloc::CompoundVal>();
   nonloc::CompoundVal::iterator VI = CV.begin(), VE = CV.end();
   unsigned index = 0, numElements = VT->getNumElements();
   RegionBindingsRef NewB(B);
@@ -1926,16 +1926,16 @@ RegionBindingsRef RegionStoreManager::bindStruct(RegionBindingsConstRef B,
     return B;
 
   // Handle lazy compound values and symbolic values.
-  if (isa<nonloc::LazyCompoundVal>(V) || isa<nonloc::SymbolVal>(V))
+  if (V.getAs<nonloc::LazyCompoundVal>() || V.getAs<nonloc::SymbolVal>())
     return bindAggregate(B, R, V);
 
   // We may get non-CompoundVal accidentally due to imprecise cast logic or
   // that we are binding symbolic struct value. Kill the field values, and if
   // the value is symbolic go and bind it as a "default" binding.
-  if (V.isUnknown() || !isa<nonloc::CompoundVal>(V))
+  if (V.isUnknown() || !V.getAs<nonloc::CompoundVal>())
     return bindAggregate(B, R, UnknownVal());
 
-  nonloc::CompoundVal& CV = cast<nonloc::CompoundVal>(V);
+  const nonloc::CompoundVal& CV = V.castAs<nonloc::CompoundVal>();
   nonloc::CompoundVal::iterator VI = CV.begin(), VE = CV.end();
 
   RecordDecl::field_iterator FI, FE;
@@ -2057,8 +2057,8 @@ void removeDeadBindingsWorker::VisitCluster(const MemRegion *baseR,
 
 void removeDeadBindingsWorker::VisitBinding(SVal V) {
   // Is it a LazyCompoundVal?  All referenced regions are live as well.
-  if (const nonloc::LazyCompoundVal *LCS =
-        dyn_cast<nonloc::LazyCompoundVal>(&V)) {
+  if (llvm::Optional<nonloc::LazyCompoundVal> LCS =
+          V.getAs<nonloc::LazyCompoundVal>()) {
 
     const RegionStoreManager::SValListTy &Vals = RM.getInterestingValues(*LCS);
 
index 96e46b8..d099a8f 100644 (file)
@@ -78,13 +78,14 @@ SVal SValBuilder::convertToArrayIndex(SVal val) {
     return val;
 
   // Common case: we have an appropriately sized integer.
-  if (nonloc::ConcreteInt* CI = dyn_cast<nonloc::ConcreteInt>(&val)) {
+  if (llvm::Optional<nonloc::ConcreteInt> CI =
+          val.getAs<nonloc::ConcreteInt>()) {
     const llvm::APSInt& I = CI->getValue();
     if (I.getBitWidth() == ArrayIndexWidth && I.isSigned())
       return val;
   }
 
-  return evalCastFromNonLoc(cast<NonLoc>(val), ArrayIndexTy);
+  return evalCastFromNonLoc(val.castAs<NonLoc>(), ArrayIndexTy);
 }
 
 nonloc::ConcreteInt SValBuilder::makeBoolVal(const CXXBoolLiteralExpr *boolean){
@@ -237,11 +238,13 @@ SVal SValBuilder::makeSymExprValNN(ProgramStateRef State,
     return makeNonLoc(symLHS, Op, symRHS, ResultTy);
 
   if (symLHS && symLHS->computeComplexity() < MaxComp)
-    if (const nonloc::ConcreteInt *rInt = dyn_cast<nonloc::ConcreteInt>(&RHS))
+    if (llvm::Optional<nonloc::ConcreteInt> rInt =
+            RHS.getAs<nonloc::ConcreteInt>())
       return makeNonLoc(symLHS, Op, rInt->getValue(), ResultTy);
 
   if (symRHS && symRHS->computeComplexity() < MaxComp)
-    if (const nonloc::ConcreteInt *lInt = dyn_cast<nonloc::ConcreteInt>(&LHS))
+    if (llvm::Optional<nonloc::ConcreteInt> lInt =
+            LHS.getAs<nonloc::ConcreteInt>())
       return makeNonLoc(lInt->getValue(), Op, symRHS, ResultTy);
 
   return UnknownVal();
@@ -257,30 +260,31 @@ SVal SValBuilder::evalBinOp(ProgramStateRef state, BinaryOperator::Opcode op,
   if (lhs.isUnknown() || rhs.isUnknown())
     return UnknownVal();
 
-  if (isa<Loc>(lhs)) {
-    if (isa<Loc>(rhs))
-      return evalBinOpLL(state, op, cast<Loc>(lhs), cast<Loc>(rhs), type);
+  if (llvm::Optional<Loc> LV = lhs.getAs<Loc>()) {
+    if (llvm::Optional<Loc> RV = rhs.getAs<Loc>())
+      return evalBinOpLL(state, op, *LV, *RV, type);
 
-    return evalBinOpLN(state, op, cast<Loc>(lhs), cast<NonLoc>(rhs), type);
+    return evalBinOpLN(state, op, *LV, rhs.castAs<NonLoc>(), type);
   }
 
-  if (isa<Loc>(rhs)) {
+  if (llvm::Optional<Loc> RV = rhs.getAs<Loc>()) {
     // Support pointer arithmetic where the addend is on the left
     // and the pointer on the right.
     assert(op == BO_Add);
 
     // Commute the operands.
-    return evalBinOpLN(state, op, cast<Loc>(rhs), cast<NonLoc>(lhs), type);
+    return evalBinOpLN(state, op, *RV, lhs.castAs<NonLoc>(), type);
   }
 
-  return evalBinOpNN(state, op, cast<NonLoc>(lhs), cast<NonLoc>(rhs), type);
+  return evalBinOpNN(state, op, lhs.castAs<NonLoc>(), rhs.castAs<NonLoc>(),
+                     type);
 }
 
 DefinedOrUnknownSVal SValBuilder::evalEQ(ProgramStateRef state,
                                          DefinedOrUnknownSVal lhs,
                                          DefinedOrUnknownSVal rhs) {
-  return cast<DefinedOrUnknownSVal>(evalBinOp(state, BO_EQ, lhs, rhs,
-                                              Context.IntTy));
+  return evalBinOp(state, BO_EQ, lhs, rhs, Context.IntTy)
+      .castAs<DefinedOrUnknownSVal>();
 }
 
 /// Recursively check if the pointer types are equal modulo const, volatile,
@@ -327,11 +331,12 @@ SVal SValBuilder::evalCast(SVal val, QualType castTy, QualType originalTy) {
   
   // Check for casts from pointers to integers.
   if (castTy->isIntegerType() && Loc::isLocType(originalTy))
-    return evalCastFromLoc(cast<Loc>(val), castTy);
+    return evalCastFromLoc(val.castAs<Loc>(), castTy);
 
   // Check for casts from integers to pointers.
   if (Loc::isLocType(castTy) && originalTy->isIntegerType()) {
-    if (nonloc::LocAsInteger *LV = dyn_cast<nonloc::LocAsInteger>(&val)) {
+    if (llvm::Optional<nonloc::LocAsInteger> LV =
+            val.getAs<nonloc::LocAsInteger>()) {
       if (const MemRegion *R = LV->getLoc().getAsRegion()) {
         StoreManager &storeMgr = StateMgr.getStoreManager();
         R = storeMgr.castRegion(R, castTy);
@@ -351,7 +356,7 @@ SVal SValBuilder::evalCast(SVal val, QualType castTy, QualType originalTy) {
   // Check for casts from array type to another type.
   if (originalTy->isArrayType()) {
     // We will always decay to a pointer.
-    val = StateMgr.ArrayToPointer(cast<Loc>(val));
+    val = StateMgr.ArrayToPointer(val.castAs<Loc>());
 
     // Are we casting from an array to a pointer?  If so just pass on
     // the decayed value.
@@ -366,7 +371,7 @@ SVal SValBuilder::evalCast(SVal val, QualType castTy, QualType originalTy) {
     // need the original decayed type.
     //    QualType elemTy = cast<ArrayType>(originalTy)->getElementType();
     //    QualType pointerTy = C.getPointerType(elemTy);
-    return evalCastFromLoc(cast<Loc>(val), castTy);
+    return evalCastFromLoc(val.castAs<Loc>(), castTy);
   }
 
   // Check for casts from a region to a specific type.
index 5906068..72959f5 100644 (file)
@@ -30,13 +30,13 @@ using llvm::APSInt;
 //===----------------------------------------------------------------------===//
 
 bool SVal::hasConjuredSymbol() const {
-  if (const nonloc::SymbolVal* SV = dyn_cast<nonloc::SymbolVal>(this)) {
+  if (llvm::Optional<nonloc::SymbolVal> SV = getAs<nonloc::SymbolVal>()) {
     SymbolRef sym = SV->getSymbol();
     if (isa<SymbolConjured>(sym))
       return true;
   }
 
-  if (const loc::MemRegionVal *RV = dyn_cast<loc::MemRegionVal>(this)) {
+  if (llvm::Optional<loc::MemRegionVal> RV = getAs<loc::MemRegionVal>()) {
     const MemRegion *R = RV->getRegion();
     if (const SymbolicRegion *SR = dyn_cast<SymbolicRegion>(R)) {
       SymbolRef sym = SR->getSymbol();
@@ -49,7 +49,7 @@ bool SVal::hasConjuredSymbol() const {
 }
 
 const FunctionDecl *SVal::getAsFunctionDecl() const {
-  if (const loc::MemRegionVal* X = dyn_cast<loc::MemRegionVal>(this)) {
+  if (llvm::Optional<loc::MemRegionVal> X = getAs<loc::MemRegionVal>()) {
     const MemRegion* R = X->getRegion();
     if (const FunctionTextRegion *CTR = R->getAs<FunctionTextRegion>())
       if (const FunctionDecl *FD = dyn_cast<FunctionDecl>(CTR->getDecl()))
@@ -66,10 +66,10 @@ const FunctionDecl *SVal::getAsFunctionDecl() const {
 /// region. If that is the case, gets the underlining region.
 SymbolRef SVal::getAsLocSymbol() const {
   // FIXME: should we consider SymbolRef wrapped in CodeTextRegion?
-  if (const nonloc::LocAsInteger *X = dyn_cast<nonloc::LocAsInteger>(this))
+  if (llvm::Optional<nonloc::LocAsInteger> X = getAs<nonloc::LocAsInteger>())
     return X->getLoc().getAsLocSymbol();
 
-  if (const loc::MemRegionVal *X = dyn_cast<loc::MemRegionVal>(this)) {
+  if (llvm::Optional<loc::MemRegionVal> X = getAs<loc::MemRegionVal>()) {
     const MemRegion *R = X->stripCasts();
     if (const SymbolicRegion *SymR = dyn_cast<SymbolicRegion>(R))
       return SymR->getSymbol();
@@ -79,7 +79,7 @@ SymbolRef SVal::getAsLocSymbol() const {
 
 /// Get the symbol in the SVal or its base region.
 SymbolRef SVal::getLocSymbolInBase() const {
-  const loc::MemRegionVal *X = dyn_cast<loc::MemRegionVal>(this);
+  llvm::Optional<loc::MemRegionVal> X = getAs<loc::MemRegionVal>();
 
   if (!X)
     return 0;
@@ -102,7 +102,7 @@ SymbolRef SVal::getLocSymbolInBase() const {
 ///  Otherwise return 0.
 SymbolRef SVal::getAsSymbol() const {
   // FIXME: should we consider SymbolRef wrapped in CodeTextRegion?
-  if (const nonloc::SymbolVal *X = dyn_cast<nonloc::SymbolVal>(this))
+  if (llvm::Optional<nonloc::SymbolVal> X = getAs<nonloc::SymbolVal>())
     return X->getSymbol();
 
   return getAsLocSymbol();
@@ -111,7 +111,7 @@ SymbolRef SVal::getAsSymbol() const {
 /// getAsSymbolicExpression - If this Sval wraps a symbolic expression then
 ///  return that expression.  Otherwise return NULL.
 const SymExpr *SVal::getAsSymbolicExpression() const {
-  if (const nonloc::SymbolVal *X = dyn_cast<nonloc::SymbolVal>(this))
+  if (llvm::Optional<nonloc::SymbolVal> X = getAs<nonloc::SymbolVal>())
     return X->getSymbol();
 
   return getAsSymbol();
@@ -125,12 +125,11 @@ const SymExpr* SVal::getAsSymExpr() const {
 }
 
 const MemRegion *SVal::getAsRegion() const {
-  if (const loc::MemRegionVal *X = dyn_cast<loc::MemRegionVal>(this))
+  if (llvm::Optional<loc::MemRegionVal> X = getAs<loc::MemRegionVal>())
     return X->getRegion();
 
-  if (const nonloc::LocAsInteger *X = dyn_cast<nonloc::LocAsInteger>(this)) {
+  if (llvm::Optional<nonloc::LocAsInteger> X = getAs<nonloc::LocAsInteger>())
     return X->getLoc().getAsRegion();
-  }
 
   return 0;
 }
@@ -165,16 +164,15 @@ nonloc::CompoundVal::iterator nonloc::CompoundVal::end() const {
 //===----------------------------------------------------------------------===//
 
 bool SVal::isConstant() const {
-  return isa<nonloc::ConcreteInt>(this) || isa<loc::ConcreteInt>(this);
+  return getAs<nonloc::ConcreteInt>() || getAs<loc::ConcreteInt>();
 }
 
 bool SVal::isConstant(int I) const {
-  if (isa<loc::ConcreteInt>(*this))
-    return cast<loc::ConcreteInt>(*this).getValue() == I;
-  else if (isa<nonloc::ConcreteInt>(*this))
-    return cast<nonloc::ConcreteInt>(*this).getValue() == I;
-  else
-    return false;
+  if (llvm::Optional<loc::ConcreteInt> LV = getAs<loc::ConcreteInt>())
+    return LV->getValue() == I;
+  if (llvm::Optional<nonloc::ConcreteInt> NV = getAs<nonloc::ConcreteInt>())
+    return NV->getValue() == I;
+  return false;
 }
 
 bool SVal::isZeroConstant() const {
@@ -239,10 +237,10 @@ void SVal::dumpToStream(raw_ostream &os) const {
       os << "Unknown";
       break;
     case NonLocKind:
-      cast<NonLoc>(this)->dumpToStream(os);
+      castAs<NonLoc>().dumpToStream(os);
       break;
     case LocKind:
-      cast<Loc>(this)->dumpToStream(os);
+      castAs<Loc>().dumpToStream(os);
       break;
     case UndefinedKind:
       os << "Undefined";
@@ -253,7 +251,7 @@ void SVal::dumpToStream(raw_ostream &os) const {
 void NonLoc::dumpToStream(raw_ostream &os) const {
   switch (getSubKind()) {
     case nonloc::ConcreteIntKind: {
-      const nonloc::ConcreteInt& C = *cast<nonloc::ConcreteInt>(this);
+      const nonloc::ConcreteInt& C = castAs<nonloc::ConcreteInt>();
       if (C.getValue().isUnsigned())
         os << C.getValue().getZExtValue();
       else
@@ -263,16 +261,16 @@ void NonLoc::dumpToStream(raw_ostream &os) const {
       break;
     }
     case nonloc::SymbolValKind: {
-      os << cast<nonloc::SymbolVal>(this)->getSymbol();
+      os << castAs<nonloc::SymbolVal>().getSymbol();
       break;
     }
     case nonloc::LocAsIntegerKind: {
-      const nonloc::LocAsInteger& C = *cast<nonloc::LocAsInteger>(this);
+      const nonloc::LocAsInteger& C = castAs<nonloc::LocAsInteger>();
       os << C.getLoc() << " [as " << C.getNumBits() << " bit integer]";
       break;
     }
     case nonloc::CompoundValKind: {
-      const nonloc::CompoundVal& C = *cast<nonloc::CompoundVal>(this);
+      const nonloc::CompoundVal& C = castAs<nonloc::CompoundVal>();
       os << "compoundVal{";
       bool first = true;
       for (nonloc::CompoundVal::iterator I=C.begin(), E=C.end(); I!=E; ++I) {
@@ -288,7 +286,7 @@ void NonLoc::dumpToStream(raw_ostream &os) const {
       break;
     }
     case nonloc::LazyCompoundValKind: {
-      const nonloc::LazyCompoundVal &C = *cast<nonloc::LazyCompoundVal>(this);
+      const nonloc::LazyCompoundVal &C = castAs<nonloc::LazyCompoundVal>();
       os << "lazyCompoundVal{" << const_cast<void *>(C.getStore())
          << ',' << C.getRegion()
          << '}';
@@ -303,13 +301,13 @@ void NonLoc::dumpToStream(raw_ostream &os) const {
 void Loc::dumpToStream(raw_ostream &os) const {
   switch (getSubKind()) {
     case loc::ConcreteIntKind:
-      os << cast<loc::ConcreteInt>(this)->getValue().getZExtValue() << " (Loc)";
+      os << castAs<loc::ConcreteInt>().getValue().getZExtValue() << " (Loc)";
       break;
     case loc::GotoLabelKind:
-      os << "&&" << cast<loc::GotoLabel>(this)->getLabel()->getName();
+      os << "&&" << castAs<loc::GotoLabel>().getLabel()->getName();
       break;
     case loc::MemRegionKind:
-      os << '&' << cast<loc::MemRegionVal>(this)->getRegion()->getString();
+      os << '&' << castAs<loc::MemRegionVal>().getRegion()->getString();
       break;
     default:
       llvm_unreachable("Pretty-printing not implemented for this Loc.");
index 4236ee4..3838830 100644 (file)
@@ -24,7 +24,7 @@ namespace ento {
 SimpleConstraintManager::~SimpleConstraintManager() {}
 
 bool SimpleConstraintManager::canReasonAbout(SVal X) const {
-  nonloc::SymbolVal *SymVal = dyn_cast<nonloc::SymbolVal>(&X);
+  llvm::Optional<nonloc::SymbolVal> SymVal = X.getAs<nonloc::SymbolVal>();
   if (SymVal && SymVal->isExpression()) {
     const SymExpr *SE = SymVal->getSymbol();
 
@@ -58,10 +58,9 @@ bool SimpleConstraintManager::canReasonAbout(SVal X) const {
 ProgramStateRef SimpleConstraintManager::assume(ProgramStateRef state,
                                                DefinedSVal Cond,
                                                bool Assumption) {
-  if (isa<NonLoc>(Cond))
-    return assume(state, cast<NonLoc>(Cond), Assumption);
-  else
-    return assume(state, cast<Loc>(Cond), Assumption);
+  if (llvm::Optional<NonLoc> NV = Cond.getAs<NonLoc>())
+    return assume(state, *NV, Assumption);
+  return assume(state, Cond.castAs<Loc>(), Assumption);
 }
 
 ProgramStateRef SimpleConstraintManager::assume(ProgramStateRef state, Loc cond,
@@ -82,7 +81,7 @@ ProgramStateRef SimpleConstraintManager::assumeAux(ProgramStateRef state,
   case loc::MemRegionKind: {
     // FIXME: Should this go into the storemanager?
 
-    const MemRegion *R = cast<loc::MemRegionVal>(Cond).getRegion();
+    const MemRegion *R = Cond.castAs<loc::MemRegionVal>().getRegion();
     const SubRegion *SubR = dyn_cast<SubRegion>(R);
 
     while (SubR) {
@@ -104,7 +103,7 @@ ProgramStateRef SimpleConstraintManager::assumeAux(ProgramStateRef state,
     return Assumption ? state : NULL;
 
   case loc::ConcreteIntKind: {
-    bool b = cast<loc::ConcreteInt>(Cond).getValue() != 0;
+    bool b = Cond.castAs<loc::ConcreteInt>().getValue() != 0;
     bool isFeasible = b ? Assumption : !Assumption;
     return isFeasible ? state : NULL;
   }
@@ -172,7 +171,7 @@ ProgramStateRef SimpleConstraintManager::assumeAux(ProgramStateRef state,
     llvm_unreachable("'Assume' not implemented for this NonLoc");
 
   case nonloc::SymbolValKind: {
-    nonloc::SymbolVal& SV = cast<nonloc::SymbolVal>(Cond);
+    nonloc::SymbolVal SV = Cond.castAs<nonloc::SymbolVal>();
     SymbolRef sym = SV.getSymbol();
     assert(sym);
 
@@ -204,13 +203,13 @@ ProgramStateRef SimpleConstraintManager::assumeAux(ProgramStateRef state,
   }
 
   case nonloc::ConcreteIntKind: {
-    bool b = cast<nonloc::ConcreteInt>(Cond).getValue() != 0;
+    bool b = Cond.castAs<nonloc::ConcreteInt>().getValue() != 0;
     bool isFeasible = b ? Assumption : !Assumption;
     return isFeasible ? state : NULL;
   }
 
   case nonloc::LocAsIntegerKind:
-    return assumeAux(state, cast<nonloc::LocAsInteger>(Cond).getLoc(),
+    return assumeAux(state, Cond.castAs<nonloc::LocAsInteger>().getLoc(),
                      Assumption);
   } // end switch
 }
index a59cd50..080e81d 100644 (file)
@@ -60,16 +60,17 @@ SValBuilder *ento::createSimpleSValBuilder(llvm::BumpPtrAllocator &alloc,
 //===----------------------------------------------------------------------===//
 
 SVal SimpleSValBuilder::dispatchCast(SVal Val, QualType CastTy) {
-  assert(isa<Loc>(&Val) || isa<NonLoc>(&Val));
-  return isa<Loc>(Val) ? evalCastFromLoc(cast<Loc>(Val), CastTy)
-                       : evalCastFromNonLoc(cast<NonLoc>(Val), CastTy);
+  assert(Val.getAs<Loc>() || Val.getAs<NonLoc>());
+  return Val.getAs<Loc>() ? evalCastFromLoc(Val.castAs<Loc>(), CastTy)
+                           : evalCastFromNonLoc(Val.castAs<NonLoc>(), CastTy);
 }
 
 SVal SimpleSValBuilder::evalCastFromNonLoc(NonLoc val, QualType castTy) {
 
   bool isLocType = Loc::isLocType(castTy);
 
-  if (nonloc::LocAsInteger *LI = dyn_cast<nonloc::LocAsInteger>(&val)) {
+  if (llvm::Optional<nonloc::LocAsInteger> LI =
+          val.getAs<nonloc::LocAsInteger>()) {
     if (isLocType)
       return LI->getLoc();
 
@@ -98,12 +99,12 @@ SVal SimpleSValBuilder::evalCastFromNonLoc(NonLoc val, QualType castTy) {
   }
 
   // If value is a non integer constant, produce unknown.
-  if (!isa<nonloc::ConcreteInt>(val))
+  if (!val.getAs<nonloc::ConcreteInt>())
     return UnknownVal();
 
   // Handle casts to a boolean type.
   if (castTy->isBooleanType()) {
-    bool b = cast<nonloc::ConcreteInt>(val).getValue().getBoolValue();
+    bool b = val.castAs<nonloc::ConcreteInt>().getValue().getBoolValue();
     return makeTruthVal(b, castTy);
   }
 
@@ -112,7 +113,7 @@ SVal SimpleSValBuilder::evalCastFromNonLoc(NonLoc val, QualType castTy) {
   if (!isLocType && !castTy->isIntegerType())
     return UnknownVal();
 
-  llvm::APSInt i = cast<nonloc::ConcreteInt>(val).getValue();
+  llvm::APSInt i = val.castAs<nonloc::ConcreteInt>().getValue();
   BasicVals.getAPSIntType(castTy).apply(i);
 
   if (isLocType)
@@ -140,10 +141,10 @@ SVal SimpleSValBuilder::evalCastFromLoc(Loc val, QualType castTy) {
   if (castTy->isIntegerType()) {
     unsigned BitWidth = Context.getTypeSize(castTy);
 
-    if (!isa<loc::ConcreteInt>(val))
+    if (!val.getAs<loc::ConcreteInt>())
       return makeLocAsInteger(val, BitWidth);
 
-    llvm::APSInt i = cast<loc::ConcreteInt>(val).getValue();
+    llvm::APSInt i = val.castAs<loc::ConcreteInt>().getValue();
     BasicVals.getAPSIntType(castTy).apply(i);
     return makeIntVal(i);
   }
@@ -161,7 +162,7 @@ SVal SimpleSValBuilder::evalCastFromLoc(Loc val, QualType castTy) {
 SVal SimpleSValBuilder::evalMinus(NonLoc val) {
   switch (val.getSubKind()) {
   case nonloc::ConcreteIntKind:
-    return cast<nonloc::ConcreteInt>(val).evalMinus(*this);
+    return val.castAs<nonloc::ConcreteInt>().evalMinus(*this);
   default:
     return UnknownVal();
   }
@@ -170,7 +171,7 @@ SVal SimpleSValBuilder::evalMinus(NonLoc val) {
 SVal SimpleSValBuilder::evalComplement(NonLoc X) {
   switch (X.getSubKind()) {
   case nonloc::ConcreteIntKind:
-    return cast<nonloc::ConcreteInt>(X).evalComplement(*this);
+    return X.castAs<nonloc::ConcreteInt>().evalComplement(*this);
   default:
     return UnknownVal();
   }
@@ -337,15 +338,15 @@ SVal SimpleSValBuilder::evalBinOpNN(ProgramStateRef state,
     default:
       return makeSymExprValNN(state, op, lhs, rhs, resultTy);
     case nonloc::LocAsIntegerKind: {
-      Loc lhsL = cast<nonloc::LocAsInteger>(lhs).getLoc();
+      Loc lhsL = lhs.castAs<nonloc::LocAsInteger>().getLoc();
       switch (rhs.getSubKind()) {
         case nonloc::LocAsIntegerKind:
           return evalBinOpLL(state, op, lhsL,
-                             cast<nonloc::LocAsInteger>(rhs).getLoc(),
+                             rhs.castAs<nonloc::LocAsInteger>().getLoc(),
                              resultTy);
         case nonloc::ConcreteIntKind: {
           // Transform the integer into a location and compare.
-          llvm::APSInt i = cast<nonloc::ConcreteInt>(rhs).getValue();
+          llvm::APSInt i = rhs.castAs<nonloc::ConcreteInt>().getValue();
           BasicVals.getAPSIntType(Context.VoidPtrTy).apply(i);
           return evalBinOpLL(state, op, lhsL, makeLoc(i), resultTy);
         }
@@ -362,7 +363,7 @@ SVal SimpleSValBuilder::evalBinOpNN(ProgramStateRef state,
       }
     }
     case nonloc::ConcreteIntKind: {
-      llvm::APSInt LHSValue = cast<nonloc::ConcreteInt>(lhs).getValue();
+      llvm::APSInt LHSValue = lhs.castAs<nonloc::ConcreteInt>().getValue();
 
       // If we're dealing with two known constants, just perform the operation.
       if (const llvm::APSInt *KnownRHSValue = getKnownValue(state, rhs)) {
@@ -425,7 +426,7 @@ SVal SimpleSValBuilder::evalBinOpNN(ProgramStateRef state,
     }
     case nonloc::SymbolValKind: {
       // We only handle LHS as simple symbols or SymIntExprs.
-      SymbolRef Sym = cast<nonloc::SymbolVal>(lhs).getSymbol();
+      SymbolRef Sym = lhs.castAs<nonloc::SymbolVal>().getSymbol();
 
       // LHS is a symbolic expression.
       if (const SymIntExpr *symIntExpr = dyn_cast<SymIntExpr>(Sym)) {
@@ -601,15 +602,15 @@ SVal SimpleSValBuilder::evalBinOpLL(ProgramStateRef state,
       if (!BinaryOperator::isComparisonOp(op))
         return UnknownVal();
 
-      const llvm::APSInt &lVal = cast<loc::ConcreteInt>(lhs).getValue();
+      const llvm::APSInt &lVal = lhs.castAs<loc::ConcreteInt>().getValue();
       return makeNonLoc(rSym, ReverseComparison(op), lVal, resultTy);
     }
 
     // If both operands are constants, just perform the operation.
-    if (loc::ConcreteInt *rInt = dyn_cast<loc::ConcreteInt>(&rhs)) {
-      SVal ResultVal = cast<loc::ConcreteInt>(lhs).evalBinOp(BasicVals, op,
-                                                             *rInt);
-      if (Loc *Result = dyn_cast<Loc>(&ResultVal))
+    if (llvm::Optional<loc::ConcreteInt> rInt = rhs.getAs<loc::ConcreteInt>()) {
+      SVal ResultVal =
+          lhs.castAs<loc::ConcreteInt>().evalBinOp(BasicVals, op, *rInt);
+      if (llvm::Optional<Loc> Result = ResultVal.getAs<Loc>())
         return evalCastFromLoc(*Result, resultTy);
       else
         return UnknownVal();
@@ -619,7 +620,7 @@ SVal SimpleSValBuilder::evalBinOpLL(ProgramStateRef state,
     // This must come after the test if the RHS is a symbol, which is used to
     // build constraints. The address of any non-symbolic region is guaranteed
     // to be non-NULL, as is any label.
-    assert(isa<loc::MemRegionVal>(rhs) || isa<loc::GotoLabel>(rhs));
+    assert(rhs.getAs<loc::MemRegionVal>() || rhs.getAs<loc::GotoLabel>());
     if (lhs.isZeroConstant()) {
       switch (op) {
       default:
@@ -640,7 +641,7 @@ SVal SimpleSValBuilder::evalBinOpLL(ProgramStateRef state,
     return UnknownVal();
   }
   case loc::MemRegionKind: {
-    if (loc::ConcreteInt *rInt = dyn_cast<loc::ConcreteInt>(&rhs)) {
+    if (llvm::Optional<loc::ConcreteInt> rInt = rhs.getAs<loc::ConcreteInt>()) {
       // If one of the operands is a symbol and the other is a constant,
       // build an expression for use by the constraint manager.
       if (SymbolRef lSym = lhs.getAsLocSymbol())
@@ -738,21 +739,21 @@ SVal SimpleSValBuilder::evalBinOpLL(ProgramStateRef state,
         // Get the left index and cast it to the correct type.
         // If the index is unknown or undefined, bail out here.
         SVal LeftIndexVal = LeftER->getIndex();
-        NonLoc *LeftIndex = dyn_cast<NonLoc>(&LeftIndexVal);
+        llvm::Optional<NonLoc> LeftIndex = LeftIndexVal.getAs<NonLoc>();
         if (!LeftIndex)
           return UnknownVal();
         LeftIndexVal = evalCastFromNonLoc(*LeftIndex, ArrayIndexTy);
-        LeftIndex = dyn_cast<NonLoc>(&LeftIndexVal);
+        LeftIndex = LeftIndexVal.getAs<NonLoc>();
         if (!LeftIndex)
           return UnknownVal();
 
         // Do the same for the right index.
         SVal RightIndexVal = RightER->getIndex();
-        NonLoc *RightIndex = dyn_cast<NonLoc>(&RightIndexVal);
+        llvm::Optional<NonLoc> RightIndex = RightIndexVal.getAs<NonLoc>();
         if (!RightIndex)
           return UnknownVal();
         RightIndexVal = evalCastFromNonLoc(*RightIndex, ArrayIndexTy);
-        RightIndex = dyn_cast<NonLoc>(&RightIndexVal);
+        RightIndex = RightIndexVal.getAs<NonLoc>();
         if (!RightIndex)
           return UnknownVal();
 
@@ -862,7 +863,8 @@ SVal SimpleSValBuilder::evalBinOpLN(ProgramStateRef state,
   // can generate comparisons that trigger this code.
   // FIXME: Are all locations guaranteed to have pointer width?
   if (BinaryOperator::isComparisonOp(op)) {
-    if (nonloc::ConcreteInt *rhsInt = dyn_cast<nonloc::ConcreteInt>(&rhs)) {
+    if (llvm::Optional<nonloc::ConcreteInt> rhsInt =
+            rhs.getAs<nonloc::ConcreteInt>()) {
       const llvm::APSInt *x = &rhsInt->getValue();
       ASTContext &ctx = Context;
       if (ctx.getTypeSize(ctx.VoidPtrTy) == x->getBitWidth()) {
@@ -879,8 +881,10 @@ SVal SimpleSValBuilder::evalBinOpLN(ProgramStateRef state,
   // We are dealing with pointer arithmetic.
 
   // Handle pointer arithmetic on constant values.
-  if (nonloc::ConcreteInt *rhsInt = dyn_cast<nonloc::ConcreteInt>(&rhs)) {
-    if (loc::ConcreteInt *lhsInt = dyn_cast<loc::ConcreteInt>(&lhs)) {
+  if (llvm::Optional<nonloc::ConcreteInt> rhsInt =
+          rhs.getAs<nonloc::ConcreteInt>()) {
+    if (llvm::Optional<loc::ConcreteInt> lhsInt =
+            lhs.getAs<loc::ConcreteInt>()) {
       const llvm::APSInt &leftI = lhsInt->getValue();
       assert(leftI.isUnsigned());
       llvm::APSInt rightI(rhsInt->getValue(), /* isUnsigned */ true);
@@ -910,7 +914,7 @@ SVal SimpleSValBuilder::evalBinOpLN(ProgramStateRef state,
 
   // Handle cases where 'lhs' is a region.
   if (const MemRegion *region = lhs.getAsRegion()) {
-    rhs = cast<NonLoc>(convertToArrayIndex(rhs));
+    rhs = convertToArrayIndex(rhs).castAs<NonLoc>();
     SVal index = UnknownVal();
     const MemRegion *superR = 0;
     QualType elementType;
@@ -929,7 +933,7 @@ SVal SimpleSValBuilder::evalBinOpLN(ProgramStateRef state,
         elementType = resultTy->getPointeeType();
     }
 
-    if (NonLoc *indexV = dyn_cast<NonLoc>(&index)) {
+    if (llvm::Optional<NonLoc> indexV = index.getAs<NonLoc>()) {
       return loc::MemRegionVal(MemMgr.getElementRegion(elementType, *indexV,
                                                        superR, getContext()));
     }
@@ -942,10 +946,10 @@ const llvm::APSInt *SimpleSValBuilder::getKnownValue(ProgramStateRef state,
   if (V.isUnknownOrUndef())
     return NULL;
 
-  if (loc::ConcreteInt* X = dyn_cast<loc::ConcreteInt>(&V))
+  if (llvm::Optional<loc::ConcreteInt> X = V.getAs<loc::ConcreteInt>())
     return &X->getValue();
 
-  if (nonloc::ConcreteInt* X = dyn_cast<nonloc::ConcreteInt>(&V))
+  if (llvm::Optional<nonloc::ConcreteInt> X = V.getAs<nonloc::ConcreteInt>())
     return &X->getValue();
 
   if (SymbolRef Sym = V.getAsSymbol())
index 128dce4..5177d0e 100644 (file)
@@ -270,7 +270,8 @@ SVal StoreManager::evalDerivedToBase(SVal Derived, const CXXBasePath &Path) {
 }
 
 SVal StoreManager::evalDerivedToBase(SVal Derived, QualType BaseType) {
-  loc::MemRegionVal *DerivedRegVal = dyn_cast<loc::MemRegionVal>(&Derived);
+  llvm::Optional<loc::MemRegionVal> DerivedRegVal =
+      Derived.getAs<loc::MemRegionVal>();
   if (!DerivedRegVal)
     return Derived;
 
@@ -289,7 +290,8 @@ SVal StoreManager::evalDynamicCast(SVal Base, QualType DerivedType,
                                    bool &Failed) {
   Failed = false;
 
-  loc::MemRegionVal *BaseRegVal = dyn_cast<loc::MemRegionVal>(&Base);
+  llvm::Optional<loc::MemRegionVal> BaseRegVal =
+      Base.getAs<loc::MemRegionVal>();
   if (!BaseRegVal)
     return UnknownVal();
   const MemRegion *BaseRegion = BaseRegVal->stripCasts(/*StripBases=*/false);
@@ -373,12 +375,12 @@ SVal StoreManager::getLValueFieldOrIvar(const Decl *D, SVal Base) {
   if (Base.isUnknownOrUndef())
     return Base;
 
-  Loc BaseL = cast<Loc>(Base);
+  Loc BaseL = Base.castAs<Loc>();
   const MemRegion* BaseR = 0;
 
   switch (BaseL.getSubKind()) {
   case loc::MemRegionKind:
-    BaseR = cast<loc::MemRegionVal>(BaseL).getRegion();
+    BaseR = BaseL.castAs<loc::MemRegionVal>().getRegion();
     break;
 
   case loc::GotoLabelKind:
@@ -415,16 +417,16 @@ SVal StoreManager::getLValueElement(QualType elementType, NonLoc Offset,
   // FIXME: For absolute pointer addresses, we just return that value back as
   //  well, although in reality we should return the offset added to that
   //  value.
-  if (Base.isUnknownOrUndef() || isa<loc::ConcreteInt>(Base))
+  if (Base.isUnknownOrUndef() || Base.getAs<loc::ConcreteInt>())
     return Base;
 
-  const MemRegion* BaseRegion = cast<loc::MemRegionVal>(Base).getRegion();
+  const MemRegion* BaseRegion = Base.castAs<loc::MemRegionVal>().getRegion();
 
   // Pointer of any type can be cast and used as array base.
   const ElementRegion *ElemR = dyn_cast<ElementRegion>(BaseRegion);
 
   // Convert the offset to the appropriate size and signedness.
-  Offset = cast<NonLoc>(svalBuilder.convertToArrayIndex(Offset));
+  Offset = svalBuilder.convertToArrayIndex(Offset).castAs<NonLoc>();
 
   if (!ElemR) {
     //
@@ -442,15 +444,16 @@ SVal StoreManager::getLValueElement(QualType elementType, NonLoc Offset,
 
   SVal BaseIdx = ElemR->getIndex();
 
-  if (!isa<nonloc::ConcreteInt>(BaseIdx))
+  if (!BaseIdx.getAs<nonloc::ConcreteInt>())
     return UnknownVal();
 
-  const llvm::APSInt& BaseIdxI = cast<nonloc::ConcreteInt>(BaseIdx).getValue();
+  const llvm::APSInt &BaseIdxI =
+      BaseIdx.castAs<nonloc::ConcreteInt>().getValue();
 
   // Only allow non-integer offsets if the base region has no offset itself.
   // FIXME: This is a somewhat arbitrary restriction. We should be using
   // SValBuilder here to add the two offsets without checking their types.
-  if (!isa<nonloc::ConcreteInt>(Offset)) {
+  if (!Offset.getAs<nonloc::ConcreteInt>()) {
     if (isa<ElementRegion>(BaseRegion->StripCasts()))
       return UnknownVal();
 
@@ -459,7 +462,7 @@ SVal StoreManager::getLValueElement(QualType elementType, NonLoc Offset,
                                                     Ctx));
   }
 
-  const llvm::APSInt& OffI = cast<nonloc::ConcreteInt>(Offset).getValue();
+  const llvm::APSInt& OffI = Offset.castAs<nonloc::ConcreteInt>().getValue();
   assert(BaseIdxI.isSigned());
 
   // Compute the new index.