Clang fails to resolve namespace alias in dependent member access (Two-Phase Lookup divergence from GCC)
- 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
Assessment
This issue has not been assessed yet.