summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJordan Rose <jordan_rose@apple.com>2012-07-17 17:46:48 +0000
committerJordan Rose <jordan_rose@apple.com>2012-07-17 17:46:48 +0000
commit63ffaa8c18f1caabc6820505ba1ce960252c5188 (patch)
tree53e8fc65bf84b348cf6d573575a0cf6907341059
parentea70bf71547b9c8d96735707541e55fe117e23b5 (diff)
downloadbcm5719-llvm-63ffaa8c18f1caabc6820505ba1ce960252c5188.tar.gz
bcm5719-llvm-63ffaa8c18f1caabc6820505ba1ce960252c5188.zip
-Wobjc-literal-compare: don't warn when comparing against nil.
Checks against nil often appear as guards in macros, and comparing Objective-C literals to nil has well-defined behavior (if tautological). On OS X, 'nil' has not been typed as 'id' since 10.6 (possibly earlier), so the warning was already not firing, but other runtimes continue to use ((id)0) or some variant. This change accepts comparisons to any null pointer; to keep it simple, it looks through all casts (not just casts to 'id'). PR13276 llvm-svn: 160379
-rw-r--r--clang/lib/Sema/SemaExpr.cpp18
-rw-r--r--clang/test/SemaObjC/objc-literal-comparison.m19
2 files changed, 33 insertions, 4 deletions
diff --git a/clang/lib/Sema/SemaExpr.cpp b/clang/lib/Sema/SemaExpr.cpp
index fabd673d1b1..34fb9d06a7a 100644
--- a/clang/lib/Sema/SemaExpr.cpp
+++ b/clang/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/clang/test/SemaObjC/objc-literal-comparison.m b/clang/test/SemaObjC/objc-literal-comparison.m
index ea42a176ef0..f1aa8ecd91e 100644
--- a/clang/test/SemaObjC/objc-literal-comparison.m
+++ b/clang/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));
+}
+
OpenPOWER on IntegriCloud