Problem ~~~~~~~~ The C frontend in GCC 4.3.1 appears to assume that the address of a function pointer is always aligned, and optimizes away certain bitwise operations. This breaks hppa-linux whose function pointers are either an OPD with a certain bit set, or a plain function pointer. In GCC 4.3 hppa-linux can no longer check to see if a function address is an OPD or not.
Background ~~~~~~~~~~~ The hppa-linux ABI supports non-OPD and OPDs. The difference is that OPDs' have bit 2 set to 1. The following testcase shows the change in behaviour between gcc-4_2-branch and gcc-4_3-branch. cat >> foo.c <<EOF #include <stdio.h> #include <stdlib.h> int main (void) { printf ("&printf = %x\n", (unsigned long)&printf); if (((unsigned long) &printf) & 3) { printf ("printf is an OPD (PLABEL32)\n"); } return 0; } EOF [EMAIL PROTECTED]:~/fsrc/gcc-work$ /usr/local/tools/bin/hppa-linux-gcc-4.2.4 -o foo foo.c [EMAIL PROTECTED]:~/fsrc/gcc-work$ ./foo &printf = 119ea printf is a PLABEL32 [EMAIL PROTECTED]:~/fsrc/gcc-work$ /usr/local/tools/bin/hppa-linux-gcc-4.3.1 -o foo foo.c [EMAIL PROTECTED]:~/fsrc/gcc-work$ ./foo &printf = 119ea GCC 4.3, even at -O0, reduces "((unsigned long) &printf) & 3)" to "0". ~~~ foo.c.003t.original ~~~ ;; Function main (main) ;; enabled by -tree-original { printf ((const char * restrict) (char *) "&printf = %x\n", (long unsigned int) printf); if (0) { printf ((const char * restrict) (char *) "printf is a PLABEL32\n"); } return 0; } ~~~ If the if condition is reduced to "0" as early as 003t.original, does that mean it's the C frontend fault? This issue is breaks glibc's detection of PLABEL32 symbols during startup relocation processing. It also likely breaks unwind code in libjava. Casting a pointer to an integer type is implementation defined, so the above change is certainly a regression. Why this didn't show up in the testing is another issue. Perhaps we just don't have a test for this (I can correct that pretty easily). Any ideas how to fix this? Pointers to the change that changed the behaviour? -- Summary: Regression: Symbol address check eliminated by C frontend. Product: gcc Version: 4.3.1 Status: UNCONFIRMED Severity: blocker Priority: P3 Component: c AssignedTo: unassigned at gcc dot gnu dot org ReportedBy: carlos at codesourcery dot com GCC build triplet: hppa-linux GCC host triplet: hppa-linux GCC target triplet: hppa-linux http://gcc.gnu.org/bugzilla/show_bug.cgi?id=35705