llvm / llvm-project

The LLVM Project is a collection of modular and reusable compiler and toolchain technologies.
http://llvm.org
Other
28.13k stars 11.62k forks source link

Incorrect deduplication of member of anonymous namespace in clang++17, 18, 19 #107642

Open mgibson-antithesis opened 2 weeks ago

mgibson-antithesis commented 2 weeks ago

The following compiles and links correctly with clang++16:

// header.h
#pragma once

#include <array>
#include <iostream>

struct Printer {
    const char* message;

    Printer(const char* message) : message(message) { }

    void print_stuff() {
        std::cout << message << std::endl;
    }
};

namespace { // Anonymous namespace which is translation-unit-specific; certain symbols aren't exposed in the symbol table as a result
    template <std::size_t N>
    struct fixed_string {
        std::array<char, N> contents;
        constexpr fixed_string( const char (&arr)[N] )
        {
            for(unsigned int i=0; i<N; i++) contents[i] = arr[i];
        }

        const char* c_str() const { return contents.data(); }
    };

    template <fixed_string message>
    struct Entry {
        [[clang::always_inline]] static inline Printer create() {
            return Printer(message.c_str());
        }

        static inline Printer printer = create();
    };
}

#define TEST(message) \
    Entry< \
        fixed_string(message) \
    >::printer.print_stuff()
// foo.cpp
#include "header.h"

void foo()
{
    TEST("Same name");
}
// bar.cpp
#include <iostream>
#include "header.h"

void bar()
{
    TEST("Same name");
}

int main(int argc, char** argv) {
    std::cout << "Hello, world" << std::endl;
    return 0;
}

Command line is:

$ clang++ --std=c++20 bar.cpp foo.cpp 
`.rodata._ZTAXtlN12_GLOBAL__N_112fixed_stringILm10EEEtlSt5arrayIcLm10EEtlA10_cLc83ELc97ELc109ELc101ELc32ELc110ELc97ELc109ELc101EEEEE' referenced in section `.data' of /run/user/1000/foo-70e9c4.o: defined in discarded section `.rodata._ZTAXtlN12_GLOBAL__N_112fixed_stringILm10EEEtlSt5arrayIcLm10EEtlA10_cLc83ELc97ELc109ELc101ELc32ELc110ELc97ELc109ELc101EEEEE[_ZTAXtlN12_GLOBAL__N_112fixed_stringILm10EEEtlSt5arrayIcLm10EEtlA10_cLc83ELc97ELc109ELc101ELc32ELc110ELc97ELc109ELc101EEEEE]' of /run/user/1000/foo-70e9c4.o
clang++: error: linker command failed with exit code 1 (use -v to see invocation)
EugeneZelenko commented 2 weeks ago

Could you please try 19 or main branch? https://godbolt.org should be helpful.

mgibson-antithesis commented 2 weeks ago

Same problem on 19.

[nix-shell:~/tmp/clang_bug]$ clang++ --version
clang version 19.1.0-rc3
Target: x86_64-unknown-linux-gnu
Thread model: posix
InstalledDir: /nix/store/sr89lhln99zkbzynqw7m1lmb445b6lx3-clang-19.1.0-rc3/bin

[nix-shell:~/tmp/clang_bug]$ clang++ -std=c++20 *.cpp
`.rodata._ZTAXtlN12_GLOBAL__N_112fixed_stringILm10EEEtlNSt3__15arrayIcLm10EEEtlA10_cLc83ELc97ELc109ELc101ELc32ELc110ELc97ELc109ELc101EEEEE' referenced in section `.data' of /tmp/foo-5b74f8.o: defined in discarded section `.rodata._ZTAXtlN12_GLOBAL__N_112fixed_stringILm10EEEtlNSt3__15arrayIcLm10EEEtlA10_cLc83ELc97ELc109ELc101ELc32ELc110ELc97ELc109ELc101EEEEE[_ZTAXtlN12_GLOBAL__N_112fixed_stringILm10EEEtlNSt3__15arrayIcLm10EEEtlA10_cLc83ELc97ELc109ELc101ELc32ELc110ELc97ELc109ELc101EEEEE]' of /tmp/foo-5b74f8.o
clang++: error: linker command failed with exit code 1 (use -v to see invocation)