Created attachment 38099 [details] Example Source Code If a class template is defined twice with the same name inside of anonymous namespaces in different translation units and then used as a template template parameter, the two templates are not treated as having globally unique names. Example: invoke.hh: #include <iostream> void invoke_foo(), invoke_bar(); template<template<int> class T> void invoke_print() { T<0>{}.print(); } foo.cc: #include "invoke.hh" namespace { template<int> struct s { void print() { std::cout << "foo\n"; } }; } void invoke_foo() { invoke_print<s>(); } bar.cc: #include "invoke.hh" namespace { template<int> struct s { void print() { std::cout << "bar\n"; } }; } void invoke_bar() { invoke_print<s>(); } main.cc: #include "invoke.hh" int main() { invoke_foo(); invoke_bar(); } Compile with g++ -obug main.cc foo.cc bar.cc -std=c++11 Expected output: foo bar Actual output: foo foo Tested with GCC 5.3.0 on x86_64. Clang 3.7.1 gets this right. The source files are attached.
Bumping this. We ran into a similar issue in GCC 6.3.0 on x86_64. We've ran the example provided by Fabian under GCC 6.3.0 on x86_64 and see the same unexpected result.
Confirmed. The problem is that _Z12invoke_printIN12_GLOBAL__N_11sEEvv is wrongly marked as comdat.
This gets wrongly set here: decl2.c: 2912 else if (DECL_TEMPLOID_INSTANTIATION (decl)) 2913 { 2914 /* DECL is an implicit instantiation of a function or static 2915 data member. */ 2916 if ((flag_implicit_templates 2917 && !flag_use_repository) 2918 || (flag_implicit_inline_templates 2919 && TREE_CODE (decl) == FUNCTION_DECL 2920 && DECL_DECLARED_INLINE_P (decl))) 2921 comdat_p = true; 2922 else But for instantiations with types defined in anon namespace this is wrong and "TREE_PUBLIC (decl) = 0" should be used instead.
Bumping this. We ran into a similar issue in GCC 6.3.0 on ARM with -flto. openSUSE enabled LTO by default, so we added a test case for all platforms which support LTO (including Debian with its stale packages that never get updated).
*** Bug 101695 has been marked as a duplicate of this bug. ***
*** Bug 107906 has been marked as a duplicate of this bug. ***
*** Bug 111423 has been marked as a duplicate of this bug. ***
The master branch has been updated by Patrick Palka <ppalka@gcc.gnu.org>: https://gcc.gnu.org/g:7226f825db049517b64442a40a6387513febb8f9 commit r14-6789-g7226f825db049517b64442a40a6387513febb8f9 Author: Patrick Palka <ppalka@redhat.com> Date: Thu Dec 21 13:53:43 2023 -0500 c++: visibility wrt template and ptrmem targs [PR70413] When constraining the visibility of an instantiation, we weren't properly considering the visibility of PTRMEM_CST and TEMPLATE_DECL template arguments. This patch fixes this. It turns out we don't maintain the relevant visibility flags for alias templates (e.g. TREE_PUBLIC is never set), so continue to ignore alias template template arguments for now. PR c++/70413 PR c++/107906 gcc/cp/ChangeLog: * decl2.cc (min_vis_expr_r): Handle PTRMEM_CST and TEMPLATE_DECL other than those for alias templates. gcc/testsuite/ChangeLog: * g++.dg/template/linkage2.C: New test. * g++.dg/template/linkage3.C: New test. * g++.dg/template/linkage4.C: New test. * g++.dg/template/linkage4a.C: New test.
Fixed for GCC 14 (other than the alias template template argument case which PR107906 tracks).