mirror of
https://github.com/Gericom/teak-llvm.git
synced 2025-06-21 12:35:47 -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))
|
if (const auto *OVE = dyn_cast<OpaqueValueExpr>(E))
|
||||||
return OVE->getSourceExpr()->isKnownToHaveBooleanValue();
|
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;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -47,3 +47,59 @@ void t2(BoolProp *bp) {
|
|||||||
bp.p = 1;
|
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}}
|
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