gcc-2.95 bug: stdcall rubs off on templates

Karl-Johan Johnsson kalle@algorithmica.se
Thu Sep 2 07:03:00 GMT 1999


The problem appears with the following versions of GCC:

gcc-2.95 linux -> i586-mingw32 cross compiler
gcc-2.95.1 linux -> i586-mingw32 cross compiler
gcc-2.95 i386-mingw32 native (Mumit Khan's binary distribution)

but not with the version of gcc included in cygwin-b20 (egcs-1.1).

When compiling the following program, the implicit instantiation
of A<0>::f() is decorated with a trailing '@4' (as if it had
been declared __stdcall), leading to an undefined reference:

bug.cpp:
----8<--[snip]-------
template <int> class A
{
public:
    static void* f(int);
};

template <int i> void* A<i>::f(int)
{
    return 0;
}

int main()
{
    return !A<0>::f(0);
}

void* __attribute__((__stdcall__)) foo(int);
----8<--[snip]-------

$ i586-mingw32-g++ bug.cpp
/tmp/ccj5gaaa.o(.text+0x11):bug.cpp: undefined reference to `A<0>::f(int)'
$ i586-mingw32-g++ -O3 -fomit-frame-pointer -S bug.cpp
$ cat bug.s
	.file	"bug.cpp"
gcc2_compiled.:
___gnu_compiled_cplusplus:
	.def	___main;	.scl	2;	.type	32;	.endef
..text
	.align 4
..globl _main
	.def	_main;	.scl	2;	.type	32;	.endef
_main:
	subl $12,%esp
	call ___main
	addl $-12,%esp
	pushl $0
	call _f__t1A1i0i
	addl $16,%esp
	testl %eax,%eax
	sete %al
	andl $255,%eax
	addl $12,%esp
	ret
..section	.text$f__t1A1i0i,"x"
	.linkonce discard
	.align 4
..globl _f__t1A1i0i@4
	.def	_f__t1A1i0i@4;	.scl	2;	.type	32;	.endef
_f__t1A1i0i@4:
	xorl %eax,%eax
	ret $4
	.def	_f__t1A1i0i;	.scl	3;	.type	32;	.endef
$

Background:

A program that uses STL and includes <windows.h> (_after_ the
standard headers) will crash with a call to address 0.
For example:

----8<--[snip]-------
#include <list>
#include <windows.h> /* Plenty of __stdcall functions. */

int main()
{
    std::list<int> l;

    return 0;
}
----8<--[snip]-------

The compiler instantiates std::__default_alloc_template<...>::_S_refill()
with @-decoration, but the call (from the list constructor) is to
the undecorated function (which does not exist).  The linker then
resolves this call to 'call 0' => crash.

Regards,

Karl-Johan Johnsson


More information about the Gcc-bugs mailing list