Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Recommit [C++20] [Modules] Trying to compare the trailing require cla…
…use from the primary template function Close #60890. For the following example: ``` export module a; export template<typename T> struct a { friend void aa(a) requires(true) { } }; ``` ``` export module b; import a; struct b { a<int> m; }; ``` ``` export module c; import a; struct c { void f() const { aa(a<int>()); } }; ``` ``` import a; import b; import c; void d() { aa(a<int>()); } ``` The current clang will reject this incorrectly. The reason is that the require clause will be replaced with the evaluated version (https://github.com/llvm/llvm-project/blob/efae3174f09560353fb0f3d528bcbffe060d5438/clang/lib/Sema/SemaConcept.cpp#L664-L665). In module 'b', the friend function is instantiated but not used so the require clause of the friend function is `(true)`. However, in module 'c', the friend function is used so the require clause is `true`. So deserializer classify these two function to two different functions instead of one. Then here is the bug report. The proposed solution is to try to compare the trailing require clause of the primary template when performing ODR checking. Reviewed By: erichkeane Differential Revision: https://reviews.llvm.org/D144626
- Loading branch information
1 parent
8a023fe
commit 2408f97
Showing
2 changed files
with
108 additions
and
3 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,82 @@ | ||
// https://github.com/llvm/llvm-project/issues/60890 | ||
// | ||
// RUN: rm -rf %t | ||
// RUN: mkdir -p %t | ||
// RUN: split-file %s %t | ||
// | ||
// RUN: %clang_cc1 -std=c++20 -emit-module-interface %t/a.cppm -o %t/a.pcm | ||
// RUN: %clang_cc1 -std=c++20 -emit-module-interface %t/b.cppm -fprebuilt-module-path=%t -o %t/b.pcm | ||
// RUN: %clang_cc1 -std=c++20 -emit-module-interface %t/c.cppm -fprebuilt-module-path=%t -o %t/c.pcm | ||
// RUN: %clang_cc1 -std=c++20 %t/d.cpp -fprebuilt-module-path=%t -S -emit-llvm -o - | ||
|
||
//--- a.cppm | ||
export module a; | ||
|
||
export template<typename T> | ||
struct a { | ||
friend void aa(a x) requires(true) {} | ||
void aaa() requires(true) {} | ||
}; | ||
|
||
export template struct a<double>; | ||
|
||
export template<typename T> | ||
void foo(T) requires(true) {} | ||
|
||
export template void foo<double>(double); | ||
|
||
export template <typename T> | ||
class A { | ||
friend void foo<>(A); | ||
}; | ||
|
||
//--- b.cppm | ||
export module b; | ||
|
||
import a; | ||
|
||
void b() { | ||
a<int> _; | ||
a<double> __; | ||
} | ||
|
||
//--- c.cppm | ||
export module c; | ||
|
||
import a; | ||
|
||
struct c { | ||
void f() const { | ||
a<int> _; | ||
aa(_); | ||
_.aaa(); | ||
|
||
a<double> __; | ||
aa(__); | ||
__.aaa(); | ||
|
||
foo<int>(5); | ||
foo<double>(3.0); | ||
foo(A<int>()); | ||
} | ||
}; | ||
|
||
//--- d.cpp | ||
// expected-no-diagnostics | ||
import a; | ||
import b; | ||
import c; | ||
|
||
void d() { | ||
a<int> _; | ||
aa(_); | ||
_.aaa(); | ||
|
||
a<double> __; | ||
aa(__); | ||
__.aaa(); | ||
|
||
foo<int>(5); | ||
foo<double>(3.0); | ||
foo(A<int>()); | ||
} |