diff options
Diffstat (limited to 'clang/lib/CodeGen/CGRecordLayoutBuilder.cpp')
-rw-r--r-- | clang/lib/CodeGen/CGRecordLayoutBuilder.cpp | 25 |
1 files changed, 14 insertions, 11 deletions
diff --git a/clang/lib/CodeGen/CGRecordLayoutBuilder.cpp b/clang/lib/CodeGen/CGRecordLayoutBuilder.cpp index 4de64a32f2ac..4e5d1d3f16f6 100644 --- a/clang/lib/CodeGen/CGRecordLayoutBuilder.cpp +++ b/clang/lib/CodeGen/CGRecordLayoutBuilder.cpp @@ -385,7 +385,8 @@ CGRecordLowering::accumulateBitFields(RecordDecl::field_iterator Field, Run = FieldEnd; continue; } - llvm::Type *Type = Types.ConvertTypeForMem(Field->getType()); + llvm::Type *Type = + Types.ConvertTypeForMem(Field->getType(), /*ForBitFields=*/true); // If we don't have a run yet, or don't live within the previous run's // allocated storage then we allocate some storage and start a new run. if (Run == FieldEnd || BitOffset >= Tail) { @@ -405,15 +406,17 @@ CGRecordLowering::accumulateBitFields(RecordDecl::field_iterator Field, return; } - // Check if OffsetInRecord is better as a single field run. When OffsetInRecord - // has legal integer width, and its bitfield offset is naturally aligned, it - // is better to make the bitfield a separate storage component so as it can be - // accessed directly with lower cost. + // Check if OffsetInRecord (the size in bits of the current run) is better + // as a single field run. When OffsetInRecord has legal integer width, and + // its bitfield offset is naturally aligned, it is better to make the + // bitfield a separate storage component so as it can be accessed directly + // with lower cost. auto IsBetterAsSingleFieldRun = [&](uint64_t OffsetInRecord, uint64_t StartBitOffset) { if (!Types.getCodeGenOpts().FineGrainedBitfieldAccesses) return false; - if (!DataLayout.isLegalInteger(OffsetInRecord)) + if (OffsetInRecord < 8 || !llvm::isPowerOf2_64(OffsetInRecord) || + !DataLayout.fitsInLegalInteger(OffsetInRecord)) return false; // Make sure StartBitOffset is natually aligned if it is treated as an // IType integer. @@ -729,8 +732,8 @@ CGBitFieldInfo CGBitFieldInfo::MakeInfo(CodeGenTypes &Types, return CGBitFieldInfo(Offset, Size, IsSigned, StorageSize, StorageOffset); } -CGRecordLayout *CodeGenTypes::ComputeRecordLayout(const RecordDecl *D, - llvm::StructType *Ty) { +std::unique_ptr<CGRecordLayout> +CodeGenTypes::ComputeRecordLayout(const RecordDecl *D, llvm::StructType *Ty) { CGRecordLowering Builder(*this, D, /*Packed=*/false); Builder.lower(/*NonVirtualBaseType=*/false); @@ -757,9 +760,9 @@ CGRecordLayout *CodeGenTypes::ComputeRecordLayout(const RecordDecl *D, // but we may need to recursively layout D while laying D out as a base type. Ty->setBody(Builder.FieldTypes, Builder.Packed); - CGRecordLayout *RL = - new CGRecordLayout(Ty, BaseTy, Builder.IsZeroInitializable, - Builder.IsZeroInitializableAsBase); + auto RL = std::make_unique<CGRecordLayout>( + Ty, BaseTy, (bool)Builder.IsZeroInitializable, + (bool)Builder.IsZeroInitializableAsBase); RL->NonVirtualBases.swap(Builder.NonVirtualBases); RL->CompleteObjectVirtualBases.swap(Builder.VirtualBases); |