Replace SVal llvm::cast support to be well-defined.

See r175462 for another example/more details.

git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@175594 91177308-0d34-0410-b5e6-96231b3b80d8
diff --git a/lib/StaticAnalyzer/Checkers/CStringChecker.cpp b/lib/StaticAnalyzer/Checkers/CStringChecker.cpp
index 0a94747..1c99567 100644
--- a/lib/StaticAnalyzer/Checkers/CStringChecker.cpp
+++ b/lib/StaticAnalyzer/Checkers/CStringChecker.cpp
@@ -201,7 +201,7 @@
 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 @@
   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 @@
   // 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 @@
       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 @@
   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 @@
   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 @@
       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 @@
   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 @@
   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 @@
     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 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 @@
     // 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 @@
 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 @@
     // 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 @@
     // 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 @@
     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 @@
       // 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 @@
     // 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 @@
       // 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 @@
         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 @@
         // 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 @@
       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 @@
                                                            *amountCopiedNL,
                                                            *strLengthNL,
                                                            cmpTy);
-          state = state->assume(cast<DefinedOrUnknownSVal>(copiedLessThanSrc),
-                                true);
+          state = state->assume(
+              copiedLessThanSrc.castAs<DefinedOrUnknownSVal>(), true);
           if (!state)
             return;
         }
@@ -1475,8 +1465,8 @@
     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 @@
       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 @@
                                                       *finalStrLengthNL,
                                                       *dstStrLengthNL,
                                                       cmpTy);
-          state = state->assume(cast<DefinedOrUnknownSVal>(destInResult),
-                                true);
+          state =
+              state->assume(destInResult.castAs<DefinedOrUnknownSVal>(), true);
           if (!state)
             return;
         }
@@ -1538,13 +1529,15 @@
 
   // 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 @@
     }
 
     // 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 @@
   // 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 @@
 
     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);
   }