Is this a gcc optimization bug?

389 views Asked by At

Here's my code:

bool func(const MY_STRUCT *const ptr, some_struct *x, int y)
{
    printf("IN: %p\n", ptr); // ok
    for (int i = 0; i < y; ++i) {
        if (ptr->foo(x[i].key) == 0) {
            return false;
        }
    }
    printf("OUT: %p\n", ptr); // ok
    return true;
}

void process(void)
{
    ... ...
    for (i = 0; i < num; ++i) {
        MY_STRUCT *ptr = obj->GetPtr(); // success
        printf("BEFORE: %p\n", ptr); // ok
        if (func(ptr, x, y) == false) {
            continue;
        }
        printf("AFTER: %p\n", ptr); // <nil> when compile with -O2
        printf("%s", ptr->data); // *** segment fault here ***
    }
}

output:

BEFORE: 0x0612d3fa
IN: 0x0612d3fa
OUT: 0x0612d3fa
AFTER: <nil>
segment fault

If I compile above code with -O0, everything works fine. However, if I compile it with -O2, after the function func is called, the ptr become NULL!

Is this a gcc bug? Did anyone ever have encountered similar bug?

My gcc version is: gcc version 3.4.5 20051201 (Red Hat 3.4.5-2)

2

There are 2 answers

1
Stephen Canon On BEST ANSWER

There is the (likely) possibility that you have a stack-smasher in func, which is overwriting ptr on the caller's stack. Make sure any array or structure accesses in func remain in bounds. If it weren't for my sour memories of gcc 3.x, I would say that this is nearly certainly what's actually going on. Even so, this is the most likely explanation.

Giving you the benefit of the doubt on that point, if your code is really as posted in your question, then yes, this may be a compiler bug:

    printf("BEFORE: %p\n", ptr); // ok
    if (func(ptr, x, y)) {
        continue;
    }
    printf("AFTER: %p\n", ptr); // <nil> when compile with -O2

ptr is passed by value to func, so it's value in the calling function should not change, regardless of what happens within func.

However, you're using a truly ancient compiler; even if you report this bug, nothing will ever come of it. It is quite likely that whatever caused this has long since changed in gcc. Try a newer version or a different compiler.

2
jalf On

Whatever bugs your compiler may or may not have, if you see the described problem in the code you posted, then your GCC is broken at any optimization level.

The problematic line of code should never be reached at all.

func always returns true, and if it returns true, the last part of the loop body is skipped.

If you suspect a compiler bug, start by writing a code sample that reproduces it.

When we don't know what your actual code looks like, it's impossible for us to guess at whether GCC's behavior is correct or not.