You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
[Modules] Don't replace local declarations with external declaration with lower visibility
Close#88400
For the reproducer:
```
//--- header.h
namespace N {
template<typename T>
concept X = true;
template<X T>
class Y {
public:
template<X U>
friend class Y;
};
inline Y<int> x;
}
//--- bar.cppm
module;
export module bar;
namespace N {
// To make sure N::Y won't get elided.
using N::x;
}
//--- foo.cc
// expected-no-diagnostics
import bar;
void y() {
N::Y<int> y{};
};
```
it will crash. The root cause is that in
`StoredDeclsList::replaceExternalDecls`, we will replace the
existing declarations with external declarations.
Then for the reproducer, the redecl chain for Y is like:
```
Y (Local) -> Y (Local, friend) -> Y (Imported) -> Y(Imported, friend)
```
Before the lookup, the stored lookup result is `Y(Local)` then we find
`Y(Imported)`. And now we repalce `Y(Local)` with `Y(Imported)`. But
`Y(Imported)` is not visible. So we tried to find if there is any
redeclarations visible but we find `Y(Local, friend)`, then problem
happens.
The solution is try to avoid the replace to happen if the external
declaration has lower visibility then we can always find the local
declarations. This may help the lookup performance slightly.
Also I found the implementation of
`StoredDeclsList::replaceExternalDecls` is not efficiency. It has an
`O(n*m)` complexities. But let's improve that in the future.
0 commit comments