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

            Bug ID: 90535
           Summary: Wrong branch selected if (--(s.ptr))
           Product: gcc
           Version: 9.1.1
            Status: UNCONFIRMED
          Severity: normal
          Priority: P3
         Component: c
          Assignee: unassigned at gcc dot gnu.org
          Reporter: vbraun.name at gmail dot com
  Target Milestone: ---

Decrementing a struct member pointer is not seen in a subsequent if() branch,
so tests like 

    if (--(s.ptr)) 

jump to the wrong branch. This is with gcc 9.1.1 and -O1 or higher, -O0 works
correctly. The following is a simplified testcase that was extracted from a
real-world reference counting implementation:

=======================================================
#include "stdio.h"

struct MyStruct {
    void *ptr;
};


int main() {
    struct MyStruct s;
    s.ptr = NULL + 1;

    // The bug only happens if we have a pointer to s, even though we don't
really use it
    struct MyStruct *struct_ptr = &s; 
    printf("MyStruct *struct_ptr = %p\n", struct_ptr);    // need to use it
once

    printf("------------ ptr = 0x1 ----------------------------\n");
    printf("ptr is 0x1: %p\n", s.ptr);
    if (s.ptr) {
        printf("ptr is truthy (correct!) %p\n", s.ptr);
    }

    printf("------------ ptr = NULL ----------------------------\n");
    (s.ptr)--;     // We should be back to 0x0 now
    // Uncomenting the following line makes the bug disappear
    // printf("ptr is null: %p\n", s.ptr);
    if (!(s.ptr)) {
        printf("ptr is falsy (correct!) %p\n", s.ptr);
    }
    if (s.ptr) {
        printf("ptr is truthy (wrong!) %p\n", s.ptr);
    }
    return 0;
}

=======================================================

$ gcc -O1 test_char_ptr.c  && ./a.out 
MyStruct *struct_ptr = 0x7ffd0b049758
------------ ptr = 0x1 ----------------------------
ptr is 0x1: 0x1
ptr is truthy (correct!) 0x1
------------ ptr = NULL ----------------------------
ptr is truthy (wrong!) (nil)

$ gcc --version
gcc (GCC) 9.1.1 20190503 (Red Hat 9.1.1-1)
Copyright (C) 2019 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.

Reply via email to