[clang] [Clang][Sema] Do not mark template parameters in the exception specification as used during partial ordering (PR #91534)
https://github.com/sdkrystian closed https://github.com/llvm/llvm-project/pull/91534 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [Clang][Sema] Do not mark template parameters in the exception specification as used during partial ordering (PR #91534)
https://github.com/sdkrystian updated https://github.com/llvm/llvm-project/pull/91534 >From 34af5511804b8c0fd8b0d742653f6017dd8e9e87 Mon Sep 17 00:00:00 2001 From: Krystian Stasiowski Date: Wed, 8 May 2024 08:43:23 -0400 Subject: [PATCH 1/2] [Clang][Sema] Do not mark template parameters in the exception specification as used during partial ordering --- clang/lib/Sema/SemaTemplateDeduction.cpp | 36 +++--- .../temp.deduct/temp.deduct.partial/p3.cpp| 72 +++ 2 files changed, 100 insertions(+), 8 deletions(-) create mode 100644 clang/test/CXX/temp/temp.fct.spec/temp.deduct/temp.deduct.partial/p3.cpp diff --git a/clang/lib/Sema/SemaTemplateDeduction.cpp b/clang/lib/Sema/SemaTemplateDeduction.cpp index 853c0e1b50619..b5d405111fe4c 100644 --- a/clang/lib/Sema/SemaTemplateDeduction.cpp +++ b/clang/lib/Sema/SemaTemplateDeduction.cpp @@ -5453,7 +5453,7 @@ static bool isAtLeastAsSpecializedAs(Sema , SourceLocation Loc, // is used. if (DeduceTemplateArgumentsByTypeMatch( S, TemplateParams, FD2->getType(), FD1->getType(), Info, Deduced, -TDF_None, +TDF_AllowCompatibleFunctionType, /*PartialOrdering=*/true) != TemplateDeductionResult::Success) return false; break; @@ -5485,20 +5485,40 @@ static bool isAtLeastAsSpecializedAs(Sema , SourceLocation Loc, switch (TPOC) { case TPOC_Call: for (unsigned I = 0, N = Args2.size(); I != N; ++I) - ::MarkUsedTemplateParameters(S.Context, Args2[I], false, - TemplateParams->getDepth(), - UsedParameters); + ::MarkUsedTemplateParameters(S.Context, Args2[I], /*OnlyDeduced=*/false, + TemplateParams->getDepth(), UsedParameters); break; case TPOC_Conversion: -::MarkUsedTemplateParameters(S.Context, Proto2->getReturnType(), false, +::MarkUsedTemplateParameters(S.Context, Proto2->getReturnType(), + /*OnlyDeduced=*/false, TemplateParams->getDepth(), UsedParameters); break; case TPOC_Other: -::MarkUsedTemplateParameters(S.Context, FD2->getType(), false, - TemplateParams->getDepth(), - UsedParameters); +// We do not deduce template arguments from the exception specification +// when determining the primary template of a function template +// specialization or when taking the address of a function template. +// Therefore, we do not mark template parameters in the exception +// specification as used during partial ordering to prevent the following +// from being ambiguous: +// +// template +// void f(U) noexcept(noexcept(T())); // #1 +// +// template +// void f(T*) noexcept; // #2 +// +// template<> +// void f(int*) noexcept; // explicit specialization of #2 +// +// Although there is no corresponding wording in the standard, this seems +// to be the intended behavior given the definition of +// 'deduction substitution loci' in [temp.deduct]. +::MarkUsedTemplateParameters( +S.Context, +S.Context.getFunctionTypeWithExceptionSpec(FD2->getType(), EST_None), +/*OnlyDeduced=*/false, TemplateParams->getDepth(), UsedParameters); break; } diff --git a/clang/test/CXX/temp/temp.fct.spec/temp.deduct/temp.deduct.partial/p3.cpp b/clang/test/CXX/temp/temp.fct.spec/temp.deduct/temp.deduct.partial/p3.cpp new file mode 100644 index 0..cc1d4ecda2ecc --- /dev/null +++ b/clang/test/CXX/temp/temp.fct.spec/temp.deduct/temp.deduct.partial/p3.cpp @@ -0,0 +1,72 @@ +// RUN: %clang_cc1 -fsyntax-only -verify %s +// expected-no-diagnostics + +template +struct A { }; + +constexpr A a; +constexpr A b; + +constexpr int* x = nullptr; +constexpr short* y = nullptr; + +namespace ExplicitArgs { + template + constexpr int f(U) noexcept(noexcept(T())) { +return 0; + } + + template + constexpr int f(T*) noexcept { +return 1; + } + + template<> + constexpr int f(int*) noexcept { +return 2; + } + + static_assert(f(1) == 0); + static_assert(f(y) == 1); + static_assert(f(x) == 2); + + template + constexpr int g(U*) noexcept(noexcept(T())) { +return 3; + } + + template + constexpr int g(T) noexcept { +return 4; + } + + template<> + constexpr int g(int*) noexcept { +return 5; + } + + static_assert(g(y) == 3); + static_assert(g(1) == 4); + static_assert(g(x) == 5); +} // namespace ExplicitArgs + +namespace DeducedArgs { + template + constexpr int f(T, A) noexcept(B) { +return 0; + } + + template + constexpr int f(T*, A) noexcept(B && B) { +return 1; + } + + template<> + constexpr int f(int*, A) { +return 2; + } + + static_assert(f(x, a) == 0); + static_assert(f(y, a) == 1); + static_assert(f(x, a) == 2); +} // namespace DeducedArgs >From
[clang] [Clang][Sema] Do not mark template parameters in the exception specification as used during partial ordering (PR #91534)
@@ -5485,20 +5485,40 @@ static bool isAtLeastAsSpecializedAs(Sema , SourceLocation Loc, switch (TPOC) { case TPOC_Call: for (unsigned I = 0, N = Args2.size(); I != N; ++I) - ::MarkUsedTemplateParameters(S.Context, Args2[I], false, - TemplateParams->getDepth(), - UsedParameters); + ::MarkUsedTemplateParameters(S.Context, Args2[I], /*OnlyDeduced=*/false, + TemplateParams->getDepth(), UsedParameters); break; case TPOC_Conversion: -::MarkUsedTemplateParameters(S.Context, Proto2->getReturnType(), false, +::MarkUsedTemplateParameters(S.Context, Proto2->getReturnType(), + /*OnlyDeduced=*/false, TemplateParams->getDepth(), UsedParameters); break; case TPOC_Other: -::MarkUsedTemplateParameters(S.Context, FD2->getType(), false, - TemplateParams->getDepth(), - UsedParameters); +// We do not deduce template arguments from the exception specification +// when determining the primary template of a function template +// specialization or when taking the address of a function template. +// Therefore, we do not mark template parameters in the exception +// specification as used during partial ordering to prevent the following +// from being ambiguous: +// +// template +// void f(U) noexcept(noexcept(T())); // #1 +// +// template +// void f(T*) noexcept; // #2 +// +// template<> +// void f(int*) noexcept; // explicit specialization of #2 +// +// Although there is no corresponding wording in the standard, this seems sdkrystian wrote: I've seen it take anywhere from a day to a month. I'll be sure to update this once the issue is opened! https://github.com/llvm/llvm-project/pull/91534 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [Clang][Sema] Do not mark template parameters in the exception specification as used during partial ordering (PR #91534)
@@ -5485,20 +5485,40 @@ static bool isAtLeastAsSpecializedAs(Sema , SourceLocation Loc, switch (TPOC) { case TPOC_Call: for (unsigned I = 0, N = Args2.size(); I != N; ++I) - ::MarkUsedTemplateParameters(S.Context, Args2[I], false, - TemplateParams->getDepth(), - UsedParameters); + ::MarkUsedTemplateParameters(S.Context, Args2[I], /*OnlyDeduced=*/false, + TemplateParams->getDepth(), UsedParameters); break; case TPOC_Conversion: -::MarkUsedTemplateParameters(S.Context, Proto2->getReturnType(), false, +::MarkUsedTemplateParameters(S.Context, Proto2->getReturnType(), + /*OnlyDeduced=*/false, TemplateParams->getDepth(), UsedParameters); break; case TPOC_Other: -::MarkUsedTemplateParameters(S.Context, FD2->getType(), false, - TemplateParams->getDepth(), - UsedParameters); +// We do not deduce template arguments from the exception specification +// when determining the primary template of a function template +// specialization or when taking the address of a function template. +// Therefore, we do not mark template parameters in the exception +// specification as used during partial ordering to prevent the following +// from being ambiguous: +// +// template +// void f(U) noexcept(noexcept(T())); // #1 +// +// template +// void f(T*) noexcept; // #2 +// +// template<> +// void f(int*) noexcept; // explicit specialization of #2 +// +// Although there is no corresponding wording in the standard, this seems erichkeane wrote: Jens is usually really quick at assigning a core issue, right? That said, you can merge this before getting one as long as you come back afterwards and fill it in. https://github.com/llvm/llvm-project/pull/91534 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [Clang][Sema] Do not mark template parameters in the exception specification as used during partial ordering (PR #91534)
@@ -5485,20 +5485,40 @@ static bool isAtLeastAsSpecializedAs(Sema , SourceLocation Loc, switch (TPOC) { case TPOC_Call: for (unsigned I = 0, N = Args2.size(); I != N; ++I) - ::MarkUsedTemplateParameters(S.Context, Args2[I], false, - TemplateParams->getDepth(), - UsedParameters); + ::MarkUsedTemplateParameters(S.Context, Args2[I], /*OnlyDeduced=*/false, + TemplateParams->getDepth(), UsedParameters); break; case TPOC_Conversion: -::MarkUsedTemplateParameters(S.Context, Proto2->getReturnType(), false, +::MarkUsedTemplateParameters(S.Context, Proto2->getReturnType(), + /*OnlyDeduced=*/false, TemplateParams->getDepth(), UsedParameters); break; case TPOC_Other: -::MarkUsedTemplateParameters(S.Context, FD2->getType(), false, - TemplateParams->getDepth(), - UsedParameters); +// We do not deduce template arguments from the exception specification +// when determining the primary template of a function template +// specialization or when taking the address of a function template. +// Therefore, we do not mark template parameters in the exception +// specification as used during partial ordering to prevent the following +// from being ambiguous: +// +// template +// void f(U) noexcept(noexcept(T())); // #1 +// +// template +// void f(T*) noexcept; // #2 +// +// template<> +// void f(int*) noexcept; // explicit specialization of #2 +// +// Although there is no corresponding wording in the standard, this seems sdkrystian wrote: @erichkeane Filed an issue [here](https://github.com/cplusplus/CWG/issues/537). It might be a little while before an actual core issue is opened, so would it be alright to merge this before that happens? https://github.com/llvm/llvm-project/pull/91534 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [Clang][Sema] Do not mark template parameters in the exception specification as used during partial ordering (PR #91534)
https://github.com/erichkeane approved this pull request. LGTM other than including the CWG issue to the comment. Feel free to merge once that is in place. https://github.com/llvm/llvm-project/pull/91534 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [Clang][Sema] Do not mark template parameters in the exception specification as used during partial ordering (PR #91534)
sdkrystian wrote: @erichkeane Release note added https://github.com/llvm/llvm-project/pull/91534 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [Clang][Sema] Do not mark template parameters in the exception specification as used during partial ordering (PR #91534)
https://github.com/sdkrystian updated https://github.com/llvm/llvm-project/pull/91534 >From eea39228271166b4d8f39b32d7866cb33dffdd0b Mon Sep 17 00:00:00 2001 From: Krystian Stasiowski Date: Wed, 8 May 2024 08:43:23 -0400 Subject: [PATCH 1/2] [Clang][Sema] Do not mark template parameters in the exception specification as used during partial ordering --- clang/lib/Sema/SemaTemplateDeduction.cpp | 36 +++--- .../temp.deduct/temp.deduct.partial/p3.cpp| 72 +++ 2 files changed, 100 insertions(+), 8 deletions(-) create mode 100644 clang/test/CXX/temp/temp.fct.spec/temp.deduct/temp.deduct.partial/p3.cpp diff --git a/clang/lib/Sema/SemaTemplateDeduction.cpp b/clang/lib/Sema/SemaTemplateDeduction.cpp index fe7e35d841510..c17c5838803a8 100644 --- a/clang/lib/Sema/SemaTemplateDeduction.cpp +++ b/clang/lib/Sema/SemaTemplateDeduction.cpp @@ -5453,7 +5453,7 @@ static bool isAtLeastAsSpecializedAs(Sema , SourceLocation Loc, // is used. if (DeduceTemplateArgumentsByTypeMatch( S, TemplateParams, FD2->getType(), FD1->getType(), Info, Deduced, -TDF_None, +TDF_AllowCompatibleFunctionType, /*PartialOrdering=*/true) != TemplateDeductionResult::Success) return false; break; @@ -5485,20 +5485,40 @@ static bool isAtLeastAsSpecializedAs(Sema , SourceLocation Loc, switch (TPOC) { case TPOC_Call: for (unsigned I = 0, N = Args2.size(); I != N; ++I) - ::MarkUsedTemplateParameters(S.Context, Args2[I], false, - TemplateParams->getDepth(), - UsedParameters); + ::MarkUsedTemplateParameters(S.Context, Args2[I], /*OnlyDeduced=*/false, + TemplateParams->getDepth(), UsedParameters); break; case TPOC_Conversion: -::MarkUsedTemplateParameters(S.Context, Proto2->getReturnType(), false, +::MarkUsedTemplateParameters(S.Context, Proto2->getReturnType(), + /*OnlyDeduced=*/false, TemplateParams->getDepth(), UsedParameters); break; case TPOC_Other: -::MarkUsedTemplateParameters(S.Context, FD2->getType(), false, - TemplateParams->getDepth(), - UsedParameters); +// We do not deduce template arguments from the exception specification +// when determining the primary template of a function template +// specialization or when taking the address of a function template. +// Therefore, we do not mark template parameters in the exception +// specification as used during partial ordering to prevent the following +// from being ambiguous: +// +// template +// void f(U) noexcept(noexcept(T())); // #1 +// +// template +// void f(T*) noexcept; // #2 +// +// template<> +// void f(int*) noexcept; // explicit specialization of #2 +// +// Although there is no corresponding wording in the standard, this seems +// to be the intended behavior given the definition of +// 'deduction substitution loci' in [temp.deduct]. +::MarkUsedTemplateParameters( +S.Context, +S.Context.getFunctionTypeWithExceptionSpec(FD2->getType(), EST_None), +/*OnlyDeduced=*/false, TemplateParams->getDepth(), UsedParameters); break; } diff --git a/clang/test/CXX/temp/temp.fct.spec/temp.deduct/temp.deduct.partial/p3.cpp b/clang/test/CXX/temp/temp.fct.spec/temp.deduct/temp.deduct.partial/p3.cpp new file mode 100644 index 0..cc1d4ecda2ecc --- /dev/null +++ b/clang/test/CXX/temp/temp.fct.spec/temp.deduct/temp.deduct.partial/p3.cpp @@ -0,0 +1,72 @@ +// RUN: %clang_cc1 -fsyntax-only -verify %s +// expected-no-diagnostics + +template +struct A { }; + +constexpr A a; +constexpr A b; + +constexpr int* x = nullptr; +constexpr short* y = nullptr; + +namespace ExplicitArgs { + template + constexpr int f(U) noexcept(noexcept(T())) { +return 0; + } + + template + constexpr int f(T*) noexcept { +return 1; + } + + template<> + constexpr int f(int*) noexcept { +return 2; + } + + static_assert(f(1) == 0); + static_assert(f(y) == 1); + static_assert(f(x) == 2); + + template + constexpr int g(U*) noexcept(noexcept(T())) { +return 3; + } + + template + constexpr int g(T) noexcept { +return 4; + } + + template<> + constexpr int g(int*) noexcept { +return 5; + } + + static_assert(g(y) == 3); + static_assert(g(1) == 4); + static_assert(g(x) == 5); +} // namespace ExplicitArgs + +namespace DeducedArgs { + template + constexpr int f(T, A) noexcept(B) { +return 0; + } + + template + constexpr int f(T*, A) noexcept(B && B) { +return 1; + } + + template<> + constexpr int f(int*, A) { +return 2; + } + + static_assert(f(x, a) == 0); + static_assert(f(y, a) == 1); + static_assert(f(x, a) == 2); +} // namespace DeducedArgs >From
[clang] [Clang][Sema] Do not mark template parameters in the exception specification as used during partial ordering (PR #91534)
@@ -5485,20 +5485,40 @@ static bool isAtLeastAsSpecializedAs(Sema , SourceLocation Loc, switch (TPOC) { case TPOC_Call: for (unsigned I = 0, N = Args2.size(); I != N; ++I) - ::MarkUsedTemplateParameters(S.Context, Args2[I], false, - TemplateParams->getDepth(), - UsedParameters); + ::MarkUsedTemplateParameters(S.Context, Args2[I], /*OnlyDeduced=*/false, + TemplateParams->getDepth(), UsedParameters); break; case TPOC_Conversion: -::MarkUsedTemplateParameters(S.Context, Proto2->getReturnType(), false, +::MarkUsedTemplateParameters(S.Context, Proto2->getReturnType(), + /*OnlyDeduced=*/false, TemplateParams->getDepth(), UsedParameters); break; case TPOC_Other: -::MarkUsedTemplateParameters(S.Context, FD2->getType(), false, - TemplateParams->getDepth(), - UsedParameters); +// We do not deduce template arguments from the exception specification +// when determining the primary template of a function template +// specialization or when taking the address of a function template. +// Therefore, we do not mark template parameters in the exception +// specification as used during partial ordering to prevent the following +// from being ambiguous: +// +// template +// void f(U) noexcept(noexcept(T())); // #1 +// +// template +// void f(T*) noexcept; // #2 +// +// template<> +// void f(int*) noexcept; // explicit specialization of #2 +// +// Although there is no corresponding wording in the standard, this seems sdkrystian wrote: I'll open it tomorrow https://github.com/llvm/llvm-project/pull/91534 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [Clang][Sema] Do not mark template parameters in the exception specification as used during partial ordering (PR #91534)
@@ -5485,20 +5485,40 @@ static bool isAtLeastAsSpecializedAs(Sema , SourceLocation Loc, switch (TPOC) { case TPOC_Call: for (unsigned I = 0, N = Args2.size(); I != N; ++I) - ::MarkUsedTemplateParameters(S.Context, Args2[I], false, - TemplateParams->getDepth(), - UsedParameters); + ::MarkUsedTemplateParameters(S.Context, Args2[I], /*OnlyDeduced=*/false, + TemplateParams->getDepth(), UsedParameters); break; case TPOC_Conversion: -::MarkUsedTemplateParameters(S.Context, Proto2->getReturnType(), false, +::MarkUsedTemplateParameters(S.Context, Proto2->getReturnType(), + /*OnlyDeduced=*/false, TemplateParams->getDepth(), UsedParameters); break; case TPOC_Other: -::MarkUsedTemplateParameters(S.Context, FD2->getType(), false, - TemplateParams->getDepth(), - UsedParameters); +// We do not deduce template arguments from the exception specification +// when determining the primary template of a function template +// specialization or when taking the address of a function template. +// Therefore, we do not mark template parameters in the exception +// specification as used during partial ordering to prevent the following +// from being ambiguous: +// +// template +// void f(U) noexcept(noexcept(T())); // #1 +// +// template +// void f(T*) noexcept; // #2 +// +// template<> +// void f(int*) noexcept; // explicit specialization of #2 +// +// Although there is no corresponding wording in the standard, this seems erichkeane wrote: Please file a core issue here! It would be great to get this fixed in CWG. @Endilll or @shafik can help with that if you need it. Also, put the CWG issue # in this comment once we have it. https://github.com/llvm/llvm-project/pull/91534 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [Clang][Sema] Do not mark template parameters in the exception specification as used during partial ordering (PR #91534)
https://github.com/erichkeane approved this pull request. This probably also needs a release note. https://github.com/llvm/llvm-project/pull/91534 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [Clang][Sema] Do not mark template parameters in the exception specification as used during partial ordering (PR #91534)
https://github.com/erichkeane edited https://github.com/llvm/llvm-project/pull/91534 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [Clang][Sema] Do not mark template parameters in the exception specification as used during partial ordering (PR #91534)
llvmbot wrote: @llvm/pr-subscribers-clang Author: Krystian Stasiowski (sdkrystian) Changes We do not deduce template arguments from the exception specification when determining the primary template of a function template specialization or when taking the address of a function template. Therefore, this patch changes `isAtLeastAsSpecializedAs` such that we do not mark template parameters in the exception specification as 'used' during partial ordering (per [[temp.deduct.partial] p12](http://eel.is/c++draft/temp.deduct.partial#12)) to prevent the following from being ambiguous: ```cpp templatetypename T, typename U void f(U) noexcept(noexcept(T())); // #1 templatetypename T void f(T*) noexcept; // #2 template void fint(int*) noexcept; // currently ambiguous, selects #2 with this patch applied ``` Although there is no corresponding wording in the standard, this seems to be the intended behavior given the definition of _deduction substitution loci_ in [[temp.deduct.general] p7](http://eel.is/c++draft/temp.deduct.general#7) (and EDG does the same thing). --- Full diff: https://github.com/llvm/llvm-project/pull/91534.diff 2 Files Affected: - (modified) clang/lib/Sema/SemaTemplateDeduction.cpp (+28-8) - (added) clang/test/CXX/temp/temp.fct.spec/temp.deduct/temp.deduct.partial/p3.cpp (+72) ``diff diff --git a/clang/lib/Sema/SemaTemplateDeduction.cpp b/clang/lib/Sema/SemaTemplateDeduction.cpp index fe7e35d841510..c17c5838803a8 100644 --- a/clang/lib/Sema/SemaTemplateDeduction.cpp +++ b/clang/lib/Sema/SemaTemplateDeduction.cpp @@ -5453,7 +5453,7 @@ static bool isAtLeastAsSpecializedAs(Sema , SourceLocation Loc, // is used. if (DeduceTemplateArgumentsByTypeMatch( S, TemplateParams, FD2->getType(), FD1->getType(), Info, Deduced, -TDF_None, +TDF_AllowCompatibleFunctionType, /*PartialOrdering=*/true) != TemplateDeductionResult::Success) return false; break; @@ -5485,20 +5485,40 @@ static bool isAtLeastAsSpecializedAs(Sema , SourceLocation Loc, switch (TPOC) { case TPOC_Call: for (unsigned I = 0, N = Args2.size(); I != N; ++I) - ::MarkUsedTemplateParameters(S.Context, Args2[I], false, - TemplateParams->getDepth(), - UsedParameters); + ::MarkUsedTemplateParameters(S.Context, Args2[I], /*OnlyDeduced=*/false, + TemplateParams->getDepth(), UsedParameters); break; case TPOC_Conversion: -::MarkUsedTemplateParameters(S.Context, Proto2->getReturnType(), false, +::MarkUsedTemplateParameters(S.Context, Proto2->getReturnType(), + /*OnlyDeduced=*/false, TemplateParams->getDepth(), UsedParameters); break; case TPOC_Other: -::MarkUsedTemplateParameters(S.Context, FD2->getType(), false, - TemplateParams->getDepth(), - UsedParameters); +// We do not deduce template arguments from the exception specification +// when determining the primary template of a function template +// specialization or when taking the address of a function template. +// Therefore, we do not mark template parameters in the exception +// specification as used during partial ordering to prevent the following +// from being ambiguous: +// +// template +// void f(U) noexcept(noexcept(T())); // #1 +// +// template +// void f(T*) noexcept; // #2 +// +// template<> +// void f(int*) noexcept; // explicit specialization of #2 +// +// Although there is no corresponding wording in the standard, this seems +// to be the intended behavior given the definition of +// 'deduction substitution loci' in [temp.deduct]. +::MarkUsedTemplateParameters( +S.Context, +S.Context.getFunctionTypeWithExceptionSpec(FD2->getType(), EST_None), +/*OnlyDeduced=*/false, TemplateParams->getDepth(), UsedParameters); break; } diff --git a/clang/test/CXX/temp/temp.fct.spec/temp.deduct/temp.deduct.partial/p3.cpp b/clang/test/CXX/temp/temp.fct.spec/temp.deduct/temp.deduct.partial/p3.cpp new file mode 100644 index 0..cc1d4ecda2ecc --- /dev/null +++ b/clang/test/CXX/temp/temp.fct.spec/temp.deduct/temp.deduct.partial/p3.cpp @@ -0,0 +1,72 @@ +// RUN: %clang_cc1 -fsyntax-only -verify %s +// expected-no-diagnostics + +template +struct A { }; + +constexpr A a; +constexpr A b; + +constexpr int* x = nullptr; +constexpr short* y = nullptr; + +namespace ExplicitArgs { + template + constexpr int f(U) noexcept(noexcept(T())) { +return 0; + } + + template + constexpr int f(T*) noexcept { +return 1; + } + + template<> + constexpr int f(int*) noexcept { +return 2; + } + + static_assert(f(1) == 0); + static_assert(f(y) == 1); + static_assert(f(x) == 2); + +
[clang] [Clang][Sema] Do not mark template parameters in the exception specification as used during partial ordering (PR #91534)
https://github.com/sdkrystian created https://github.com/llvm/llvm-project/pull/91534 We do not deduce template arguments from the exception specification when determining the primary template of a function template specialization or when taking the address of a function template. Therefore, this patch changes `isAtLeastAsSpecializedAs` such that we do not mark template parameters in the exception specification as 'used' during partial ordering (per [[temp.deduct.partial] p12](http://eel.is/c++draft/temp.deduct.partial#12)) to prevent the following from being ambiguous: ```cpp template void f(U) noexcept(noexcept(T())); // #1 template void f(T*) noexcept; // #2 template<> void f(int*) noexcept; // currently ambiguous, selects #2 with this patch applied ``` Although there is no corresponding wording in the standard, this seems to be the intended behavior given the definition of _deduction substitution loci_ in [[temp.deduct.general] p7](http://eel.is/c++draft/temp.deduct.general#7) (and EDG does the same thing). >From 0ef86c6bdf8fc89e771039a0e4bae88a8ebb2702 Mon Sep 17 00:00:00 2001 From: Krystian Stasiowski Date: Wed, 8 May 2024 08:43:23 -0400 Subject: [PATCH] [Clang][Sema] Do not mark template parameters in the exception specification as used during partial ordering --- clang/lib/Sema/SemaTemplateDeduction.cpp | 36 +++--- .../temp.deduct/temp.deduct.partial/p3.cpp| 72 +++ 2 files changed, 100 insertions(+), 8 deletions(-) create mode 100644 clang/test/CXX/temp/temp.fct.spec/temp.deduct/temp.deduct.partial/p3.cpp diff --git a/clang/lib/Sema/SemaTemplateDeduction.cpp b/clang/lib/Sema/SemaTemplateDeduction.cpp index fe7e35d841510..c17c5838803a8 100644 --- a/clang/lib/Sema/SemaTemplateDeduction.cpp +++ b/clang/lib/Sema/SemaTemplateDeduction.cpp @@ -5453,7 +5453,7 @@ static bool isAtLeastAsSpecializedAs(Sema , SourceLocation Loc, // is used. if (DeduceTemplateArgumentsByTypeMatch( S, TemplateParams, FD2->getType(), FD1->getType(), Info, Deduced, -TDF_None, +TDF_AllowCompatibleFunctionType, /*PartialOrdering=*/true) != TemplateDeductionResult::Success) return false; break; @@ -5485,20 +5485,40 @@ static bool isAtLeastAsSpecializedAs(Sema , SourceLocation Loc, switch (TPOC) { case TPOC_Call: for (unsigned I = 0, N = Args2.size(); I != N; ++I) - ::MarkUsedTemplateParameters(S.Context, Args2[I], false, - TemplateParams->getDepth(), - UsedParameters); + ::MarkUsedTemplateParameters(S.Context, Args2[I], /*OnlyDeduced=*/false, + TemplateParams->getDepth(), UsedParameters); break; case TPOC_Conversion: -::MarkUsedTemplateParameters(S.Context, Proto2->getReturnType(), false, +::MarkUsedTemplateParameters(S.Context, Proto2->getReturnType(), + /*OnlyDeduced=*/false, TemplateParams->getDepth(), UsedParameters); break; case TPOC_Other: -::MarkUsedTemplateParameters(S.Context, FD2->getType(), false, - TemplateParams->getDepth(), - UsedParameters); +// We do not deduce template arguments from the exception specification +// when determining the primary template of a function template +// specialization or when taking the address of a function template. +// Therefore, we do not mark template parameters in the exception +// specification as used during partial ordering to prevent the following +// from being ambiguous: +// +// template +// void f(U) noexcept(noexcept(T())); // #1 +// +// template +// void f(T*) noexcept; // #2 +// +// template<> +// void f(int*) noexcept; // explicit specialization of #2 +// +// Although there is no corresponding wording in the standard, this seems +// to be the intended behavior given the definition of +// 'deduction substitution loci' in [temp.deduct]. +::MarkUsedTemplateParameters( +S.Context, +S.Context.getFunctionTypeWithExceptionSpec(FD2->getType(), EST_None), +/*OnlyDeduced=*/false, TemplateParams->getDepth(), UsedParameters); break; } diff --git a/clang/test/CXX/temp/temp.fct.spec/temp.deduct/temp.deduct.partial/p3.cpp b/clang/test/CXX/temp/temp.fct.spec/temp.deduct/temp.deduct.partial/p3.cpp new file mode 100644 index 0..cc1d4ecda2ecc --- /dev/null +++ b/clang/test/CXX/temp/temp.fct.spec/temp.deduct/temp.deduct.partial/p3.cpp @@ -0,0 +1,72 @@ +// RUN: %clang_cc1 -fsyntax-only -verify %s +// expected-no-diagnostics + +template +struct A { }; + +constexpr A a; +constexpr A b; + +constexpr int* x = nullptr; +constexpr short* y = nullptr; + +namespace ExplicitArgs { + template + constexpr int f(U) noexcept(noexcept(T())) { +return