summaryrefslogtreecommitdiffstats
path: root/clang/lib/CodeGen
diff options
context:
space:
mode:
authorDavid Majnemer <david.majnemer@gmail.com>2014-09-18 22:05:54 +0000
committerDavid Majnemer <david.majnemer@gmail.com>2014-09-18 22:05:54 +0000
commit99281065366dad75b16b3344d76ddcf64150c677 (patch)
treeb82f825762d90cd1ea7155a8ed3fcc48ef4442e1 /clang/lib/CodeGen
parent1f684518c82c5371463a915e04169927d7135384 (diff)
downloadbcm5719-llvm-99281065366dad75b16b3344d76ddcf64150c677.tar.gz
bcm5719-llvm-99281065366dad75b16b3344d76ddcf64150c677.zip
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
Diffstat (limited to 'clang/lib/CodeGen')
-rw-r--r--clang/lib/CodeGen/CGCXXABI.h4
-rw-r--r--clang/lib/CodeGen/CodeGenFunction.cpp11
-rw-r--r--clang/lib/CodeGen/CodeGenFunction.h13
-rw-r--r--clang/lib/CodeGen/CodeGenTypes.cpp4
-rw-r--r--clang/lib/CodeGen/MicrosoftCXXABI.cpp13
5 files changed, 31 insertions, 14 deletions
diff --git a/clang/lib/CodeGen/CGCXXABI.h b/clang/lib/CodeGen/CGCXXABI.h
index b7ce0b07e57..f021e886c02 100644
--- a/clang/lib/CodeGen/CGCXXABI.h
+++ b/clang/lib/CodeGen/CGCXXABI.h
@@ -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);
diff --git a/clang/lib/CodeGen/CodeGenFunction.cpp b/clang/lib/CodeGen/CodeGenFunction.cpp
index f49e9ec1267..9f359185381 100644
--- a/clang/lib/CodeGen/CodeGenFunction.cpp
+++ b/clang/lib/CodeGen/CodeGenFunction.cpp
@@ -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);
diff --git a/clang/lib/CodeGen/CodeGenFunction.h b/clang/lib/CodeGen/CodeGenFunction.h
index b67860cab18..eebdbf34a8e 100644
--- a/clang/lib/CodeGen/CodeGenFunction.h
+++ b/clang/lib/CodeGen/CodeGenFunction.h
@@ -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
diff --git a/clang/lib/CodeGen/CodeGenTypes.cpp b/clang/lib/CodeGen/CodeGenTypes.cpp
index 1f39eb88c01..1404dfd7a9d 100644
--- a/clang/lib/CodeGen/CodeGenTypes.cpp
+++ b/clang/lib/CodeGen/CodeGenTypes.cpp
@@ -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;
diff --git a/clang/lib/CodeGen/MicrosoftCXXABI.cpp b/clang/lib/CodeGen/MicrosoftCXXABI.cpp
index 36392bc5ed0..dd6a4580d49 100644
--- a/clang/lib/CodeGen/MicrosoftCXXABI.cpp
+++ b/clang/lib/CodeGen/MicrosoftCXXABI.cpp
@@ -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;
OpenPOWER on IntegriCloud