https://gcc.gnu.org/bugzilla/show_bug.cgi?id=119195
Bug ID: 119195 Summary: GCC 14.2.0: Incorrect Handling of const std::string_view& as a Template Argument Product: gcc Version: 14.2.0 Status: UNCONFIRMED Severity: normal Priority: P3 Component: c++ Assignee: unassigned at gcc dot gnu.org Reporter: hansolshin at vacuumzero dot com Target Milestone: --- Using const std::string_view& as a template argument in GCC 14.2.0 causes the function to be assigned weak symbols (W) with global visibility when its argument is local to the translation unit (e.g., a reference to static constexpr std::string_view defined in a single source file). This can lead to incorrect symbol resolution at link time. This issue does not occur in GCC 13.3.0, suggesting a regression in GCC 14.2.0. Minimal Reproducer: a.hpp: #pragma once #include <string_view> template <const std::string_view& Str> auto get_length() { return Str.length(); } main.cpp: #include <iostream> #include "a.hpp" namespace { static constexpr std::string_view sssss = "123"; } int main() { std::cout << get_length<sssss>() << std::endl; return 0; } unused.cpp: #include <string_view> #include "a.hpp" namespace { static constexpr std::string_view sssss = "12345"; } auto unused_function() { return get_length<sssss>(); } Build and Run Commands: g++ -std=c++23 -c -o main.o main.cpp g++ -std=c++23 -c -o unused.o unused.cpp g++ -std=c++23 -o out unused.o main.o ./out Expected Output: 3 Actual Output (GCC 14.2.0): 5 Analysis: Running nm on the object files shows that both unused.o and main.o define the same weak symbol (W) with global visibility. nm unused.o | grep get_length 0000000000000000 W _Z10get_lengthIL_ZN12_GLOBAL__N_1L5sssssEEEDav nm main.o | grep get_length 0000000000000000 W _Z10get_lengthIL_ZN12_GLOBAL__N_1L5sssssEEEDav Since the function is emitted as 'W' (a weak symbol with global visibility) instead of 'w' (local visibility), the linker arbitrarily picks one definition, which results in incorrect program output. Regression: GCC 14.2.0 → Bug occurs GCC 13.3.0 → Works correctly Expected Behavior: Each translation unit should have a distinct instantiation of get_length<sssss>(), since sssss has different addresses. Instead, GCC incorrectly treats them as the same, leading to linker issues. Additional Information: GCC Version: 14.2.0 Target Architecture: x86_64-pc-linux-gnu OS: Ubuntu 24.04.2 LTS