| Issue |
174769
|
| Summary |
[C++ Modules] Access control failure: Exported template calling non-exported friend function template
|
| Labels |
new issue
|
| Assignees |
|
| Reporter |
QuaziElectro
|
**Description:**
I have encountered a bug where Clang fails to respect a `friend` declaration when the friend function is a **non-exported template** called by an **exported template** within the same module.
When the exported template (`Func2`) is instantiated from an external consumer (e.g., `main`), it calls the internal friend function (`Func1`). Clang correctly finds `Func1` but fails the access check for the private constructor it attempts to access, acting as if the friendship does not exist.
**Variations observed:**
* **Fails:** `Func1` is *not exported* + `Func2` *is a template* (The reproduction below).
* **Works:** If `Func1` is also `export`ed.
* **Works:** If `Func2` is a regular function (not a template).
**Environment:**
* **Compiler:** Clang 21.1.8
* **Target:** x86_64-pc-windows-msvc
* **Standard:** `-std=c++26`
**Reproduction:**
**`L1.cppm`**
```cpp
module;
export module L1;
template<int>
class Class
{
// Friend declaration
template<int> friend void Func1();
Class() {}; // Private constructor
};
// Non-exported friend function template
template<int t>
void Func1()
{
// Should have access to Class<t> private constructor
Class<t>();
}
// Exported interface template
export template<int>
void Func2()
{
// Calls the non-exported friend
Func1<0>();
};
```
**`main.cpp`**
```cpp
import L1;
int main()
{
// Triggers instantiation of Func2, which calls Func1
Func2<0>();
}
```
**Compilation Command:**
```cmd
clang++ -std=c++26 --precompile -x c++-module L1.cppm -o L1.pcm
clang++ -std=c++26 main.cpp -fmodule-file=L1=L1.pcm -o test.exe
```
**Actual Results (Error Log):**
```text
In file included from main.cpp:1:
L1.cppm:15:2: error: calling a private constructor of class 'Class<0>'
15 | Class<t>();
| ^
L1.cppm:21:2: note: in instantiation of function template specialization 'Func1<0>' requested here
21 | Func1<0>();
| ^
main.cpp:5:2: note: in instantiation of function template specialization 'Func2<0>' requested here
5 | Func2<0>();
| ^
L1.cppm:8:2: note: implicitly declared private here
8 | Class() {};
| ^
1 error generated.
```
**Expected Results:**
The code should compile successfully. `Func1` is defined in the same module unit as `Class` and is explicitly declared as a friend. The fact that `Func2` is a template instantiated from outside the module should not break the visibility of the friendship inside `L1`.
_______________________________________________
llvm-bugs mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-bugs