Bug 26730 - Pointer assignment used together with ++ leads to an update of the wrong structure
Summary: Pointer assignment used together with ++ leads to an update of the wrong stru...
Status: RESOLVED DUPLICATE of bug 11751
Alias: None
Product: gcc
Classification: Unclassified
Component: c (show other bugs)
Version: 4.1.0
: P3 major
Target Milestone: ---
Assignee: Not yet assigned to anyone
URL:
Keywords:
Depends on:
Blocks:
 
Reported: 2006-03-17 16:54 UTC by Simon Reed
Modified: 2006-03-17 16:59 UTC (History)
47 users (show)

See Also:
Host: i586-suse-linux
Target: i586-suse-linux
Build: i586-suse-linux
Known to work:
Known to fail:
Last reconfirmed:


Attachments

Note You need to log in before you can comment on or make changes to this bug.
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:

sadd.i:
# 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;

        pos=&pos->sub[pos->no++];
        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
stem-zlib
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:
 /usr/local/include
 /usr/local/gcc-4.1.0/include
 /usr/local/gcc-4.1.0/lib/gcc/i586-suse-linux/4.1.0/include
 /usr/include
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 2.16.91.0.2 (i586-suse-linux) using BFD version 2.16.91.0.2 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
        pos=&pos->sub[pos->no++];


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

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