diff options
author | Devang Patel <dpatel@apple.com> | 2008-05-06 19:57:59 +0000 |
---|---|---|
committer | Devang Patel <dpatel@apple.com> | 2008-05-06 19:57:59 +0000 |
commit | 243d5cd2833cd124ffda807189f17eb8ca3442e7 (patch) | |
tree | 4f8b6098ce26d8bc8c91185194a6a931dd01e965 /clang/lib | |
parent | 6ea927b1d7624bed517daf3bcd7a018dbf91927a (diff) | |
download | bcm5719-llvm-243d5cd2833cd124ffda807189f17eb8ca3442e7.tar.gz bcm5719-llvm-243d5cd2833cd124ffda807189f17eb8ca3442e7.zip |
Fix PR2101 - Codegen crash during bitfield initialization.
llvm-svn: 50769
Diffstat (limited to 'clang/lib')
-rw-r--r-- | clang/lib/CodeGen/CodeGenTypes.cpp | 32 |
1 files changed, 29 insertions, 3 deletions
diff --git a/clang/lib/CodeGen/CodeGenTypes.cpp b/clang/lib/CodeGen/CodeGenTypes.cpp index a7f6670cb6e..751cd3a0777 100644 --- a/clang/lib/CodeGen/CodeGenTypes.cpp +++ b/clang/lib/CodeGen/CodeGenTypes.cpp @@ -521,7 +521,28 @@ void RecordOrganizer::layoutStructFields(const ASTRecordLayout &RL) { unsigned StructAlign = RL.getAlignment(); if (llvmSize % StructAlign) { unsigned StructPadding = StructAlign - (llvmSize % StructAlign); - addPaddingFields(llvmSize + StructPadding); + bool needStructPadding = true; + if (!LLVMFields.empty()) { + const llvm::Type *LastFieldType = LLVMFields.back(); + const llvm::Type *LastFieldDeclType = + CGT.ConvertTypeRecursive(FieldDecls.back()->getType()); + if (LastFieldType != LastFieldDeclType) { + unsigned LastFieldTypeSize = + CGT.getTargetData().getABITypeSizeInBits(LastFieldType); + unsigned LastFieldDeclTypeSize = + CGT.getTargetData().getABITypeSizeInBits(LastFieldDeclType); + if (LastFieldDeclTypeSize > LastFieldTypeSize + && StructPadding == (LastFieldDeclTypeSize - LastFieldTypeSize)) { + // Replace last LLVMField with a LastFieldDeclType field will + // to avoid extra padding fields. + LLVMFields.pop_back(); + LLVMFields.push_back(LastFieldDeclType); + needStructPadding = false; + } + } + } + if (needStructPadding) + addPaddingFields(llvmSize + StructPadding); } STy = llvm::StructType::get(LLVMFields); @@ -533,8 +554,13 @@ void RecordOrganizer::addPaddingFields(unsigned WaterMark) { assert(WaterMark >= llvmSize && "Invalid padding Field"); unsigned RequiredBits = WaterMark - llvmSize; unsigned RequiredBytes = (RequiredBits + 7) / 8; - for (unsigned i = 0; i != RequiredBytes; ++i) - addLLVMField(llvm::Type::Int8Ty, true); + if (RequiredBytes == 1) + // This is a bitfield that is using few bits from this byte. + // It is not a padding field. + addLLVMField(llvm::Type::Int8Ty, false); + else + for (unsigned i = 0; i != RequiredBytes; ++i) + addLLVMField(llvm::Type::Int8Ty, true); } /// addLLVMField - Add llvm struct field that corresponds to llvm type Ty. |