File tree 4 files changed +52
-2
lines changed
4 files changed +52
-2
lines changed Original file line number Diff line number Diff line change @@ -1106,6 +1106,10 @@ Bug Fixes to C++ Support
1106
1106
- Fix a crash when an unresolved overload set is encountered on the RHS of a ``.* `` operator.
1107
1107
(`#53815 <https://github.com/llvm/llvm-project/issues/53815 >`_)
1108
1108
1109
+ - Fixed a regression in CTAD that a friend declaration that befriends itself may cause
1110
+ incorrect constraint substitution.
1111
+ (`#86769 <https://github.com/llvm/llvm-project/issues/86769 >`_)
1112
+
1109
1113
Bug Fixes to AST Handling
1110
1114
^^^^^^^^^^^^^^^^^^^^^^^^^
1111
1115
- Fixed an import failure of recursive friend class template.
Original file line number Diff line number Diff line change @@ -1830,7 +1830,27 @@ static TemplateParameterList *GetTemplateParameterList(TemplateDecl *TD) {
1830
1830
// Make sure we get the template parameter list from the most
1831
1831
// recent declaration, since that is the only one that is guaranteed to
1832
1832
// have all the default template argument information.
1833
- return cast<TemplateDecl>(TD->getMostRecentDecl ())->getTemplateParameters ();
1833
+ Decl *D = TD->getMostRecentDecl ();
1834
+ // C++11 [temp.param]p12:
1835
+ // A default template argument shall not be specified in a friend class
1836
+ // template declaration.
1837
+ //
1838
+ // Skip past friend *declarations* because they are not supposed to contain
1839
+ // default template arguments. Moreover, these declarations may introduce
1840
+ // template parameters living in different template depths than the
1841
+ // corresponding template parameters in TD, causing unmatched constraint
1842
+ // substitution.
1843
+ //
1844
+ // FIXME: Diagnose such cases within a class template:
1845
+ // template <class T>
1846
+ // struct S {
1847
+ // template <class = void> friend struct C;
1848
+ // };
1849
+ // template struct S<int>;
1850
+ while (D->getFriendObjectKind () != Decl::FriendObjectKind::FOK_None &&
1851
+ D->getPreviousDecl ())
1852
+ D = D->getPreviousDecl ();
1853
+ return cast<TemplateDecl>(D)->getTemplateParameters ();
1834
1854
}
1835
1855
1836
1856
DeclResult Sema::CheckClassTemplate (
Original file line number Diff line number Diff line change @@ -478,3 +478,29 @@ template <Concept> class Foo {
478
478
};
479
479
480
480
} // namespace FriendOfFriend
481
+
482
+ namespace GH86769 {
483
+
484
+ template <typename T>
485
+ concept X = true ;
486
+
487
+ template <X T> struct Y {
488
+ Y (T) {}
489
+ template <X U> friend struct Y ;
490
+ template <X U> friend struct Y ;
491
+ template <X U> friend struct Y ;
492
+ };
493
+
494
+ template <class T >
495
+ struct Z {
496
+ // FIXME: This is ill-formed per C++11 [temp.param]p12:
497
+ // A default template argument shall not be specified in a friend class
498
+ // template declaration.
499
+ template <X U = void > friend struct Y ;
500
+ };
501
+
502
+ template struct Y <int >;
503
+ template struct Z <int >;
504
+ Y y (1 );
505
+
506
+ }
Original file line number Diff line number Diff line change 53
53
template <class T , class B > struct Y { Y(T); };
54
54
template <class T , class B =void > struct Y ;
55
55
Y y (1 );
56
- };
56
+ }
You can’t perform that action at this time.
0 commit comments