public inbox for gcc-bugs@sourceware.org
help / color / mirror / Atom feed
* [Bug c/33629]  New: bad code with -O2 if pointer dereference followed by null test
@ 2007-10-02 17:49 david_albert at axiometric dot com
  2007-10-02 18:08 ` [Bug c/33629] " rask at gcc dot gnu dot org
                   ` (2 more replies)
  0 siblings, 3 replies; 4+ messages in thread
From: david_albert at axiometric dot com @ 2007-10-02 17:49 UTC (permalink / raw)
  To: gcc-bugs

With optimization level -Os or -O2, the function below will generate code that
does not perform the conditional test.  The test is necessary on embedded
systems where de-referencing a pointer to address 0 may be legitimate and would
not cause an exception in the de-reference of b (line 4).  The defect occurs in
all tested versions of gcc including native and cross compilers: 

   host:i686-pc-cygwin/target:arm-elf-gcc/build:3.4.0, 
   host:i686-pc-cygwin/target:arm-elf-gcc/build:4.2.0 (GNUARM)
   host:i686-pc-cygwin/target:i686-pc-cygwin/build:3.4.4
   host:i486-linux-gnu/target:i486-linux-gnu/build:4.1.2 (20061115 prerelease -
debian4.1.1-21)

The assembly output shows that the assignment d=c (on line 8) is performed
without performing the conditional test for a non-null value of b (line 7):

-------------------------------------------------

void bad_code(void *a)
{
   int *b = a;
   int c = *b;
   static int d;

   if (b) {
      d = c;
   }
}

$ arm-elf-gcc -c -g -MD -I. -mcpu=arm7tdmi -mthumb-interwork -std=c99 -Os -Wall
 -Werror test.c -o test.o

$ arm-elf-objdump -S test.o

test.o:     file format elf32-littlearm

Disassembly of section .text:

00000000 <bad_code>:
   int c = *b;
   static int d;

   if (b) {
      d = c;
   0:   e5902000        ldr     r2, [r0]
   4:   e59f3004        ldr     r3, [pc, #4]    ; 10 <.text+0x10>
   8:   e5832000        str     r2, [r3]
   }
}
   c:   e12fff1e        bx      lr
  10:   00000000        andeq   r0, r0, r0

Same code compiled with native cygwin compiler: (3.4.4)

$ gcc -O2 -c test.c -o test.o

$ objdump -S test.o

test.o:     file format pe-i386

Disassembly of section .text:

00000000 <_bad_code>:
   0:   55                      push   %ebp
   1:   89 e5                   mov    %esp,%ebp
   3:   8b 45 08                mov    0x8(%ebp),%eax
   6:   5d                      pop    %ebp
   7:   8b 00                   mov    (%eax),%eax
   9:   a3 00 00 00 00          mov    %eax,0x0
   e:   c3                      ret
   f:   90                      nop


Same code compiled on Native linux-gnu (4.1.2):

foo.o:     file format elf32-i386

Disassembly of section .text:

00000000 <bad_code>:
   0:   55                      push   %ebp
   1:   89 e5                   mov    %esp,%ebp
   3:   8b 45 08                mov    0x8(%ebp),%eax
   6:   5d                      pop    %ebp
   7:   8b 00                   mov    (%eax),%eax
   9:   a3 00 00 00 00          mov    %eax,0x0
   e:   c3                      ret    


It appears that the optimizer takes the dereference of b as an implicit sign
that b can be assumed to be non-zero after that point in the code - certainly,
on a cygwin or linux system, dereferencing a zero address causes a segmentation
fault, but on an embedded arm system, this is the most practical way to access
the interrupt vectors from C.


-- 
           Summary: bad code with -O2 if pointer dereference followed by
                    null test
           Product: gcc
           Version: 4.2.1
            Status: UNCONFIRMED
          Severity: normal
          Priority: P3
         Component: c
        AssignedTo: unassigned at gcc dot gnu dot org
        ReportedBy: david_albert at axiometric dot com
 GCC build triplet: 4.2.1
  GCC host triplet: i486-linux-gnu
