File tree 4 files changed +51
-2
lines changed
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
357
357
- Fixes an assertion failure on invalid code when trying to define member
358
358
functions in lambdas.
359
359
360
+ - Fixed a regression in CTAD that a friend declaration that befriends itself may cause
361
+ incorrect constraint substitution. (#GH86769).
362
+
360
363
Bug Fixes to Compiler Builtins
361
364
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
362
365
Original file line number Diff line number Diff line change @@ -1836,7 +1836,27 @@ static TemplateParameterList *GetTemplateParameterList(TemplateDecl *TD) {
1836
1836
// Make sure we get the template parameter list from the most
1837
1837
// recent declaration, since that is the only one that is guaranteed to
1838
1838
// 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();
1840
1860
}
1841
1861
1842
1862
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 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 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