This is the mail archive of the
gcc@gcc.gnu.org
mailing list for the GCC project.
i386-specific G++ bug
- To: egcs at cygnus dot com
- Subject: i386-specific G++ bug
- From: "Charles M. Hannum" <mycroft at mit dot edu>
- Date: Sun, 28 Sep 1997 07:02:59 -0400 (EDT)
egcs-970910 compiles the following code incorrectly with `g++ -fPIC'
on an i386-unknown-netbsd system:
-----8<-----snip-----8<-----snip-----8<-----snip-----8<-----snip-----8<-----
typedef void thunk(void);
static void foo(void);
thunk *bar()
{
return (foo);
}
static void foo(void)
{
}
-----8<-----snip-----8<-----snip-----8<-----snip-----8<-----snip-----8<-----
(PLEASE NOTE that I'm compiling this as C++ code. It compiles
correctly as C code.)
The problem is that the following instruction is output:
movl _foo__Fv@GOT(%ebx),%edx
for the reference to foo() inside bar(). Since foo() is static, this
is an invalid GOT reference. The correct instruction would be:
leal _foo__Fv@GOTOFF(%ebx),%edx
After some investigation, I've found that this is because the C++
frontend is violating the RTL interface. To wit, grokfndecl() has the
following code:
/* All function decls start out public; we'll fix their linkage later (at
definition or EOF) if appropriate. */
TREE_PUBLIC (decl) = 1;
This causes TREE_PUBLIC() to be true for all function declarations,
including static ones. Because the i386 port uses TREE_PUBLIC() to
set SYMBOL_REF_FLAG(), and in turn uses SYMBOL_REF_FLAG() to decide
how to reference a symbol, this means that all references to static
top-level C++ functions that have been declared are compiled
incorrectly. Amazingly, I've only seen this occur in one piece of
real code.
The obvious fix is to change the above to:
TREE_PUBLIC (decl) = publicp;
(and move it after the check for main(), obviously). However, I'm not
entirely sure this won't break some obscure path that I haven't
thought about. What I'd really like to know is why the code was
originally written as it is.
Anyone? Bueller?
(FWIW, with this change, the library I was trying to compile does in
fact compile and run correctly. This is obviously not an exhaustive
test, however.)