[clang] [clang] visit constraint of NTTP (PR #91842)
jcsxky wrote: > I don't think this is the right approach. I stepped though the example and > the reason we reject is because: > > * We substitute a dependent `AutoType` in for the types of the template > parameters when they are initially built. > * We call `getMoreSpecialized` determine whether the partial specialization > is more specialized than the primary. > * We determine that neither template is at least as specialized as the other > via `isAtLeastAsSpecializedAs`. > * We call `TemplateParameterListsAreEqual` per [[temp.func.order] > p6.2.2](http://eel.is/c++draft/temp.func.order#6.2.2) to check for template > parameter equivalence, and compare the two template parameters by calling > `MatchTemplateParameterKind`. > * `MatchTemplateParameterKind` calls `ASTContext::getUnconstrainedType` to > get the unconstrained type of the template parameters per [[temp.over.link] > p6 sentence 2](http://eel.is/c++draft/temp.over.link#6.sentence-2). For the > class templates template parameter, it returns the type unchanged (a > _**dependent**_ `AutoType`). For the class template partial specializations > template parameter, it returns an unconstrained `AutoType` _**that isn't > dependent**_. > * We compare the adjusted types and determine they aren't equal, so we > consider neither template to be more specialized than the other. > > So, I think the correct fix is to propagate dependence in > `ASTContext::getUnconstrainedType`. I have a branch that implements this > [here](https://github.com/sdkrystian/llvm-project/tree/partial-spec-dependent-auto). > WDYT @erichkeane @cor3ntin @zyn0217? This is really a perfect approach and it has addressed the underlying issue. And thanks for your explaination! https://github.com/llvm/llvm-project/pull/91842 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [clang] visit constraint of NTTP (PR #91842)
zyn0217 wrote: > So, I think the correct fix is to propagate dependence in > ASTContext::getUnconstrainedType. I have a branch that implements this here. > WDYT @erichkeane @cor3ntin @zyn0217 That looks similar to the approach which I investigated some time ago. The difference is that I removed the constraint check in getUnconstrainedType but yours is to propagate the dependency — i think that looks more reasonable than mine that way. https://github.com/llvm/llvm-project/pull/91842 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [clang] visit constraint of NTTP (PR #91842)
https://github.com/erichkeane closed https://github.com/llvm/llvm-project/pull/91842 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [clang] visit constraint of NTTP (PR #91842)
erichkeane wrote: > > Yeah, that seems incredibly reasonable and a much lower touch here with > > fewer concerns about the side-effects that we got here. > > Should I open a PR then? Yep, I think you should. Sorry @jcsxky : We're going to close this one, it seems that @sdkrystian has a 'more correct' patch here, so we'll go with his. I hope/encourage you to help review it! https://github.com/llvm/llvm-project/pull/91842 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [clang] visit constraint of NTTP (PR #91842)
sdkrystian wrote: > Yeah, that seems incredibly reasonable and a much lower touch here with fewer > concerns about the side-effects that we got here. Should I open a PR then? https://github.com/llvm/llvm-project/pull/91842 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [clang] visit constraint of NTTP (PR #91842)
erichkeane wrote: > I don't think this is the right approach. I stepped though the example and > the reason we reject is because: > > * We substitute a dependent `AutoType` in for the types of the template > parameters when they are initially built. > > * We call `getMoreSpecialized` determine whether the partial > specialization is more specialized than the primary. > > * We determine that neither template is at least as specialized as the > other via `isAtLeastAsSpecializedAs`. > > * We call `TemplateParameterListsAreEqual` per [[temp.func.order] > p6.2.2](http://eel.is/c++draft/temp.func.order#6.2.2) to check for template > parameter equivalence, and compare the two template parameters by calling > `MatchTemplateParameterKind`. > > * `MatchTemplateParameterKind` calls `ASTContext::getUnconstrainedType` > to get the unconstrained type of the template parameters per > [[temp.over.link] p6 sentence > 2](http://eel.is/c++draft/temp.over.link#6.sentence-2). For class templates > template parameter, it returns the type unchanged (a _**dependent**_ > `AutoType`). For the class template partial specializations template > parameter, it returns an unconstrained `AutoType` _**that isn't dependent**_. > > * We compare the adjusted types and determine they aren't equal, so we > consider neither template to be more specialized than the other. > > > So, I think the correct fix is to propagate dependence in > `ASTContext::getUnconstrainedType`. I have a branch that implements this > [here](https://github.com/sdkrystian/llvm-project/tree/partial-spec-dependent-auto). > WDYT @erichkeane @cor3ntin @zyn0217? Yeah, that seems incredibly reasonable and a much lower touch here with fewer concerns about the side-effects that we got here. https://github.com/llvm/llvm-project/pull/91842 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [clang] visit constraint of NTTP (PR #91842)
sdkrystian wrote: I don't think this is the right approach. I stepped though the example and the reason we reject is because: - We substitute a dependent `AutoType` in for the types of the template parameters when they are initially built. - We call `getMoreSpecialized` determine whether the partial specialization is more specialized than the primary. - We determine that neither template is at least as specialized as the other via `isAtLeastAsSpecializedAs`. - We call `TemplateParameterListsAreEqual` per [[temp.func.order] p6.2.2](http://eel.is/c++draft/temp.func.order#6.2.2) to check for template parameter equivalence, and compare the two template parameters by calling `MatchTemplateParameterKind`. - `MatchTemplateParameterKind` calls `ASTContext::getUnconstrainedType` to get the unconstrained type of the template parameters per [[temp.over.link] p6 sentence 2](http://eel.is/c++draft/temp.over.link#6.sentence-2). For class templates template parameter, it returns the type unchanged (a ***dependent*** `AutoType`). For the class template partial specializations template parameter, it returns an unconstrained `AutoType` ***that isn't dependent***. - We compare the adjusted types and determine they aren't equal, so we consider neither template to be more specialized than the other. So, I think the correct fix is to propagate dependence in `ASTContext::getUnconstrainedType`. I have a branch that implements this [here](https://github.com/sdkrystian/llvm-project/tree/partial-spec-dependent-auto). WDYT @erichkeane @cor3ntin? https://github.com/llvm/llvm-project/pull/91842 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [clang] visit constraint of NTTP (PR #91842)
https://github.com/jcsxky updated https://github.com/llvm/llvm-project/pull/91842 >From 0ebdcec675c39b26b8bee1a8b07c12fae2c58523 Mon Sep 17 00:00:00 2001 From: huqizhi Date: Sat, 11 May 2024 14:04:23 +0800 Subject: [PATCH] [clang] visit constraint of NTTP --- clang/docs/ReleaseNotes.rst | 1 + clang/lib/AST/StmtProfile.cpp | 4 .../temp.fct/temp.func.order/p6.cpp | 6 +++--- clang/test/SemaCXX/PR77377.cpp| 19 +++ 4 files changed, 27 insertions(+), 3 deletions(-) create mode 100644 clang/test/SemaCXX/PR77377.cpp diff --git a/clang/docs/ReleaseNotes.rst b/clang/docs/ReleaseNotes.rst index 7c5dcc59c7016..30d359c582d3f 100644 --- a/clang/docs/ReleaseNotes.rst +++ b/clang/docs/ReleaseNotes.rst @@ -707,6 +707,7 @@ Bug Fixes to C++ Support initialized, rather than evaluating them as a part of the larger manifestly constant evaluated expression. - Fix a bug in access control checking due to dealyed checking of friend declaration. Fixes (#GH12361). +- Fix a bug on template class partial specialization due to traverse of constraint of NTTP. Fixes (#GH77377). Bug Fixes to AST Handling ^ diff --git a/clang/lib/AST/StmtProfile.cpp b/clang/lib/AST/StmtProfile.cpp index 8fb8940142eb0..a23a2efa2389e 100644 --- a/clang/lib/AST/StmtProfile.cpp +++ b/clang/lib/AST/StmtProfile.cpp @@ -2257,6 +2257,10 @@ void StmtProfiler::VisitSubstNonTypeTemplateParmExpr( const SubstNonTypeTemplateParmExpr *E) { // Profile exactly as the replacement expression. Visit(E->getReplacement()); + if (auto *NTTP = dyn_cast(E->getParameter()); + NTTP && NTTP->getPlaceholderTypeConstraint()) { +Visit(NTTP->getPlaceholderTypeConstraint()); + } } void StmtProfiler::VisitFunctionParmPackExpr(const FunctionParmPackExpr *S) { diff --git a/clang/test/CXX/temp/temp.decls/temp.fct/temp.func.order/p6.cpp b/clang/test/CXX/temp/temp.decls/temp.fct/temp.func.order/p6.cpp index 9f44878da6254..5f9719a2dc561 100644 --- a/clang/test/CXX/temp/temp.decls/temp.fct/temp.func.order/p6.cpp +++ b/clang/test/CXX/temp/temp.decls/temp.fct/temp.func.order/p6.cpp @@ -79,14 +79,14 @@ template struct Y2 {}; // expected-note {{partial template class U, typename... Z> struct Y3 { Y3()=delete; }; template class U, typename... Z> -struct Y3 { Y3()=delete; }; +struct Y3 { Y3()=delete; }; // expected-note {{partial specialization matches [with T = int, I = 1, W = 1, S = A{}, U = S, Z = ]}} template class U, typename... Z> -struct Y3 {}; +struct Y3 {}; // expected-note {{partial specialization matches [with T = int, I = 1, W = 1, S = A{}, U = S, Z = ]}} void f() { Y1 a; Y2 b; // expected-error {{ambiguous partial specializations}} - Y3 c; + Y3 c; // expected-error {{ambiguous partial specializations of 'Y3'}} } // Per [temp.func.order]p6.2.2, specifically "if the function parameters that diff --git a/clang/test/SemaCXX/PR77377.cpp b/clang/test/SemaCXX/PR77377.cpp new file mode 100644 index 0..ae34809c3903d --- /dev/null +++ b/clang/test/SemaCXX/PR77377.cpp @@ -0,0 +1,19 @@ +// RUN: %clang_cc1 -verify -std=c++20 -fsyntax-only %s +// expected-no-diagnostics + +template +constexpr bool is_same_v = false; + +template +constexpr bool is_same_v = true; + +template +concept same_as = is_same_v; + +template +struct A {}; + +template auto p> +struct A {}; + +A<0> a; ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [clang] visit constraint of NTTP (PR #91842)
https://github.com/jcsxky updated https://github.com/llvm/llvm-project/pull/91842 >From 4133001711b82c93e057e1bd05476c5d052d597f Mon Sep 17 00:00:00 2001 From: huqizhi Date: Sat, 11 May 2024 14:04:23 +0800 Subject: [PATCH] [clang] visit constraint of NTTP --- clang/docs/ReleaseNotes.rst | 1 + clang/lib/AST/StmtProfile.cpp | 4 .../temp.fct/temp.func.order/p6.cpp | 6 +++--- clang/test/SemaCXX/PR77377.cpp| 19 +++ 4 files changed, 27 insertions(+), 3 deletions(-) create mode 100644 clang/test/SemaCXX/PR77377.cpp diff --git a/clang/docs/ReleaseNotes.rst b/clang/docs/ReleaseNotes.rst index 7c5dcc59c7016..30d359c582d3f 100644 --- a/clang/docs/ReleaseNotes.rst +++ b/clang/docs/ReleaseNotes.rst @@ -707,6 +707,7 @@ Bug Fixes to C++ Support initialized, rather than evaluating them as a part of the larger manifestly constant evaluated expression. - Fix a bug in access control checking due to dealyed checking of friend declaration. Fixes (#GH12361). +- Fix a bug on template class partial specialization due to traverse of constraint of NTTP. Fixes (#GH77377). Bug Fixes to AST Handling ^ diff --git a/clang/lib/AST/StmtProfile.cpp b/clang/lib/AST/StmtProfile.cpp index 8fb8940142eb0..a23a2efa2389e 100644 --- a/clang/lib/AST/StmtProfile.cpp +++ b/clang/lib/AST/StmtProfile.cpp @@ -2257,6 +2257,10 @@ void StmtProfiler::VisitSubstNonTypeTemplateParmExpr( const SubstNonTypeTemplateParmExpr *E) { // Profile exactly as the replacement expression. Visit(E->getReplacement()); + if (auto *NTTP = dyn_cast(E->getParameter()); + NTTP && NTTP->getPlaceholderTypeConstraint()) { +Visit(NTTP->getPlaceholderTypeConstraint()); + } } void StmtProfiler::VisitFunctionParmPackExpr(const FunctionParmPackExpr *S) { diff --git a/clang/test/CXX/temp/temp.decls/temp.fct/temp.func.order/p6.cpp b/clang/test/CXX/temp/temp.decls/temp.fct/temp.func.order/p6.cpp index 9f44878da6254..5f9719a2dc561 100644 --- a/clang/test/CXX/temp/temp.decls/temp.fct/temp.func.order/p6.cpp +++ b/clang/test/CXX/temp/temp.decls/temp.fct/temp.func.order/p6.cpp @@ -79,14 +79,14 @@ template struct Y2 {}; // expected-note {{partial template class U, typename... Z> struct Y3 { Y3()=delete; }; template class U, typename... Z> -struct Y3 { Y3()=delete; }; +struct Y3 { Y3()=delete; }; // expected-note {{partial specialization matches [with T = int, I = 1, W = 1, S = A{}, U = S, Z = ]}} template class U, typename... Z> -struct Y3 {}; +struct Y3 {}; // expected-note {{partial specialization matches [with T = int, I = 1, W = 1, S = A{}, U = S, Z = ]}} void f() { Y1 a; Y2 b; // expected-error {{ambiguous partial specializations}} - Y3 c; + Y3 c; // expected-error {{ambiguous partial specializations of 'Y3'}} } // Per [temp.func.order]p6.2.2, specifically "if the function parameters that diff --git a/clang/test/SemaCXX/PR77377.cpp b/clang/test/SemaCXX/PR77377.cpp new file mode 100644 index 0..ae34809c3903d --- /dev/null +++ b/clang/test/SemaCXX/PR77377.cpp @@ -0,0 +1,19 @@ +// RUN: %clang_cc1 -verify -std=c++20 -fsyntax-only %s +// expected-no-diagnostics + +template +constexpr bool is_same_v = false; + +template +constexpr bool is_same_v = true; + +template +concept same_as = is_same_v; + +template +struct A {}; + +template auto p> +struct A {}; + +A<0> a; ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [clang] visit constraint of NTTP (PR #91842)
@@ -79,14 +79,14 @@ template struct Y2 {}; // expected-note {{partial template class U, typename... Z> struct Y3 { Y3()=delete; }; template class U, typename... Z> -struct Y3 { Y3()=delete; }; +struct Y3 { Y3()=delete; }; // expected-note {{partial specialization matches [with T = int, I = 1, W = 1, S = A{}, U = S, Z = ]}} template class U, typename... Z> -struct Y3 {}; +struct Y3 {}; // expected-note {{partial specialization matches [with T = int, I = 1, W = 1, S = A{}, U = S, Z = ]}} void f() { Y1 a; Y2 b; // expected-error {{ambiguous partial specializations}} - Y3 c; + Y3 c; // expected-error {{ambiguous partial specializations of 'Y3'}} jcsxky wrote: When instantiation, we are checking which one of the two partial specialization is more specialized. Obviously, the first one(`auto D`) is not more specialized than the second(`auto E`). When applied this patch, the second one is not more specialized than the first as well. This is because `isSameTemplateArg` return `false` and the result is not `TemplateDeductionResult::Success`. Although we get correct result, it is not because of ignoring the type-constraint. Back to the quote, if we ignore the use of type-constraints for placeholder types, is the following example ill-formed due to their equivalent template arguments? ```cpp template constexpr bool True = true; template concept C = True; template concept D = C && sizeof(T) > 2; template concept E = D && alignof(T) > 1; template struct Y3 { Y3()=delete; }; template struct Y3 { Y3()=delete; }; template struct Y3 {}; ``` But EDG, gcc and MSVC all accept this code. So I think the existing test is rejected may not be related to the quote. WDYT? @cor3ntin @zyn0217 @erichkeane https://github.com/llvm/llvm-project/pull/91842 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [clang] visit constraint of NTTP (PR #91842)
https://github.com/jcsxky edited https://github.com/llvm/llvm-project/pull/91842 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [clang] visit constraint of NTTP (PR #91842)
@@ -79,14 +79,14 @@ template struct Y2 {}; // expected-note {{partial template class U, typename... Z> struct Y3 { Y3()=delete; }; template class U, typename... Z> -struct Y3 { Y3()=delete; }; +struct Y3 { Y3()=delete; }; // expected-note {{partial specialization matches [with T = int, I = 1, W = 1, S = A{}, U = S, Z = ]}} template class U, typename... Z> -struct Y3 {}; +struct Y3 {}; // expected-note {{partial specialization matches [with T = int, I = 1, W = 1, S = A{}, U = S, Z = ]}} void f() { Y1 a; Y2 b; // expected-error {{ambiguous partial specializations}} - Y3 c; + Y3 c; // expected-error {{ambiguous partial specializations of 'Y3'}} jcsxky wrote: I think the quote can explain why we should report error here. Maybe more work are required to find out where we do the ignore and how this patch impacts this case. https://github.com/llvm/llvm-project/pull/91842 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [clang] visit constraint of NTTP (PR #91842)
@@ -79,14 +79,14 @@ template struct Y2 {}; // expected-note {{partial template class U, typename... Z> struct Y3 { Y3()=delete; }; template class U, typename... Z> -struct Y3 { Y3()=delete; }; +struct Y3 { Y3()=delete; }; // expected-note {{partial specialization matches [with T = int, I = 1, W = 1, S = A{}, U = S, Z = ]}} template class U, typename... Z> -struct Y3 {}; +struct Y3 {}; // expected-note {{partial specialization matches [with T = int, I = 1, W = 1, S = A{}, U = S, Z = ]}} void f() { Y1 a; Y2 b; // expected-error {{ambiguous partial specializations}} - Y3 c; + Y3 c; // expected-error {{ambiguous partial specializations of 'Y3'}} zyn0217 wrote: [[temp.over.link]p6.3](https://eel.is/c++draft/temp.over.link#6.3) > Two template-parameters are equivalent under the following conditions: > if they declare non-type template parameters, they have equivalent types > *ignoring* the use of type-constraints for placeholder types Oops, I forgot I posted the standard wording on that issue, and therefore this seems reasonable..? https://github.com/llvm/llvm-project/pull/91842 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [clang] visit constraint of NTTP (PR #91842)
@@ -79,14 +79,14 @@ template struct Y2 {}; // expected-note {{partial template class U, typename... Z> struct Y3 { Y3()=delete; }; template class U, typename... Z> -struct Y3 { Y3()=delete; }; +struct Y3 { Y3()=delete; }; // expected-note {{partial specialization matches [with T = int, I = 1, W = 1, S = A{}, U = S, Z = ]}} template class U, typename... Z> -struct Y3 {}; +struct Y3 {}; // expected-note {{partial specialization matches [with T = int, I = 1, W = 1, S = A{}, U = S, Z = ]}} void f() { Y1 a; Y2 b; // expected-error {{ambiguous partial specializations}} - Y3 c; + Y3 c; // expected-error {{ambiguous partial specializations of 'Y3'}} cor3ntin wrote: https://compiler-explorer.com/z/c87771xKf https://github.com/llvm/llvm-project/pull/91842 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [clang] visit constraint of NTTP (PR #91842)
@@ -79,14 +79,14 @@ template struct Y2 {}; // expected-note {{partial template class U, typename... Z> struct Y3 { Y3()=delete; }; template class U, typename... Z> -struct Y3 { Y3()=delete; }; +struct Y3 { Y3()=delete; }; // expected-note {{partial specialization matches [with T = int, I = 1, W = 1, S = A{}, U = S, Z = ]}} template class U, typename... Z> -struct Y3 {}; +struct Y3 {}; // expected-note {{partial specialization matches [with T = int, I = 1, W = 1, S = A{}, U = S, Z = ]}} void f() { Y1 a; Y2 b; // expected-error {{ambiguous partial specializations}} - Y3 c; + Y3 c; // expected-error {{ambiguous partial specializations of 'Y3'}} cor3ntin wrote: The only difference is `D auto` vs `E auto` `E` subsumes `D` so the second partial specialization is more constrained and we should pick that. So I believe the existing test is correct and we would be introducing a regression. It is interesting to consider that GCC, EGG and MSVC all reject that code so it is possible I am missing something https://github.com/llvm/llvm-project/pull/91842 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [clang] visit constraint of NTTP (PR #91842)
@@ -2257,6 +2257,11 @@ void StmtProfiler::VisitSubstNonTypeTemplateParmExpr( const SubstNonTypeTemplateParmExpr *E) { // Profile exactly as the replacement expression. Visit(E->getReplacement()); + if (auto *NTTP = + dyn_cast_if_present(E->getParameter()); zyn0217 wrote: In `SubstNonTypeTemplateParmExpr::getParameter()` we returned a `NonTypeTemplateParmDecl` after a cast; so an `if_present` is unnecessary, at least `E->getParameter()` was presumed to return always non-null. https://github.com/llvm/llvm-project/pull/91842 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [clang] visit constraint of NTTP (PR #91842)
@@ -79,14 +79,14 @@ template struct Y2 {}; // expected-note {{partial template class U, typename... Z> struct Y3 { Y3()=delete; }; template class U, typename... Z> -struct Y3 { Y3()=delete; }; +struct Y3 { Y3()=delete; }; // expected-note {{partial specialization matches [with T = int, I = 1, W = 1, S = A{}, U = S, Z = ]}} template class U, typename... Z> -struct Y3 {}; +struct Y3 {}; // expected-note {{partial specialization matches [with T = int, I = 1, W = 1, S = A{}, U = S, Z = ]}} void f() { Y1 a; Y2 b; // expected-error {{ambiguous partial specializations}} - Y3 c; + Y3 c; // expected-error {{ambiguous partial specializations of 'Y3'}} zyn0217 wrote: This is suspicious... I don't see any FIXMEs around suggesting this was not in conformance with the standards. @erichkeane @cor3ntin any thoughts? https://github.com/llvm/llvm-project/pull/91842 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [clang] visit constraint of NTTP (PR #91842)
llvmbot wrote: @llvm/pr-subscribers-clang-modules Author: Qizhi Hu (jcsxky) Changes attempt to fix https://github.com/llvm/llvm-project/issues/77377 `isSameTemplateArg` returns incorrect result since clang didn't visit constraint of NTTP. Furthermore, It makes class template partial specialization not more specialized than the class template itself. --- Full diff: https://github.com/llvm/llvm-project/pull/91842.diff 4 Files Affected: - (modified) clang/docs/ReleaseNotes.rst (+1) - (modified) clang/lib/AST/StmtProfile.cpp (+5) - (modified) clang/test/CXX/temp/temp.decls/temp.fct/temp.func.order/p6.cpp (+3-3) - (added) clang/test/SemaCXX/PR77377.cpp (+19) ``diff diff --git a/clang/docs/ReleaseNotes.rst b/clang/docs/ReleaseNotes.rst index 7c5dcc59c7016..30d359c582d3f 100644 --- a/clang/docs/ReleaseNotes.rst +++ b/clang/docs/ReleaseNotes.rst @@ -707,6 +707,7 @@ Bug Fixes to C++ Support initialized, rather than evaluating them as a part of the larger manifestly constant evaluated expression. - Fix a bug in access control checking due to dealyed checking of friend declaration. Fixes (#GH12361). +- Fix a bug on template class partial specialization due to traverse of constraint of NTTP. Fixes (#GH77377). Bug Fixes to AST Handling ^ diff --git a/clang/lib/AST/StmtProfile.cpp b/clang/lib/AST/StmtProfile.cpp index 8fb8940142eb0..0bb5a40d7350e 100644 --- a/clang/lib/AST/StmtProfile.cpp +++ b/clang/lib/AST/StmtProfile.cpp @@ -2257,6 +2257,11 @@ void StmtProfiler::VisitSubstNonTypeTemplateParmExpr( const SubstNonTypeTemplateParmExpr *E) { // Profile exactly as the replacement expression. Visit(E->getReplacement()); + if (auto *NTTP = + dyn_cast_if_present(E->getParameter()); + NTTP && NTTP->getPlaceholderTypeConstraint()) { +Visit(NTTP->getPlaceholderTypeConstraint()); + } } void StmtProfiler::VisitFunctionParmPackExpr(const FunctionParmPackExpr *S) { diff --git a/clang/test/CXX/temp/temp.decls/temp.fct/temp.func.order/p6.cpp b/clang/test/CXX/temp/temp.decls/temp.fct/temp.func.order/p6.cpp index 9f44878da6254..5f9719a2dc561 100644 --- a/clang/test/CXX/temp/temp.decls/temp.fct/temp.func.order/p6.cpp +++ b/clang/test/CXX/temp/temp.decls/temp.fct/temp.func.order/p6.cpp @@ -79,14 +79,14 @@ template struct Y2 {}; // expected-note {{partial template class U, typename... Z> struct Y3 { Y3()=delete; }; template class U, typename... Z> -struct Y3 { Y3()=delete; }; +struct Y3 { Y3()=delete; }; // expected-note {{partial specialization matches [with T = int, I = 1, W = 1, S = A{}, U = S, Z = ]}} template class U, typename... Z> -struct Y3 {}; +struct Y3 {}; // expected-note {{partial specialization matches [with T = int, I = 1, W = 1, S = A{}, U = S, Z = ]}} void f() { Y1 a; Y2 b; // expected-error {{ambiguous partial specializations}} - Y3 c; + Y3 c; // expected-error {{ambiguous partial specializations of 'Y3'}} } // Per [temp.func.order]p6.2.2, specifically "if the function parameters that diff --git a/clang/test/SemaCXX/PR77377.cpp b/clang/test/SemaCXX/PR77377.cpp new file mode 100644 index 0..ae34809c3903d --- /dev/null +++ b/clang/test/SemaCXX/PR77377.cpp @@ -0,0 +1,19 @@ +// RUN: %clang_cc1 -verify -std=c++20 -fsyntax-only %s +// expected-no-diagnostics + +template +constexpr bool is_same_v = false; + +template +constexpr bool is_same_v = true; + +template +concept same_as = is_same_v; + +template +struct A {}; + +template auto p> +struct A {}; + +A<0> a; `` https://github.com/llvm/llvm-project/pull/91842 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [clang] visit constraint of NTTP (PR #91842)
llvmbot wrote: @llvm/pr-subscribers-clang Author: Qizhi Hu (jcsxky) Changes attempt to fix https://github.com/llvm/llvm-project/issues/77377 `isSameTemplateArg` returns incorrect result since clang didn't visit constraint of NTTP. Furthermore, It makes class template partial specialization not more specialized than the class template itself. --- Full diff: https://github.com/llvm/llvm-project/pull/91842.diff 4 Files Affected: - (modified) clang/docs/ReleaseNotes.rst (+1) - (modified) clang/lib/AST/StmtProfile.cpp (+5) - (modified) clang/test/CXX/temp/temp.decls/temp.fct/temp.func.order/p6.cpp (+3-3) - (added) clang/test/SemaCXX/PR77377.cpp (+19) ``diff diff --git a/clang/docs/ReleaseNotes.rst b/clang/docs/ReleaseNotes.rst index 7c5dcc59c7016..30d359c582d3f 100644 --- a/clang/docs/ReleaseNotes.rst +++ b/clang/docs/ReleaseNotes.rst @@ -707,6 +707,7 @@ Bug Fixes to C++ Support initialized, rather than evaluating them as a part of the larger manifestly constant evaluated expression. - Fix a bug in access control checking due to dealyed checking of friend declaration. Fixes (#GH12361). +- Fix a bug on template class partial specialization due to traverse of constraint of NTTP. Fixes (#GH77377). Bug Fixes to AST Handling ^ diff --git a/clang/lib/AST/StmtProfile.cpp b/clang/lib/AST/StmtProfile.cpp index 8fb8940142eb0..0bb5a40d7350e 100644 --- a/clang/lib/AST/StmtProfile.cpp +++ b/clang/lib/AST/StmtProfile.cpp @@ -2257,6 +2257,11 @@ void StmtProfiler::VisitSubstNonTypeTemplateParmExpr( const SubstNonTypeTemplateParmExpr *E) { // Profile exactly as the replacement expression. Visit(E->getReplacement()); + if (auto *NTTP = + dyn_cast_if_present(E->getParameter()); + NTTP && NTTP->getPlaceholderTypeConstraint()) { +Visit(NTTP->getPlaceholderTypeConstraint()); + } } void StmtProfiler::VisitFunctionParmPackExpr(const FunctionParmPackExpr *S) { diff --git a/clang/test/CXX/temp/temp.decls/temp.fct/temp.func.order/p6.cpp b/clang/test/CXX/temp/temp.decls/temp.fct/temp.func.order/p6.cpp index 9f44878da6254..5f9719a2dc561 100644 --- a/clang/test/CXX/temp/temp.decls/temp.fct/temp.func.order/p6.cpp +++ b/clang/test/CXX/temp/temp.decls/temp.fct/temp.func.order/p6.cpp @@ -79,14 +79,14 @@ template struct Y2 {}; // expected-note {{partial template class U, typename... Z> struct Y3 { Y3()=delete; }; template class U, typename... Z> -struct Y3 { Y3()=delete; }; +struct Y3 { Y3()=delete; }; // expected-note {{partial specialization matches [with T = int, I = 1, W = 1, S = A{}, U = S, Z = ]}} template class U, typename... Z> -struct Y3 {}; +struct Y3 {}; // expected-note {{partial specialization matches [with T = int, I = 1, W = 1, S = A{}, U = S, Z = ]}} void f() { Y1 a; Y2 b; // expected-error {{ambiguous partial specializations}} - Y3 c; + Y3 c; // expected-error {{ambiguous partial specializations of 'Y3'}} } // Per [temp.func.order]p6.2.2, specifically "if the function parameters that diff --git a/clang/test/SemaCXX/PR77377.cpp b/clang/test/SemaCXX/PR77377.cpp new file mode 100644 index 0..ae34809c3903d --- /dev/null +++ b/clang/test/SemaCXX/PR77377.cpp @@ -0,0 +1,19 @@ +// RUN: %clang_cc1 -verify -std=c++20 -fsyntax-only %s +// expected-no-diagnostics + +template +constexpr bool is_same_v = false; + +template +constexpr bool is_same_v = true; + +template +concept same_as = is_same_v; + +template +struct A {}; + +template auto p> +struct A {}; + +A<0> a; `` https://github.com/llvm/llvm-project/pull/91842 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [clang] visit constraint of NTTP (PR #91842)
https://github.com/jcsxky edited https://github.com/llvm/llvm-project/pull/91842 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [clang] visit constraint of NTTP (PR #91842)
https://github.com/jcsxky created https://github.com/llvm/llvm-project/pull/91842 attempt to fix `isSameTemplateArg` returns incorrect result since clang didn't visit constraint of NTTP. Furthermore, It makes class template partial specialization not more specialized than the class template itself. >From ddc0fbb7a249fbc6f2d2795fda262b2e7ca0a4e9 Mon Sep 17 00:00:00 2001 From: huqizhi Date: Sat, 11 May 2024 14:04:23 +0800 Subject: [PATCH] [clang] visit constraint of NTTP --- clang/docs/ReleaseNotes.rst | 1 + clang/lib/AST/StmtProfile.cpp | 5 + .../temp.fct/temp.func.order/p6.cpp | 6 +++--- clang/test/SemaCXX/PR77377.cpp| 19 +++ 4 files changed, 28 insertions(+), 3 deletions(-) create mode 100644 clang/test/SemaCXX/PR77377.cpp diff --git a/clang/docs/ReleaseNotes.rst b/clang/docs/ReleaseNotes.rst index 7c5dcc59c7016..30d359c582d3f 100644 --- a/clang/docs/ReleaseNotes.rst +++ b/clang/docs/ReleaseNotes.rst @@ -707,6 +707,7 @@ Bug Fixes to C++ Support initialized, rather than evaluating them as a part of the larger manifestly constant evaluated expression. - Fix a bug in access control checking due to dealyed checking of friend declaration. Fixes (#GH12361). +- Fix a bug on template class partial specialization due to traverse of constraint of NTTP. Fixes (#GH77377). Bug Fixes to AST Handling ^ diff --git a/clang/lib/AST/StmtProfile.cpp b/clang/lib/AST/StmtProfile.cpp index 8fb8940142eb0..0bb5a40d7350e 100644 --- a/clang/lib/AST/StmtProfile.cpp +++ b/clang/lib/AST/StmtProfile.cpp @@ -2257,6 +2257,11 @@ void StmtProfiler::VisitSubstNonTypeTemplateParmExpr( const SubstNonTypeTemplateParmExpr *E) { // Profile exactly as the replacement expression. Visit(E->getReplacement()); + if (auto *NTTP = + dyn_cast_if_present(E->getParameter()); + NTTP && NTTP->getPlaceholderTypeConstraint()) { +Visit(NTTP->getPlaceholderTypeConstraint()); + } } void StmtProfiler::VisitFunctionParmPackExpr(const FunctionParmPackExpr *S) { diff --git a/clang/test/CXX/temp/temp.decls/temp.fct/temp.func.order/p6.cpp b/clang/test/CXX/temp/temp.decls/temp.fct/temp.func.order/p6.cpp index 9f44878da6254..5f9719a2dc561 100644 --- a/clang/test/CXX/temp/temp.decls/temp.fct/temp.func.order/p6.cpp +++ b/clang/test/CXX/temp/temp.decls/temp.fct/temp.func.order/p6.cpp @@ -79,14 +79,14 @@ template struct Y2 {}; // expected-note {{partial template class U, typename... Z> struct Y3 { Y3()=delete; }; template class U, typename... Z> -struct Y3 { Y3()=delete; }; +struct Y3 { Y3()=delete; }; // expected-note {{partial specialization matches [with T = int, I = 1, W = 1, S = A{}, U = S, Z = ]}} template class U, typename... Z> -struct Y3 {}; +struct Y3 {}; // expected-note {{partial specialization matches [with T = int, I = 1, W = 1, S = A{}, U = S, Z = ]}} void f() { Y1 a; Y2 b; // expected-error {{ambiguous partial specializations}} - Y3 c; + Y3 c; // expected-error {{ambiguous partial specializations of 'Y3'}} } // Per [temp.func.order]p6.2.2, specifically "if the function parameters that diff --git a/clang/test/SemaCXX/PR77377.cpp b/clang/test/SemaCXX/PR77377.cpp new file mode 100644 index 0..ae34809c3903d --- /dev/null +++ b/clang/test/SemaCXX/PR77377.cpp @@ -0,0 +1,19 @@ +// RUN: %clang_cc1 -verify -std=c++20 -fsyntax-only %s +// expected-no-diagnostics + +template +constexpr bool is_same_v = false; + +template +constexpr bool is_same_v = true; + +template +concept same_as = is_same_v; + +template +struct A {}; + +template auto p> +struct A {}; + +A<0> a; ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits