https://gcc.gnu.org/bugzilla/show_bug.cgi?id=78160
Bug ID: 78160 Summary: explicit template instantation with hidden symbols fails Product: gcc Version: 6.2.0 Status: UNCONFIRMED Severity: normal Priority: P3 Component: c++ Assignee: unassigned at gcc dot gnu.org Reporter: gcc at ebasoft dot com.pl Target Milestone: --- Created attachment 39922 --> https://gcc.gnu.org/bugzilla/attachment.cgi?id=39922&action=edit full source code with CMake configuration When some template struct is specialized in shared library on other type that has hidden visibility it passes compilation but no code is generated. This causes missing symbols in library. If base type is required to be default visible it should fail at compilation stage with error instead of causing hard to understand source of problems. I reproducted this error on gcc 5.4.1, 6.2.0 //Example code (full cmake project attached) ///LIBRARY HEADER some_shared.h //------------------------------ #include <cstdint> #include <memory> #define visibility_hidden __attribute__((visibility("hidden"))) #define visibility_default __attribute__((visibility("default"))) struct visibility_default base_spec_char { using value_type = char; char foo[10]; }; //SPECIALIZING ON THIS TYPE WILL CAUSE MISSING CODE AND SYMBOLS struct visibility_hidden base_spec_uint8 { using value_type = uint8_t; uint8_t foo[20]; }; template<typename VarStoreType> struct visibility_default var_t { using var_store_t = VarStoreType; using value_type = typename var_store_t::value_type; std::unique_ptr<var_store_t> alloc(); }; using varchar_t = var_t<base_spec_char>; using varbinary_t = var_t<base_spec_uint8>; ///LIBRARY SOURCE //------------------------------ #include "some_shared.h" template<typename T> std::unique_ptr<typename var_t<T>::var_store_t> var_t<T>::alloc( ) { return std::make_unique<var_store_t>(); } template struct var_t<base_spec_char>; template struct var_t<base_spec_uint8>; //MAIN PROGRAM LINKED TO SHARED LIBRARY #include <iostream> #include "some_shared.h" int main(int argc, char **argv) { varchar_t foo; varbinary_t bar; auto obj = foo.alloc(); auto obj2 = bar.alloc(); //<- unresolved symbols std::cout << "Hello, world!"<< obj.get()<< obj2.get() << std::endl; return 0; } main.cpp:10: undefined reference to `var_t<base_spec_uint8>::alloc()'