gcc 2.95.2: attribute((regparm(N))) and function ptr type casts
Fergus Henderson
fjh@cs.mu.OZ.AU
Fri Nov 24 01:55:00 GMT 2000
gcc 2.95.2's handling of calling convention attributes in function
pointer types is very nasty: it silently ignores them. This
behaviour is very counter-intuitive, and not documented.
At very least gcc ought to issue a warning that the attribute is
ignored. But a much nicer solution would be to make attributes that
affect the calling convention a fully-fledged part of the function type.
The following program demonstrates the problem.
$ cat bug.c
#define MR_CALL __attribute__((__regparm__(2)))
int MR_CALL foo(int x, int y, int z, int a) {
return x + y + z + a;
}
int bar(int (MR_CALL *g)(int,int,int,int)) {
#if 0
/* This works fine */
return (*g)(1,2,3,4);
#else
/* Adding a superfluous cast to the same type breaks it: */
/* GCC ignores the MR_CALL in the function pointer type. */
return (*(int (MR_CALL *)(int,int,int,int))g)(1,2,3,4);
#endif
}
#include <stdio.h>
int main(void) {
printf("%d\n", bar(foo));
return 0;
}
$ gcc bug.c
$ ./a.out
-1073745592
The following gdb transcript shows that the problem is that
gcc uses the wrong calling convention for the call to `g'
$ gcc -g bug.c
$ gdb ./a.out
(gdb) b main
Breakpoint 1 at 0x804842e: file bug.c, line 21.
(gdb) r
Breakpoint 1, main () at bug.c:21
21 printf("%d\n", bar(foo));
(gdb) s
bar (g=0x80483e0 <foo>) at bug.c:14
14 return (*(int (MR_CALL *)(int,int,int,int))g)(1,2,3,4);
(gdb) s
foo (x=-1073745612, y=1, z=1, a=2) at bug.c:4
4 return x + y + z + a;
(gdb)
--
Fergus Henderson <fjh@cs.mu.oz.au> | "I have always known that the pursuit
| of excellence is a lethal habit"
WWW: < http://www.cs.mu.oz.au/~fjh > | -- the last words of T. S. Garp.
More information about the Gcc-bugs
mailing list