This is the mail archive of the gcc-bugs@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

[Bug c++/78160] New: explicit template instantation with hidden symbols fails


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()'

Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]