Skip to content

Frontends consider calls to "XYZ foo()" to be var-args, but this is wrong #11085

@llvmbot

Description

@llvmbot
Bugzilla Link 10713
Resolution FIXED
Resolved on Sep 21, 2011 03:09
Version trunk
OS Linux
Blocks #11054
Reporter LLVM Bugzilla Contributor
CC @asl,@efriedma-quic,@rjmccall

Extended Description

Clang/llvm-gcc and dragonegg all consider a call to a function declared without
any parameters to be a var-args function call. However this gives the wrong
results when using the stdcall calling convention (with stdcall, the callee pops
arguments except if it is a varargs function; so any mistake in the
"var-argness" of a call is fatal, unlike with the usual C convention where it
doesn't make any difference).

Consider the following testcase. (The second call to bar is to make the stack
adjustments or lack of them clearer in the assembler):

#define STDCALL attribute((stdcall))

void STDCALL foo(); // Var-args or not var-args, that is the question!
void STDCALL bar(int); // Definitely not var-args
void STDCALL varg(int, ...); // Definitely var-args

void g(int x, int y)
{
foo(x, y);
bar(x);
varg(x, y);
bar(y);
}

GCC assembler snippets (compiled with: gcc -m32 -O2 -S):

call	foo
subl	$8, %esp     <= Stack adjust, indicates not var-args!

...
call bar
subl $4, %esp <= Stack adjust; not var-args
...
call varg
movl %ebx, (%esp) <= No stack adjust; var-args
...

Clang etc assembler snippets:

calll	foo
movl	%edi, (%esp) <= No stack adjust, indicates var-args; disagrees with GCC

...
calll bar
subl $4, %esp <= Stack adjust; not var-args; agrees with GCC
...
calll varg
movl %esi, (%esp) <= No stack adjust; var-args; agrees with GCC
...

This difference seems to be the cause of some crashes when running wine compiled
with LLVM.

Note that using C++ and declaring foo "void foo(...)" doesn't make any
difference: GCC still calls it as if it were not var-args!

Digging into the GCC logic, the var-argness of a function type is determined
by the stdarg_p predicate (which returns true for var-args). This special
cases function types with no parameters (as produced by the C front-end for
XYZ foo() and by the C++ front-end for XYZ foo(...)) as not being var-args.

Metadata

Metadata

Assignees

No one assigned

    Labels

    bugzillaIssues migrated from bugzillaclang:codegenIR generation bugs: mangling, exceptions, etc.

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions