diff --git a/gen/llvmhelpers.cpp b/gen/llvmhelpers.cpp index 83ed21341c..8472433603 100644 --- a/gen/llvmhelpers.cpp +++ b/gen/llvmhelpers.cpp @@ -906,27 +906,18 @@ void DtoVarDeclaration(VarDeclaration *vd) { // We also allocate a variable for zero-sized variables, because they are technically not `null` when loaded. // The x86_64 ABI "loads" zero-sized function arguments, and without an allocation ASan will report an error (Github #4816). - llvm::Value *allocainst; - bool isRealAlloca = false; LLType *lltype = DtoType(type); // void for noreturn if (lltype->isVoidTy()) { - allocainst = getNullPtr(); - } else if (type != vd->type) { - allocainst = DtoAlloca(type, vd->toChars()); - isRealAlloca = true; + irLocal->value = getNullPtr(); } else { - allocainst = DtoAlloca(vd, vd->toChars()); - isRealAlloca = true; - } - - irLocal->value = allocainst; + auto allocainst = type != vd->type ? DtoAlloca(type, vd->toChars()) + : DtoAlloca(vd, vd->toChars()); - if (!lltype->isVoidTy()) + irLocal->value = allocainst; gIR->DBuilder.EmitLocalVariable(allocainst, vd); - // Lifetime annotation is only valid on alloca. - if (isRealAlloca) { - // The lifetime of a stack variable starts from the point it is declared + // The lifetime of a stack variable starts from the + // point it is declared gIR->funcGen().localVariableLifetimeAnnotator.addLocalVariable( allocainst, DtoConstUlong(size(type))); } diff --git a/gen/variable_lifetime.cpp b/gen/variable_lifetime.cpp index cf21104de2..7bf575ba8c 100644 --- a/gen/variable_lifetime.cpp +++ b/gen/variable_lifetime.cpp @@ -37,7 +37,7 @@ LocalVariableLifetimeAnnotator::LocalVariableLifetimeAnnotator(IRState &irs) void LocalVariableLifetimeAnnotator::pushScope() { scopes.emplace_back(); } -void LocalVariableLifetimeAnnotator::addLocalVariable(llvm::Value *address, +void LocalVariableLifetimeAnnotator::addLocalVariable(llvm::AllocaInst *address, llvm::Value *size) { assert(address); assert(size); @@ -52,8 +52,13 @@ void LocalVariableLifetimeAnnotator::addLocalVariable(llvm::Value *address, scopes.back().variables.emplace_back(size, address); // Emit lifetime start - irs.CreateCallOrInvoke(getLLVMLifetimeStartFn(), {size, address}, "", - true /*nothrow*/); + irs.CreateCallOrInvoke(getLLVMLifetimeStartFn(), +#if LDC_LLVM_VER >= 2200 + {address}, +#else + {size, address}, +#endif + "", true /*nothrow*/); } // Emits end-of-lifetime annotation for all variables in current scope. @@ -62,13 +67,21 @@ void LocalVariableLifetimeAnnotator::popScope() { return; for (const auto &var : scopes.back().variables) { +#if LDC_LLVM_VER < 2200 auto size = var.first; +#endif auto address = var.second; assert(address); - irs.CreateCallOrInvoke(getLLVMLifetimeEndFn(), {size, address}, "", - true /*nothrow*/); + irs.CreateCallOrInvoke(getLLVMLifetimeEndFn(), +#if LDC_LLVM_VER >= 2200 + {address}, +#else + {size, address}, +#endif + "", true /*nothrow*/); + } scopes.pop_back(); } diff --git a/gen/variable_lifetime.h b/gen/variable_lifetime.h index f482030c9a..2dcf02090f 100644 --- a/gen/variable_lifetime.h +++ b/gen/variable_lifetime.h @@ -21,12 +21,13 @@ namespace llvm { class Function; class Type; class Value; +class AllocaInst; } struct IRState; struct LocalVariableLifetimeAnnotator { struct LocalVariableScope { - std::vector> variables; + std::vector> variables; }; /// Stack of scopes, each scope can have multiple variables. std::vector scopes; @@ -52,5 +53,5 @@ struct LocalVariableLifetimeAnnotator { void popScope(); /// Register a new local variable for lifetime annotation. - void addLocalVariable(llvm::Value *address, llvm::Value *size); + void addLocalVariable(llvm::AllocaInst *address, llvm::Value *size); }; diff --git a/runtime/druntime/src/ldc/intrinsics.di b/runtime/druntime/src/ldc/intrinsics.di index c0d88d8e2d..e0f17e1488 100644 --- a/runtime/druntime/src/ldc/intrinsics.di +++ b/runtime/druntime/src/ldc/intrinsics.di @@ -27,6 +27,7 @@ else version (LDC_LLVM_1801) enum LLVM_version = 1801; else version (LDC_LLVM_1901) enum LLVM_version = 1901; else version (LDC_LLVM_2001) enum LLVM_version = 2001; else version (LDC_LLVM_2100) enum LLVM_version = 2100; +else version (LDC_LLVM_2200) enum LLVM_version = 2200; else static assert(false, "LDC LLVM version not supported"); enum LLVM_atleast(int major) = (LLVM_version >= major * 100);