diff options
author | John McCall <rjmccall@apple.com> | 2009-11-12 00:06:05 +0000 |
---|---|---|
committer | John McCall <rjmccall@apple.com> | 2009-11-12 00:06:05 +0000 |
commit | c8d8ac5f454311d0154d2d080196cc150edbb2d6 (patch) | |
tree | f9c26e4ab4d26f06844f3ab6a81d77b65d2c6052 | |
parent | eaf75f4e0f65444bb122ade7725a4a32badcbf77 (diff) |
Add <foo> = [<bar> nextObject] to the -Widiomatic-parentheses category,
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
-rw-r--r-- | include/clang/Basic/DiagnosticSemaKinds.td | 5 | ||||
-rw-r--r-- | lib/Sema/SemaExpr.cpp | 25 | ||||
-rw-r--r-- | test/SemaObjC/idiomatic-parentheses.m | 35 |
3 files changed, 55 insertions, 10 deletions
diff --git a/include/clang/Basic/DiagnosticSemaKinds.td b/include/clang/Basic/DiagnosticSemaKinds.td index 3abacd9b3a..26693aa78c 100644 --- a/include/clang/Basic/DiagnosticSemaKinds.td +++ b/include/clang/Basic/DiagnosticSemaKinds.td @@ -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< diff --git a/lib/Sema/SemaExpr.cpp b/lib/Sema/SemaExpr.cpp index 5050dbcce8..9d6af7a1b8 100644 --- a/lib/Sema/SemaExpr.cpp +++ b/lib/Sema/SemaExpr.cpp @@ -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 index 0000000000..b4c52fa0d1 --- /dev/null +++ b/test/SemaObjC/idiomatic-parentheses.m @@ -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 |