[llvm-dev] [cfe-dev] Is it a va_arg bug in clang?

Shi, Steven via llvm-dev llvm-dev at lists.llvm.org
Fri Jan 8 19:15:34 PST 2016


Hi Richard,
Thank you for the info.  I build my code in Ubuntu-64bits with simply commands: “clang X64.c”, then run “./a.out” to see the output. If I replace my va_list, va_start, va_arg va_end with __builtin_ms_va_list, __builtin_ms_va_start, __builtin_ms_va_arg, __builtin_ms_va_end, my code will build fail in Ubuntu with below message. Do you suggest I should build it in windows and not in Linux? Or did I miss any build option here? Appreciate if you could let me know the correct build steps.



jshi19 at jshi19-Intel:/mnt/disk3$ clang X64.c
X64.c:12:2: error: unknown type name '__builtin_ms_va_list'; did you mean
      '__builtin_va_list'?
        __builtin_ms_va_list   Marker;
        ^~~~~~~~~~~~~~~~~~~~
        __builtin_va_list
note: '__builtin_va_list' declared here
X64.c:15:2: error: use of unknown builtin '__builtin_ms_va_start'
      [-Wimplicit-function-declaration]
        __builtin_ms_va_start (Marker, Format);
        ^
X64.c:17:11: error: use of unknown builtin '__builtin_ms_va_arg'
      [-Wimplicit-function-declaration]
                Value = __builtin_ms_va_arg (Marker, int);
                        ^
X64.c:17:11: note: did you mean '__builtin_ms_va_start'?
X64.c:15:2: note: '__builtin_ms_va_start' declared here
        __builtin_ms_va_start (Marker, Format);
        ^
X64.c:17:40: error: expected expression
                Value = __builtin_ms_va_arg (Marker, int);
                                                     ^
X64.c:20:2: error: use of unknown builtin '__builtin_ms_va_end'
      [-Wimplicit-function-declaration]
        __builtin_ms_va_end  (Marker);
        ^
X64.c:20:2: note: did you mean '__builtin_ms_va_arg'?
X64.c:17:11: note: '__builtin_ms_va_arg' declared here
                Value = __builtin_ms_va_arg (Marker, int);
                        ^
5 errors generated.





Steven Shi
Intel\SSG\STO\UEFI Firmware

Tel: +86 021-61166522
iNet: 821-6522

From: metafoo at gmail.com [mailto:metafoo at gmail.com] On Behalf Of Richard Smith
Sent: Saturday, January 09, 2016 3:26 AM
To: Shi, Steven
Cc: cfe-dev at lists.llvm.org; llvm-dev at lists.llvm.org
Subject: Re: [cfe-dev] Is it a va_arg bug in clang?

On Thu, Jan 7, 2016 at 11:15 PM, Shi, Steven via cfe-dev <cfe-dev at lists.llvm.org<mailto:cfe-dev at lists.llvm.org>> wrote:
For the variadic function error with AMD64 abi and windows calling convention on 64bits x86, I find it has been tracked in Bug 20847 (https://llvm.org/bugs/show_bug.cgi?id=20847) (http://reviews.llvm.org/D1622#inline-9345). Do we still plan to fix it?

You know, I meet exactly same va_arg mistake with llvm3.7 when I enable the Uefi firmware (http://www.uefi.org/) build with clang. The ms_abi is the Uefi firmware binary module standard interface. I really hope this bug fix can been checked in as soon as possible. If we cannot fix it in short time, could we offer a temporary fix patch based on llvm3.7?

This is already fixed in clang trunk. Your code is rejected as follows:

<stdin>:15:17: error: 'va_start' used in Win64 ABI function
                va_start (Marker, Format);
                ^

You need to use __builtin_ms_va_list, __builtin_ms_va_start, __builtin_ms_va_end to use ms_abi varargs semantics. (In particular, note that __builtin_ms_va_list is a different type from va_list, so this can't "just work" in the way you expect it to.)

Steven Shi
Intel\SSG\STO\UEFI Firmware

Tel: +86 021-61166522<tel:%2B86%20021-61166522>
iNet: 821-6522

From: Shi, Steven
Sent: Thursday, January 07, 2016 11:07 PM
To: 'cfe-dev at lists.llvm.org<mailto:cfe-dev at lists.llvm.org>'
Subject: Is it a va_arg bug in clang?

Hello,
I’m trying to use the clang3.7 to compile  64bits x86 code with Microsoft ABI in Ubuntu 64bit, but I find the va_arg get the wrong variable argument from the va_list. Below is my test code.

#include <stdio.h>
#include <stdarg.h>

void
__attribute__((ms_abi))
Foo_va_list (
    int                       VaNum,
    const char  *Format,
  ...
  )
{
                va_list  Marker;
                long long    Value;

                va_start (Marker, Format);
                for (int i = 0; i < VaNum; i++ ) {
                                Value = va_arg (Marker, int);
                                printf("Value = 0x%llx\n", Value);
                }
                va_end (Marker);
}


int main()
{
  Foo_va_list (16, "0123456789abcdef= %x%x%x%x%x%x%x%x%x%x%x%x%x%x%x%x \n", 0,1,2,3,4,5,6,7,8,9,0xa,0xb,0xc,0xd,0xe,0xf);
  return 0;
}

The expected output are:
Value = 0x0
Value = 0x1
Value = 0x2
Value = 0x3
Value = 0x4
Value = 0x5
Value = 0x6
Value = 0x7
Value = 0x8
Value = 0x9
Value = 0xa
Value = 0xb
Value = 0xc
Value = 0xd
Value = 0xe
Value = 0xf

But the real output are:
Value = 0x0
Value = 0x1
Value = 0x2
Value = 0x3
Value = 0x4
Value = 0x5
Value = 0x0
Value = 0x1
Value = 0x2
Value = 0x3
Value = 0x4
Value = 0x5
Value = 0x6
Value = 0x7
Value = 0x8
Value = 0x9

After I remove the Microsoft ABI definition __attribute__((ms_abi)) above  Foo_va_list () in the code, the output will become correct. I find GCC also have similar wrong behavior with __attribute__((ms_abi)). I don’t know how to make the __attribute__((ms_abi)) work correctly with va_arg.  I appreciate if any suggestion.






Steven Shi
Intel\SSG\STO\UEFI Firmware

Tel: +86 021-61166522<tel:%2B86%20021-61166522>
iNet: 821-6522


_______________________________________________
cfe-dev mailing list
cfe-dev at lists.llvm.org<mailto:cfe-dev at lists.llvm.org>
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-dev

-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.llvm.org/pipermail/llvm-dev/attachments/20160109/29d15aa8/attachment.html>


More information about the llvm-dev mailing list