]> granicus.if.org Git - clang/commitdiff
Add <foo> = [<bar> nextObject] to the -Widiomatic-parentheses category,
authorJohn McCall <rjmccall@apple.com>
Thu, 12 Nov 2009 00:06:05 +0000 (00:06 +0000)
committerJohn McCall <rjmccall@apple.com>
Thu, 12 Nov 2009 00:06:05 +0000 (00:06 +0000)
and give that category an explicit test.  Generalize the internal diagnostic
name.

git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@86905 91177308-0d34-0410-b5e6-96231b3b80d8

include/clang/Basic/DiagnosticSemaKinds.td
lib/Sema/SemaExpr.cpp
test/SemaObjC/idiomatic-parentheses.m [new file with mode: 0644]

index 3abacd9b3acf66d92c6d8934c10aaadaa7a60b2b..26693aa78cf214217d610aa22dd7dc65a5cfec0c 100644 (file)
@@ -1815,8 +1815,9 @@ def err_incomplete_object_call : Error<
 def warn_condition_is_assignment : Warning<"using the result of an "
   "assignment as a condition without parentheses">,
   InGroup<Parentheses>;
-def warn_condition_is_self_assignment : Warning<"using the result of an "
-  "assignment to 'self' as a condition without parentheses">,
+// Completely identical except off by default.
+def warn_condition_is_idiomatic_assignment : Warning<"using the result "
+  "of an assignment as a condition without parentheses">,
   InGroup<DiagGroup<"idiomatic-parentheses">>, DefaultIgnore;
 
 def warn_value_always_zero : Warning<
index 5050dbcce8c89d7e1fcc8a59a524f024a557612e..9d6af7a1b89216151d7996b104ad748d488f485c 100644 (file)
@@ -6517,14 +6517,23 @@ void Sema::DiagnoseAssignmentAsCondition(Expr *E) {
     if (Op->getOpcode() != BinaryOperator::Assign)
       return;
 
-    // Greylist the following Cocoa ObjC idiom by putting it into a
-    // warning subcategory which defaults off:
-    //   if (self = [super init])
-    // The selector can vary, and it's possible that the base might,
-    // too, so we just recognize any message call.
-    if (isSelfExpr(Op->getLHS()) &&
-        isa<ObjCMessageExpr>(Op->getRHS()->IgnoreParenCasts()))
-      diagnostic = diag::warn_condition_is_self_assignment;
+    // Greylist some idioms by putting them into a warning subcategory.
+    if (ObjCMessageExpr *ME
+          = dyn_cast<ObjCMessageExpr>(Op->getRHS()->IgnoreParenCasts())) {
+      Selector Sel = ME->getSelector();
+
+      llvm::errs() << "selector is '" << Sel.getIdentifierInfoForSlot(0)->getName() << "'\n";
+
+      // self = [<foo> init...]
+      if (isSelfExpr(Op->getLHS())
+          && Sel.getIdentifierInfoForSlot(0)->getName().startswith("init"))
+        diagnostic = diag::warn_condition_is_idiomatic_assignment;
+
+      // <foo> = [<bar> nextObject]
+      else if (Sel.isUnarySelector() &&
+               Sel.getIdentifierInfoForSlot(0)->getName() == "nextObject")
+        diagnostic = diag::warn_condition_is_idiomatic_assignment;
+    }
 
     Loc = Op->getOperatorLoc();
   } else if (isa<CXXOperatorCallExpr>(E)) {
diff --git a/test/SemaObjC/idiomatic-parentheses.m b/test/SemaObjC/idiomatic-parentheses.m
new file mode 100644 (file)
index 0000000..b4c52fa
--- /dev/null
@@ -0,0 +1,35 @@
+// RUN: clang-cc -fsyntax-only -verify %s
+
+// Don't warn about some common ObjC idioms unless we have -Wparentheses on.
+// <rdar://problem/7382435>
+
+@interface Object 
+- (id) init;
+- (id) initWithInt: (int) i;
+- (void) iterate: (id) coll;
+- (id) nextObject;
+@end
+
+@implementation Object
+- (id) init {
+  if (self = [self init]) {
+  }
+  return self;
+}
+
+- (id) initWithInt: (int) i {
+  if (self = [self initWithInt: i]) {
+  }
+  return self;
+}
+
+- (void) iterate: (id) coll {
+  id cur;
+  while (cur = [coll nextObject]) {
+  }
+}
+
+- (id) nextObject {
+  return self;
+}
+@end