Bug 26730

Summary: Pointer assignment used together with ++ leads to an update of the wrong structure
Product: gcc Reporter: Simon Reed <SimonX200>
Component: cAssignee: Not yet assigned to anyone <unassigned>
Severity: major CC: algorithmus, arminu, asokumar, av1474, bala, barnarr, bmead15, buergel, carpman, ceniza666, chuchunxin, devnull, d_picco, eric.mcvicker, fuchsia.groan, gaurav_har, gcc-bugs, gcc, ggs, horsh, jandres, janis, jompo, krs, lid, lindahlb, lxg8906, mayer, mikaldaz, nakkore, nobs, pierre.van.de.laar_at_philips.com, qyang, raoulgough, rglan, rjvbertin, robc, s9322036, SimonX200, smartmouse714, suan, super.aorta, svetozarmarkov, tczarnecki, vanveghel, vitaly, zshao
Priority: P3    
Version: 4.1.0   
Target Milestone: ---   
Host: i586-suse-linux Target: i586-suse-linux
Build: i586-suse-linux Known to work:
Known to fail: Last reconfirmed:

Description Simon Reed 2006-03-17 16:54:02 UTC
This is not the same as bug 11751 as the variable used with ++ is not reused. Here the simple code:

# 1 "sadd.c"
# 1 "<built-in>"
# 1 "<command line>"
# 1 "sadd.c"

typedef struct A A;

struct A {
        int no;
        A *sub;

void main()
{ A sub={0, ((void*)0)};
        A root={0, &sub};
        A *pos=&root;

        printf("%d %d %p %p %p\n", root.no, sub.no, &root, &sub, pos);

Here the compiler call:

<~/test> 82>/usr/local/gcc-4.1.0/bin/gcc -v -save-temps sadd.c
Using built-in specs.
Target: i586-suse-linux
Configured with: ../gcc-4.1.0/configure --prefix=/usr/local/gcc-4.1.0 --enable-java-awt=gtk --with-cpu=pentium4 --enable-threads=posix 
--enable-languages=c,c++,java --disable-checking --host=i586-suse-linux --disable-libjava-multilib --without-system-libunwind --with-sy
Thread model: posix
gcc version 4.1.0
 /usr/local/gcc-4.1.0/libexec/gcc/i586-suse-linux/4.1.0/cc1 -E -quiet -v sadd.c -mtune=pentium4 -fpch-preprocess -o sadd.i
ignoring nonexistent directory "/usr/local/gcc-4.1.0/lib/gcc/i586-suse-linux/4.1.0/../../../../i586-suse-linux/include"
#include "..." search starts here:
#include <...> search starts here:
End of search list.
 /usr/local/gcc-4.1.0/libexec/gcc/i586-suse-linux/4.1.0/cc1 -fpreprocessed sadd.i -quiet -dumpbase sadd.c -mtune=pentium4 -auxbase sadd
 -version -o sadd.s
GNU C version 4.1.0 (i586-suse-linux)
        compiled by GNU C version 4.1.0.
GGC heuristics: --param ggc-min-expand=100 --param ggc-min-heapsize=131072
Compiler executable checksum: 9c3116972ab61a6d962b78330fe593eb
sadd.c: In function ‘main’:
sadd.c:15: warning: incompatible implicit declaration of built-in function ‘printf’
sadd.c:10: warning: return type of ‘main’ is not ‘int’
 as -V -Qy -o sadd.o sadd.s
GNU assembler version (i586-suse-linux) using BFD version 20050720 (SuSE Linux)
 /usr/local/gcc-4.1.0/libexec/gcc/i586-suse-linux/4.1.0/collect2 --eh-frame-hdr -m elf_i386 -dynamic-linker /lib/ld-linux.so.2 /usr/lib
/crt1.o /usr/lib/crti.o /usr/local/gcc-4.1.0/lib/gcc/i586-suse-linux/4.1.0/crtbegin.o -L/usr/local/gcc-4.1.0/lib/gcc/i586-suse-linux/4.
1.0 -L/usr/local/gcc-4.1.0/lib/gcc/i586-suse-linux/4.1.0/../../.. sadd.o -lgcc --as-needed -lgcc_s --no-as-needed -lc -lgcc --as-needed
 -lgcc_s --no-as-needed /usr/local/gcc-4.1.0/lib/gcc/i586-suse-linux/4.1.0/crtend.o /usr/lib/crtn.o

Here the command execution.
<~/test> 85>sadd
0 1 0xbf995550 0xbf995558 0xbf995558

The problem is that the updated pos pointer is used to perform the ++ on the field "no" while the assignment should be actually the last statement. Also pos->no was needed and fetched before to actually calculate the new pos.

The problem is present even with -O0 on the gcc-4.0.2 (from SuSe 10.0) and gcc-4.1.0 (see above)

The compilers gcc-3.4.6, gcc-3.3.1 don't have that problem on the same platform  and on Tru64 5.1. Also the Tru64 5.1 standard C compiler does not have the problem.
<~/test> >gcc -o sadd sadd.c
sadd.c: In function `main':
sadd.c:10: warning: return type of `main' is not `int'
<~/test> >sadd
1 0 11fffbfe0 11fffbfd0 11fffbfd0
<~/test> >gcc -v
Reading specs from /usr/local/gcc-3.3.1/lib/gcc-lib/alphaev68-dec-osf5.1/3.3.1/specs
Configured with: ../gcc-3.3.1/configure --prefix=/usr/local/gcc-3.3.1 --disable-shared
Thread model: single
gcc version 3.3.1

<~/test> >cc -o sadd sadd.c
<~/test> >sadd
1 0 11fffbfd8 11fffbfe8 11fffbfe8
<~/test> >cc -V
Compaq C V6.4-216 (dtk) on Compaq Tru64 UNIX V5.1A (Rev. 1885)
Compiler Driver V6.4-013 (dtk) cc Driver
<~/test> >
Comment 1 Andrew Pinski 2006-03-17 16:59:23 UTC

This is undefined. You assign pos and use it without a sequence point.

*** This bug has been marked as a duplicate of 11751 ***