mirror of
https://github.com/Gericom/teak-llvm.git
synced 2025-06-20 12:05:48 -04:00
[Sema] Fix a -Wobjc-signed-char-bool false-positive
Unsigned bit-field flags can only have boolean values, so handle that case in Expr::isKnownToHaveBooleanValue. rdar://56256999
This commit is contained in:
parent
626260cfe3
commit
8bfb353bb3
@ -191,6 +191,12 @@ bool Expr::isKnownToHaveBooleanValue() const {
|
||||
if (const auto *OVE = dyn_cast<OpaqueValueExpr>(E))
|
||||
return OVE->getSourceExpr()->isKnownToHaveBooleanValue();
|
||||
|
||||
if (const FieldDecl *FD = E->getSourceBitField())
|
||||
if (FD->getType()->isUnsignedIntegerType() &&
|
||||
!FD->getBitWidth()->isValueDependent() &&
|
||||
FD->getBitWidthValue(FD->getASTContext()) == 1)
|
||||
return true;
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
|
@ -47,3 +47,59 @@ void t2(BoolProp *bp) {
|
||||
bp.p = 1;
|
||||
bp.p = 2; // expected-warning {{implicit conversion from constant value 2 to 'BOOL'; the only well defined values for 'BOOL' are YES and NO}}
|
||||
}
|
||||
|
||||
struct has_bf {
|
||||
int signed_bf1 : 1;
|
||||
int signed_bf2 : 2;
|
||||
unsigned unsigned_bf1 : 1;
|
||||
unsigned unsigned_bf2 : 2;
|
||||
|
||||
struct has_bf *nested;
|
||||
};
|
||||
|
||||
void t3(struct has_bf *bf) {
|
||||
b = bf->signed_bf1; // expected-warning{{implicit conversion from integral type 'int' to 'BOOL'}}
|
||||
b = bf->signed_bf2; // expected-warning{{implicit conversion from integral type 'int' to 'BOOL'}}
|
||||
b = bf->unsigned_bf1; // no warning
|
||||
b = bf->unsigned_bf2; // expected-warning{{implicit conversion from integral type 'unsigned int' to 'BOOL'}}
|
||||
struct has_bf local;
|
||||
b = local.unsigned_bf1;
|
||||
b = local.unsigned_bf2; // expected-warning{{implicit conversion from integral type 'unsigned int' to 'BOOL'}}
|
||||
b = local.nested->unsigned_bf1;
|
||||
b = local.nested->unsigned_bf2; // expected-warning{{implicit conversion from integral type 'unsigned int' to 'BOOL'}}
|
||||
}
|
||||
|
||||
__attribute__((objc_root_class))
|
||||
@interface BFIvar {
|
||||
struct has_bf bf;
|
||||
unsigned unsigned_bf1 : 1;
|
||||
unsigned unsigned_bf2 : 2;
|
||||
}
|
||||
@end
|
||||
|
||||
@implementation BFIvar
|
||||
-(void)m {
|
||||
b = bf.unsigned_bf1;
|
||||
b = bf.unsigned_bf2; // expected-warning{{implicit conversion from integral type 'unsigned int' to 'BOOL'}}
|
||||
b = unsigned_bf1;
|
||||
b = unsigned_bf2; // expected-warning{{implicit conversion from integral type 'unsigned int' to 'BOOL'}}
|
||||
}
|
||||
@end
|
||||
|
||||
#ifdef __cplusplus
|
||||
template <class T>
|
||||
struct S {
|
||||
unsigned i : sizeof(T);
|
||||
};
|
||||
|
||||
template <class T>
|
||||
void f() {
|
||||
S<T> i;
|
||||
BOOL b = i.i; // expected-warning{{implicit conversion from integral type 'unsigned int' to 'BOOL'}}
|
||||
}
|
||||
|
||||
int main() {
|
||||
f<char>();
|
||||
f<short>(); // expected-note {{in instantiation of function template specialization 'f<short>' requested here}}
|
||||
}
|
||||
#endif
|
||||
|
Loading…
Reference in New Issue
Block a user