[clang] [Clang][Concepts] Correct the CurContext for friend declarations (PR #106890)

Younan Zhang via cfe-commits cfe-commits at lists.llvm.org
Sun Sep 1 00:18:13 PDT 2024


https://github.com/zyn0217 updated https://github.com/llvm/llvm-project/pull/106890

>From 679ece827467a25b14d0a718ac10f221327f5bef Mon Sep 17 00:00:00 2001
From: Younan Zhang <zyn7109 at gmail.com>
Date: Sun, 1 Sep 2024 14:55:22 +0800
Subject: [PATCH 1/2] [Clang][Concepts] Correct the CurContext for friend
 declarations

---
 clang/docs/ReleaseNotes.rst                   |  1 +
 .../clang/Basic/DiagnosticSemaKinds.td        |  2 +-
 clang/lib/Sema/SemaConcept.cpp                |  5 +++-
 clang/lib/Sema/SemaTemplateInstantiate.cpp    |  3 +--
 .../temp.constr/temp.constr.normal/p1.cpp     |  2 +-
 clang/test/SemaTemplate/concepts-friends.cpp  | 23 +++++++++++++++++++
 6 files changed, 31 insertions(+), 5 deletions(-)

diff --git a/clang/docs/ReleaseNotes.rst b/clang/docs/ReleaseNotes.rst
index 98fb0174d4a37e..fc940db4813948 100644
--- a/clang/docs/ReleaseNotes.rst
+++ b/clang/docs/ReleaseNotes.rst
@@ -338,6 +338,7 @@ Bug Fixes to C++ Support
 - Fixed an assertion failure when converting vectors to int/float with invalid expressions. (#GH105486)
 - Template parameter names are considered in the name lookup of out-of-line class template
   specialization right before its declaration context. (#GH64082)
+- Fixed a constraint comparison bug for friend declarations. (#GH78101)
 
 Bug Fixes to AST Handling
 ^^^^^^^^^^^^^^^^^^^^^^^^^
diff --git a/clang/include/clang/Basic/DiagnosticSemaKinds.td b/clang/include/clang/Basic/DiagnosticSemaKinds.td
index 66f8890da75e5d..dcb49d8a67604a 100644
--- a/clang/include/clang/Basic/DiagnosticSemaKinds.td
+++ b/clang/include/clang/Basic/DiagnosticSemaKinds.td
@@ -5603,7 +5603,7 @@ def note_checking_constraints_for_function_here : Note<
 def note_constraint_substitution_here : Note<
   "while substituting template arguments into constraint expression here">;
 def note_constraint_normalization_here : Note<
-  "while calculating associated constraint of template '%0' here">;
+  "while calculating associated constraint of template %0 here">;
 def note_parameter_mapping_substitution_here : Note<
   "while substituting into concept arguments here; substitution failures not "
   "allowed in concept arguments">;
diff --git a/clang/lib/Sema/SemaConcept.cpp b/clang/lib/Sema/SemaConcept.cpp
index 86d6f308a51cc2..afbfe278680240 100644
--- a/clang/lib/Sema/SemaConcept.cpp
+++ b/clang/lib/Sema/SemaConcept.cpp
@@ -1012,7 +1012,10 @@ static const Expr *SubstituteConstraintExpressionWithoutSatisfaction(
   // possible that e.g. constraints involving C<Class<T>> and C<Class> are
   // perceived identical.
   std::optional<Sema::ContextRAII> ContextScope;
-  if (auto *RD = dyn_cast<CXXRecordDecl>(DeclInfo.getDeclContext())) {
+  if (auto *RD =
+          dyn_cast<CXXRecordDecl>(DeclInfo.getDecl()->getFriendObjectKind()
+                                      ? DeclInfo.getLexicalDeclContext()
+                                      : DeclInfo.getDeclContext())) {
     ThisScope.emplace(S, const_cast<CXXRecordDecl *>(RD), Qualifiers());
     ContextScope.emplace(S, const_cast<DeclContext *>(cast<DeclContext>(RD)),
                          /*NewThisContext=*/false);
diff --git a/clang/lib/Sema/SemaTemplateInstantiate.cpp b/clang/lib/Sema/SemaTemplateInstantiate.cpp
index 776297479e141e..c42cc250bb904a 100644
--- a/clang/lib/Sema/SemaTemplateInstantiate.cpp
+++ b/clang/lib/Sema/SemaTemplateInstantiate.cpp
@@ -1226,8 +1226,7 @@ void Sema::PrintInstantiationStack() {
     case CodeSynthesisContext::ConstraintNormalization:
       Diags.Report(Active->PointOfInstantiation,
                    diag::note_constraint_normalization_here)
-          << cast<NamedDecl>(Active->Entity)->getName()
-          << Active->InstantiationRange;
+          << cast<NamedDecl>(Active->Entity) << Active->InstantiationRange;
       break;
     case CodeSynthesisContext::ParameterMappingSubstitution:
       Diags.Report(Active->PointOfInstantiation,
diff --git a/clang/test/CXX/temp/temp.constr/temp.constr.normal/p1.cpp b/clang/test/CXX/temp/temp.constr/temp.constr.normal/p1.cpp
index d80710937cdfa1..3992835c444027 100644
--- a/clang/test/CXX/temp/temp.constr/temp.constr.normal/p1.cpp
+++ b/clang/test/CXX/temp/temp.constr/temp.constr.normal/p1.cpp
@@ -15,7 +15,7 @@ template<typename T> requires Bar2<T> struct S2 { };
 // expected-note at -1{{template is declared here}}
 template<typename T> requires Bar2<T> && true struct S2<T> { };
 // expected-error at -1{{class template partial specialization is not more specialized than the primary template}}
-// expected-note at -2{{while calculating associated constraint of template 'S2' here}}
+// expected-note at -2{{while calculating associated constraint of template 'S2<T>' here}}
 
 namespace type_pack {
   template<typename... Args>
diff --git a/clang/test/SemaTemplate/concepts-friends.cpp b/clang/test/SemaTemplate/concepts-friends.cpp
index 14b37d78d951dc..d05be423a8cfcd 100644
--- a/clang/test/SemaTemplate/concepts-friends.cpp
+++ b/clang/test/SemaTemplate/concepts-friends.cpp
@@ -525,3 +525,26 @@ struct S {
 };
 
 }
+
+namespace GH78101 {
+
+template <typename T, int i>
+concept True = true;
+
+template <typename T, int I> struct Template {
+  static constexpr int i = I;
+
+  friend constexpr auto operator+(True<i> auto f) { return i; }
+};
+
+template <int I> struct Template<float, I> {
+  static constexpr int i = I;
+
+  friend constexpr auto operator+(True<i> auto f) { return i; }
+};
+
+Template<void, 4> f{};
+
+static_assert(+Template<float, 5>{} == 5);
+
+} // namespace GH78101

>From 21173ee585302d53c09d4403552833aa1c3bff3b Mon Sep 17 00:00:00 2001
From: Younan Zhang <zyn7109 at gmail.com>
Date: Sun, 1 Sep 2024 15:17:46 +0800
Subject: [PATCH 2/2] Guard against nullptrs

---
 clang/lib/Sema/SemaConcept.cpp | 12 ++++++++----
 1 file changed, 8 insertions(+), 4 deletions(-)

diff --git a/clang/lib/Sema/SemaConcept.cpp b/clang/lib/Sema/SemaConcept.cpp
index afbfe278680240..6a1b32598bb4a6 100644
--- a/clang/lib/Sema/SemaConcept.cpp
+++ b/clang/lib/Sema/SemaConcept.cpp
@@ -1012,10 +1012,14 @@ static const Expr *SubstituteConstraintExpressionWithoutSatisfaction(
   // possible that e.g. constraints involving C<Class<T>> and C<Class> are
   // perceived identical.
   std::optional<Sema::ContextRAII> ContextScope;
-  if (auto *RD =
-          dyn_cast<CXXRecordDecl>(DeclInfo.getDecl()->getFriendObjectKind()
-                                      ? DeclInfo.getLexicalDeclContext()
-                                      : DeclInfo.getDeclContext())) {
+  const DeclContext *DC = [&] {
+    if (!DeclInfo.getDecl())
+      return DeclInfo.getDeclContext();
+    return DeclInfo.getDecl()->getFriendObjectKind()
+               ? DeclInfo.getLexicalDeclContext()
+               : DeclInfo.getDeclContext();
+  }();
+  if (auto *RD = dyn_cast<CXXRecordDecl>(DC)) {
     ThisScope.emplace(S, const_cast<CXXRecordDecl *>(RD), Qualifiers());
     ContextScope.emplace(S, const_cast<DeclContext *>(cast<DeclContext>(RD)),
                          /*NewThisContext=*/false);



More information about the cfe-commits mailing list