diff options
-rw-r--r-- | include/clang/Sema/Sema.h | 8 | ||||
-rw-r--r-- | lib/Sema/SemaDecl.cpp | 6 | ||||
-rw-r--r-- | lib/Sema/SemaExpr.cpp | 5 | ||||
-rw-r--r-- | test/SemaObjC/unused.m | 16 |
4 files changed, 25 insertions, 10 deletions
diff --git a/include/clang/Sema/Sema.h b/include/clang/Sema/Sema.h index 5fdb09caea..919bd6883e 100644 --- a/include/clang/Sema/Sema.h +++ b/include/clang/Sema/Sema.h @@ -7244,6 +7244,14 @@ public: } AvailabilityResult getCurContextAvailability() const; + + const DeclContext *getCurObjCLexicalContext() const { + const DeclContext *DC = getCurLexicalContext(); + // A category implicitly has the attribute of the interface. + if (const ObjCCategoryDecl *CatD = dyn_cast<ObjCCategoryDecl>(DC)) + DC = CatD->getClassInterface(); + return DC; + } }; /// \brief RAII object that enters a new expression evaluation context. diff --git a/lib/Sema/SemaDecl.cpp b/lib/Sema/SemaDecl.cpp index 711ea4c729..b3db840397 100644 --- a/lib/Sema/SemaDecl.cpp +++ b/lib/Sema/SemaDecl.cpp @@ -11101,10 +11101,6 @@ Decl *Sema::getObjCDeclContext() const { } AvailabilityResult Sema::getCurContextAvailability() const { - const Decl *D = cast<Decl>(getCurLexicalContext()); - // A category implicitly has the availability of the interface. - if (const ObjCCategoryDecl *CatD = dyn_cast<ObjCCategoryDecl>(D)) - D = CatD->getClassInterface(); - + const Decl *D = cast<Decl>(getCurObjCLexicalContext()); return D->getAvailability(); } diff --git a/lib/Sema/SemaExpr.cpp b/lib/Sema/SemaExpr.cpp index a67d5c6bd0..cfa9ccbfc3 100644 --- a/lib/Sema/SemaExpr.cpp +++ b/lib/Sema/SemaExpr.cpp @@ -69,10 +69,7 @@ bool Sema::CanUseDecl(NamedDecl *D) { static void DiagnoseUnusedOfDecl(Sema &S, NamedDecl *D, SourceLocation Loc) { // Warn if this is used but marked unused. if (D->hasAttr<UnusedAttr>()) { - const Decl *DC = cast<Decl>(S.getCurLexicalContext()); - // A category implicitly has the availability of the interface. - if (const ObjCCategoryDecl *CatD = dyn_cast<ObjCCategoryDecl>(DC)) - DC = CatD->getClassInterface(); + const Decl *DC = cast<Decl>(S.getCurObjCLexicalContext()); if (!DC->hasAttr<UnusedAttr>()) S.Diag(Loc, diag::warn_used_but_marked_unused) << D->getDeclName(); } diff --git a/test/SemaObjC/unused.m b/test/SemaObjC/unused.m index 5c7542bf47..efaf9c8f3e 100644 --- a/test/SemaObjC/unused.m +++ b/test/SemaObjC/unused.m @@ -1,4 +1,4 @@ -// RUN: %clang_cc1 -verify -Wunused -Wunused-parameter -fsyntax-only -Wno-objc-root-class %s +// RUN: %clang_cc1 -verify -Wused-but-marked-unused -Wno-objc-protocol-method-implementation -Wunused -Wunused-parameter -fsyntax-only -Wno-objc-root-class %s int printf(const char *, ...); @@ -53,3 +53,17 @@ void test2() { // rdar://10777111 static NSString *x = @"hi"; // expected-warning {{unused variable 'x'}} + +// rdar://12233989 +@interface TestTransitiveUnused +- (void) a __attribute__((unused)); +- (void) b __attribute__((unused)); +@end + +@interface TestTransitiveUnused(CAT) +@end + +@implementation TestTransitiveUnused(CAT) +- (void) b {} +- (void) a { [self b]; } +@end |