]> granicus.if.org Git - clang/commitdiff
Make SemaAccess smarter about determining when a dependent class might
authorRichard Smith <richard-llvm@metafoo.co.uk>
Wed, 23 Mar 2016 20:39:06 +0000 (20:39 +0000)
committerRichard Smith <richard-llvm@metafoo.co.uk>
Wed, 23 Mar 2016 20:39:06 +0000 (20:39 +0000)
instantiate to match a friend class declaration. It's still pretty dumb,
though.

git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@264189 91177308-0d34-0410-b5e6-96231b3b80d8

lib/Sema/SemaAccess.cpp
test/CXX/drs/dr5xx.cpp
test/SemaCXX/access.cpp
www/cxx_dr_status.html

index 4bca280824be16144c00681a616e0eda3a03d9f8..28ecc0e406f559c5a0586647f125824bdaadccb7 100644 (file)
@@ -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;
     }
   }
index 96d3494bf060f61617b5d70a87dc1d14e355c86f..e0bab57e5254ba887e2103eba2df4a348c732733 100644 (file)
@@ -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() {}
index cd65f907b8b58a4c52792d39dd4ec8418af14334..29a58a1388acf07ed8705188277545ec93ed162d 100644 (file)
@@ -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>(); }
 }
index 28af0749a5d042f56918a3c609029612c106dd33..8e0646d8ee4c63c100099280877156c32f9c50cb 100644 (file)
@@ -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>