forked from OSchip/llvm-project
MS ABI: Don't ICE for pointers to pointers to members of incomplete classes
CodeGen would try to come up with an LLVM IR type for a pointer to member type on the way to forming an LLVM IR type for a pointer to pointer to member type. However, if the pointer to member representation has not been locked in yet, we would not be able to come up with a pointer to member IR type. In these cases, make the pointer to member type an incomplete type. This will make the pointer to pointer to member type a pointer to an incomplete type. If the class eventually obtains an inheritance model, we will make the pointer to member type represent the actual inheritance model. Differential Revision: http://reviews.llvm.org/D5373 llvm-svn: 218084
This commit is contained in:
parent
1f684518c8
commit
9928106536
|
@ -161,6 +161,10 @@ public:
|
|||
return true;
|
||||
}
|
||||
|
||||
virtual bool isTypeInfoCalculable(QualType Ty) const {
|
||||
return !Ty->isIncompleteType();
|
||||
}
|
||||
|
||||
/// Create a null member pointer of the given type.
|
||||
virtual llvm::Constant *EmitNullMemberPointer(const MemberPointerType *MPT);
|
||||
|
||||
|
|
|
@ -79,6 +79,17 @@ CodeGenFunction::~CodeGenFunction() {
|
|||
}
|
||||
}
|
||||
|
||||
LValue CodeGenFunction::MakeNaturalAlignAddrLValue(llvm::Value *V, QualType T) {
|
||||
CharUnits Alignment;
|
||||
if (CGM.getCXXABI().isTypeInfoCalculable(T)) {
|
||||
Alignment = getContext().getTypeAlignInChars(T);
|
||||
unsigned MaxAlign = getContext().getLangOpts().MaxTypeAlign;
|
||||
if (MaxAlign && Alignment.getQuantity() > MaxAlign &&
|
||||
!getContext().isAlignmentRequired(T))
|
||||
Alignment = CharUnits::fromQuantity(MaxAlign);
|
||||
}
|
||||
return LValue::MakeAddr(V, T, Alignment, getContext(), CGM.getTBAAInfo(T));
|
||||
}
|
||||
|
||||
llvm::Type *CodeGenFunction::ConvertTypeForMem(QualType T) {
|
||||
return CGM.getTypes().ConvertTypeForMem(T);
|
||||
|
|
|
@ -1401,18 +1401,7 @@ public:
|
|||
CGM.getTBAAInfo(T));
|
||||
}
|
||||
|
||||
LValue MakeNaturalAlignAddrLValue(llvm::Value *V, QualType T) {
|
||||
CharUnits Alignment;
|
||||
if (!T->isIncompleteType()) {
|
||||
Alignment = getContext().getTypeAlignInChars(T);
|
||||
unsigned MaxAlign = getContext().getLangOpts().MaxTypeAlign;
|
||||
if (MaxAlign && Alignment.getQuantity() > MaxAlign &&
|
||||
!getContext().isAlignmentRequired(T))
|
||||
Alignment = CharUnits::fromQuantity(MaxAlign);
|
||||
}
|
||||
return LValue::MakeAddr(V, T, Alignment, getContext(),
|
||||
CGM.getTBAAInfo(T));
|
||||
}
|
||||
LValue MakeNaturalAlignAddrLValue(llvm::Value *V, QualType T);
|
||||
|
||||
/// CreateTempAlloca - This creates a alloca and inserts it into the entry
|
||||
/// block. The caller is responsible for setting an appropriate alignment on
|
||||
|
|
|
@ -81,7 +81,7 @@ void CodeGenTypes::addRecordTypeName(const RecordDecl *RD,
|
|||
/// ConvertType in that it is used to convert to the memory representation for
|
||||
/// a type. For example, the scalar representation for _Bool is i1, but the
|
||||
/// memory representation is usually i8 or i32, depending on the target.
|
||||
llvm::Type *CodeGenTypes::ConvertTypeForMem(QualType T){
|
||||
llvm::Type *CodeGenTypes::ConvertTypeForMem(QualType T) {
|
||||
llvm::Type *R = ConvertType(T);
|
||||
|
||||
// If this is a non-bool type, don't map it.
|
||||
|
@ -587,6 +587,8 @@ llvm::Type *CodeGenTypes::ConvertType(QualType T) {
|
|||
}
|
||||
|
||||
case Type::MemberPointer: {
|
||||
if (!getCXXABI().isMemberPointerConvertible(cast<MemberPointerType>(Ty)))
|
||||
return llvm::StructType::create(getLLVMContext());
|
||||
ResultType =
|
||||
getCXXABI().ConvertMemberPointerType(cast<MemberPointerType>(Ty));
|
||||
break;
|
||||
|
|
|
@ -488,7 +488,18 @@ public:
|
|||
|
||||
bool isMemberPointerConvertible(const MemberPointerType *MPT) const override {
|
||||
const CXXRecordDecl *RD = MPT->getMostRecentCXXRecordDecl();
|
||||
return RD->getAttr<MSInheritanceAttr>() != nullptr;
|
||||
return RD->hasAttr<MSInheritanceAttr>();
|
||||
}
|
||||
|
||||
virtual bool isTypeInfoCalculable(QualType Ty) const {
|
||||
if (!CGCXXABI::isTypeInfoCalculable(Ty))
|
||||
return false;
|
||||
if (const auto *MPT = Ty->getAs<MemberPointerType>()) {
|
||||
const CXXRecordDecl *RD = MPT->getMostRecentCXXRecordDecl();
|
||||
if (!RD->hasAttr<MSInheritanceAttr>())
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
llvm::Constant *EmitNullMemberPointer(const MemberPointerType *MPT) override;
|
||||
|
|
|
@ -1,9 +1,19 @@
|
|||
// RUN: %clang_cc1 -std=c++11 -fno-rtti -emit-llvm %s -o - -triple=i386-pc-win32 -fms-extensions | FileCheck %s
|
||||
// RUN: %clang_cc1 -std=c++11 -fno-rtti -emit-llvm %s -o - -triple=x86_64-pc-win32 -fms-extensions | FileCheck %s -check-prefix=X64
|
||||
// RUN: %clang_cc1 -std=c++11 -fno-rtti -emit-llvm %s -o - -triple=i386-pc-win32 -DINCOMPLETE_VIRTUAL -fms-extensions -verify
|
||||
// RUN: %clang_cc1 -std=c++11 -fno-rtti -emit-llvm %s -o - -triple=i386-pc-win32 -DINCOMPLETE_VIRTUAL -DMEMFUN -fms-extensions -verify
|
||||
// FIXME: Test x86_64 member pointers when codegen no longer asserts on records
|
||||
// with virtual bases.
|
||||
// RUN: %clang_cc1 -std=c++11 -Wno-uninitialized -fno-rtti -emit-llvm %s -o - -triple=i386-pc-win32 -fms-extensions | FileCheck %s
|
||||
// RUN: %clang_cc1 -std=c++11 -Wno-uninitialized -fno-rtti -emit-llvm %s -o - -triple=x86_64-pc-win32 -fms-extensions | FileCheck %s -check-prefix=X64
|
||||
// RUN: %clang_cc1 -std=c++11 -Wno-uninitialized -fno-rtti -emit-llvm %s -o - -triple=i386-pc-win32 -DINCOMPLETE_VIRTUAL -fms-extensions -verify
|
||||
// RUN: %clang_cc1 -std=c++11 -Wno-uninitialized -fno-rtti -emit-llvm %s -o - -triple=i386-pc-win32 -DINCOMPLETE_VIRTUAL -DMEMFUN -fms-extensions -verify
|
||||
|
||||
namespace PR20947 {
|
||||
struct A;
|
||||
int A::**a = nullptr;
|
||||
// CHECK: %[[opaque0:.*]] = type opaque
|
||||
// CHECK: %[[opaque1:.*]] = type opaque
|
||||
// CHECK: @"\01?a@PR20947@@3PAPQA@1@HA" = global %[[opaque0]]* null, align 4
|
||||
|
||||
struct B;
|
||||
int B::*&b = b;
|
||||
// CHECK: @"\01?b@PR20947@@3AAPQB@1@HA" = global %[[opaque1]]* null, align 4
|
||||
}
|
||||
|
||||
#ifndef INCOMPLETE_VIRTUAL
|
||||
struct B1 {
|
||||
|
|
Loading…
Reference in New Issue