[clang] [clang] visit constraint of NTTP (PR #91842)
Qizhi Hu via cfe-commits
cfe-commits at lists.llvm.org
Fri May 10 23:25:54 PDT 2024
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 <huqizhi at feysh.com>
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<NonTypeTemplateParmDecl>(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<C T, int I> struct Y2<T*, I, I+1+1> {}; // expected-note {{partial
template<C T, C auto I, int W, A S, template<typename, auto, int, A, typename...> class U, typename... Z>
struct Y3 { Y3()=delete; };
template<C T, D auto I, int W, A S, template<typename, auto, int, A, typename...> class U, typename... Z>
-struct Y3<T, I, W, S, U, Z...> { Y3()=delete; };
+struct Y3<T, I, W, S, U, Z...> { Y3()=delete; }; // expected-note {{partial specialization matches [with T = int, I = 1, W = 1, S = A{}, U = S, Z = <int>]}}
template<C T, E auto I, int W, A S, template<typename, auto, int, A, typename...> class U, typename... Z>
-struct Y3<T, I, W, S, U, Z...> {};
+struct Y3<T, I, W, S, U, Z...> {}; // expected-note {{partial specialization matches [with T = int, I = 1, W = 1, S = A{}, U = S, Z = <int>]}}
void f() {
Y1<int, 2> a;
Y2<char*, 1, 3> b; // expected-error {{ambiguous partial specializations}}
- Y3<int, 1, 1, A{}, S, int> c;
+ Y3<int, 1, 1, A{}, S, int> c; // expected-error {{ambiguous partial specializations of 'Y3<int, 1, 1, A{}, S, int>'}}
}
// 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 0000000000000..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<typename T, typename U>
+constexpr bool is_same_v = false;
+
+template<typename T>
+constexpr bool is_same_v<T, T> = true;
+
+template<typename T, typename U>
+concept same_as = is_same_v<T, U>;
+
+template <auto>
+struct A {};
+
+template <same_as<int> auto p>
+struct A<p> {};
+
+A<0> a;
More information about the cfe-commits
mailing list