aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--lib/Sema/SemaExpr.cpp18
-rw-r--r--test/SemaObjC/objc-literal-comparison.m19
2 files changed, 33 insertions, 4 deletions
diff --git a/lib/Sema/SemaExpr.cpp b/lib/Sema/SemaExpr.cpp
index fabd673d1b..34fb9d06a7 100644
--- a/lib/Sema/SemaExpr.cpp
+++ b/lib/Sema/SemaExpr.cpp
@@ -6742,10 +6742,24 @@ static bool hasIsEqualMethod(Sema &S, const Expr *LHS, const Expr *RHS) {
static void diagnoseObjCLiteralComparison(Sema &S, SourceLocation Loc,
ExprResult &LHS, ExprResult &RHS,
BinaryOperator::Opcode Opc){
- Expr *Literal = (isObjCObjectLiteral(LHS) ? LHS : RHS).get();
+ Expr *Literal;
+ Expr *Other;
+ if (isObjCObjectLiteral(LHS)) {
+ Literal = LHS.get();
+ Other = RHS.get();
+ } else {
+ Literal = RHS.get();
+ Other = LHS.get();
+ }
+
+ // Don't warn on comparisons against nil.
+ Other = Other->IgnoreParenCasts();
+ if (Other->isNullPointerConstant(S.getASTContext(),
+ Expr::NPC_ValueDependentIsNotNull))
+ return;
// This should be kept in sync with warn_objc_literal_comparison.
- // LK_String should always be last, since it has its own flag.
+ // LK_String should always be last, since it has its own warning flag.
enum {
LK_Array,
LK_Dictionary,
diff --git a/test/SemaObjC/objc-literal-comparison.m b/test/SemaObjC/objc-literal-comparison.m
index ea42a176ef..f1aa8ecd91 100644
--- a/test/SemaObjC/objc-literal-comparison.m
+++ b/test/SemaObjC/objc-literal-comparison.m
@@ -1,8 +1,10 @@
-// RUN: %clang_cc1 -fsyntax-only -Wno-everything -Wobjc-literal-compare -verify %s
+// RUN: %clang_cc1 -fsyntax-only -Wno-everything -Wobjc-literal-compare "-Dnil=((id)0)" -verify %s
+// RUN: %clang_cc1 -fsyntax-only -Wno-everything -Wobjc-literal-compare "-Dnil=(id)0" -verify %s
+// RUN: %clang_cc1 -fsyntax-only -Wno-everything -Wobjc-literal-compare "-Dnil=0" -verify %s
// (test the warning flag as well)
-typedef unsigned char BOOL;
+typedef signed char BOOL;
@interface BaseObject
+ (instancetype)new;
@@ -79,3 +81,16 @@ void testWarningFlags(id obj) {
#pragma clang diagnostic pop
+
+void testNilComparison() {
+ // Don't warn when comparing to nil in a macro.
+#define RETURN_IF_NIL(x) if (x == nil || nil == x) return
+ RETURN_IF_NIL(@"");
+ RETURN_IF_NIL(@1);
+ RETURN_IF_NIL(@1.0);
+ RETURN_IF_NIL(@[]);
+ RETURN_IF_NIL(@{});
+ RETURN_IF_NIL(@__objc_yes);
+ RETURN_IF_NIL(@(1+1));
+}
+