[clang] 5aeaabf - [Concepts] Check constraints for explicit template instantiations
Erich Keane via cfe-commits
cfe-commits at lists.llvm.org
Thu Mar 3 06:33:54 PST 2022
Author: Roy Jacobson
Date: 2022-03-03T06:33:49-08:00
New Revision: 5aeaabf35eaddf9e5bfb05c0ec901a8aecfaa36a
URL: https://github.com/llvm/llvm-project/commit/5aeaabf35eaddf9e5bfb05c0ec901a8aecfaa36a
DIFF: https://github.com/llvm/llvm-project/commit/5aeaabf35eaddf9e5bfb05c0ec901a8aecfaa36a.diff
LOG: [Concepts] Check constraints for explicit template instantiations
The standard requires[0] member function constraints to be checked when
explicitly instantiating classes. This patch adds this constraints
check.
This issue is tracked as #46029 [1].
Note that there's an related open CWG issue (2421[2]) about what to do when
multiple candidates have satisfied constraints. This is particularly an
issue because mangling doesn't contain function constraints, and so the
following code still ICEs with definition with same mangled name
'_ZN1BIiE1fEv' as another definition:
template<class T>
struct B {
int f() requires std::same_as<T, int> {
return 0;
}
int f() requires (std::same_as<T, int> &&
!std::same_as<T, char>) {
return 1;
}
};
template struct B<int>;
Also note that the constraints checking while instantiating *functions*
is still not implemented. I started looking at it but It's a bit more
complicated. I believe in such a case we have to consider the partial
constraints order and potentially choose the best candidate out of the
set of multiple valid ones.
[0]: https://eel.is/c++draft/temp.explicit#10
[1]: https://github.com/llvm/llvm-project/issues/46029
[2]: https://cplusplus.github.io/CWG/issues/2421.html
Differential Revision: https://reviews.llvm.org/D120255
Added:
clang/test/AST/constraints-explicit-instantiation.cpp
Modified:
clang/lib/Sema/SemaTemplateInstantiate.cpp
Removed:
################################################################################
diff --git a/clang/lib/Sema/SemaTemplateInstantiate.cpp b/clang/lib/Sema/SemaTemplateInstantiate.cpp
index 2675665202971..46da97968a937 100644
--- a/clang/lib/Sema/SemaTemplateInstantiate.cpp
+++ b/clang/lib/Sema/SemaTemplateInstantiate.cpp
@@ -3230,6 +3230,14 @@ Sema::InstantiateClassMembers(SourceLocation PointOfInstantiation,
if (FunctionDecl *Pattern =
Function->getInstantiatedFromMemberFunction()) {
+ if (Function->getTrailingRequiresClause()) {
+ ConstraintSatisfaction Satisfaction;
+ if (CheckFunctionConstraints(Function, Satisfaction) ||
+ !Satisfaction.IsSatisfied) {
+ continue;
+ }
+ }
+
if (Function->hasAttr<ExcludeFromExplicitInstantiationAttr>())
continue;
diff --git a/clang/test/AST/constraints-explicit-instantiation.cpp b/clang/test/AST/constraints-explicit-instantiation.cpp
new file mode 100644
index 0000000000000..10b6432f2db8c
--- /dev/null
+++ b/clang/test/AST/constraints-explicit-instantiation.cpp
@@ -0,0 +1,38 @@
+// RUN: %clang_cc1 -std=c++20 -ast-dump %s | FileCheck %s
+
+namespace PR46029 {
+
+template <int N>
+void canary1();
+template <int N>
+void canary2();
+
+template <int N>
+struct A {
+ void f() requires(N == 1) {
+ static_assert(N == 1);
+ canary1<N>();
+ }
+ void f() requires(N == 2) {
+ static_assert(N == 2);
+ canary2<N>();
+ }
+};
+
+// This checks that `canary1<1>` and `canaray2<2>` are instantiated, thus
+// indirectly validating that the correct candidates of `A::f` were really
+// instantiated each time.
+// The `static_assert`s validate we don't instantiate wrong candidates.
+
+// CHECK:{{.*}}FunctionTemplateDecl {{.*}} canary1
+// CHECK: {{.*}}TemplateArgument integral
+// CHECK-SAME: {{1$}}
+template struct A<1>;
+
+// CHECK: {{.*}}FunctionTemplateDecl {{.*}} canary2
+// CHECK: {{.*}}TemplateArgument integral
+// CHECK-SAME: {{2$}}
+template struct A<2>;
+
+template struct A<3>;
+}
More information about the cfe-commits
mailing list