diff --git a/clang/lib/Sema/SemaTemplateInstantiate.cpp b/clang/lib/Sema/SemaTemplateInstantiate.cpp --- a/clang/lib/Sema/SemaTemplateInstantiate.cpp +++ b/clang/lib/Sema/SemaTemplateInstantiate.cpp @@ -3230,6 +3230,14 @@ if (FunctionDecl *Pattern = Function->getInstantiatedFromMemberFunction()) { + if (Function->getTrailingRequiresClause()) { + ConstraintSatisfaction Satisfaction; + if (CheckFunctionConstraints(Function, Satisfaction) || + !Satisfaction.IsSatisfied) { + continue; + } + } + if (Function->hasAttr()) continue; diff --git a/clang/test/AST/constraints-explicit-instantiation.cpp b/clang/test/AST/constraints-explicit-instantiation.cpp new file mode 100644 --- /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 +void canary1(); +template +void canary2(); + +template +struct A { + void f() requires(N == 1) { + static_assert(N == 1); + canary1(); + } + void f() requires(N == 2) { + static_assert(N == 2); + canary2(); + } +}; + +// 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>; +}