[Go] Adjust last patch to avoid write-after-write data race on global
variable. Only set the variable if another global variable is true, but that variable is always false. The effect is that the variable is never written, but as far as the compiler is concerned it might escape.
This commit is contained in:
parent
abcb656b51
commit
0577ff2220
2 changed files with 41 additions and 14 deletions
|
|
@ -225,6 +225,16 @@ type _ unsafe.Pointer
|
|||
|
||||
%}
|
||||
|
||||
/* Swig_always_false is used to conditionally assign parameters to
|
||||
Swig_escape_val so that the compiler thinks that they escape. We
|
||||
only assign them if Swig_always_false is true, which it never is.
|
||||
We export the variable so that the compiler doesn't realize that it
|
||||
is never set. */
|
||||
%insert(go_header) %{
|
||||
var Swig_escape_always_false bool
|
||||
var Swig_escape_val interface{}
|
||||
%}
|
||||
|
||||
/* Function pointers are translated by the code in go.cxx into
|
||||
_swig_fnptr. Member pointers are translated to _swig_memberptr. */
|
||||
|
||||
|
|
|
|||
|
|
@ -920,15 +920,8 @@ private:
|
|||
needs_wrapper = true;
|
||||
}
|
||||
|
||||
// If the parameter has an argout or freearg typemap, we need to
|
||||
// make sure that it escapes, in case it contains any pointers.
|
||||
if (Getattr(p, "tmap:argout") || Getattr(p, "tmap:freearg")) {
|
||||
if (!goTypeIsInterface(p, Getattr(p, "type"))) {
|
||||
String *tm = goWrapperType(p, Getattr(p, "type"), false);
|
||||
Printf(f_go_wrappers, "var %s_escape_%d %s\n", wname, i, tm);
|
||||
Delete(tm);
|
||||
needs_wrapper = true;
|
||||
}
|
||||
if (paramNeedsEscape(p)) {
|
||||
needs_wrapper = true;
|
||||
}
|
||||
|
||||
p = nextParm(p);
|
||||
|
|
@ -1218,11 +1211,10 @@ private:
|
|||
|
||||
// If the parameter has an argout or freearg typemap, make
|
||||
// sure that it escapes.
|
||||
if (Getattr(p, "tmap:argout") || Getattr(p, "tmap:freearg")) {
|
||||
// No need to do anything for C++ class type.
|
||||
if (!goTypeIsInterface(p, pt)) {
|
||||
Printf(f_go_wrappers, "\t%s_escape_%d = %s\n", wname, i, Getattr(p, "emit:goinput"));
|
||||
}
|
||||
if (paramNeedsEscape(p)) {
|
||||
Printv(f_go_wrappers, "\tif Swig_escape_always_false {\n", NULL);
|
||||
Printv(f_go_wrappers, "\t\tSwig_escape_val = ", Getattr(p, "emit:goinput"), "\n", NULL);
|
||||
Printv(f_go_wrappers, "\t}\n", NULL);
|
||||
}
|
||||
|
||||
p = nextParm(p);
|
||||
|
|
@ -1291,6 +1283,31 @@ private:
|
|||
return "base";
|
||||
}
|
||||
|
||||
/* ----------------------------------------------------------------------
|
||||
* paramNeedsEscape()
|
||||
*
|
||||
* A helper for goFunctionWrapper that returns whether a parameter
|
||||
* needs to explicitly escape. This is true if the parameter has a
|
||||
* non-empty argout or freearg typemap, because in those cases the
|
||||
* Go argument might be or contain a pointer. We need to ensure
|
||||
* that that pointer does not oint into the stack, which means that
|
||||
* it needs to escape.
|
||||
* ---------------------------------------------------------------------- */
|
||||
bool paramNeedsEscape(Parm *p) {
|
||||
String *argout = Getattr(p, "tmap:argout");
|
||||
String *freearg = Getattr(p, "tmap:freearg");
|
||||
if ((!argout || Len(argout) == 0) && (!freearg || Len(freearg) == 0)) {
|
||||
return false;
|
||||
}
|
||||
// If a C++ type is represented as an interface type in Go, then
|
||||
// we don't care whether it escapes, because we know that the
|
||||
// pointer is a C++ pointer.
|
||||
if (goTypeIsInterface(p, Getattr(p, "type"))) {
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
/* ----------------------------------------------------------------------
|
||||
* gcFunctionWrapper()
|
||||
*
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue