diff options
author | Erik Pilkington <erik.pilkington@gmail.com> | 2019-07-09 17:29:40 +0000 |
---|---|---|
committer | Erik Pilkington <erik.pilkington@gmail.com> | 2019-07-09 17:29:40 +0000 |
commit | abffae3a563d67d0a31a9687aecc4de33a4cc273 (patch) | |
tree | 42e62001dc2067d512719cc27b5f798f1fa901bf /clang/lib/Sema/SemaChecking.cpp | |
parent | 0efac296f140f9e6eac31a9f979dbd0dc0659c24 (diff) | |
download | bcm5719-llvm-abffae3a563d67d0a31a9687aecc4de33a4cc273.tar.gz bcm5719-llvm-abffae3a563d67d0a31a9687aecc4de33a4cc273.zip |
[ObjC] Add a warning for implicit conversions of a constant non-boolean value to BOOL
rdar://51954400
Differential revision: https://reviews.llvm.org/D63912
llvm-svn: 365518
Diffstat (limited to 'clang/lib/Sema/SemaChecking.cpp')
-rw-r--r-- | clang/lib/Sema/SemaChecking.cpp | 28 |
1 files changed, 28 insertions, 0 deletions
diff --git a/clang/lib/Sema/SemaChecking.cpp b/clang/lib/Sema/SemaChecking.cpp index 7ab0f2d312a..64ee7c86ca5 100644 --- a/clang/lib/Sema/SemaChecking.cpp +++ b/clang/lib/Sema/SemaChecking.cpp @@ -11149,6 +11149,11 @@ static bool isSameWidthConstantConversion(Sema &S, Expr *E, QualType T, return true; } +static bool isObjCSignedCharBool(Sema &S, QualType Ty) { + return Ty->isSpecificBuiltinType(BuiltinType::SChar) && + S.getLangOpts().ObjC && S.NSAPIObj->isObjCBOOLType(Ty); +} + static void CheckImplicitConversion(Sema &S, Expr *E, QualType T, SourceLocation CC, bool *ICContext = nullptr) { @@ -11192,6 +11197,29 @@ CheckImplicitConversion(Sema &S, Expr *E, QualType T, SourceLocation CC, } } + // If the we're converting a constant to an ObjC BOOL on a platform where BOOL + // is a typedef for signed char (macOS), then that constant value has to be 1 + // or 0. + if (isObjCSignedCharBool(S, T) && Source->isIntegralType(S.Context)) { + Expr::EvalResult Result; + if (E->EvaluateAsInt(Result, S.getASTContext(), + Expr::SE_AllowSideEffects) && + Result.Val.getInt() != 1 && Result.Val.getInt() != 0) { + auto Builder = S.Diag(CC, diag::warn_impcast_constant_int_to_objc_bool) + << Result.Val.getInt().toString(10); + Expr *Ignored = E->IgnoreImplicit(); + bool NeedsParens = isa<AbstractConditionalOperator>(Ignored) || + isa<BinaryOperator>(Ignored) || + isa<CXXOperatorCallExpr>(Ignored); + SourceLocation EndLoc = S.getLocForEndOfToken(E->getEndLoc()); + if (NeedsParens) + Builder << FixItHint::CreateInsertion(E->getBeginLoc(), "(") + << FixItHint::CreateInsertion(EndLoc, ")"); + Builder << FixItHint::CreateInsertion(EndLoc, " ? YES : NO"); + return; + } + } + // Check implicit casts from Objective-C collection literals to specialized // collection types, e.g., NSArray<NSString *> *. if (auto *ArrayLiteral = dyn_cast<ObjCArrayLiteral>(E)) |