[pkg-d-commits] [ldc] 40/74: Only non-typesafe variadics need to take LLVM varargs (#2127)
Matthias Klumpp
mak at moszumanska.debian.org
Thu Jul 13 20:54:17 UTC 2017
This is an automated email from the git hooks/post-receive script.
mak pushed a commit to annotated tag v1.3.0-beta2
in repository ldc.
commit c9112f3daf586a749e58893102a947b6e6090112
Author: David Nadlinger <code at klickverbot.at>
Date: Mon May 22 08:37:05 2017 +0100
Only non-typesafe variadics need to take LLVM varargs (#2127)
* gen/functions: Re-clang-format, minor style cleanup [nfc]
* Only non-typesafe variadics need to take LLVM varargs
GitHub: Fixes #2121.
---
gen/functions.cpp | 61 ++++++++++++++++++++++---------------------------
ir/irfuncty.h | 3 ---
tests/codegen/varargs.d | 7 ++++++
3 files changed, 34 insertions(+), 37 deletions(-)
diff --git a/gen/functions.cpp b/gen/functions.cpp
index 498455a..60dd18d 100644
--- a/gen/functions.cpp
+++ b/gen/functions.cpp
@@ -123,20 +123,14 @@ llvm::FunctionType *DtoFunctionType(Type *type, IrFuncTy &irFty, Type *thistype,
++nextLLArgIdx;
}
- // vararg functions are special too
- if (f->varargs) {
- if (f->linkage == LINKd) {
- // d style with hidden args
- // 2 (array) is handled by the frontend
- if (f->varargs == 1) {
- // _arguments
- newIrFty.arg_arguments =
- new IrFuncTyArg(Type::dtypeinfo->type->arrayOf(), false);
- ++nextLLArgIdx;
- }
- }
-
- newIrFty.c_vararg = true;
+ // Non-typesafe variadics (both C and D styles) are also variadics on the LLVM
+ // level.
+ const bool isLLVMVariadic = (f->varargs == 1);
+ if (isLLVMVariadic && f->linkage == LINKd) {
+ // Add extra `_arguments` parameter for D-style variadic functions.
+ newIrFty.arg_arguments =
+ new IrFuncTyArg(Type::dtypeinfo->type->arrayOf(), false);
+ ++nextLLArgIdx;
}
// if this _Dmain() doesn't have an argument, we force it to have one
@@ -226,7 +220,7 @@ llvm::FunctionType *DtoFunctionType(Type *type, IrFuncTy &irFty, Type *thistype,
}
irFty.funcType =
- LLFunctionType::get(irFty.ret->ltype, argtypes, irFty.c_vararg);
+ LLFunctionType::get(irFty.ret->ltype, argtypes, isLLVMVariadic);
IF_LOG Logger::cout() << "Final function type: " << *irFty.funcType << "\n";
@@ -518,15 +512,13 @@ void DtoDeclareFunction(FuncDeclaration *fdecl) {
vafunc = DtoDeclareVaFunction(fdecl);
}
- // calling convention
- LINK link = f->linkage;
- if (vafunc || DtoIsIntrinsic(fdecl)
- // DMD treats _Dmain as having C calling convention and this has been
- // hardcoded into druntime, even if the frontend type has D linkage.
- // See Bugzilla issue 9028.
- || fdecl->isMain()) {
- link = LINKc;
- }
+ // Calling convention.
+ //
+ // DMD treats _Dmain as having C calling convention and this has been
+ // hardcoded into druntime, even if the frontend type has D linkage (Bugzilla
+ // issue 9028).
+ const bool forceC = vafunc || DtoIsIntrinsic(fdecl) || fdecl->isMain();
+ const auto link = forceC ? LINKc : f->linkage;
// mangled name
std::string mangledName = getMangledName(fdecl, link);
@@ -540,8 +532,9 @@ void DtoDeclareFunction(FuncDeclaration *fdecl) {
func = LLFunction::Create(functype, llvm::GlobalValue::ExternalLinkage,
mangledName, &gIR->module);
} else if (func->getFunctionType() != functype) {
- error(fdecl->loc, "Function type does not match previously declared "
- "function with the same mangled name: %s",
+ error(fdecl->loc,
+ "Function type does not match previously declared "
+ "function with the same mangled name: %s",
mangleExact(fdecl));
fatal();
}
@@ -793,8 +786,7 @@ void DtoDefineFunction(FuncDeclaration *fd, bool linkageAvailableExternally) {
llvm::Function *func = getIrFunc(fd)->getLLVMFunc();
assert(nullptr != func);
if (!linkageAvailableExternally &&
- (func->getLinkage() ==
- llvm::GlobalValue::AvailableExternallyLinkage)) {
+ (func->getLinkage() == llvm::GlobalValue::AvailableExternallyLinkage)) {
// Fix linkage
const auto lwc = lowerFuncLinkage(fd);
setLinkage(lwc, func);
@@ -817,8 +809,9 @@ void DtoDefineFunction(FuncDeclaration *fd, bool linkageAvailableExternally) {
// This function failed semantic3() with errors but the errors were gagged.
// In contrast to DMD we immediately bail out here, since other parts of
// the codegen expect irFunc to be set for defined functions.
- error(fd->loc, "Internal Compiler Error: function not fully analyzed; "
- "previous unreported errors compiling %s?",
+ error(fd->loc,
+ "Internal Compiler Error: function not fully analyzed; "
+ "previous unreported errors compiling %s?",
fd->toPrettyChars());
fatal();
}
@@ -878,8 +871,9 @@ void DtoDefineFunction(FuncDeclaration *fd, bool linkageAvailableExternally) {
assert(fd->ident != Id::empty);
if (fd->semanticRun != PASSsemantic3done) {
- error(fd->loc, "Internal Compiler Error: function not fully analyzed; "
- "previous unreported errors compiling %s?",
+ error(fd->loc,
+ "Internal Compiler Error: function not fully analyzed; "
+ "previous unreported errors compiling %s?",
fd->toPrettyChars());
fatal();
}
@@ -1063,8 +1057,7 @@ void DtoDefineFunction(FuncDeclaration *fd, bool linkageAvailableExternally) {
gIR->scopebb());
// copy _arguments to a memory location
- irFunc->_arguments =
- DtoAllocaDump(irFunc->_arguments, 0, "_arguments_mem");
+ irFunc->_arguments = DtoAllocaDump(irFunc->_arguments, 0, "_arguments_mem");
// Push cleanup block that calls va_end to match the va_start call.
{
diff --git a/ir/irfuncty.h b/ir/irfuncty.h
index 24a4636..26bcbc9 100644
--- a/ir/irfuncty.h
+++ b/ir/irfuncty.h
@@ -101,9 +101,6 @@ struct IrFuncTy {
using ArgList = std::vector<IrFuncTyArg *>;
ArgList args;
- // C varargs
- bool c_vararg = false;
-
// range of normal parameters to reverse
bool reverseParams = false;
diff --git a/tests/codegen/varargs.d b/tests/codegen/varargs.d
new file mode 100644
index 0000000..f305b89
--- /dev/null
+++ b/tests/codegen/varargs.d
@@ -0,0 +1,7 @@
+// RUN: %ldc -output-ll -of=%t.ll %s && FileCheck %s < %t.ll
+
+// Make sure typesafe variadics are not lowered to LLVM variadics.
+void typesafe(size_t[2] a...) {}
+// CHECK: define{{.*}}typesafe
+// CHECK-NOT: ...
+// CHECK-SAME: {
--
Alioth's /usr/local/bin/git-commit-notice on /srv/git.debian.org/git/pkg-d/ldc.git
More information about the pkg-d-commits
mailing list