r203693 - Objective-C. Issue diagnostics on mismatched methods when their selector is used
Fariborz Jahanian
fjahanian at apple.com
Wed Mar 12 11:34:01 PDT 2014
Author: fjahanian
Date: Wed Mar 12 13:34:01 2014
New Revision: 203693
URL: http://llvm.org/viewvc/llvm-project?rev=203693&view=rev
Log:
Objective-C. Issue diagnostics on mismatched methods when their selector is used
in an @selector expression. // rdar://15794055
Modified:
cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td
cfe/trunk/lib/Sema/SemaExprObjC.cpp
cfe/trunk/test/SemaObjC/selector-1.m
Modified: cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td?rev=203693&r1=203692&r2=203693&view=diff
==============================================================================
--- cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td (original)
+++ cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td Wed Mar 12 13:34:01 2014
@@ -892,7 +892,9 @@ def warn_unimplemented_selector: Warnin
InGroup<Selector>, DefaultIgnore;
def warn_unimplemented_protocol_method : Warning<
"method %0 in protocol %1 not implemented">, InGroup<Protocol>;
-
+def warning_multiple_selectors: Warning<
+ "several methods with selector %0 of mismatched types are found for the @selector expression">,
+ InGroup<SelectorTypeMismatch>;
// C++ declarations
def err_static_assert_expression_is_not_constant : Error<
"static_assert expression is not an integral constant expression">;
Modified: cfe/trunk/lib/Sema/SemaExprObjC.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaExprObjC.cpp?rev=203693&r1=203692&r2=203693&view=diff
==============================================================================
--- cfe/trunk/lib/Sema/SemaExprObjC.cpp (original)
+++ cfe/trunk/lib/Sema/SemaExprObjC.cpp Wed Mar 12 13:34:01 2014
@@ -973,6 +973,58 @@ ExprResult Sema::ParseObjCEncodeExpressi
return BuildObjCEncodeExpression(AtLoc, TInfo, RParenLoc);
}
+static bool HelperToDiagnoseMismatchedMethodsInGlobalPool(Sema &S,
+ SourceLocation AtLoc,
+ ObjCMethodDecl *Method,
+ ObjCMethodList &MethList) {
+ ObjCMethodList *M = &MethList;
+ bool Warned = false;
+ for (M = M->getNext(); M; M=M->getNext()) {
+ ObjCMethodDecl *MatchingMethodDecl = M->Method;
+ if (MatchingMethodDecl == Method ||
+ isa<ObjCImplDecl>(MatchingMethodDecl->getDeclContext()) ||
+ MatchingMethodDecl->getSelector() != Method->getSelector())
+ continue;
+ if (!S.MatchTwoMethodDeclarations(Method,
+ MatchingMethodDecl, Sema::MMS_loose)) {
+ if (!Warned) {
+ Warned = true;
+ S.Diag(AtLoc, diag::warning_multiple_selectors)
+ << Method->getSelector();
+ S.Diag(Method->getLocation(), diag::note_method_declared_at)
+ << Method->getDeclName();
+ }
+ S.Diag(MatchingMethodDecl->getLocation(), diag::note_method_declared_at)
+ << MatchingMethodDecl->getDeclName();
+ }
+ }
+ return Warned;
+}
+
+static void DiagnoseMismatchedSelectors(Sema &S, SourceLocation AtLoc,
+ ObjCMethodDecl *Method) {
+ unsigned DIAG = diag::warning_multiple_selectors;
+ if (S.Diags.getDiagnosticLevel(DIAG, SourceLocation())
+ == DiagnosticsEngine::Ignored)
+ 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,
+ Method, InstMethList))
+ Warned = true;
+
+ // second, class methods
+ ObjCMethodList &ClsMethList = b->second.second;
+ if (HelperToDiagnoseMismatchedMethodsInGlobalPool(S, AtLoc,
+ Method, ClsMethList) ||
+ Warned)
+ return;
+ }
+}
+
ExprResult Sema::ParseObjCSelectorExpression(Selector Sel,
SourceLocation AtLoc,
SourceLocation SelLoc,
@@ -994,7 +1046,8 @@ ExprResult Sema::ParseObjCSelectorExpres
} else
Diag(SelLoc, diag::warn_undeclared_selector) << Sel;
- }
+ } else
+ DiagnoseMismatchedSelectors(*this, AtLoc, Method);
if (!Method ||
Method->getImplementationControl() != ObjCMethodDecl::Optional) {
Modified: cfe/trunk/test/SemaObjC/selector-1.m
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/SemaObjC/selector-1.m?rev=203693&r1=203692&r2=203693&view=diff
==============================================================================
--- cfe/trunk/test/SemaObjC/selector-1.m (original)
+++ cfe/trunk/test/SemaObjC/selector-1.m Wed Mar 12 13:34:01 2014
@@ -1,18 +1,17 @@
// RUN: %clang_cc1 -verify %s
-// expected-no-diagnostics
@interface I
-- (id) compare: (char) arg1;
+- (id) compare: (char) arg1; // expected-note {{method 'compare:' declared here}}
- length;
@end
@interface J
-- (id) compare: (id) arg1;
+- (id) compare: (id) arg1; // expected-note {{method 'compare:' declared here}}
@end
SEL func()
{
- return @selector(compare:); // no warning on multiple selector found.
+ return @selector(compare:); // expected-warning {{several methods with selector 'compare:' of mismatched types are found for the @selector expression}}
}
int main() {
@@ -27,3 +26,26 @@ int main() {
SEL s9 = @selector(:enum:bool:);
}
+
+// rdar://15794055
+ at interface NSObject @end
+
+ at class NSNumber;
+
+ at interface XBRecipe : NSObject
+ at property (nonatomic, assign) float finalVolume; // expected-note {{method 'setFinalVolume:' declared here}}
+ at end
+
+ at interface XBDocument : NSObject
+ at end
+
+ at interface XBDocument ()
+- (void)setFinalVolume:(NSNumber *)finalVolumeNumber; // expected-note {{method 'setFinalVolume:' declared here}}
+ at end
+
+ at implementation XBDocument
+- (void)setFinalVolume:(NSNumber *)finalVolumeNumber
+{
+ (void)@selector(setFinalVolume:); // expected-warning {{several methods with selector 'setFinalVolume:' of mismatched types are found for the @selector expression}}
+}
+ at end
More information about the cfe-commits
mailing list