File tree Expand file tree Collapse file tree 4 files changed +51
-2
lines changed Expand file tree Collapse file tree 4 files changed +51
-2
lines changed Original file line number Diff line number Diff line change @@ -357,6 +357,9 @@ Bug Fixes in This Version
357357- Fixes an assertion failure on invalid code when trying to define member
358358 functions in lambdas.
359359
360+ - Fixed a regression in CTAD that a friend declaration that befriends itself may cause
361+ incorrect constraint substitution. (#GH86769).
362+
360363Bug Fixes to Compiler Builtins
361364^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
362365
Original file line number Diff line number Diff line change @@ -1836,7 +1836,27 @@ static TemplateParameterList *GetTemplateParameterList(TemplateDecl *TD) {
18361836 // Make sure we get the template parameter list from the most
18371837 // recent declaration, since that is the only one that is guaranteed to
18381838 // have all the default template argument information.
1839- return cast<TemplateDecl>(TD->getMostRecentDecl ())->getTemplateParameters ();
1839+ Decl *D = TD->getMostRecentDecl ();
1840+ // C++11 N3337 [temp.param]p12:
1841+ // A default template argument shall not be specified in a friend class
1842+ // template declaration.
1843+ //
1844+ // Skip past friend *declarations* because they are not supposed to contain
1845+ // default template arguments. Moreover, these declarations may introduce
1846+ // template parameters living in different template depths than the
1847+ // corresponding template parameters in TD, causing unmatched constraint
1848+ // substitution.
1849+ //
1850+ // FIXME: Diagnose such cases within a class template:
1851+ // template <class T>
1852+ // struct S {
1853+ // template <class = void> friend struct C;
1854+ // };
1855+ // template struct S<int>;
1856+ while (D->getFriendObjectKind () != Decl::FriendObjectKind::FOK_None &&
1857+ D->getPreviousDecl ())
1858+ D = D->getPreviousDecl ();
1859+ return cast<TemplateDecl>(D)->getTemplateParameters ();
18401860}
18411861
18421862DeclResult Sema::CheckClassTemplate (
Original file line number Diff line number Diff line change @@ -478,3 +478,29 @@ template <Concept> class Foo {
478478};
479479
480480} // 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 N3337 [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 5353template <class T , class B > struct Y { Y(T); };
5454template <class T , class B =void > struct Y ;
5555Y y (1 );
56- };
56+ }
You can’t perform that action at this time.
0 commit comments