royjacobson updated this revision to Diff 412557. royjacobson added a comment.
Thanks for the quick feedback :) I looked again at the AST and found out that there is a difference between instantiated and non-instantiated functions I missed - the instantiated functions have actual code AST. I had some trouble matching the actual generated AST, so I ended up testing that indirectly - I call a second 'canary' template function and validate that it was instantiated with the correct arguments. Couldn't think of something simpler unfortunately :/ Repository: rG LLVM Github Monorepo CHANGES SINCE LAST ACTION https://reviews.llvm.org/D120255/new/ https://reviews.llvm.org/D120255 Files: clang/lib/Sema/SemaTemplateInstantiate.cpp clang/test/AST/constraints-explicit-instantiation.cpp Index: clang/test/AST/constraints-explicit-instantiation.cpp =================================================================== --- /dev/null +++ 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>; +} Index: clang/lib/Sema/SemaTemplateInstantiate.cpp =================================================================== --- clang/lib/Sema/SemaTemplateInstantiate.cpp +++ 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<ExcludeFromExplicitInstantiationAttr>()) continue;
Index: clang/test/AST/constraints-explicit-instantiation.cpp =================================================================== --- /dev/null +++ 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>; +} Index: clang/lib/Sema/SemaTemplateInstantiate.cpp =================================================================== --- clang/lib/Sema/SemaTemplateInstantiate.cpp +++ 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<ExcludeFromExplicitInstantiationAttr>()) continue;
_______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits