aboutsummaryrefslogtreecommitdiff
path: root/lib/CodeGen
diff options
context:
space:
mode:
authorArgyrios Kyrtzidis <akyrtzi@gmail.com>2010-12-10 00:11:00 +0000
committerArgyrios Kyrtzidis <akyrtzi@gmail.com>2010-12-10 00:11:00 +0000
commitdb2b42fb4d43be5af14ba33d49bbd163f01646ec (patch)
tree9d709afacb37af0016fada69ee5a57c201a67aeb /lib/CodeGen
parent4cf8b1ecf2875ca1d7360116b5d754fac41570b7 (diff)
Fix another obscure corner layout case.
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@121436 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/CodeGen')
-rw-r--r--lib/CodeGen/CGRecordLayoutBuilder.cpp22
1 files changed, 13 insertions, 9 deletions
diff --git a/lib/CodeGen/CGRecordLayoutBuilder.cpp b/lib/CodeGen/CGRecordLayoutBuilder.cpp
index 4beaa82e5d..5571e43f78 100644
--- a/lib/CodeGen/CGRecordLayoutBuilder.cpp
+++ b/lib/CodeGen/CGRecordLayoutBuilder.cpp
@@ -125,7 +125,7 @@ private:
const ASTRecordLayout &Layout);
/// ComputeNonVirtualBaseType - Compute the non-virtual base field types.
- void ComputeNonVirtualBaseType(const CXXRecordDecl *RD);
+ bool ComputeNonVirtualBaseType(const CXXRecordDecl *RD);
/// LayoutField - layout a single field. Returns false if the operation failed
/// because the current struct is not packed.
@@ -612,7 +612,7 @@ CGRecordLayoutBuilder::LayoutNonVirtualBases(const CXXRecordDecl *RD,
}
}
-void
+bool
CGRecordLayoutBuilder::ComputeNonVirtualBaseType(const CXXRecordDecl *RD) {
const ASTRecordLayout &Layout = Types.getContext().getASTRecordLayout(RD);
@@ -624,26 +624,27 @@ CGRecordLayoutBuilder::ComputeNonVirtualBaseType(const CXXRecordDecl *RD) {
// First check if we can use the same fields as for the complete class.
if (AlignedNonVirtualTypeSize == Layout.getSize() / 8) {
NonVirtualBaseTypeIsSameAsCompleteType = true;
- return;
+ return true;
}
- NonVirtualBaseFieldTypes = FieldTypes;
-
// Check if we need padding.
uint64_t AlignedNextFieldOffset =
llvm::RoundUpToAlignment(NextFieldOffsetInBytes,
getAlignmentAsLLVMStruct());
- assert(AlignedNextFieldOffset <= AlignedNonVirtualTypeSize &&
- "Size mismatch!");
+ if (AlignedNextFieldOffset > AlignedNonVirtualTypeSize)
+ return false; // Needs packing.
+
+ NonVirtualBaseFieldTypes = FieldTypes;
if (AlignedNonVirtualTypeSize == AlignedNextFieldOffset) {
// We don't need any padding.
- return;
+ return true;
}
uint64_t NumBytes = AlignedNonVirtualTypeSize - AlignedNextFieldOffset;
NonVirtualBaseFieldTypes.push_back(getByteArrayType(NumBytes));
+ return true;
}
bool CGRecordLayoutBuilder::LayoutFields(const RecordDecl *D) {
@@ -670,7 +671,10 @@ bool CGRecordLayoutBuilder::LayoutFields(const RecordDecl *D) {
if (RD) {
// We've laid out the non-virtual bases and the fields, now compute the
// non-virtual base field types.
- ComputeNonVirtualBaseType(RD);
+ if (!ComputeNonVirtualBaseType(RD)) {
+ assert(!Packed && "Could not layout even with a packed LLVM struct!");
+ return false;
+ }
// And lay out the virtual bases.
RD->getIndirectPrimaryBases(IndirectPrimaryBases);