compiler: make sure variables captured by defer closure live
commit474bbac91d6f3b10b8338465e8d44a0ea64e631a
authorian <ian@138bc75d-0d04-0410-961f-82ee72b054a4>
Mon, 15 Jan 2018 19:13:47 +0000 (15 19:13 +0000)
committerian <ian@138bc75d-0d04-0410-961f-82ee72b054a4>
Mon, 15 Jan 2018 19:13:47 +0000 (15 19:13 +0000)
treecc0acfcf32f205c7abfac4cada88e3136e992ca0
parentcb4580683442b0e33e9db5eb26d4909e4f4abc92
compiler: make sure variables captured by defer closure live

    Local variables captured by the deferred closure need to be live
    until the function finishes, especially when the deferred
    function runs. In Function::build, for function that has a defer,
    we wrap the function body in a try block. So the backend sees
    the local variables only live in the try block, without knowing
    that they are needed also in the finally block where we invoke
    the deferred function. Fix this by creating top-level
    declarations for non-escaping address-taken locals when there
    is a defer.

    An example of miscompilation without this CL:

    func F(fn func()) {
            didPanic := true
            defer func() {
                    println(didPanic)
            }()
            fn()
            didPanic = false
    }

    With escape analysis turned on, at optimization level -O1 or -O2,
    the store "didPanic = false" is elided by the backend's
    optimizer, presumably because it thinks "didPanic" is not live
    after the store, so the store is useless.

    Reviewed-on: https://go-review.googlesource.com/86241

git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@256706 138bc75d-0d04-0410-961f-82ee72b054a4
gcc/go/gofrontend/MERGE
gcc/go/gofrontend/gogo.cc