October 14
https://issues.dlang.org/show_bug.cgi?id=24814

          Issue ID: 24814
           Summary: betterC not able to use core.stdc.stdarg
           Product: D
           Version: D2
          Hardware: All
                OS: Linux
            Status: NEW
          Severity: major
          Priority: P1
         Component: dmd
          Assignee: nobody@puremagic.com
          Reporter: dfawcus+dlang@employees.org

Created attachment 1920
  --> https://issues.dlang.org/attachment.cgi?id=1920&action=edit
Patch to fix the library file

Trying to use va_end() or va_copy() from a betterC program fails due to missing
symbols.  See this forum thread:
https://forum.dlang.org/post/veackr$2n3c$1@digitalmars.com

This was with 'DMD64 D Compiler v2.109.1'.  These stdarg issues do not arise with GDC or LDC as they make use of compiler intrinsics, not actual functions with bodies.

stdarg1.d:
```d
import core.stdc.stdarg;

pragma(printf)
public extern(C) int wrap_printf(scope const char* f, ...) {
        import core.stdc.stdio;

        va_list ap;

        va_start(ap, f);
        auto rc = vprintf(f, ap);
        va_end(ap);

        return rc;
}

extern(C) void main() {
        wrap_printf("Foo\n");
}
```

```
$ dmd -betterC stdarg1.d
/usr/bin/ld: stdarg1.o: in function `wrap_printf':
stdarg1.d:(.text.wrap_printf[wrap_printf]+0xce): undefined reference to
`_D4core4stdc6stdarg6va_endFNbNiPSQBf8internal6vararg8sysv_x6413__va_list_tagZv'
collect2: error: ld returned 1 exit status
Error: undefined reference to `nothrow @nogc void
core.stdc.stdarg.va_end(core.internal.vararg.sysv_x64.__va_list_tag*)`
       referenced from `wrap_printf`
       perhaps `.d` files need to be added on the command line, or use `-i` to
compile imports
Error: linker exited with status 1
       cc stdarg1.o -o stdarg1 -m64 -Xlinker --export-dynamic
-L/usr/lib/x86_64-linux-gnu -lpthread -lm -lrt -ldl
```

A similar issue arises if one tries to use va_copy().

The thread mentions a couple of workarounds, applying these makes things work.
However I attach a patch which makes va_end() and va_copy() work (for -m32),
but only va_end() for -m64.

That is because va_copy() on x64 requires the use of alloca(), and that is also
not satisfied when compiling with -betterC, however that can be a different
ticket.

The va_copy issue can be demonstrated with this modified version, and differences between -m32 and -m64 observed even when the patch is applied to the library source file.

stdarg1a:
```d
import core.stdc.stdarg;

pragma(printf)
public extern(C) int wrap_printf(scope const char* f, ...) {
        import core.stdc.stdio;

        va_list ap, ap2;

        va_start(ap, f);
        va_copy(ap2, ap);
        auto rc = vprintf(f, ap);
        va_end(ap2);
        va_end(ap);

        return rc;
}

extern(C) void main() {
        wrap_printf("Foo\n");
}
```

--