Add <foo> = [<bar> nextObject] to the -Widiomatic-parentheses category,

and give that category an explicit test.  Generalize the internal diagnostic
name.

llvm-svn: 86905
This commit is contained in:
John McCall 2009-11-12 00:06:05 +00:00
parent c998409cce
commit b0e419e34d
3 changed files with 55 additions and 10 deletions

View 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<

View 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)) {

View File

@ -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