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

Reply via email to