llvm / llvm-project

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

[C++] namespace extending namespace inside inline namespace mangled as if it wasn't inside the inline namespace #95154

Open MitalAshok opened 3 weeks ago

MitalAshok commented 3 weeks ago
#include <typeinfo>

inline namespace inline_namespace {
    namespace extended_outside {
        struct Y;
    }
}

int before = __builtin_printf("%s\n", typeid(inline_namespace::extended_outside::Y*).name());

namespace extended_outside {
    struct X {};
    struct Y {};
}

int main() {
    __builtin_printf("%s\n", typeid(inline_namespace::extended_outside::X).name());
    __builtin_printf("%s\n", typeid(inline_namespace::extended_outside::Y*).name());
}

With Itanium name mangling, this currently prints (clang trunk: https://godbolt.org/z/45d9dsfz9)

PN16inline_namespace16extended_outside1YE
N16extended_outside1XE
PN16extended_outside1YE

When it is expected to print (and does print with GCC):

PN16inline_namespace16extended_outside1YE
N16inline_namespace16extended_outside1XE
PN16inline_namespace16extended_outside1YE

This also applies to mangling of function/variable names if they physically appear in the second time the namespace is opened outside. Seems like the scope isn't calculated properly (it should be the same as if it was namespace inline_namespace::extended_outside {)

Relevant standard quote: https://eel.is/c++draft/namespace.def.general#2

llvmbot commented 3 weeks ago

@llvm/issue-subscribers-clang-frontend

Author: Mital Ashok (MitalAshok)

```c++ #include <typeinfo> inline namespace inline_namespace { namespace extended_outside { struct Y; } } int before = __builtin_printf("%s\n", typeid(inline_namespace::extended_outside::Y*).name()); namespace extended_outside { struct X {}; struct Y {}; } int main() { __builtin_printf("%s\n", typeid(inline_namespace::extended_outside::X).name()); __builtin_printf("%s\n", typeid(inline_namespace::extended_outside::Y*).name()); } ``` With Itanium name mangling, this currently prints (clang trunk: <https://godbolt.org/z/45d9dsfz9>) ```c++ PN16inline_namespace16extended_outside1YE N16extended_outside1XE PN16extended_outside1YE ``` When it is expected to print (and does print with GCC): ```c++ PN16inline_namespace16extended_outside1YE N16inline_namespace16extended_outside1XE PN16inline_namespace16extended_outside1YE ``` This also applies to mangling of function/variable names if they physically appear in the second time the namespace is opened outside. Seems like the scope isn't calculated properly (it should be the same as if it was `namespace inline_namespace::extended_outside {`) Relevant standard quote: https://eel.is/c++draft/namespace.def.general#2
shafik commented 3 weeks ago

This looks wrong but this is not my area.

CC @rjmccall @zygoloid

zygoloid commented 3 weeks ago

Yes, GCC is right. This was a core issue resolution from a few years back as I recall.