aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--include/clang/Sema/Sema.h8
-rw-r--r--lib/Sema/SemaDecl.cpp6
-rw-r--r--lib/Sema/SemaExpr.cpp5
-rw-r--r--test/SemaObjC/unused.m16
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