[llvm-branch-commits] [clang] release/18.x: Backport PR86914 "Fix a CTAD regression after 42239d2e9" (PR #87084)
via llvm-branch-commits
llvm-branch-commits at lists.llvm.org
Fri Mar 29 09:21:54 PDT 2024
llvmbot wrote:
<!--LLVM PR SUMMARY COMMENT-->
@llvm/pr-subscribers-clang
Author: Younan Zhang (zyn0217)
<details>
<summary>Changes</summary>
This fixes a regression that was introduced in 18, which we don't want to carry it over to 19 anyways.
---
Full diff: https://github.com/llvm/llvm-project/pull/87084.diff
4 Files Affected:
- (modified) clang/docs/ReleaseNotes.rst (+4)
- (modified) clang/lib/Sema/SemaTemplate.cpp (+21-1)
- (modified) clang/test/SemaTemplate/concepts-friends.cpp (+26)
- (modified) clang/test/SemaTemplate/ctad.cpp (+1-1)
``````````diff
diff --git a/clang/docs/ReleaseNotes.rst b/clang/docs/ReleaseNotes.rst
index d4401a43c123e7..ebeb47a871e27b 100644
--- a/clang/docs/ReleaseNotes.rst
+++ b/clang/docs/ReleaseNotes.rst
@@ -1106,6 +1106,10 @@ Bug Fixes to C++ Support
- Fix a crash when an unresolved overload set is encountered on the RHS of a ``.*`` operator.
(`#53815 <https://github.com/llvm/llvm-project/issues/53815>`_)
+- Fixed a regression in CTAD that a friend declaration that befriends itself may cause
+ incorrect constraint substitution.
+ (`#86769 <https://github.com/llvm/llvm-project/issues/86769>`_)
+
Bug Fixes to AST Handling
^^^^^^^^^^^^^^^^^^^^^^^^^
- Fixed an import failure of recursive friend class template.
diff --git a/clang/lib/Sema/SemaTemplate.cpp b/clang/lib/Sema/SemaTemplate.cpp
index a381d876a54c67..b619f5d729e86b 100644
--- a/clang/lib/Sema/SemaTemplate.cpp
+++ b/clang/lib/Sema/SemaTemplate.cpp
@@ -1830,7 +1830,27 @@ static TemplateParameterList *GetTemplateParameterList(TemplateDecl *TD) {
// Make sure we get the template parameter list from the most
// recent declaration, since that is the only one that is guaranteed to
// have all the default template argument information.
- return cast<TemplateDecl>(TD->getMostRecentDecl())->getTemplateParameters();
+ Decl *D = TD->getMostRecentDecl();
+ // C++11 [temp.param]p12:
+ // A default template argument shall not be specified in a friend class
+ // template declaration.
+ //
+ // Skip past friend *declarations* because they are not supposed to contain
+ // default template arguments. Moreover, these declarations may introduce
+ // template parameters living in different template depths than the
+ // corresponding template parameters in TD, causing unmatched constraint
+ // substitution.
+ //
+ // FIXME: Diagnose such cases within a class template:
+ // template <class T>
+ // struct S {
+ // template <class = void> friend struct C;
+ // };
+ // template struct S<int>;
+ while (D->getFriendObjectKind() != Decl::FriendObjectKind::FOK_None &&
+ D->getPreviousDecl())
+ D = D->getPreviousDecl();
+ return cast<TemplateDecl>(D)->getTemplateParameters();
}
DeclResult Sema::CheckClassTemplate(
diff --git a/clang/test/SemaTemplate/concepts-friends.cpp b/clang/test/SemaTemplate/concepts-friends.cpp
index 255b0858917fb6..0b008811f13621 100644
--- a/clang/test/SemaTemplate/concepts-friends.cpp
+++ b/clang/test/SemaTemplate/concepts-friends.cpp
@@ -478,3 +478,29 @@ template <Concept> class Foo {
};
} // namespace FriendOfFriend
+
+namespace GH86769 {
+
+template <typename T>
+concept X = true;
+
+template <X T> struct Y {
+ Y(T) {}
+ template <X U> friend struct Y;
+ template <X U> friend struct Y;
+ template <X U> friend struct Y;
+};
+
+template <class T>
+struct Z {
+ // FIXME: This is ill-formed per C++11 [temp.param]p12:
+ // A default template argument shall not be specified in a friend class
+ // template declaration.
+ template <X U = void> friend struct Y;
+};
+
+template struct Y<int>;
+template struct Z<int>;
+Y y(1);
+
+}
diff --git a/clang/test/SemaTemplate/ctad.cpp b/clang/test/SemaTemplate/ctad.cpp
index 388ed7d4cced18..ec144d4f44ba8c 100644
--- a/clang/test/SemaTemplate/ctad.cpp
+++ b/clang/test/SemaTemplate/ctad.cpp
@@ -53,4 +53,4 @@ X x;
template<class T, class B> struct Y { Y(T); };
template<class T, class B=void> struct Y ;
Y y(1);
-};
+}
``````````
</details>
https://github.com/llvm/llvm-project/pull/87084
More information about the llvm-branch-commits
mailing list