GCC target triplet: arm-elf-gcc


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


^ permalink raw reply	[flat|nested] 4+ messages in thread

* [Bug c/33629] bad code with -O2 if pointer dereference followed by null test
  2007-10-02 17:49 [Bug c/33629] New: bad code with -O2 if pointer dereference followed by null test david_albert at axiometric dot com
@ 2007-10-02 18:08 ` rask at gcc dot gnu dot org
  2007-10-02 18:24 ` david_albert at axiometric dot com
  2007-10-03 22:13 ` rask at gcc dot gnu dot org
  2 siblings, 0 replies; 4+ messages in thread
From: rask at gcc dot gnu dot org @ 2007-10-02 18:08 UTC (permalink / raw)
  To: gcc-bugs



------- Comment #1 from rask at gcc dot gnu dot org  2007-10-02 18:08 -------
This behaviour is as documented.
http://gcc.gnu.org/onlinedocs/gcc/Optimize-Options.html


-- 

rask at gcc dot gnu dot org changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
             Status|UNCONFIRMED                 |RESOLVED
         Resolution|                            |INVALID


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


^ permalink raw reply	[flat|nested] 4+ messages in thread

* [Bug c/33629] bad code with -O2 if pointer dereference followed by null test
  2007-10-02 17:49 [Bug c/33629] New: bad code with -O2 if pointer dereference followed by null test david_albert at axiometric dot com
  2007-10-02 18:08 ` [Bug c/33629] " rask at gcc dot gnu dot org
@ 2007-10-02 18:24 ` david_albert at axiometric dot com
  2007-10-03 22:13 ` rask at gcc dot gnu dot org
  2 siblings, 0 replies; 4+ messages in thread
From: david_albert at axiometric dot com @ 2007-10-02 18:24 UTC (permalink / raw)
  To: gcc-bugs



------- Comment #2 from david_albert at axiometric dot com  2007-10-02 18:24 -------
There is a compiler flag to prevent this optimization:
-fno-delete-null-pointer-checks

This flag should be included by default for popular targets such as the ARM7
that do not have hardware memory managers so that gcc does not by default
generate code that silently fails.


-- 

david_albert at axiometric dot com changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
                 CC|                            |david_albert at axiometric
                   |                            |dot com


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


^ permalink raw reply	[flat|nested] 4+ messages in thread

* [Bug c/33629] bad code with -O2 if pointer dereference followed by null test
  2007-10-02 17:49 [Bug c/33629] New: bad code with -O2 if pointer dereference followed by null test david_albert at axiometric dot com
  2007-10-02 18:08 ` [Bug c/33629] " rask at gcc dot gnu dot org
  2007-10-02 18:24 ` david_albert at axiometric dot com
@ 2007-10-03 22:13 ` rask at gcc dot gnu dot org
  2 siblings, 0 replies; 4+ messages in thread
From: rask at gcc dot gnu dot org @ 2007-10-03 22:13 UTC (permalink / raw)
  To: gcc-bugs



------- Comment #3 from rask at gcc dot gnu dot org  2007-10-03 22:13 -------
You could open a request for a warning when a null pointer check is optimized
away after dereferencing the pointer.


-- 


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


^ permalink raw reply	[flat|nested] 4+ messages in thread

end of thread, other threads:[~2007-10-03 22:13 UTC | newest]

Thread overview: 4+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2007-10-02 17:49 [Bug c/33629] New: bad code with -O2 if pointer dereference followed by null test david_albert at axiometric dot com
2007-10-02 18:08 ` [Bug c/33629] " rask at gcc dot gnu dot org
2007-10-02 18:24 ` david_albert at axiometric dot com
2007-10-03 22:13 ` rask at gcc dot gnu dot org

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).