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?).

Reply via email to