Force hidden visibility on functions needing distinct static locals

This commit adds a PYBIND11_UNSHARED_STATIC_LOCALS macro that forces a
function to have hidden visibility under gcc and gcc-compatible
compilers.  gcc, in particular, needs this to to avoid sharing static
local variables across modules (which happens even under a RTLD_LOCAL
dlopen()!).  clang doesn't appear to have this issue, but the forced
visibility on internal pybind functions certainly won't hurt it and icc.

This updates the workaround from #862 to use this rather than the
version-specific template.
This commit is contained in:
Jason Rhinelander 2017-07-28 21:56:51 -04:00
parent 373da82486
commit e98d31d697
2 changed files with 14 additions and 6 deletions

View File

@ -60,12 +60,10 @@ struct type_info {
bool default_holder : 1;
};
// Store the static internals pointer in a version-specific function so that we're guaranteed it
// will be distinct for modules compiled for different pybind11 versions. Without this, some
// compilers (i.e. gcc) can use the same static pointer storage location across different .so's,
// even though the `get_internals()` function itself is local to each shared object.
template <int = PYBIND11_VERSION_MAJOR, int = PYBIND11_VERSION_MINOR>
internals *&get_internals_ptr() { static internals *internals_ptr = nullptr; return internals_ptr; }
PYBIND11_UNSHARED_STATIC_LOCALS PYBIND11_NOINLINE inline internals *&get_internals_ptr() {
static internals *internals_ptr = nullptr;
return internals_ptr;
}
PYBIND11_NOINLINE inline internals &get_internals() {
internals *&internals_ptr = get_internals_ptr();

View File

@ -68,6 +68,16 @@
# endif
#endif
// Attribute macro for a function containing one or more static local variables that mustn't share
// the variable across shared objects (for example, because the value might be incompatible for
// modules compiled under different pybind versions). This is required under g++ (depending on the
// specific compiler and linker options), and won't hurt under gcc-compatible compilers:
#if defined(__GNUG__)
# define PYBIND11_UNSHARED_STATIC_LOCALS __attribute__ ((visibility("hidden")))
#else
# define PYBIND11_UNSHARED_STATIC_LOCALS
#endif
#if defined(_MSC_VER)
# define PYBIND11_NOINLINE __declspec(noinline)
#else