diff options
-rw-r--r-- | lib/Sema/SemaExpr.cpp | 18 | ||||
-rw-r--r-- | test/SemaObjC/objc-literal-comparison.m | 19 |
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)); +} + |