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

Reply via email to