https://gcc.gnu.org/bugzilla/show_bug.cgi?id=61421
Bug ID: 61421
Summary: Invalid -O2 optimization breaks program
Product: gcc
Version: 4.9.0
Status: UNCONFIRMED
Severity: major
Priority: P3
Component: c++
Assignee: unassigned at gcc dot gnu.org
Reporter: mimamer at gmail dot com
Created attachment 32895
--> https://gcc.gnu.org/bugzilla/attachment.cgi?id=32895&action=edit
disassembly of faulty binary snippet
It seems that C++ carries out an invalid optimization when compiled with -O2
that breaks the following code snippet:
_dprintf("p %p, n %p, t %p\n", include_list2.head()->prev,
include_list2.head()->next, include_list2.end());
while ( (node = include_list2.dequeue()) != include_list2.end() ) {
//asm volatile("":::"memory");
main_list.insert_at( &iterator->main_node, &node->main_node );
iterator = node;
}
_dprintf("p %p, n %p, t %p\n", include_list2.head()->prev,
include_list2.head()->next, include_list2.end());
Output:
p 0x007f9e44, n 0x007f9e44, t 0x007f9e44
p 0x007f9e44, n 0x00000000, t 0x007f9e44
Expected output:
p 0x007f9e44, n 0x007f9e44, t 0x007f9e44
p 0x007f9e44, n 0x007f9e44, t 0x007f9e44
Explanation: include_list2 implements a simple doubly-linked list, which
happens to be empty at the beginning (i.e., the head's previous and next
pointers both point to the list's anchor, returned by end()). dequeue() thus
should return the anchor, which equals end() (i.e., the while loop should not
be entered). So, nothing should have changed after the loop, yet the anchor's
next pointer suddenly has become zero. Adding the memory barrier (i.e.,
uncommenting the line with the asm statement) gives the expected result.
Disassambled binary output for the snippet is attached, once in its faulty
version and once with the memory barrier. A minimal implementation of list2 is
attached as well. All in one file (why can't I submit more than one?).