Fix <rdar://problem/6845148>. Signed integers compared against pointers should
implicitly be changed to unsigned values in GRSimpleVals.cpp. This can happen
when the comparison involves logic in specialized transfer functions (e.g.,
OSAtomicCompareAndSwap).
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@71200 91177308-0d34-0410-b5e6-96231b3b80d8
diff --git a/lib/Analysis/GRSimpleVals.cpp b/lib/Analysis/GRSimpleVals.cpp
index 3d1c764..17e3c38 100644
--- a/lib/Analysis/GRSimpleVals.cpp
+++ b/lib/Analysis/GRSimpleVals.cpp
@@ -267,10 +267,15 @@
// FIXME: Are all locations guaranteed to have pointer width?
if (BinaryOperator::isEqualityOp(Op)) {
if (nonloc::ConcreteInt *RInt = dyn_cast<nonloc::ConcreteInt>(&R)) {
- const llvm::APSInt &X = RInt->getValue();
+ const llvm::APSInt *X = &RInt->getValue();
ASTContext &C = Eng.getContext();
- if (C.getTypeSize(C.VoidPtrTy) == X.getBitWidth())
- return EvalBinOp(Eng, Op, L, loc::ConcreteInt(X));
+ if (C.getTypeSize(C.VoidPtrTy) == X->getBitWidth()) {
+ // Convert the signedness of the integer (if necessary).
+ if (X->isSigned())
+ X = &Eng.getBasicVals().getValue(*X, true);
+
+ return EvalBinOp(Eng, Op, L, loc::ConcreteInt(*X));
+ }
}
}