http://gcc.gnu.org/bugzilla/show_bug.cgi?id=50466
Bug #: 50466 Summary: Compiled code behaves differently with "-O2 -fPIC" flag combination Classification: Unclassified Product: gcc Version: 4.3.4 Status: UNCONFIRMED Severity: normal Priority: P3 Component: c AssignedTo: unassig...@gcc.gnu.org ReportedBy: hmil...@gluster.com Compiled code behaves differently with "-O2 -fPIC" flag combination. Taking out either of the flags makes the compiled code behave predictably. Also, commenting out certain lines in the code (highlighted as comments) makes the code compile predictably even in the presence of "-O2 -fPIC". Other compiler versions always behave predictably for this test case. #include <stdlib.h> #include <assert.h> #include <stdio.h> struct list_head { struct list_head *next; struct list_head *prev; }; struct pool { struct list_head list; int count; unsigned long size; void *slab; }; char global_init; /* Uncommenting the prototype with attribute masks the bug */ //void *__calloc (size_t nmemb, size_t size) __attribute_malloc__; void * __calloc (size_t nmemb, size_t size) { return calloc (nmemb, size); } void pool_validate (struct pool *pool) { struct list_head *list = NULL; struct list_head *head = NULL; int count = 0; head = &pool->list; for (list = head->next; list != head; list = list->next) { count++; } if (pool->count == count) { printf ("GOOD :)\n"); } else { printf ("BAD :(\n"); } } struct pool * pool_new (int size, int count) { struct pool *pool = NULL; void *slab = NULL; int i = 0; struct list_head *list = NULL; struct list_head *head = NULL; /* commenting the below line hides the bug */ do { if (!global_init) break; } while (0); pool = __calloc (sizeof (*pool), 1); if (!pool) return NULL; head = &pool->list; head->next = head->prev = head; pool->size = size; pool->count = count; slab = __calloc (count, size); if (!slab) { free (pool); return NULL; } for (i = 0; i < count; i++) { list = slab + (i * (size)); list->next = list->prev = list; list->next = head; list->prev = head->prev; list->next->prev = list; list->prev->next = list; } pool->slab = slab; return pool; } int main (int argc, char *argv[]) { struct pool *pool = NULL; pool = pool_new (1024, 1024); pool_validate (pool); return 0; } ------------- blackhole:~/comp-bug # gcc --version gcc (SUSE Linux) 4.3.4 [gcc-4_3-branch revision 152973] Copyright (C) 2008 Free Software Foundation, Inc. This is free software; see the source for copying conditions. There is NO warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. blackhole:~/comp-bug # make all gcc-4.3 -Wall -O0 -fPIC pool.c -o good gcc-4.3 -Wall -O2 -fPIC pool.c -o bad ./good GOOD :) ./bad BAD :(