From a72a12eef6133dacfa6d0a93ca8de63a71e92da7 Mon Sep 17 00:00:00 2001
From: Jonas Maebe <jonas@freepascal.org>
Date: Tue, 1 Jan 2019 16:55:41 +0000
Subject: [PATCH]   * don't emit 0-sized parameters for LLVM: clang doesn't
 either, and some     LLVM backends (like the AArch64 one) trigger internal
 errors when     encountering them

git-svn-id: trunk@40736 -
---
 compiler/llvm/hlcgllvm.pas |  3 +++
 compiler/llvm/llvmdef.pas  | 14 ++++++++++++--
 compiler/parabase.pas      | 22 +++++++++++++++++++++-
 3 files changed, 36 insertions(+), 3 deletions(-)

diff --git a/compiler/llvm/hlcgllvm.pas b/compiler/llvm/hlcgllvm.pas
index 961c931732..12ef427151 100644
--- a/compiler/llvm/hlcgllvm.pas
+++ b/compiler/llvm/hlcgllvm.pas
@@ -434,6 +434,9 @@ implementation
     callparas:=tfplist.Create;
     for i:=0 to high(paras) do
       begin
+        { skip parameters without data }
+        if paras[i]^.isempty then
+          continue;
         paraloc:=paras[i]^.location;
         while assigned(paraloc) do
           begin
diff --git a/compiler/llvm/llvmdef.pas b/compiler/llvm/llvmdef.pas
index a93ce99eab..15b5cbab6f 100644
--- a/compiler/llvm/llvmdef.pas
+++ b/compiler/llvm/llvmdef.pas
@@ -682,9 +682,19 @@ implementation
             exit
           end;
         if withparaname then
-          paraloc:=hp.paraloc[calleeside].location
+          begin
+            { don't add parameters that don't take up registers or stack space;
+              clang doesn't either and some LLVM backends don't support them }
+            if hp.paraloc[calleeside].isempty then
+              exit;
+            paraloc:=hp.paraloc[calleeside].location
+          end
         else
-          paraloc:=hp.paraloc[callerside].location;
+          begin
+            if hp.paraloc[callerside].isempty then
+              exit;
+            paraloc:=hp.paraloc[callerside].location;
+          end;
         repeat
           usedef:=paraloc^.def;
           llvmextractvalueextinfo(hp.vardef,usedef,signext);
diff --git a/compiler/parabase.pas b/compiler/parabase.pas
index 7a205be0f7..12d59797a6 100644
--- a/compiler/parabase.pas
+++ b/compiler/parabase.pas
@@ -118,6 +118,7 @@ unit parabase;
           function    add_location:pcgparalocation;
           procedure   get_location(var newloc:tlocation);
           function    locations_count:integer;
+          function    isempty: boolean; { no data, and not varargs para }
 
           procedure   buildderef;
           procedure   deref;
@@ -161,7 +162,7 @@ implementation
 
     uses
       systems,verbose,
-      symsym;
+      symsym,defutil;
 
 
 {****************************************************************************
@@ -317,6 +318,25 @@ implementation
       end;
 
 
+    function TCGPara.isempty: boolean;
+      var
+        hlocation: pcgparalocation;
+      begin
+        { can happen if e.g. [] is passed to a cdecl varargs para }
+        if not assigned(def) then
+          exit(true);
+        if is_array_of_const(def) then
+          exit(false);
+        hlocation:=location;
+        while assigned(hlocation) do
+          begin
+            if hlocation^.Loc<>LOC_VOID then
+              exit(false);
+            hlocation:=hlocation^.next;
+          end;
+        result:=true;
+      end;
+
     procedure TCGPara.buildderef;
       begin
         defderef.build(def);