aboutsummaryrefslogtreecommitdiff
path: root/contrib/llvm-project/clang/lib/CodeGen/CGClass.cpp
diff options
context:
space:
mode:
authorDimitry Andric <dim@FreeBSD.org>2023-04-14 21:41:27 +0000
committerDimitry Andric <dim@FreeBSD.org>2023-06-22 18:20:56 +0000
commitbdd1243df58e60e85101c09001d9812a789b6bc4 (patch)
treea1ce621c7301dd47ba2ddc3b8eaa63b441389481 /contrib/llvm-project/clang/lib/CodeGen/CGClass.cpp
parent781624ca2d054430052c828ba8d2c2eaf2d733e7 (diff)
parente3b557809604d036af6e00c60f012c2025b59a5e (diff)
Diffstat (limited to 'contrib/llvm-project/clang/lib/CodeGen/CGClass.cpp')
-rw-r--r--contrib/llvm-project/clang/lib/CodeGen/CGClass.cpp94
1 files changed, 68 insertions, 26 deletions
diff --git a/contrib/llvm-project/clang/lib/CodeGen/CGClass.cpp b/contrib/llvm-project/clang/lib/CodeGen/CGClass.cpp
index c6696c4df775..0795ea598411 100644
--- a/contrib/llvm-project/clang/lib/CodeGen/CGClass.cpp
+++ b/contrib/llvm-project/clang/lib/CodeGen/CGClass.cpp
@@ -29,6 +29,7 @@
#include "llvm/IR/Intrinsics.h"
#include "llvm/IR/Metadata.h"
#include "llvm/Transforms/Utils/SanitizerStats.h"
+#include <optional>
using namespace clang;
using namespace CodeGen;
@@ -1505,7 +1506,7 @@ void CodeGenFunction::EmitDestructorBody(FunctionArgList &Args) {
}
// Fallthrough: act like we're in the base variant.
- LLVM_FALLTHROUGH;
+ [[fallthrough]];
case Dtor_Base:
assert(Body);
@@ -1649,23 +1650,58 @@ namespace {
}
};
- static void EmitSanitizerDtorCallback(CodeGenFunction &CGF, llvm::Value *Ptr,
- CharUnits::QuantityType PoisonSize) {
+ class DeclAsInlineDebugLocation {
+ CGDebugInfo *DI;
+ llvm::MDNode *InlinedAt;
+ std::optional<ApplyDebugLocation> Location;
+
+ public:
+ DeclAsInlineDebugLocation(CodeGenFunction &CGF, const NamedDecl &Decl)
+ : DI(CGF.getDebugInfo()) {
+ if (!DI)
+ return;
+ InlinedAt = DI->getInlinedAt();
+ DI->setInlinedAt(CGF.Builder.getCurrentDebugLocation());
+ Location.emplace(CGF, Decl.getLocation());
+ }
+
+ ~DeclAsInlineDebugLocation() {
+ if (!DI)
+ return;
+ Location.reset();
+ DI->setInlinedAt(InlinedAt);
+ }
+ };
+
+ static void EmitSanitizerDtorCallback(
+ CodeGenFunction &CGF, StringRef Name, llvm::Value *Ptr,
+ std::optional<CharUnits::QuantityType> PoisonSize = {}) {
CodeGenFunction::SanitizerScope SanScope(&CGF);
// Pass in void pointer and size of region as arguments to runtime
// function
- llvm::Value *Args[] = {CGF.Builder.CreateBitCast(Ptr, CGF.VoidPtrTy),
- llvm::ConstantInt::get(CGF.SizeTy, PoisonSize)};
+ SmallVector<llvm::Value *, 2> Args = {
+ CGF.Builder.CreateBitCast(Ptr, CGF.VoidPtrTy)};
+ SmallVector<llvm::Type *, 2> ArgTypes = {CGF.VoidPtrTy};
- llvm::Type *ArgTypes[] = {CGF.VoidPtrTy, CGF.SizeTy};
+ if (PoisonSize.has_value()) {
+ Args.emplace_back(llvm::ConstantInt::get(CGF.SizeTy, *PoisonSize));
+ ArgTypes.emplace_back(CGF.SizeTy);
+ }
llvm::FunctionType *FnType =
llvm::FunctionType::get(CGF.VoidTy, ArgTypes, false);
- llvm::FunctionCallee Fn =
- CGF.CGM.CreateRuntimeFunction(FnType, "__sanitizer_dtor_callback");
+ llvm::FunctionCallee Fn = CGF.CGM.CreateRuntimeFunction(FnType, Name);
+
CGF.EmitNounwindRuntimeCall(Fn, Args);
}
+ static void
+ EmitSanitizerDtorFieldsCallback(CodeGenFunction &CGF, llvm::Value *Ptr,
+ CharUnits::QuantityType PoisonSize) {
+ EmitSanitizerDtorCallback(CGF, "__sanitizer_dtor_callback_fields", Ptr,
+ PoisonSize);
+ }
+
/// Poison base class with a trivial destructor.
struct SanitizeDtorTrivialBase final : EHScopeStack::Cleanup {
const CXXRecordDecl *BaseClass;
@@ -1687,7 +1723,11 @@ namespace {
if (!BaseSize.isPositive())
return;
- EmitSanitizerDtorCallback(CGF, Addr.getPointer(), BaseSize.getQuantity());
+ // Use the base class declaration location as inline DebugLocation. All
+ // fields of the class are destroyed.
+ DeclAsInlineDebugLocation InlineHere(CGF, *BaseClass);
+ EmitSanitizerDtorFieldsCallback(CGF, Addr.getPointer(),
+ BaseSize.getQuantity());
// Prevent the current stack frame from disappearing from the stack trace.
CGF.CurFn->addFnAttr("disable-tail-calls", "true");
@@ -1735,7 +1775,10 @@ namespace {
if (!PoisonSize.isPositive())
return;
- EmitSanitizerDtorCallback(CGF, OffsetPtr, PoisonSize.getQuantity());
+ // Use the top field declaration location as inline DebugLocation.
+ DeclAsInlineDebugLocation InlineHere(
+ CGF, **std::next(Dtor->getParent()->field_begin(), StartIndex));
+ EmitSanitizerDtorFieldsCallback(CGF, OffsetPtr, PoisonSize.getQuantity());
// Prevent the current stack frame from disappearing from the stack trace.
CGF.CurFn->addFnAttr("disable-tail-calls", "true");
@@ -1752,15 +1795,13 @@ namespace {
void Emit(CodeGenFunction &CGF, Flags flags) override {
assert(Dtor->getParent()->isDynamicClass());
(void)Dtor;
- ASTContext &Context = CGF.getContext();
// Poison vtable and vtable ptr if they exist for this class.
llvm::Value *VTablePtr = CGF.LoadCXXThis();
- CharUnits::QuantityType PoisonSize =
- Context.toCharUnitsFromBits(CGF.PointerWidthInBits).getQuantity();
// Pass in void pointer and size of region as arguments to runtime
// function
- EmitSanitizerDtorCallback(CGF, VTablePtr, PoisonSize);
+ EmitSanitizerDtorCallback(CGF, "__sanitizer_dtor_callback_vptr",
+ VTablePtr);
}
};
@@ -1768,12 +1809,12 @@ namespace {
ASTContext &Context;
EHScopeStack &EHStack;
const CXXDestructorDecl *DD;
- llvm::Optional<unsigned> StartIndex;
+ std::optional<unsigned> StartIndex;
public:
SanitizeDtorCleanupBuilder(ASTContext &Context, EHScopeStack &EHStack,
const CXXDestructorDecl *DD)
- : Context(Context), EHStack(EHStack), DD(DD), StartIndex(llvm::None) {}
+ : Context(Context), EHStack(EHStack), DD(DD), StartIndex(std::nullopt) {}
void PushCleanupForField(const FieldDecl *Field) {
if (Field->isZeroSize(Context))
return;
@@ -1782,15 +1823,15 @@ namespace {
if (!StartIndex)
StartIndex = FieldIndex;
} else if (StartIndex) {
- EHStack.pushCleanup<SanitizeDtorFieldRange>(
- NormalAndEHCleanup, DD, StartIndex.value(), FieldIndex);
- StartIndex = None;
+ EHStack.pushCleanup<SanitizeDtorFieldRange>(NormalAndEHCleanup, DD,
+ *StartIndex, FieldIndex);
+ StartIndex = std::nullopt;
}
}
void End() {
if (StartIndex)
EHStack.pushCleanup<SanitizeDtorFieldRange>(NormalAndEHCleanup, DD,
- StartIndex.value(), -1);
+ *StartIndex, -1);
}
};
} // end anonymous namespace
@@ -2543,7 +2584,7 @@ void CodeGenFunction::InitializeVTablePointer(const VPtr &Vptr) {
llvm::FunctionType::get(CGM.Int32Ty, /*isVarArg=*/true)
->getPointerTo(ProgAS)
->getPointerTo(GlobalsAS);
- // vtable field is is derived from `this` pointer, therefore they should be in
+ // vtable field is derived from `this` pointer, therefore they should be in
// the same addr space. Note that this might not be LLVM address space 0.
VTableField = Builder.CreateElementBitCast(VTableField, VTablePtrTy);
VTableAddressPoint = Builder.CreateBitCast(VTableAddressPoint, VTablePtrTy);
@@ -2955,7 +2996,7 @@ void CodeGenFunction::EmitLambdaBlockInvokeBody() {
CallArgs.add(RValue::get(ThisPtr.getPointer()), ThisType);
// Add the rest of the parameters.
- for (auto param : BD->parameters())
+ for (auto *param : BD->parameters())
EmitDelegateCallArg(CallArgs, param, param->getBeginLoc());
assert(!Lambda->isGenericLambda() &&
@@ -2969,12 +3010,13 @@ void CodeGenFunction::EmitLambdaDelegatingInvokeBody(const CXXMethodDecl *MD) {
// Start building arguments for forwarding call
CallArgList CallArgs;
- QualType ThisType = getContext().getPointerType(getContext().getRecordType(Lambda));
- llvm::Value *ThisPtr = llvm::UndefValue::get(getTypes().ConvertType(ThisType));
- CallArgs.add(RValue::get(ThisPtr), ThisType);
+ QualType LambdaType = getContext().getRecordType(Lambda);
+ QualType ThisType = getContext().getPointerType(LambdaType);
+ Address ThisPtr = CreateMemTemp(LambdaType, "unused.capture");
+ CallArgs.add(RValue::get(ThisPtr.getPointer()), ThisType);
// Add the rest of the parameters.
- for (auto Param : MD->parameters())
+ for (auto *Param : MD->parameters())
EmitDelegateCallArg(CallArgs, Param, Param->getBeginLoc());
const CXXMethodDecl *CallOp = Lambda->getLambdaCallOperator();