[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