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

Reply via email to