-Wselector should warn on implemented selectors only

when selector metadata is generated, which is triggered 
by at least on class implementation. This is to match gcc's
behavior. // rdar://8851684.

llvm-svn: 124909
This commit is contained in:
Fariborz Jahanian 2011-02-04 23:19:27 +00:00
parent 191524e8a5
commit c9b7c209bb
4 changed files with 43 additions and 26 deletions

View File

@ -1381,6 +1381,11 @@ public:
/// \brief Get the implementation of ObjCCategoryDecl, or NULL if none exists. /// \brief Get the implementation of ObjCCategoryDecl, or NULL if none exists.
ObjCCategoryImplDecl *getObjCImplementation(ObjCCategoryDecl *D); ObjCCategoryImplDecl *getObjCImplementation(ObjCCategoryDecl *D);
/// \brief returns true if there is at lease one @implementation in TU.
bool AnyObjCImplementation() {
return !ObjCImpls.empty();
}
/// \brief Set the implementation of ObjCInterfaceDecl. /// \brief Set the implementation of ObjCInterfaceDecl.
void setObjCImplementation(ObjCInterfaceDecl *IFaceD, void setObjCImplementation(ObjCInterfaceDecl *IFaceD,
ObjCImplementationDecl *ImplD); ObjCImplementationDecl *ImplD);

View File

@ -1994,7 +1994,11 @@ void ObjCImplementationDecl::setIvarInitializers(ASTContext &C,
} }
void Sema::DiagnoseUseOfUnimplementedSelectors() { void Sema::DiagnoseUseOfUnimplementedSelectors() {
if (ReferencedSelectors.empty()) // Warning will be issued only when selector table is
// generated (which means there is at lease one implementation
// in the TU). This is to match gcc's behavior.
if (ReferencedSelectors.empty() ||
!Context.AnyObjCImplementation())
return; return;
for (llvm::DenseMap<Selector, SourceLocation>::iterator S = for (llvm::DenseMap<Selector, SourceLocation>::iterator S =
ReferencedSelectors.begin(), ReferencedSelectors.begin(),

View File

@ -1,35 +1,29 @@
// RUN: %clang_cc1 -verify %s // RUN: %clang_cc1 -fsyntax-only -Wselector -verify %s
// rdar://8851684
@interface Lancelot @end @interface Foo
@implementation Lancelot - (void) foo;
- (void) bar;
@end
- (void):(int)x {} @implementation Foo
- (void)xx:(int)x :(int)y { } - (void) bar
{
}
- (void) foo
{
SEL a,b,c;
a = @selector(b1ar); // expected-warning {{unimplemented selector 'b1ar'}}
b = @selector(bar);
}
@end @end
@interface I @interface I
- (id) compare: (char) arg1; - length;
@end @end
@interface J SEL func()
- (id) compare: (id) arg1;
@end
SEL foo()
{ {
return @selector(compare:); // Non warning on multiple selector found. return @selector(length); // expected-warning {{unimplemented selector 'length'}}
}
int main() {
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:);
} }

View File

@ -0,0 +1,14 @@
// RUN: %clang_cc1 -fsyntax-only -Wselector -verify %s
// rdar://8851684
@interface I
- length;
@end
static inline SEL IsEmpty() {
return @selector(length);
}
int main (int argc, const char * argv[]) {
return 0;
}