llvm / llvm/llvm-project

[C++] ambiguity from inline namespace is not properly rejected

Open
#173,578 1 comment 0 reactions 0 assignees View on GitHub
clang:frontend diverges-from:gcc diverges-from:msvc
Dominant language
LLVM
Stars
40.5k
Forks
18.7k
PR merge metrics
PR metrics pending

Description

[Godbolt](https://godbolt.org/z/r7sdzoos3) inspired by [this example](https://github.com/llvm/llvm-project/issues/95154#issuecomment-3675173618)
```cpp
namespace a {
inline namespace b {
struct foo;
void f(const foo *);
} // namespace b
void f(const foo *);
} // namespace a

#if 1
struct a::foo {};
#endif

void a::f(const foo *) {
}
```

It seems that Clang has a different name resolution result from the other two major implementations, MSVC and GCC, which rejects this code on the basis of ambiguity around `void a::f(const foo *) {...}`.

My prudent guess here is that the other major implementations are correct in this matter from my interpretation of the ISO/IEC 14882-2011 text. Section 7.3.1 _Namespace definition_ Paragraph 8 says the following.
> a _using-directive_ (7.3.4) that names the inline namespace is implicitly inserted into the enclosing namespace as for
an unnamed namespace (7.3.1.1).

The existing rule concerning the `using namespace` directive already rejects ambiguous names arising from `a::f` as a proper member of `namespace a` and `a::b::f` through the implicit `using namespace b` inside `namespace a`. Unfortunately Clang as of writing accepts this code and resolves `void a::f(const foo *)` to `void a::b::f(const foo*)`.

Contributor guide

Open the contributing guide

Assessment

This issue has not been assessed yet.

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.