aboutsummaryrefslogtreecommitdiff
path: root/contrib/llvm-project/clang/lib/CodeGen/CGClass.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'contrib/llvm-project/clang/lib/CodeGen/CGClass.cpp')
-rw-r--r--contrib/llvm-project/clang/lib/CodeGen/CGClass.cpp103
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;
}