compiler, runtime: Fix unexpected GC interfering with closure passing.
commitb8e86a51a7dd10213c84f94677ca43dc58ad71d9
authorian <ian@138bc75d-0d04-0410-961f-82ee72b054a4>
Wed, 13 Aug 2014 22:31:44 +0000 (13 22:31 +0000)
committerian <ian@138bc75d-0d04-0410-961f-82ee72b054a4>
Wed, 13 Aug 2014 22:31:44 +0000 (13 22:31 +0000)
tree198fc07cf8ca2bd9c972c9d40b113a7f73865227
parente3108d46cb035331be28f3ce347373b464cad6dc
compiler, runtime: Fix unexpected GC interfering with closure passing.

The Go frontend passes closures through to functions using the
functions __go_set_closure and __go_get_closure.  The
expectation is that there are no function calls between
set_closure and get_closure.  However, it turns out that there
can be function calls if some of the function arguments
require type conversion to an interface type.  Converting to
an interface type can allocate memory, and that can in turn
trigger a garbage collection, and that can in turn call pool
cleanup functions that may call __go_set_closure.  So the
called function can see the wrong closure value, which is bad.

This patch fixes the problem in two different ways.  First, we
move all type conversions in function arguments into temporary
variables so that they can not appear before the call to
__go_set_closure.  (This required shifting the flatten phase
after the simplify_thunk phase, since the latter expects to
work with unconverted argument types.)  Second, we fix the
memory allocation function to preserve the closure value
across any possible garbage collection.

A test case is the libgo database/sql check run with the
environment variable GOGC set to 1.

git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@213932 138bc75d-0d04-0410-961f-82ee72b054a4
gcc/go/gofrontend/expressions.cc
gcc/go/gofrontend/go.cc
libgo/runtime/malloc.goc