[Modules][ObjC] Check definition from canonical decl on designated initializers

Use definition from canonical decl when checking for designated
initializers. This is necessary since deserialization of a interface
might reuse the definition from the canonical one (see r281119).

rdar://problem/29360655

llvm-svn: 301382
This commit is contained in:
Bruno Cardoso Lopes 2017-04-26 05:06:20 +00:00
parent 3fef15b73f
commit faaeae5d6e
7 changed files with 49 additions and 1 deletions

@ -539,9 +539,18 @@ void ObjCInterfaceDecl::getDesignatedInitializers(
bool ObjCInterfaceDecl::isDesignatedInitializer(Selector Sel,
const ObjCMethodDecl **InitMethod) const {
bool HasCompleteDef = isThisDeclarationADefinition();
// During deserialization the data record for the ObjCInterfaceDecl could
// be made invariant by reusing the canonical decl. Take this into account
// when checking for the complete definition.
if (!HasCompleteDef && getCanonicalDecl()->hasDefinition() &&
getCanonicalDecl()->getDefinition() == getDefinition())
HasCompleteDef = true;
// Check for a complete definition and recover if not so.
if (!isThisDeclarationADefinition())
if (!HasCompleteDef)
return false;
if (data().ExternallyCompleted)
LoadExternalDefinition();

@ -0,0 +1 @@
#import "A2.h"

@ -0,0 +1,4 @@
#import "Base.h"
@interface A2 : Base
@end

@ -0,0 +1,4 @@
@class NSString;
@interface Base
- (id)initWithNibName:(NSString *)nibNameOrNil __attribute__((objc_designated_initializer));
@end

@ -0,0 +1,4 @@
#import "A2.h"
@interface X : A2
@end

@ -0,0 +1,9 @@
module Base {
header "Base.h"
export *
}
module A {
header "A.h"
export *
}

@ -0,0 +1,17 @@
// RUN: rm -rf %t
// RUN: %clang_cc1 -fmodules-cache-path=%t -fmodules -fimplicit-module-maps -I %S/Inputs/objc-desig-init %s -verify
// expected-no-diagnostics
#import "X.h"
#import "Base.h"
#import "A.h"
@implementation X
- (instancetype)initWithNibName:(NSString *)nibName {
if ((self = [super initWithNibName:nibName])) {
return self;
}
return self;
}
@end