[clang] fed4e3a - [clang] Exclude non-template classes when checking if constraint refers to containing template arguments (#74265)

via cfe-commits cfe-commits at lists.llvm.org
Wed Dec 6 17:18:03 PST 2023


Author: antangelo
Date: 2023-12-06T20:17:59-05:00
New Revision: fed4e3a6eb5d04856169951347892d983695f86a

URL: https://github.com/llvm/llvm-project/commit/fed4e3a6eb5d04856169951347892d983695f86a
DIFF: https://github.com/llvm/llvm-project/commit/fed4e3a6eb5d04856169951347892d983695f86a.diff

LOG: [clang] Exclude non-template classes when checking if constraint refers to containing template arguments (#74265)

When checking if the constraint uses any enclosing template parameters
for [temp.friend]p9, if a containing record is used as argument, we
assume that the constraint depends on enclosing template parameters
without checking if the record is templated. The reproducer from the bug
is included as a test case.

Fixes #71595

Added: 
    clang/test/SemaTemplate/GH71595.cpp

Modified: 
    clang/docs/ReleaseNotes.rst
    clang/lib/Sema/SemaTemplate.cpp

Removed: 
    


################################################################################
diff  --git a/clang/docs/ReleaseNotes.rst b/clang/docs/ReleaseNotes.rst
index 43a322030baae..1fbd332f74057 100644
--- a/clang/docs/ReleaseNotes.rst
+++ b/clang/docs/ReleaseNotes.rst
@@ -653,6 +653,9 @@ Bug Fixes in This Version
 - Fixed false positive error emitted by clang when performing qualified name
   lookup and the current class instantiation has dependent bases.
   Fixes (`#13826 <https://github.com/llvm/llvm-project/issues/13826>`_)
+- Fix a ``clang-17`` regression where a templated friend with constraints is not
+  properly applied when its parameters reference an enclosing non-template class.
+  Fixes (`#71595 <https://github.com/llvm/llvm-project/issues/71595>`_)
 - Fix the name of the ifunc symbol emitted for multiversion functions declared with the
   ``target_clones`` attribute. This addresses a linker error that would otherwise occur
   when these functions are referenced from other TUs.

diff  --git a/clang/lib/Sema/SemaTemplate.cpp b/clang/lib/Sema/SemaTemplate.cpp
index 603ad2b79cecb..f10abeaba0d45 100644
--- a/clang/lib/Sema/SemaTemplate.cpp
+++ b/clang/lib/Sema/SemaTemplate.cpp
@@ -1712,6 +1712,8 @@ class ConstraintRefersToContainingTemplateChecker
   // Friend, likely because it was referred to without its template arguments.
   void CheckIfContainingRecord(const CXXRecordDecl *CheckingRD) {
     CheckingRD = CheckingRD->getMostRecentDecl();
+    if (!CheckingRD->isTemplated())
+      return;
 
     for (const DeclContext *DC = Friend->getLexicalDeclContext();
          DC && !DC->isFileContext(); DC = DC->getParent())

diff  --git a/clang/test/SemaTemplate/GH71595.cpp b/clang/test/SemaTemplate/GH71595.cpp
new file mode 100644
index 0000000000000..7d34d1bf054e4
--- /dev/null
+++ b/clang/test/SemaTemplate/GH71595.cpp
@@ -0,0 +1,34 @@
+// RUN: %clang_cc1 -std=c++20 -verify %s
+
+template<class T, class U>
+concept C = true;
+
+class non_temp {
+    template<C<non_temp> T>
+    friend void f();
+
+    non_temp();
+};
+
+template<C<non_temp> T>
+void f() {
+    auto v = non_temp();
+}
+
+template<class A>
+class temp {
+    template<C<temp> T>
+    friend void g();
+
+    temp(); // expected-note {{implicitly declared private here}}
+};
+
+template<C<temp<int>> T>
+void g() {
+    auto v = temp<T>(); // expected-error {{calling a private constructor of class 'temp<int>'}}
+}
+
+void h() {
+    f<int>();
+    g<int>(); // expected-note {{in instantiation of function template specialization 'g<int>' requested here}}
+}


        


More information about the cfe-commits mailing list