[Bug c++/43376] New: template member function instantiations are not hidden if the class has default visibility and -fvisibility-ms-compat is used

fjoe at samodelkin dot net gcc-bugzilla@gcc.gnu.org
Mon Mar 15 11:29:00 GMT 2010


Stock RHEL5 g++ 4.4 version:

[Mon Mar 15 17:04:26] kenny:~/work$g++44 -v
Using built-in specs.
Target: i386-redhat-linux6E
Configured with: ../configure --prefix=/usr --mandir=/usr/share/man
--infodir=/usr/share/info --with-bugurl=http://bugzilla.redhat.com/bugzilla
--enable-bootstrap --enable-shared --enable-threads=posix
--enable-checking=release --with-system-zlib --enable-__cxa_atexit
--disable-libunwind-exceptions --enable-languages=c,c++,fortran
--disable-libgcj
--with-mpfr=/builddir/build/BUILD/gcc-4.4.0-20090514/obj-i386-redhat-linux6E/mpfr-install/
--with-ppl=/builddir/build/BUILD/gcc-4.4.0-20090514/obj-i386-redhat-linux6E/ppl-install
--with-cloog=/builddir/build/BUILD/gcc-4.4.0-20090514/obj-i386-redhat-linux6E/cloog-install
--with-tune=generic --with-arch=i586 --build=i386-redhat-linux6E
Thread model: posix
gcc version 4.4.0 20090514 (Red Hat 4.4.0-6) (GCC) 

Assume that there is a C++ shared library that uses STL extensively and is
compiled with -fvisibility-ms-compat. Template member instantiations are
however still visible:

[Mon Mar 15 17:18:00] kenny:~/work$g++44 -c -fvisibility-ms-compat vis2.cc

[Mon Mar 15 17:18:03] kenny:~/work$readelf -sW vis2.o | grep foo
   153: 00000000   207 FUNC    GLOBAL DEFAULT   72 _Z3foov

ok, we want "foo" to be visible outside our shared library, but we do not want
the following symbol to be visible:

[Mon Mar 15 17:18:07] kenny:~/work$readelf -sW vis2.o | grep _M_range
   179: 00000000   505 FUNC    WEAK   DEFAULT  121
_ZNSt5dequeIiSaIiEE19_M_range_initializeISt15_Deque_iteratorIiRiPiEEEvT_S7_St20forward_iterator_tag

vis2.cc source code is:

--- cut vis2.cc ---
#include <deque>

#define FOO_EXPORT __attribute__((visibility("default")))

int FOO_EXPORT
foo()
{
        std::deque<int> a;
        std::deque<int> b(a.begin(), a.end());
        return 0;
}
--- cut vis2.cc ---

This can be considered as an STL bug ("std" namespace is declared as having
default visibility and thus all classes and all their members have default
visibility) -- one may set "hidden" visibility on template member functions.

But I think that at least -fvisibility-ms-compat should produce the code when
template instantiations have hidden visibility, otherwise it will not be
possible to be source-compatible with Visual Studio on this matter. I mean that
the following source code (being an example of source compatibility with Visual
Studio wrt. hidden visibility) will be compiled differently if used in shared
library (or .DLL):

--- cut foo.h ---
#include <iostream>

#if defined(_MSC_VER)
#define FOO_EXPORT __declspec(dllexport)
#define FOO_IMPORT __declspec(dllimport)
#else
#define FOO_EXPORT __attribute__((visibility("default")))
#define FOO_IMPORT __attribute__((visibility("default")))
#endif

#if defined(_BUILD_FOO_DLL)
#define FOO_API FOO_EXPORT
#else
#define FOO_API FOO_IMPORT
#endif

class FOO_API Foo
{
public:
        template<typename T>
        void foo(const T &t) {
                std::cout << t << std::endl;
        }
};
--- cut foo.h ---

Or there should be additional command line option that enables such behavior.


-- 
           Summary: template member function instantiations are not hidden
                    if the class has default visibility and -fvisibility-ms-
                    compat is used
           Product: gcc
           Version: unknown
            Status: UNCONFIRMED
          Severity: major
          Priority: P3
         Component: c++
        AssignedTo: unassigned at gcc dot gnu dot org
        ReportedBy: fjoe at samodelkin dot net


http://gcc.gnu.org/bugzilla/show_bug.cgi?id=43376



More information about the Gcc-bugs mailing list