llvm / llvm/llvm-project

Clang fails to resolve namespace alias in dependent member access (Two-Phase Lookup divergence from GCC)

Open
#190,146 2 comments 0 reactions 0 assignees View on GitHub
clang:frontend needs-reduction
Dominant language
LLVM
Stars
40.5k
Forks
18.7k
PR merge metrics
PR metrics pending

Description

### **Description**
When calling a destructor through a pointer to a dependent type member, `clang++` fails to resolve a namespace alias that is visible in the current scope, whereas `g++` (GCC) handles it correctly. This appears to be a difference in how the two compilers handle name lookup on the right-hand side of the `->` operator during Phase 1 of template parsing.

### **Environment**
* **Compiler:** `clang++` (Observed in versions 10.0 through latest)
* **Comparison:** `g++` (Compiles successfully)
* **Standards:** Reproducible with `-std=c++11`, `-std=c++14`, and `-std=c++17`

### **Minimal Reproducible Example**
```cpp
#include

// Mocking a library structure (e.g., Boost.Container PMR)
namespace boost {
namespace container {
namespace pmr {
class monotonic_buffer_resource {
public:
monotonic_buffer_resource() = default;
~monotonic_buffer_resource() = default;
};
}
}
}

namespace std {
namespace pmr = boost::container::pmr;
}

// Local namespace alias
namespace {
namespace pmr = std::pmr;
}

template
struct ObjectWrapperHeadWithBuff {
pmr::monotonic_buffer_resource buff_;
};

template
struct ObjectChunkHead {
static void Destroy(T *obj) {
auto wrapper_ptr = reinterpret_cast *>(obj);

// Clang error here: "use of undeclared identifier 'pmr'"
// GCC: Compiles successfully
std::addressof(wrapper_ptr->buff_)
->pmr::monotonic_buffer_resource::~monotonic_buffer_resource();
}
};

int main() {
ObjectWrapperHeadWithBuff obj;
ObjectChunkHead::Destroy(reinterpret_cast(&obj));
return 0;
}
```

### **Steps to Reproduce**
1. Compile with Clang:
`clang++ -std=c++11 reproduce.cpp -o reproduce`
**Result:** `error: use of undeclared identifier 'pmr'`

2. Compile with GCC:
`g++ -std=c++11 reproduce.cpp -o reproduce`
**Result:** Compilation successful.

### **Expected Behavior**
The compiler should be able to look up `pmr` in the lexical scope when it cannot be found as a member of the dependent class `ObjectWrapperHeadWithBuff`, especially since the `::` suffix clearly indicates a namespace or nested type rather than a data member.

### **Workaround Found**
Explicitly qualifying the namespace from the global scope (`->::pmr::...`) or removing the namespace qualification for the destructor call entirely (`->~monotonic_buffer_resource()`) allows Clang to compile.

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.