diff options
Diffstat (limited to 'contrib/llvm-project/clang/lib/CodeGen/CGClass.cpp')
-rw-r--r-- | contrib/llvm-project/clang/lib/CodeGen/CGClass.cpp | 103 |
1 files changed, 55 insertions, 48 deletions
diff --git a/contrib/llvm-project/clang/lib/CodeGen/CGClass.cpp b/contrib/llvm-project/clang/lib/CodeGen/CGClass.cpp index 4d143e3e1bdf..ba221dbbc83b 100644 --- a/contrib/llvm-project/clang/lib/CodeGen/CGClass.cpp +++ b/contrib/llvm-project/clang/lib/CodeGen/CGClass.cpp @@ -18,6 +18,7 @@ #include "TargetInfo.h" #include "clang/AST/Attr.h" #include "clang/AST/CXXInheritance.h" +#include "clang/AST/CharUnits.h" #include "clang/AST/DeclTemplate.h" #include "clang/AST/EvaluatedExprVisitor.h" #include "clang/AST/RecordLayout.h" @@ -798,9 +799,8 @@ void CodeGenFunction::EmitAsanPrologueOrEpilogue(bool Prologue) { size_t NumFields = 0; for (const auto *Field : ClassDecl->fields()) { const FieldDecl *D = Field; - std::pair<CharUnits, CharUnits> FieldInfo = - Context.getTypeInfoInChars(D->getType()); - CharUnits FieldSize = FieldInfo.first; + auto FieldInfo = Context.getTypeInfoInChars(D->getType()); + CharUnits FieldSize = FieldInfo.Width; assert(NumFields < SSV.size()); SSV[NumFields].Size = D->isBitField() ? 0 : FieldSize.getQuantity(); NumFields++; @@ -947,7 +947,7 @@ namespace { LastField->isBitField() ? LastField->getBitWidthValue(Ctx) : Ctx.toBits( - Ctx.getTypeInfoDataSizeInChars(LastField->getType()).first); + Ctx.getTypeInfoDataSizeInChars(LastField->getType()).Width); uint64_t MemcpySizeBits = LastFieldOffset + LastFieldSize - FirstByteOffset + Ctx.getCharWidth() - 1; CharUnits MemcpySize = Ctx.toCharUnitsFromBits(MemcpySizeBits); @@ -1694,28 +1694,33 @@ namespace { // Construct pointer to region to begin poisoning, and calculate poison // size, so that only members declared in this class are poisoned. ASTContext &Context = CGF.getContext(); - unsigned fieldIndex = 0; - int startIndex = -1; - // RecordDecl::field_iterator Field; - for (const FieldDecl *Field : Dtor->getParent()->fields()) { - // Poison field if it is trivial - if (FieldHasTrivialDestructorBody(Context, Field)) { - // Start sanitizing at this field - if (startIndex < 0) - startIndex = fieldIndex; - - // Currently on the last field, and it must be poisoned with the - // current block. - if (fieldIndex == Layout.getFieldCount() - 1) { - PoisonMembers(CGF, startIndex, Layout.getFieldCount()); - } - } else if (startIndex >= 0) { - // No longer within a block of memory to poison, so poison the block - PoisonMembers(CGF, startIndex, fieldIndex); - // Re-set the start index - startIndex = -1; - } - fieldIndex += 1; + + const RecordDecl *Decl = Dtor->getParent(); + auto Fields = Decl->fields(); + auto IsTrivial = [&](const FieldDecl *F) { + return FieldHasTrivialDestructorBody(Context, F); + }; + + auto IsZeroSize = [&](const FieldDecl *F) { + return F->isZeroSize(Context); + }; + + // Poison blocks of fields with trivial destructors making sure that block + // begin and end do not point to zero-sized fields. They don't have + // correct offsets so can't be used to calculate poisoning range. + for (auto It = Fields.begin(); It != Fields.end();) { + It = std::find_if(It, Fields.end(), [&](const FieldDecl *F) { + return IsTrivial(F) && !IsZeroSize(F); + }); + if (It == Fields.end()) + break; + auto Start = It++; + It = std::find_if(It, Fields.end(), [&](const FieldDecl *F) { + return !IsTrivial(F) && !IsZeroSize(F); + }); + + PoisonMembers(CGF, (*Start)->getFieldIndex(), + It == Fields.end() ? -1 : (*It)->getFieldIndex()); } } @@ -1725,37 +1730,35 @@ namespace { /// \param layoutEndOffset index of the ASTRecordLayout field to /// end poisoning (exclusive) void PoisonMembers(CodeGenFunction &CGF, unsigned layoutStartOffset, - unsigned layoutEndOffset) { + unsigned layoutEndOffset) { ASTContext &Context = CGF.getContext(); const ASTRecordLayout &Layout = Context.getASTRecordLayout(Dtor->getParent()); - llvm::ConstantInt *OffsetSizePtr = llvm::ConstantInt::get( - CGF.SizeTy, - Context.toCharUnitsFromBits(Layout.getFieldOffset(layoutStartOffset)) - .getQuantity()); + // It's a first trivia field so it should be at the begining of char, + // still round up start offset just in case. + CharUnits PoisonStart = + Context.toCharUnitsFromBits(Layout.getFieldOffset(layoutStartOffset) + + Context.getCharWidth() - 1); + llvm::ConstantInt *OffsetSizePtr = + llvm::ConstantInt::get(CGF.SizeTy, PoisonStart.getQuantity()); llvm::Value *OffsetPtr = CGF.Builder.CreateGEP( CGF.Builder.CreateBitCast(CGF.LoadCXXThis(), CGF.Int8PtrTy), OffsetSizePtr); - CharUnits::QuantityType PoisonSize; + CharUnits PoisonEnd; if (layoutEndOffset >= Layout.getFieldCount()) { - PoisonSize = Layout.getNonVirtualSize().getQuantity() - - Context.toCharUnitsFromBits( - Layout.getFieldOffset(layoutStartOffset)) - .getQuantity(); + PoisonEnd = Layout.getNonVirtualSize(); } else { - PoisonSize = Context.toCharUnitsFromBits( - Layout.getFieldOffset(layoutEndOffset) - - Layout.getFieldOffset(layoutStartOffset)) - .getQuantity(); + PoisonEnd = + Context.toCharUnitsFromBits(Layout.getFieldOffset(layoutEndOffset)); } - - if (PoisonSize == 0) + CharUnits PoisonSize = PoisonEnd - PoisonStart; + if (!PoisonSize.isPositive()) return; - EmitSanitizerDtorCallback(CGF, OffsetPtr, PoisonSize); + EmitSanitizerDtorCallback(CGF, OffsetPtr, PoisonSize.getQuantity()); } }; @@ -2509,12 +2512,16 @@ void CodeGenFunction::InitializeVTablePointer(const VPtr &Vptr) { // Finally, store the address point. Use the same LLVM types as the field to // support optimization. + unsigned GlobalsAS = CGM.getDataLayout().getDefaultGlobalsAddressSpace(); + unsigned ProgAS = CGM.getDataLayout().getProgramAddressSpace(); llvm::Type *VTablePtrTy = llvm::FunctionType::get(CGM.Int32Ty, /*isVarArg=*/true) - ->getPointerTo() - ->getPointerTo(); - VTableField = Builder.CreateBitCast(VTableField, VTablePtrTy->getPointerTo()); - VTableAddressPoint = Builder.CreateBitCast(VTableAddressPoint, VTablePtrTy); + ->getPointerTo(ProgAS) + ->getPointerTo(GlobalsAS); + VTableField = Builder.CreatePointerBitCastOrAddrSpaceCast( + VTableField, VTablePtrTy->getPointerTo(GlobalsAS)); + VTableAddressPoint = Builder.CreatePointerBitCastOrAddrSpaceCast( + VTableAddressPoint, VTablePtrTy); llvm::StoreInst *Store = Builder.CreateStore(VTableAddressPoint, VTableField); TBAAAccessInfo TBAAInfo = CGM.getTBAAVTablePtrAccessInfo(VTablePtrTy); @@ -2796,7 +2803,7 @@ void CodeGenFunction::EmitVTablePtrCheck(const CXXRecordDecl *RD, } if (CGM.getCodeGenOpts().SanitizeTrap.has(M)) { - EmitTrapCheck(TypeTest); + EmitTrapCheck(TypeTest, SanitizerHandler::CFICheckFail); return; } |