This is the mail archive of the gcc-bugs@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

[Bug c/28073] New: Type-punned pointer passed as function parameter generates bad assembly sequence


The following test code
-- begin --
typedef struct {
  int val;
} Foo;

int func(long longPtr) {
  Foo *pFoo = *(Foo **)&longPtr; /* BAD! */
  /* Foo *pFoo = (Foo *)longPtr; If you do this instead it works */
  return pFoo->val;
}

int main(int argc, const char *argv[]) {
  Foo foo;
  foo.val = 1;

  return func((long)(&foo));
}
-- end --
When compiled with -O2 (which implies -fstrict-aliasing) on the x86_64
architectures changes the generated assembly sequence
<       movl    (%rdi), %eax
<       movq    %rdi, -8(%rsp)
--
>       movq    -8(%rsp), %rax
>       movl    (%rax), %eax

Comparing to other architectures, for example, i686 - the -O2 generated code
with -fstrict-aliasing and -fno-strict-aliasing is identical.  The code
generated with strict aliasing on the x86_64 is pretty much nonsense and
in the case of this test program will result in garbage from the stack being
returned from main (or, possibly, a seg fault)

Compare x86_64
$ gcc -O2 -Wall badcase.c; ./a.out; echo $?
badcase.c: In function ?func?:
badcase.c:9: warning: dereferencing type-punned pointer will break
strict-aliasing rules
76
$ gcc -O2 -fno-strict-aliasing -Wall badcase.c; ./a.out; echo $?
1
with i686
$ gcc -O2 -Wall badcase.c; ./a.out; echo $?
badcase.c: In function `func':
badcase.c:9: warning: dereferencing type-punned pointer will break
strict-aliasing rules
1

Please note that putting in any diagnostic code into func (for example a 
print statement) will "fix" it because it changes the determination of
aliasing.
This makes this particular interaction extra hard to spot.

After some considerable debate with my colleagues about the nature of the code
and its use of type-punning to convert a long into a pointer, I decided to
submit this as a bug because (1) google reveals that a great many distribution
builders are adding -fno-strict-aliasing to get their distributions building
and working on x86_64 and (2) this ugly construct is the exact type of code
that the current version of the (somewhat) popular swig library wrapper
generates.  I intend to open a bug against SWIG as well as there is no good
reason why a code generator should generate code like this.

Some of us believe that this code violates the standard (although how
specifically they cannot say) and, thus, the compiler is under no obligation to
compile it correctly.  Even so, in this particular case, it would be better not
to generate the eroneous instruction sequence.  Hopefully it will be reasonably
easy to pin down under which conditions the instruction sequence is changed,
for this particular architecture, and perhaps this might point the way to a
more fundamental bug.

$ gcc -v
Using built-in specs.
Target: x86_64-redhat-linux
Configured with: ../configure --prefix=/usr --mandir=/usr/share/man
--infodir=/usr/share/info --enable-shared --enable-threads=posix
--enable-checking=release --with-system-zlib --enable-__cxa_atexit
--disable-libunwind-exceptions --enable-libgcj-multifile
--enable-languages=c,c++,objc,obj-c++,java,fortran,ada --enable-java-awt=gtk
--disable-dssi --with-java-home=/usr/lib/jvm/java-1.4.2-gcj-1.4.2.0/jre
--with-cpu=generic --host=x86_64-redhat-linux
Thread model: posix
gcc version 4.1.0 20060304 (Red Hat 4.1.0-3)


-- 
           Summary: Type-punned pointer passed as function parameter
                    generates bad assembly sequence
           Product: gcc
           Version: 4.1.0
            Status: UNCONFIRMED
          Severity: normal
          Priority: P3
         Component: c
        AssignedTo: unassigned at gcc dot gnu dot org
        ReportedBy: sorenj at us dot ibm dot com
 GCC build triplet: x86_64-linux-gnu
  GCC host triplet: x86_64-linux-gnu
GCC target triplet: x86_64-linux-gnu


http://gcc.gnu.org/bugzilla/show_bug.cgi?id=28073


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]