Bug 108763 - va_arg usage in D doesn't compile
Summary: va_arg usage in D doesn't compile
Status: RESOLVED WONTFIX
Alias: None
Product: gcc
Classification: Unclassified
Component: d (show other bugs)
Version: 12.2.0
: P3 normal
Target Milestone: ---
Assignee: Iain Buclaw
URL:
Keywords:
Depends on:
Blocks:
 
Reported: 2023-02-11 23:28 UTC by Steven Schveighoffer
Modified: 2023-03-03 19:44 UTC (History)
1 user (show)

See Also:
Host:
Target:
Build:
Known to work:
Known to fail:
Last reconfirmed:


Attachments

Note You need to log in before you can comment on or make changes to this bug.
Description Steven Schveighoffer 2023-02-11 23:28:17 UTC
Compiling a valid D module that uses varargs does not compile. The following is the source of `test.d`:

```d
import core.vararg;
void foo(...)
{
    ubyte[128] buf;
    foreach(ti; _arguments)
    {
        va_arg(_argptr, ti, buf.ptr);
    }
}
```

This is confirmed a valid module using both other D compilers, dmd and ldc.

The output information of -v is:

COLLECT_GCC=/opt/compiler-explorer/gcc-12.2.0/bin/gdc
Target: x86_64-linux-gnu
Configured with: ../gcc-12.2.0/configure --prefix=/opt/compiler-explorer/gcc-build/staging --build=x86_64-linux-gnu --host=x86_64-linux-gnu --target=x86_64-linux-gnu --disable-bootstrap --enable-multiarch --with-abi=m64 --with-multilib-list=m32,m64,mx32 --enable-multilib --enable-clocale=gnu --enable-languages=c,c++,fortran,ada,objc,obj-c++,go,d --enable-ld=yes --enable-gold=yes --enable-libstdcxx-debug --enable-libstdcxx-time=yes --enable-linker-build-id --enable-lto --enable-plugins --enable-threads=posix --with-pkgversion=Compiler-Explorer-Build-gcc--binutils-2.38 --enable-libstdcxx-backtrace=yes
Thread model: posix
Supported LTO compression algorithms: zlib
gcc version 12.2.0 (Compiler-Explorer-Build-gcc--binutils-2.38) 
COLLECT_GCC_OPTIONS='-fdiagnostics-color=always' '-g' '-o' '/app/output.s' '-masm=intel' '-S' '-v' '-shared-libgcc' '-mtune=generic' '-march=x86-64' '-dumpdir' '/app/'
 /opt/compiler-explorer/gcc-12.2.0/bin/../libexec/gcc/x86_64-linux-gnu/12.2.0/d21 <source> -quiet -dumpdir /app/ -dumpbase output.d -dumpbase-ext .d -masm=intel -mtune=generic -march=x86-64 -g -version -fdiagnostics-color=always -o /app/output.s -imultiarch x86_64-linux-gnu -iprefix /opt/compiler-explorer/gcc-12.2.0/bin/../lib/gcc/x86_64-linux-gnu/12.2.0/ -v
GNU D (Compiler-Explorer-Build-gcc--binutils-2.38) version 12.2.0 (x86_64-linux-gnu)
	compiled by GNU C version 9.4.0, GMP version 6.2.1, MPFR version 4.1.0, MPC version 1.2.1, isl version isl-0.24-GMP

GGC heuristics: --param ggc-min-expand=100 --param ggc-min-heapsize=131072
GNU D (Compiler-Explorer-Build-gcc--binutils-2.38) version 12.2.0 (x86_64-linux-gnu)
	compiled by GNU C version 9.4.0, GMP version 6.2.1, MPFR version 4.1.0, MPC version 1.2.1, isl version isl-0.24-GMP

GGC heuristics: --param ggc-min-expand=100 --param ggc-min-heapsize=131072
binary    /opt/compiler-explorer/gcc-12.2.0/bin/../libexec/gcc/x86_64-linux-gnu/12.2.0/d21
version   v2.100.1

predefs   GNU D_Version2 LittleEndian GNU_DWARF2_Exceptions GNU_StackGrowsDown GNU_InlineAsm D_LP64 assert D_PreConditions D_PostConditions D_Invariants D_ModuleInfo D_Exceptions D_TypeInfo all X86_64 D_HardFloat Posix linux CRuntime_Glibc CppRuntime_Gcc

As far as the command line, it would be:

gdc -o test test.d

The compiler output is:


