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
This commit is contained in:
Ted Kremenek 2009-05-08 00:32:39 +00:00
Родитель 5dc0867af1
Коммит 25258f8bfb
2 изменённых файлов: 32 добавлений и 3 удалений

Просмотреть файл

@ -267,10 +267,15 @@ SVal GRSimpleVals::EvalBinOp(GRExprEngine& Eng, BinaryOperator::Opcode Op,
// 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));
}
}
}

Просмотреть файл

@ -6,6 +6,7 @@
// <rdar://problem/6440393> - A bunch of misc. failures involving evaluating
// these expressions and building CFGs. These tests are here to prevent
// regressions.
typedef long long int64_t;
@class NSString, NSDictionary;
typedef long NSInteger;
typedef unsigned long NSUInteger;
@ -23,3 +24,26 @@ void rdar_6440393_1(NSDictionary *dict) {
shazam(x, &bufptr);
}
// <rdar://problem/6845148> - In this example we got a signedness
// mismatch between the literal '0' and the value of 'scrooge'. The
// trick is to have the evaluator convert the literal to an unsigned
// integer when doing a comparison with the pointer. This happens
// because of the transfer function logic of
// OSAtomicCompareAndSwap64Barrier, which doesn't have special casts
// in place to do this for us.
_Bool OSAtomicCompareAndSwap64Barrier( int64_t __oldValue, int64_t __newValue, volatile int64_t *__theValue );
extern id objc_lookUpClass(const char *name);
void rdar_6845148(id debug_yourself) {
if (!debug_yourself) {
const char *wacky = ((void *)0);
Class scrooge = wacky ? (Class)objc_lookUpClass(wacky) : ((void *)0);
OSAtomicCompareAndSwap64Barrier(0, (int64_t)scrooge, (int64_t*)&debug_yourself);
}
}
void rdar_6845148_b(id debug_yourself) {
if (!debug_yourself) {
const char *wacky = ((void *)0);
Class scrooge = wacky ? (Class)objc_lookUpClass(wacky) : ((void *)0);
OSAtomicCompareAndSwap64Barrier((int64_t)scrooge, 0, (int64_t*)&debug_yourself);
}
}