r211611 - Objective-C. When we use @selector(save:), etc. there may be more
Fariborz Jahanian
fjahanian at apple.com
Tue Jun 24 10:02:20 PDT 2014
Author: fjahanian
Date: Tue Jun 24 12:02:19 2014
New Revision: 211611
URL: http://llvm.org/viewvc/llvm-project?rev=211611&view=rev
Log:
Objective-C. When we use @selector(save:), etc. there may be more
than one method with mismatched type of same selector name.
clang issues a warning to point this out since it may cause
undefined behavior. There are cases though that some APIs
don't care about user methods and such warnings are perceived as
noise. This patch allows users to add paren delimiters around
selector name to turn off such warnings. So, @selector((save:)) will
turn off the warning. It also provides 'fixit' so user knows
what to do. // rdar://16458579
Added:
cfe/trunk/test/FixIt/fixit-multiple-selector-warnings.m
Modified:
cfe/trunk/include/clang/Sema/Sema.h
cfe/trunk/lib/Parse/ParseObjc.cpp
cfe/trunk/lib/Sema/SemaExprObjC.cpp
cfe/trunk/test/SemaObjC/selector-1.m
Modified: cfe/trunk/include/clang/Sema/Sema.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Sema/Sema.h?rev=211611&r1=211610&r2=211611&view=diff
==============================================================================
--- cfe/trunk/include/clang/Sema/Sema.h (original)
+++ cfe/trunk/include/clang/Sema/Sema.h Tue Jun 24 12:02:19 2014
@@ -4748,7 +4748,8 @@ public:
SourceLocation AtLoc,
SourceLocation SelLoc,
SourceLocation LParenLoc,
- SourceLocation RParenLoc);
+ SourceLocation RParenLoc,
+ bool WarnMultipleSelectors);
/// ParseObjCProtocolExpression - Build protocol expression for \@protocol
ExprResult ParseObjCProtocolExpression(IdentifierInfo * ProtocolName,
Modified: cfe/trunk/lib/Parse/ParseObjc.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Parse/ParseObjc.cpp?rev=211611&r1=211610&r2=211611&view=diff
==============================================================================
--- cfe/trunk/lib/Parse/ParseObjc.cpp (original)
+++ cfe/trunk/lib/Parse/ParseObjc.cpp Tue Jun 24 12:02:19 2014
@@ -2839,7 +2839,7 @@ Parser::ParseObjCProtocolExpression(Sour
}
/// objc-selector-expression
-/// @selector '(' objc-keyword-selector ')'
+/// @selector '(' '('[opt] objc-keyword-selector ')'[opt] ')'
ExprResult Parser::ParseObjCSelectorExpression(SourceLocation AtLoc) {
SourceLocation SelectorLoc = ConsumeToken();
@@ -2851,7 +2851,10 @@ ExprResult Parser::ParseObjCSelectorExpr
BalancedDelimiterTracker T(*this, tok::l_paren);
T.consumeOpen();
-
+ bool HasOptionalParen = Tok.is(tok::l_paren);
+ if (HasOptionalParen)
+ ConsumeParen();
+
if (Tok.is(tok::code_completion)) {
Actions.CodeCompleteObjCSelector(getCurScope(), KeyIdents);
cutOffParsing();
@@ -2864,6 +2867,7 @@ ExprResult Parser::ParseObjCSelectorExpr
return ExprError(Diag(Tok, diag::err_expected) << tok::identifier);
KeyIdents.push_back(SelIdent);
+
unsigned nColons = 0;
if (Tok.isNot(tok::r_paren)) {
while (1) {
@@ -2891,11 +2895,14 @@ ExprResult Parser::ParseObjCSelectorExpr
break;
}
}
+ if (HasOptionalParen && Tok.is(tok::r_paren))
+ ConsumeParen(); // ')'
T.consumeClose();
Selector Sel = PP.getSelectorTable().getSelector(nColons, &KeyIdents[0]);
return Actions.ParseObjCSelectorExpression(Sel, AtLoc, SelectorLoc,
T.getOpenLocation(),
- T.getCloseLocation());
+ T.getCloseLocation(),
+ !HasOptionalParen);
}
void Parser::ParseLexedObjCMethodDefs(LexedMethod &LM, bool parseMethod) {
Modified: cfe/trunk/lib/Sema/SemaExprObjC.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaExprObjC.cpp?rev=211611&r1=211610&r2=211611&view=diff
==============================================================================
--- cfe/trunk/lib/Sema/SemaExprObjC.cpp (original)
+++ cfe/trunk/lib/Sema/SemaExprObjC.cpp Tue Jun 24 12:02:19 2014
@@ -976,6 +976,8 @@ ExprResult Sema::ParseObjCEncodeExpressi
static bool HelperToDiagnoseMismatchedMethodsInGlobalPool(Sema &S,
SourceLocation AtLoc,
+ SourceLocation LParenLoc,
+ SourceLocation RParenLoc,
ObjCMethodDecl *Method,
ObjCMethodList &MethList) {
ObjCMethodList *M = &MethList;
@@ -991,7 +993,8 @@ static bool HelperToDiagnoseMismatchedMe
if (!Warned) {
Warned = true;
S.Diag(AtLoc, diag::warning_multiple_selectors)
- << Method->getSelector();
+ << Method->getSelector() << FixItHint::CreateInsertion(LParenLoc, "(")
+ << FixItHint::CreateInsertion(RParenLoc, ")");
S.Diag(Method->getLocation(), diag::note_method_declared_at)
<< Method->getDeclName();
}
@@ -1003,23 +1006,26 @@ static bool HelperToDiagnoseMismatchedMe
}
static void DiagnoseMismatchedSelectors(Sema &S, SourceLocation AtLoc,
- ObjCMethodDecl *Method) {
- if (S.Diags.isIgnored(diag::warning_multiple_selectors, SourceLocation()))
+ ObjCMethodDecl *Method,
+ SourceLocation LParenLoc,
+ SourceLocation RParenLoc,
+ bool WarnMultipleSelectors) {
+ if (!WarnMultipleSelectors ||
+ S.Diags.isIgnored(diag::warning_multiple_selectors, SourceLocation()))
return;
bool Warned = false;
for (Sema::GlobalMethodPool::iterator b = S.MethodPool.begin(),
e = S.MethodPool.end(); b != e; b++) {
// first, instance methods
ObjCMethodList &InstMethList = b->second.first;
- if (HelperToDiagnoseMismatchedMethodsInGlobalPool(S, AtLoc,
+ if (HelperToDiagnoseMismatchedMethodsInGlobalPool(S, AtLoc, LParenLoc, RParenLoc,
Method, InstMethList))
Warned = true;
// second, class methods
ObjCMethodList &ClsMethList = b->second.second;
- if (HelperToDiagnoseMismatchedMethodsInGlobalPool(S, AtLoc,
- Method, ClsMethList) ||
- Warned)
+ if (HelperToDiagnoseMismatchedMethodsInGlobalPool(S, AtLoc, LParenLoc, RParenLoc,
+ Method, ClsMethList) || Warned)
return;
}
}
@@ -1028,7 +1034,8 @@ ExprResult Sema::ParseObjCSelectorExpres
SourceLocation AtLoc,
SourceLocation SelLoc,
SourceLocation LParenLoc,
- SourceLocation RParenLoc) {
+ SourceLocation RParenLoc,
+ bool WarnMultipleSelectors) {
ObjCMethodDecl *Method = LookupInstanceMethodInGlobalPool(Sel,
SourceRange(LParenLoc, RParenLoc), false, false);
if (!Method)
@@ -1046,7 +1053,8 @@ ExprResult Sema::ParseObjCSelectorExpres
} else
Diag(SelLoc, diag::warn_undeclared_selector) << Sel;
} else
- DiagnoseMismatchedSelectors(*this, AtLoc, Method);
+ DiagnoseMismatchedSelectors(*this, AtLoc, Method, LParenLoc, RParenLoc,
+ WarnMultipleSelectors);
if (Method &&
Method->getImplementationControl() != ObjCMethodDecl::Optional &&
Added: cfe/trunk/test/FixIt/fixit-multiple-selector-warnings.m
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/FixIt/fixit-multiple-selector-warnings.m?rev=211611&view=auto
==============================================================================
--- cfe/trunk/test/FixIt/fixit-multiple-selector-warnings.m (added)
+++ cfe/trunk/test/FixIt/fixit-multiple-selector-warnings.m Tue Jun 24 12:02:19 2014
@@ -0,0 +1,26 @@
+/* RUN: cp %s %t
+ RUN: %clang_cc1 -x objective-c -Wselector-type-mismatch -fixit %t
+ RUN: %clang_cc1 -x objective-c -Wselector-type-mismatch -Werror %t
+*/
+// rdar://16458579
+
+ at interface I
+- (id) compare: (char) arg1;
+- length;
+ at end
+
+ at interface J
+- (id) compare: (id) arg1;
+ at end
+
+SEL func()
+{
+ (void)@selector( compare: );
+ (void)@selector (compare:);
+ (void)@selector( compare:);
+ (void)@selector(compare: );
+ (void)@selector ( compare: );
+ return @selector(compare:);
+}
+
+
Modified: cfe/trunk/test/SemaObjC/selector-1.m
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/SemaObjC/selector-1.m?rev=211611&r1=211610&r2=211611&view=diff
==============================================================================
--- cfe/trunk/test/SemaObjC/selector-1.m (original)
+++ cfe/trunk/test/SemaObjC/selector-1.m Tue Jun 24 12:02:19 2014
@@ -14,6 +14,18 @@ SEL func()
return @selector(compare:); // expected-warning {{several methods with selector 'compare:' of mismatched types are found for the @selector expression}}
}
+// rdar://16458579
+void Test16458579() {
+ SEL s = @selector((retain));
+ SEL s1 = @selector((meth1:));
+ SEL s2 = @selector((retainArgument::));
+ SEL s3 = @selector((retainArgument:::::));
+ SEL s4 = @selector((retainArgument:with:));
+ SEL s5 = @selector((meth1:with:with:));
+ SEL s6 = @selector((getEnum:enum:bool:));
+ SEL s7 = @selector((char:float:double:unsigned:short:long:));
+ SEL s9 = @selector((:enum:bool:));
+}
int main() {
SEL s = @selector(retain);
SEL s1 = @selector(meth1:);
More information about the cfe-commits
mailing list