Skip to content

Mangling the name of an externally visible lambda in a static data member of a class  #157

@dwblaikie

Description

@dwblaikie

Clang fails and emits these with local linkage and non-standard mangling (if they are actually internal, that'd be fine)
GCC emits these names without using the member name in the mangling and a numbering that's not local to the member, or even local to the type (similar names in subsequent classes get numberings that differ depending on the previous class - despite the class name in the mangling)
https://godbolt.org/z/7514cTh5o

struct A {
    static constexpr auto x = [] {
        return 1;
    };
};
template <typename>
struct B {
    static constexpr auto x = [] {
        return 1;
    };
};
template <typename T>
struct C {
    static int x;
};
void side_effect();
template <typename T>
int C<T>::x = (side_effect(), [] { return 1; }());
template int C<int>::x;
void f() {
    A::x();
    B<int>::x();
}

GCC produces these manglings:

A::{lambda()#1}::operator()() const
_ZNK1AUlvE_clEv

B<int>::{lambda()#3}::operator()() const
_ZNK1BIiEUlvE1_clEv

C<int>::x::{lambda()#1}::operator()() const
_ZNK1CIiE1xMUlvE_clEv

Clang produces these manglings:

A::$_0::operator()() const
_ZNK1A3$_0clEv

B<int>::x::{lambda()#1}::operator()() const
_ZNK1BIiE1xMUlvE_clEv

C<int>::x::{lambda()#1}::operator()() const
_ZNK1CIiE1xMUlvE_clEv

I think both GCC and Clang gets C right, Clang gets B right (& GCC gets it wrong) and both Clang and GCC get A wrong for different reasons. (and it should be like Clang's B behavior).

This is discussed in Clang (llvm/llvm-project#58819) and GCC (https://gcc.gnu.org/bugzilla/show_bug.cgi?id=107741)

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions