r365518 - [ObjC] Add a warning for implicit conversions of a constant non-boolean value to BOOL
Erik Pilkington via cfe-commits
cfe-commits at lists.llvm.org
Tue Jul 9 10:29:41 PDT 2019
Author: epilk
Date: Tue Jul 9 10:29:40 2019
New Revision: 365518
URL: http://llvm.org/viewvc/llvm-project?rev=365518&view=rev
Log:
[ObjC] Add a warning for implicit conversions of a constant non-boolean value to BOOL
rdar://51954400
Differential revision: https://reviews.llvm.org/D63912
Added:
cfe/trunk/test/Sema/objc-bool-constant-conversion-fixit.m
cfe/trunk/test/Sema/objc-bool-constant-conversion.m
Modified:
cfe/trunk/include/clang/Basic/DiagnosticGroups.td
cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td
cfe/trunk/lib/Sema/SemaChecking.cpp
Modified: cfe/trunk/include/clang/Basic/DiagnosticGroups.td
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Basic/DiagnosticGroups.td?rev=365518&r1=365517&r2=365518&view=diff
==============================================================================
--- cfe/trunk/include/clang/Basic/DiagnosticGroups.td (original)
+++ cfe/trunk/include/clang/Basic/DiagnosticGroups.td Tue Jul 9 10:29:40 2019
@@ -48,8 +48,10 @@ def BitFieldWidth : DiagGroup<"bitfield-
def CoroutineMissingUnhandledException :
DiagGroup<"coroutine-missing-unhandled-exception">;
def Coroutine : DiagGroup<"coroutine", [CoroutineMissingUnhandledException]>;
-def ConstantConversion :
- DiagGroup<"constant-conversion", [ BitFieldConstantConversion ] >;
+def ObjCBoolConstantConversion : DiagGroup<"objc-bool-constant-conversion">;
+def ConstantConversion : DiagGroup<"constant-conversion",
+ [BitFieldConstantConversion,
+ ObjCBoolConstantConversion]>;
def LiteralConversion : DiagGroup<"literal-conversion">;
def StringConversion : DiagGroup<"string-conversion">;
def SignConversion : DiagGroup<"sign-conversion">;
Modified: cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td?rev=365518&r1=365517&r2=365518&view=diff
==============================================================================
--- cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td (original)
+++ cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td Tue Jul 9 10:29:40 2019
@@ -3248,6 +3248,10 @@ def warn_impcast_integer_precision_const
def warn_impcast_bitfield_precision_constant : Warning<
"implicit truncation from %2 to bit-field changes value from %0 to %1">,
InGroup<BitFieldConstantConversion>;
+def warn_impcast_constant_int_to_objc_bool : Warning<
+ "implicit conversion from constant value %0 to BOOL; "
+ "the only well defined values for BOOL are YES and NO">,
+ InGroup<ObjCBoolConstantConversion>;
def warn_impcast_fixed_point_range : Warning<
"implicit conversion from %0 cannot fit within the range of values for %1">,
Modified: cfe/trunk/lib/Sema/SemaChecking.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaChecking.cpp?rev=365518&r1=365517&r2=365518&view=diff
==============================================================================
--- cfe/trunk/lib/Sema/SemaChecking.cpp (original)
+++ cfe/trunk/lib/Sema/SemaChecking.cpp Tue Jul 9 10:29:40 2019
@@ -11149,6 +11149,11 @@ static bool isSameWidthConstantConversio
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
}
}
+ // 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))
Added: cfe/trunk/test/Sema/objc-bool-constant-conversion-fixit.m
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Sema/objc-bool-constant-conversion-fixit.m?rev=365518&view=auto
==============================================================================
--- cfe/trunk/test/Sema/objc-bool-constant-conversion-fixit.m (added)
+++ cfe/trunk/test/Sema/objc-bool-constant-conversion-fixit.m Tue Jul 9 10:29:40 2019
@@ -0,0 +1,40 @@
+// RUN: %clang_cc1 -Werror=constant-conversion %s -fixit-recompile -fixit-to-temporary -E -o - | FileCheck %s
+
+typedef signed char BOOL;
+
+BOOL b;
+
+int main() {
+ BOOL b = 2;
+ // CHECK: BOOL b = 2 ? YES : NO;
+
+ b = b ? 2 : 1;
+ // CHECK: b = b ? 2 ? YES : NO : 1;
+
+ b = b ? 1 : 2;
+ // CHECK: b = b ? 1 : 2 ? YES : NO;
+
+ b = b ? 2 : 2;
+ // CHECK: b = b ? 2 ? YES : NO : 2 ? YES : NO;
+
+ b = 1 + 1;
+ // CHECK: b = (1 + 1) ? YES : NO;
+
+ b = 1 | 2;
+ // CHECK: b = (1 | 2) ? YES : NO;
+
+ b = 1 << 1;
+ // CHECK: b = (1 << 1) ? YES : NO;
+}
+
+ at interface BoolProp
+ at property BOOL b;
+ at end
+
+void f(BoolProp *bp) {
+ bp.b = 43;
+ // CHECK: bp.b = 43 ? YES : NO;
+
+ [bp setB:43];
+ // CHECK: [bp setB:43 ? YES : NO];
+}
Added: cfe/trunk/test/Sema/objc-bool-constant-conversion.m
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Sema/objc-bool-constant-conversion.m?rev=365518&view=auto
==============================================================================
--- cfe/trunk/test/Sema/objc-bool-constant-conversion.m (added)
+++ cfe/trunk/test/Sema/objc-bool-constant-conversion.m Tue Jul 9 10:29:40 2019
@@ -0,0 +1,38 @@
+// RUN: %clang_cc1 %s -verify -fsyntax-only
+
+typedef signed char BOOL;
+#define YES __objc_yes
+#define NO __objc_no
+
+BOOL B;
+
+int main() {
+ B = 0;
+ B = 1;
+ B = YES;
+ B = NO;
+
+ B = -1; // expected-warning{{implicit conversion from constant value -1 to BOOL; the only well defined values for BOOL are YES and NO}}
+ B = 0 - 1; // expected-warning{{implicit conversion from constant value -1 to BOOL; the only well defined values for BOOL are YES and NO}}
+ B = YES + YES; // expected-warning {{implicit conversion from constant value 2 to BOOL; the only well defined values for BOOL are YES and NO}}
+ B = YES | YES;
+
+ B = B ? 2 : 2; // expected-warning 2 {{implicit conversion from constant value 2 to BOOL; the only well defined values for BOOL are YES and NO}}
+
+ BOOL Init = -1; // expected-warning{{implicit conversion from constant value -1 to BOOL; the only well defined values for BOOL are YES and NO}}
+ BOOL Init2 = B ? 2 : 2; // expected-warning 2 {{implicit conversion from constant value 2 to BOOL; the only well defined values for BOOL are YES and NO}}
+
+ void takesbool(BOOL);
+ takesbool(43); // expected-warning {{implicit conversion from constant value 43 to BOOL; the only well defined values for BOOL are YES and NO}}
+
+ BOOL OutOfRange = 400; // expected-warning{{implicit conversion from constant value 400 to BOOL; the only well defined values for BOOL are YES and NO}}
+}
+
+ at interface BoolProp
+ at property BOOL b;
+ at end
+
+void f(BoolProp *bp) {
+ bp.b = 43; // expected-warning {{implicit conversion from constant value 43 to BOOL; the only well defined values for BOOL are YES and NO}}
+ [bp setB:43]; // expected-warning {{implicit conversion from constant value 43 to BOOL; the only well defined values for BOOL are YES and NO}}
+}
More information about the cfe-commits
mailing list