[SemaObjC] Fix a -Wobjc-signed-char-bool false-positive with binary conditional operator

We were previously bypassing the conditional expression special case for binary
conditional expressions.

rdar://64134411

Differential revision: https://reviews.llvm.org/D81751
This commit is contained in:
Erik Pilkington 2020-07-07 11:13:47 -04:00
parent 7437a94965
commit 2f71cf6d77
2 changed files with 23 additions and 7 deletions

View File

@ -11936,27 +11936,31 @@ static void CheckImplicitConversion(Sema &S, Expr *E, QualType T,
}
}
static void CheckConditionalOperator(Sema &S, ConditionalOperator *E,
static void CheckConditionalOperator(Sema &S, AbstractConditionalOperator *E,
SourceLocation CC, QualType T);
static void CheckConditionalOperand(Sema &S, Expr *E, QualType T,
SourceLocation CC, bool &ICContext) {
E = E->IgnoreParenImpCasts();
if (isa<ConditionalOperator>(E))
return CheckConditionalOperator(S, cast<ConditionalOperator>(E), CC, T);
if (auto *CO = dyn_cast<AbstractConditionalOperator>(E))
return CheckConditionalOperator(S, CO, CC, T);
AnalyzeImplicitConversions(S, E, CC);
if (E->getType() != T)
return CheckImplicitConversion(S, E, T, CC, &ICContext);
}
static void CheckConditionalOperator(Sema &S, ConditionalOperator *E,
static void CheckConditionalOperator(Sema &S, AbstractConditionalOperator *E,
SourceLocation CC, QualType T) {
AnalyzeImplicitConversions(S, E->getCond(), E->getQuestionLoc());
Expr *TrueExpr = E->getTrueExpr();
if (auto *BCO = dyn_cast<BinaryConditionalOperator>(E))
TrueExpr = BCO->getCommon();
bool Suspicious = false;
CheckConditionalOperand(S, E->getTrueExpr(), T, CC, Suspicious);
CheckConditionalOperand(S, TrueExpr, T, CC, Suspicious);
CheckConditionalOperand(S, E->getFalseExpr(), T, CC, Suspicious);
if (T->isBooleanType())
@ -11975,7 +11979,7 @@ static void CheckConditionalOperator(Sema &S, ConditionalOperator *E,
if (E->getType() == T) return;
Suspicious = false;
CheckImplicitConversion(S, E->getTrueExpr()->IgnoreParenImpCasts(),
CheckImplicitConversion(S, TrueExpr->IgnoreParenImpCasts(),
E->getType(), CC, &Suspicious);
if (!Suspicious)
CheckImplicitConversion(S, E->getFalseExpr()->IgnoreParenImpCasts(),
@ -12038,7 +12042,7 @@ static void AnalyzeImplicitConversions(
// For conditional operators, we analyze the arguments as if they
// were being fed directly into the output.
if (auto *CO = dyn_cast<ConditionalOperator>(SourceExpr)) {
if (auto *CO = dyn_cast<AbstractConditionalOperator>(SourceExpr)) {
CheckConditionalOperator(S, CO, CC, T);
return;
}

View File

@ -108,3 +108,15 @@ int main() {
f<short>(); // expected-note {{in instantiation of function template specialization 'f<short>' requested here}}
}
#endif
void t5(BOOL b) {
int i;
b = b ?: YES; // no warning
b = b ?: i; // expected-warning {{implicit conversion from integral type 'int' to 'BOOL'}}
b = (b = i) // expected-warning {{implicit conversion from integral type 'int' to 'BOOL'}}
?: YES;
b = (1 ? YES : i) ?: YES; // expected-warning {{implicit conversion from integral type 'int' to 'BOOL'}}
b = b ?: (1 ? i : i); // expected-warning 2 {{implicit conversion from integral type 'int' to 'BOOL'}}
b = b ? YES : (i ?: 0); // expected-warning {{implicit conversion from integral type 'int' to 'BOOL'}}
}