summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--clang/lib/AST/DeclObjC.cpp40
-rw-r--r--clang/lib/Sema/SemaDeclObjC.cpp2
-rw-r--r--clang/test/Sema/warn-documentation.m12
3 files changed, 37 insertions, 17 deletions
diff --git a/clang/lib/AST/DeclObjC.cpp b/clang/lib/AST/DeclObjC.cpp
index 0291803fd46..3895a520857 100644
--- a/clang/lib/AST/DeclObjC.cpp
+++ b/clang/lib/AST/DeclObjC.cpp
@@ -627,23 +627,29 @@ ObjCMethodDecl *ObjCMethodDecl::getNextRedeclaration() {
Decl *CtxD = cast<Decl>(getDeclContext());
- if (ObjCInterfaceDecl *IFD = dyn_cast<ObjCInterfaceDecl>(CtxD)) {
- if (ObjCImplementationDecl *ImplD = Ctx.getObjCImplementation(IFD))
- Redecl = ImplD->getMethod(getSelector(), isInstanceMethod());
-
- } else if (ObjCCategoryDecl *CD = dyn_cast<ObjCCategoryDecl>(CtxD)) {
- if (ObjCCategoryImplDecl *ImplD = Ctx.getObjCImplementation(CD))
- Redecl = ImplD->getMethod(getSelector(), isInstanceMethod());
-
- } else if (ObjCImplementationDecl *ImplD =
- dyn_cast<ObjCImplementationDecl>(CtxD)) {
- if (ObjCInterfaceDecl *IFD = ImplD->getClassInterface())
- Redecl = IFD->getMethod(getSelector(), isInstanceMethod());
-
- } else if (ObjCCategoryImplDecl *CImplD =
- dyn_cast<ObjCCategoryImplDecl>(CtxD)) {
- if (ObjCCategoryDecl *CatD = CImplD->getCategoryDecl())
- Redecl = CatD->getMethod(getSelector(), isInstanceMethod());
+ if (!CtxD->isInvalidDecl()) {
+ if (ObjCInterfaceDecl *IFD = dyn_cast<ObjCInterfaceDecl>(CtxD)) {
+ if (ObjCImplementationDecl *ImplD = Ctx.getObjCImplementation(IFD))
+ if (!ImplD->isInvalidDecl())
+ Redecl = ImplD->getMethod(getSelector(), isInstanceMethod());
+
+ } else if (ObjCCategoryDecl *CD = dyn_cast<ObjCCategoryDecl>(CtxD)) {
+ if (ObjCCategoryImplDecl *ImplD = Ctx.getObjCImplementation(CD))
+ if (!ImplD->isInvalidDecl())
+ Redecl = ImplD->getMethod(getSelector(), isInstanceMethod());
+
+ } else if (ObjCImplementationDecl *ImplD =
+ dyn_cast<ObjCImplementationDecl>(CtxD)) {
+ if (ObjCInterfaceDecl *IFD = ImplD->getClassInterface())
+ if (!IFD->isInvalidDecl())
+ Redecl = IFD->getMethod(getSelector(), isInstanceMethod());
+
+ } else if (ObjCCategoryImplDecl *CImplD =
+ dyn_cast<ObjCCategoryImplDecl>(CtxD)) {
+ if (ObjCCategoryDecl *CatD = CImplD->getCategoryDecl())
+ if (!CatD->isInvalidDecl())
+ Redecl = CatD->getMethod(getSelector(), isInstanceMethod());
+ }
}
if (!Redecl && isRedeclaration()) {
diff --git a/clang/lib/Sema/SemaDeclObjC.cpp b/clang/lib/Sema/SemaDeclObjC.cpp
index d8517f49f47..687cdf114a6 100644
--- a/clang/lib/Sema/SemaDeclObjC.cpp
+++ b/clang/lib/Sema/SemaDeclObjC.cpp
@@ -935,6 +935,7 @@ Decl *Sema::ActOnStartCategoryImplementation(
<< CatName;
Diag(CatIDecl->getImplementation()->getLocation(),
diag::note_previous_definition);
+ CDecl->setInvalidDecl();
} else {
CatIDecl->setImplementation(CDecl);
// Warn on implementating category of deprecated class under
@@ -1056,6 +1057,7 @@ Decl *Sema::ActOnStartClassImplementation(
Diag(ClassLoc, diag::err_dup_implementation_class) << ClassName;
Diag(IDecl->getImplementation()->getLocation(),
diag::note_previous_definition);
+ IMPDecl->setInvalidDecl();
} else { // add it to the list.
IDecl->setImplementation(IMPDecl);
PushOnScopeChains(IMPDecl, TUScope);
diff --git a/clang/test/Sema/warn-documentation.m b/clang/test/Sema/warn-documentation.m
index 1d3114617eb..17dd92e6eba 100644
--- a/clang/test/Sema/warn-documentation.m
+++ b/clang/test/Sema/warn-documentation.m
@@ -203,3 +203,15 @@ int FooBar();
@interface Asset : NSObject
@end
+// rdar://14024851 Check that this does not enter an infinite loop
+@interface rdar14024851
+-(void)meth; // expected-note {{declared here}}
+@end
+
+@implementation rdar14024851 // expected-warning {{method definition for 'meth' not found}} expected-note {{previous definition}}
+@end
+
+@implementation rdar14024851 // expected-error {{reimplementation}}
+/// \brief comment
+-(void)meth {}
+@end
OpenPOWER on IntegriCloud