diff --git a/lib/Sema/SemaAccess.cpp b/lib/Sema/SemaAccess.cpp index 4bca280824be16144c00681a616e0eda3a03d9f8..28ecc0e406f559c5a0586647f125824bdaadccb7 100644 --- a/lib/Sema/SemaAccess.cpp +++ b/lib/Sema/SemaAccess.cpp @@ -291,9 +291,10 @@ static AccessResult IsDerivedFromInclusive(const CXXRecordDecl *Derived, SmallVector<const CXXRecordDecl*, 8> Queue; // actually a stack while (true) { - if (Derived->isDependentContext() && !Derived->hasDefinition()) + if (Derived->isDependentContext() && !Derived->hasDefinition() && + !Derived->isLambda()) return AR_dependent; - + for (const auto &I : Derived->bases()) { const CXXRecordDecl *RD; @@ -410,14 +411,8 @@ static AccessResult MatchesFriend(Sema &S, return AR_accessible; if (EC.isDependent()) { - CanQualType FriendTy - = S.Context.getCanonicalType(S.Context.getTypeDeclType(Friend)); - - for (EffectiveContext::record_iterator - I = EC.Records.begin(), E = EC.Records.end(); I != E; ++I) { - CanQualType ContextTy - = S.Context.getCanonicalType(S.Context.getTypeDeclType(*I)); - if (MightInstantiateTo(S, ContextTy, FriendTy)) + for (const CXXRecordDecl *Context : EC.Records) { + if (MightInstantiateTo(Context, Friend)) return AR_dependent; } } diff --git a/test/CXX/drs/dr5xx.cpp b/test/CXX/drs/dr5xx.cpp index 96d3494bf060f61617b5d70a87dc1d14e355c86f..e0bab57e5254ba887e2103eba2df4a348c732733 100644 --- a/test/CXX/drs/dr5xx.cpp +++ b/test/CXX/drs/dr5xx.cpp @@ -814,7 +814,7 @@ namespace dr577 { // dr577: yes } } -namespace dr580 { // dr580: no +namespace dr580 { // dr580: partial class C; struct A { static C c; }; struct B { static C c; }; @@ -822,7 +822,7 @@ namespace dr580 { // dr580: no C(); // expected-note {{here}} ~C(); // expected-note {{here}} - typedef int I; // expected-note {{here}} + typedef int I; // expected-note 2{{here}} template<int> struct X; template<int> friend struct Y; template<int> void f(); @@ -832,7 +832,20 @@ namespace dr580 { // dr580: no template<C::I> struct C::X {}; template<C::I> struct Y {}; - template<C::I> struct Z {}; // FIXME: should reject, accepted because C befriends A! + template<C::I> struct Z {}; // expected-error {{private}} + + struct C2 { + class X { + struct A; + typedef int I; + friend struct A; + }; + class Y { + template<X::I> struct A {}; // FIXME: We incorrectly accept this + // because we think C2::Y::A<...> might + // instantiate to C2::X::A + }; + }; template<C::I> void C::f() {} template<C::I> void g() {} diff --git a/test/SemaCXX/access.cpp b/test/SemaCXX/access.cpp index cd65f907b8b58a4c52792d39dd4ec8418af14334..29a58a1388acf07ed8705188277545ec93ed162d 100644 --- a/test/SemaCXX/access.cpp +++ b/test/SemaCXX/access.cpp @@ -167,5 +167,5 @@ namespace ThisLambdaIsNotMyFriend { template <class T> void foo() { []() { A::foo(); }(); // expected-error {{private}} } - void bar() { foo<void>(); } // expected-note {{instantiation}} + void bar() { foo<void>(); } } diff --git a/www/cxx_dr_status.html b/www/cxx_dr_status.html index 28af0749a5d042f56918a3c609029612c106dd33..8e0646d8ee4c63c100099280877156c32f9c50cb 100644 --- a/www/cxx_dr_status.html +++ b/www/cxx_dr_status.html @@ -3523,7 +3523,7 @@ and <I>POD class</I></td> <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#580">580</a></td> <td>C++11</td> <td>Access in <I>template-parameter</I>s of member and friend definitions</td> - <td class="none" align="center">No</td> + <td class="partial" align="center">Partial</td> </tr> <tr class="open" id="581"> <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_active.html#581">581</a></td>