KJK::Hyperion schrieb:
Timo Kreuzer wrote:
  
In other words the register *is dead* on entering the try branch.
    

Read and compare the disassembled code of continue_search_3 before and
after my last change
  
Yes, it's fixed now. At least this case. It's still not the holy grail I think.

What about this one:

DEFINE_TEST(set_before_exception)
{
    int ret1, ret2;

    ret2 = ret1 = 0;

    _SEH2_TRY
    {
        ret2 = 1;
        volatile char * p = 0;
        *p = 0;
        ret1 = 1;
    }
    _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
    {
        ret1 = -1;
    }
    _SEH2_END;

    return (ret1 == -1 && ret2 == 1);
}

The compiler assumes that on entering the except block, that not a single instruction of the try block has been executed. And it will use this to optimize away everything it can. MSVC will preserve the instruction order and make sure all variables are stored in memory locations.
I don't think you can get this handled equally without hacking it into gcc.

This case isn't that bad. We just have the following requirement:
Do not make any assumptions about the order in which code is executed inside the try block!
Not even if normally you could say that something must be executed in a special order (like x = func1(); y = func2(x);)

But there's another thing that bothers me. It's guaranteed that all variables that are used after the call to _SEH2EnterFrame are either constants or stored in a memory location at the time that SEH2EnterFrame is called. No more, no less. It is not guaranteed that the variables stay there.
Now the compiler could decide to move a variable into a register directly after the call (maybe because it's needed in this register in both branches) and before the branch. Then in the try branch later it's moved into another register just before the exception occurs.

Now this is hypothetical, because I couldn't find a real situation where this happens. I just think it might be possible.

Regards,
Timo