[Bug c++/92914] New: Hidden visibility incompatible with extern'd specialized explicit template instantiations
steveire at gmail dot com
gcc-bugzilla@gcc.gnu.org
Wed Dec 11 13:59:00 GMT 2019
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=92914
Bug ID: 92914
Summary: Hidden visibility incompatible with extern'd
specialized explicit template instantiations
Product: gcc
Version: 10.0
Status: UNCONFIRMED
Severity: normal
Priority: P3
Component: c++
Assignee: unassigned at gcc dot gnu.org
Reporter: steveire at gmail dot com
Target Milestone: ---
I'm trying to use hidden visibility with a library which is already used with
MSVC. It uses exported explicit template specializations.
mylib.h:-------------
#pragma once
#if _MSC_VER
# ifdef mylib_EXPORTS
# define MYLIB_EXPORT __declspec(dllexport)
# else
# define MYLIB_EXPORT __declspec(dllimport)
# endif
#else
# ifdef mylib_EXPORTS
# define MYLIB_EXPORT __attribute__((visibility("default")))
# else
# define MYLIB_EXPORT
# endif
#endif
template<typename T>
class Templ
{
public:
T getNum() const;
T getAnotherNum() const;
};
#ifdef SPECIALIZE_INT
template<> MYLIB_EXPORT int Templ<int>::getNum() const;
#endif
#ifndef mylib_EXPORTS
extern template class Templ<int>;
extern template class Templ<float>;
#endif
-----------------
mylib.cpp---------
#include "mylib.h"
template<typename T>
T Templ<T>::getNum() const
{
return 7;
}
template<typename T>
T Templ<T>::getAnotherNum() const
{
return 5;
}
#ifdef SPECIALIZE_INT
template<>
int Templ<int>::getNum() const
{
return 42;
}
#endif
template class MYLIB_EXPORT Templ<int>;
template class MYLIB_EXPORT Templ<float>;
-----------------
main.cpp--------------
#include "mylib.h"
#include <iostream>
int main()
{
Templ<int> ti;
Templ<float> tf;
std::cout
<< ti.getNum() << " -- " << ti.getAnotherNum()
<< tf.getNum() << " -- " << tf.getAnotherNum() << std::endl;
return 0;
}
---------------------
build.sh--------------
#!/bin/sh
set -x
COMPILE_DRIVER=g++
COMPILE_DRIVER=clang++
$COMPILE_DRIVER -Dmylib_EXPORTS -fPIC -fvisibility=hidden
-fvisibility-inlines-hidden -o mylib.$COMPILE_DRIVER.o -c ../mylib.cpp
$COMPILE_DRIVER -fPIC -Wl,--no-undefined -shared -o libmylib.so
mylib.$COMPILE_DRIVER.o
$COMPILE_DRIVER -fvisibility=hidden -fvisibility-inlines-hidden -o
main.$COMPILE_DRIVER.o -c ../main.cpp
$COMPILE_DRIVER main.$COMPILE_DRIVER.o -o myexe -Wl,-rpath,$PWD libmylib.so
# Compile with SPECIALIZE_INT defined:
$COMPILE_DRIVER -DSPECIALIZE_INT -Dmylib_EXPORTS -fPIC -fvisibility=hidden
-fvisibility-inlines-hidden -o mylib.$COMPILE_DRIVER.o -c ../mylib.cpp
$COMPILE_DRIVER -fPIC -Wl,--no-undefined -shared -o libmylib.so
mylib.$COMPILE_DRIVER.o
$COMPILE_DRIVER -DSPECIALIZE_INT -fvisibility=hidden
-fvisibility-inlines-hidden -o main.$COMPILE_DRIVER.o -c ../main.cpp
$COMPILE_DRIVER main.$COMPILE_DRIVER.o -o myexe -Wl,-rpath,$PWD libmylib.so
-----------------------
clang ---------------
+ clang++ -Dmylib_EXPORTS -fPIC -fvisibility=hidden -fvisibility-inlines-hidden
-o mylib.clang++.o -c ../mylib.cpp
+ clang++ -fPIC -Wl,--no-undefined -shared -o libmylib.so mylib.clang++.o
+ clang++ -fvisibility=hidden -fvisibility-inlines-hidden -o main.clang++.o -c
../main.cpp
+ clang++ main.clang++.o -o myexe
-Wl,-rpath,/home/stephen/dev/src/playground/cpp/build libmylib.so
+ clang++ -DSPECIALIZE_INT -Dmylib_EXPORTS -fPIC -fvisibility=hidden
-fvisibility-inlines-hidden -o mylib.clang++.o -c ../mylib.cpp
+ clang++ -fPIC -Wl,--no-undefined -shared -o libmylib.so mylib.clang++.o
+ clang++ -DSPECIALIZE_INT -fvisibility=hidden -fvisibility-inlines-hidden -o
main.clang++.o -c ../main.cpp
+ clang++ main.clang++.o -o myexe
-Wl,-rpath,/home/stephen/dev/src/playground/cpp/build libmylib.so
---------------------------
While this works with clang above, it does not work with GCC:
gcc -------------------
+ g++ -Dmylib_EXPORTS -fPIC -fvisibility=hidden -fvisibility-inlines-hidden -o
mylib.g++.o -c ../mylib.cpp
+ g++ -fPIC -Wl,--no-undefined -shared -o libmylib.so mylib.g++.o
+ g++ -fvisibility=hidden -fvisibility-inlines-hidden -o main.g++.o -c
../main.cpp
+ g++ main.g++.o -o myexe -Wl,-rpath,/home/stephen/dev/src/playground/cpp/build
libmylib.so
+ g++ -DSPECIALIZE_INT -Dmylib_EXPORTS -fPIC -fvisibility=hidden
-fvisibility-inlines-hidden -o mylib.g++.o -c ../mylib.cpp
../mylib.cpp:24:29: warning: type attributes ignored after type is already
defined [-Wattributes]
template class MYLIB_EXPORT Templ<int>;
^~~~~~~~~~
+ g++ -fPIC -Wl,--no-undefined -shared -o libmylib.so mylib.g++.o
+ g++ -DSPECIALIZE_INT -fvisibility=hidden -fvisibility-inlines-hidden -o
main.g++.o -c ../main.cpp
+ g++ main.g++.o -o myexe -Wl,-rpath,/home/stephen/dev/src/playground/cpp/build
libmylib.so
main.g++.o: In function `main':
main.cpp:(.text+0x4c): undefined reference to `Templ<int>::getAnotherNum()
const'
collect2: error: ld returned 1 exit status
-----------------------
More information about the Gcc-bugs
mailing list