https://gcc.gnu.org/bugzilla/show_bug.cgi?id=67857

            Bug ID: 67857
           Summary: noreturn + volatile results in wrong code
           Product: gcc
           Version: 5.2.0
            Status: UNCONFIRMED
          Severity: normal
          Priority: P3
         Component: middle-end
          Assignee: unassigned at gcc dot gnu.org
          Reporter: karl at skomski dot com
  Target Milestone: ---

On Linux/x86-64, GCC 5.2 (g++ -m32 -O1) optimizes this test into wrong code:
Important is the volatile argument to Increment and __noreturn__ function in
the if clause.

```
#include <stdlib.h>
#include <stdio.h>

int Increment(volatile int* ptr, int increment) { // volatile
  int temp = *ptr;
  *ptr += increment;
  return temp + increment;
}

int main() {
  // Test at rollover boundary between int_max and int_min.
  int test_val = 1 << (sizeof(int) * 8 - 1);
  int value = -1 ^ test_val;
  int new_value = Increment(&value, 1);

  if (test_val != value) exit(100);
  if (value != new_value) exit(200);

  return 0;
}
```
produces 

```
Fatal 200
[1]    3789 exit 200
```

```
        .cfi_startproc
        lea     ecx, [esp+4]
        .cfi_def_cfa 1, 0
        and     esp, -16
        push    DWORD PTR [ecx-4]
        push    ebp
        .cfi_escape 0x10,0x5,0x2,0x75,0
        mov     ebp, esp
        push    ecx
        .cfi_escape 0xf,0x3,0x75,0x7c,0x6
        sub     esp, 20
        mov     DWORD PTR [ebp-12], 2147483647
        mov     eax, DWORD PTR [ebp-12]
        mov     eax, DWORD PTR [ebp-12]
        add     eax, 1
        mov     DWORD PTR [ebp-12], eax
        cmp     DWORD PTR [ebp-12], -2147483648
        je      .L4
        sub     esp, 12
        push    100
        call    exit
.L4:
        sub     esp, 12
        push    200
        call    exit
        .cfi_endproc

```

Reply via email to