<source>:7:11: error: none of the overloads of template 'core.stdc.stdarg.va_arg' are callable using argument types '!()(__va_list_tag[1], TypeInfo, ubyte*)'
    7 |     va_arg(_argptr, ti, buf.ptr);
      |           ^
/opt/compiler-explorer/gcc-12.2.0/lib/gcc/x86_64-linux-gnu/12.2.0/include/d/core/stdc/stdarg.d:172:7: note: Candidates are: 'va_arg(T)(ref va_list ap)'
  172 |     T va_arg(T)(ref va_list ap); // intrinsic
      |       ^
/opt/compiler-explorer/gcc-12.2.0/lib/gcc/x86_64-linux-gnu/12.2.0/include/d/core/stdc/stdarg.d:271:10: note:                 'va_arg(T)(ref va_list ap, ref T parmn)'
  271 |     void va_arg(T)(ref va_list ap, ref T parmn); // intrinsic
      |          ^

The expected function should be implemented as identified in the D library here: https://dlang.org/phobos/core_vararg.html#.va_arg
Comment 1 Andrew Pinski 2023-02-11 23:35:08 UTC
https://github.com/dlang/dmd/blob/master/druntime/src/core/vararg.d

version (GNU) { /* TypeInfo-based va_arg overload unsupported */ }

...
Comment 2 Steven Schveighoffer 2023-02-11 23:45:05 UTC
(In reply to Andrew Pinski from comment #1)
> https://github.com/dlang/dmd/blob/master/druntime/src/core/vararg.d
> 
> version (GNU) { /* TypeInfo-based va_arg overload unsupported */ }
> 
> ...

oof. This is somewhat of a problem, because the undead package (https://github.com/dlang/undead) uses it inside doformat, and this means that anyone wanting to use those packages cannot do so with GDC.

The undead package is a collection of modules that are no longer in mainline D, and so the point is to be able to use older modules with older code.

If this is deemed to be unsupportable, then people will just have to live with not being able to use GDC for programs using that package. I also can look at possibly disabling the offending code for GDC users, and then people can use the other parts of undead (e.g. undead.xml)

Thanks for pointing that out!
Comment 3 Andrew Pinski 2023-02-11 23:48:23 UTC
Reading the code on I think it would need some huge work to get it working on GDC really. Especially on aarch64. Mainly because the way var_args is defined is something which is very much target specific. and GCC implements var_args internally to optimize some cases sometimes.
Comment 4 Steven Schveighoffer 2023-02-11 23:52:13 UTC
I don't think it's worth a major effort. Nobody is using this kind of varargs in D these days, it's mostly for legacy code (newer code will use template varargs).

When I filed this bug, it was because I thought there was just a missing piece in the library, I did not expect it to be a conscious decision to omit this feature.

I'm OK with closing this if the effort is great. Don't spend time on it, projects can avoid doformat pretty easily. I was hoping for a quick fix!
Comment 5 Iain Buclaw 2023-02-12 08:07:15 UTC
I abandoned the idea of supporting RTTI-based variadics years ago. Even the current reference implementation only supports a subset of the x86_64 ABI in its current incarnation as far as I recall.

I had considered maybe libffi might allow us to do this, but I didn't see anything that would allow me to say "retrieve the next variadic argument of size SIZE and mode MODE". But I could not see anything that looked exactly as that, even though as I understand there is limited support for constructing a variadic call to a C function.
Comment 6 Iain Buclaw 2023-02-12 08:20:33 UTC
I'll add it as a note to the deviations page.

https://gcc.gnu.org/onlinedocs/gdc/Missing-Features.html#Missing-Features

I'd actually forgotten about this.
Comment 7 GCC Commits 2023-03-03 19:42:59 UTC
The master branch has been updated by Iain Buclaw <ibuclaw@gcc.gnu.org>:

https://gcc.gnu.org/g:1f83aee5864129c4147a95c1a4e35d37c7eb7e59

commit r13-6463-g1f83aee5864129c4147a95c1a4e35d37c7eb7e59
Author: Iain Buclaw <ibuclaw@gdcproject.org>
Date:   Fri Mar 3 20:39:59 2023 +0100

    d: Document that TypeInfo-based va_arg is not implemented
    
            PR d/108763
    
    gcc/d/ChangeLog:
    
            * implement-d.texi (Missing Features): Document that TypeInfo-based
            va_arg is not implemented.
Comment 8 Iain Buclaw 2023-03-03 19:44:17 UTC
Added note on the missing features page.