зеркало из https://github.com/microsoft/clang.git
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:
Родитель
5dc0867af1
Коммит
25258f8bfb
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
|
Загрузка…
Ссылка в новой задаче