Per feedback from Eli, recognize in the transfer function logic for
__builtin_offsetof in the static analyzer that __builtin_offsetof is
not guaranteed to return an integer constant.  We will need to shore
this up later, but now at least we have correct support for when this
*is* an integer constant.


git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@81830 91177308-0d34-0410-b5e6-96231b3b80d8
diff --git a/lib/Analysis/GRExprEngine.cpp b/lib/Analysis/GRExprEngine.cpp
index 0e08cd2..251a4b7 100644
--- a/lib/Analysis/GRExprEngine.cpp
+++ b/lib/Analysis/GRExprEngine.cpp
@@ -2431,12 +2431,18 @@
     }
 
     case UnaryOperator::OffsetOf: {
-      const APSInt &IV = U->EvaluateAsInt(getContext());
-      assert(IV.getBitWidth() == getContext().getTypeSize(U->getType()));
-      assert(U->getType()->isIntegerType());
-      assert(IV.isSigned() == U->getType()->isSignedIntegerType());
-      SVal X = ValMgr.makeIntVal(IV);      
-      MakeNode(Dst, U, Pred, GetState(Pred)->BindExpr(U, X));
+      Expr::EvalResult Res;
+      if (U->Evaluate(Res, getContext()) && Res.Val.isInt()) {
+        const APSInt &IV = Res.Val.getInt();
+        assert(IV.getBitWidth() == getContext().getTypeSize(U->getType()));
+        assert(U->getType()->isIntegerType());
+        assert(IV.isSigned() == U->getType()->isSignedIntegerType());
+        SVal X = ValMgr.makeIntVal(IV);      
+        MakeNode(Dst, U, Pred, GetState(Pred)->BindExpr(U, X));
+        return;
+      }
+      // FIXME: Handle the case where __builtin_offsetof is not a constant.
+      Dst.Add(Pred);
       return;
     }