From b7b58b1fcd3007730fd46471583543c9b57c7693 Mon Sep 17 00:00:00 2001 From: Chris Lattner Date: Sun, 19 Apr 2009 06:02:28 +0000 Subject: [PATCH] Fix rdar://6804402 - crash on objc implementations declared with @class but no implementation. This was broken in all 3 runtime impls. git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@69512 91177308-0d34-0410-b5e6-96231b3b80d8 --- lib/CodeGen/CGObjCGNU.cpp | 8 ++++++-- lib/CodeGen/CGObjCMac.cpp | 25 +++++++++++++++++-------- test/CodeGenObjC/class-type.m | 14 +++++++++++++- 3 files changed, 36 insertions(+), 11 deletions(-) diff --git a/lib/CodeGen/CGObjCGNU.cpp b/lib/CodeGen/CGObjCGNU.cpp index cd94290000..f7936fda55 100644 --- a/lib/CodeGen/CGObjCGNU.cpp +++ b/lib/CodeGen/CGObjCGNU.cpp @@ -739,8 +739,12 @@ void CGObjCGNU::GenerateClass(const ObjCImplementationDecl *OID) { // Get the size of instances. For runtimes that support late-bound instances // this should probably be something different (size just of instance // varaibles in this class, not superclasses?). - const llvm::Type *ObjTy = - CGM.getTypes().ConvertType(Context.getObjCInterfaceType(ClassDecl)); + const llvm::Type *ObjTy; + + if (ClassDecl->isForwardDecl()) + ObjTy = llvm::StructType::get(NULL, NULL); + else + ObjTy = CGM.getTypes().ConvertType(Context.getObjCInterfaceType(ClassDecl)); int instanceSize = CGM.getTargetData().getTypePaddedSize(ObjTy); // Collect information about instance variables. diff --git a/lib/CodeGen/CGObjCMac.cpp b/lib/CodeGen/CGObjCMac.cpp index 0d6dd6aa77..238f7c5ead 100644 --- a/lib/CodeGen/CGObjCMac.cpp +++ b/lib/CodeGen/CGObjCMac.cpp @@ -1484,7 +1484,11 @@ void CGObjCMac::GenerateClass(const ObjCImplementationDecl *ID) { EmitProtocolList("\01L_OBJC_CLASS_PROTOCOLS_" + ID->getNameAsString(), Interface->protocol_begin(), Interface->protocol_end()); - const llvm::Type *InterfaceTy = + const llvm::Type *InterfaceTy; + if (Interface->isForwardDecl()) + InterfaceTy = llvm::StructType::get(NULL, NULL); + else + InterfaceTy = CGM.getTypes().ConvertType(CGM.getContext().getObjCInterfaceType(Interface)); unsigned Flags = eClassFlags_Factory; unsigned Size = CGM.getTargetData().getTypePaddedSize(InterfaceTy); @@ -2562,10 +2566,16 @@ llvm::Constant *CGObjCCommonMac::GetClassName(IdentifierInfo *Ident) { /// interface declaration. const llvm::StructLayout *CGObjCCommonMac::GetInterfaceDeclStructLayout( const ObjCInterfaceDecl *OID) const { - const llvm::Type *InterfaceTy = - CGM.getTypes().ConvertType( - CGM.getContext().getObjCInterfaceType( - const_cast(OID))); + const llvm::Type *InterfaceTy; + + if (OID->isForwardDecl()) { + InterfaceTy = llvm::StructType::get(NULL, NULL); + } else { + QualType T = CGM.getContext().getObjCInterfaceType( + const_cast(OID)); + InterfaceTy = CGM.getTypes().ConvertType(T); + } + const llvm::StructLayout *Layout = CGM.getTargetData().getStructLayout(cast(InterfaceTy)); return Layout; @@ -4263,8 +4273,7 @@ void CGObjCNonFragileABIMac::GenerateClass(const ObjCImplementationDecl *ID) { if (!ID->getClassInterface()->getSuperClass()) { flags |= CLS_ROOT; SuperClassGV = 0; - } - else { + } else { // Has a root. Current class is not a root. std::string RootClassName = ID->getClassInterface()->getSuperClass()->getNameAsString(); @@ -4273,7 +4282,7 @@ void CGObjCNonFragileABIMac::GenerateClass(const ObjCImplementationDecl *ID) { // FIXME: Gross InstanceStart = InstanceSize = 0; if (ObjCInterfaceDecl *OID = - const_cast(ID->getClassInterface())) { + const_cast(ID->getClassInterface())) { // FIXME. Share this with the one in EmitIvarList. const llvm::StructLayout *Layout = GetInterfaceDeclStructLayout(OID); diff --git a/test/CodeGenObjC/class-type.m b/test/CodeGenObjC/class-type.m index 423415bbf2..794d9a3557 100644 --- a/test/CodeGenObjC/class-type.m +++ b/test/CodeGenObjC/class-type.m @@ -1,4 +1,7 @@ -// RUN: clang-cc -triple x86_64-unknown-unknown -emit-llvm -o - %s +// RUN: clang-cc -triple x86_64-unknown-unknown -emit-llvm -o - %s && +// RUN: clang-cc -triple i386-apple-darwin9 -emit-llvm -o - %s && +// RUN: clang-cc -triple x86_64-apple-darwin9 -emit-llvm -o - %s + @interface I0 { struct { int a; } a; @@ -22,3 +25,12 @@ @end +// Implementations without interface declarations. +// rdar://6804402 +@class foo; +@implementation foo +@end + +@implementation bar +@end + -- 2.40.0