Index: cfe/trunk/lib/AST/DeclObjC.cpp =================================================================== --- cfe/trunk/lib/AST/DeclObjC.cpp +++ cfe/trunk/lib/AST/DeclObjC.cpp @@ -870,6 +870,12 @@ } } + // Ensure that the discovered method redeclaration has a valid declaration + // context. Used to prevent infinite loops when iterating redeclarations in + // a partially invalid AST. + if (Redecl && cast(Redecl->getDeclContext())->isInvalidDecl()) + Redecl = nullptr; + if (!Redecl && isRedeclaration()) { // This is the last redeclaration, go back to the first method. return cast(CtxD)->getMethod(getSelector(), Index: cfe/trunk/test/SemaObjC/method-redecls-invalid-interface.m =================================================================== --- cfe/trunk/test/SemaObjC/method-redecls-invalid-interface.m +++ cfe/trunk/test/SemaObjC/method-redecls-invalid-interface.m @@ -0,0 +1,21 @@ +// RUN: %clang_cc1 -fsyntax-only -verify -Wdocumentation -Wno-objc-root-class %s +// rdar://29220965 + +@interface InvalidInterface { // expected-note {{previous definition is here}} + int *_property; +} + +@end + +/*! + */ + +@interface InvalidInterface // expected-error {{duplicate interface definition for class 'InvalidInterface'}} +@property int *property; + +-(void) method; +@end + +@implementation InvalidInterface +-(void) method { } +@end