Improve access control diagnostics.  Perform access control on member-pointer
conversions.  Fix an access-control bug where privileges were not considered
at intermediate points along the inheritance path.  Prepare for friends.



git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@95775 91177308-0d34-0410-b5e6-96231b3b80d8
diff --git a/test/SemaCXX/access-base-class.cpp b/test/SemaCXX/access-base-class.cpp
index f4c58d9..d0b0fb8 100644
--- a/test/SemaCXX/access-base-class.cpp
+++ b/test/SemaCXX/access-base-class.cpp
@@ -2,10 +2,10 @@
 namespace T1 {
   
 class A { };
-class B : private A { }; // expected-note {{'private' inheritance specifier here}}
+class B : private A { }; // expected-note {{declared private here}}
 
 void f(B* b) {
-  A *a = b; // expected-error{{conversion from 'class T1::B' to inaccessible base class 'class T1::A'}}
+  A *a = b; // expected-error{{cannot cast 'class T1::B' to its private base class 'class T1::A'}}
 }
 
 }
@@ -13,10 +13,10 @@
 namespace T2 { 
 
 class A { };
-class B : A { }; // expected-note {{inheritance is implicitly 'private'}}
+class B : A { }; // expected-note {{implicitly declared private here}}
 
 void f(B* b) {
-  A *a = b; // expected-error {{conversion from 'class T2::B' to inaccessible base class 'class T2::A'}}
+  A *a = b; // expected-error {{cannot cast 'class T2::B' to its private base class 'class T2::A'}}
 }
 
 }
@@ -63,13 +63,13 @@
   
   class A {};
   
-  class B : private A { // expected-note {{'private' inheritance specifier here}}
+  class B : private A { // expected-note {{declared private here}}
     void f(C* c);
   };
   
   class C : public B { 
     void f(C *c) {
-      A* a = c; // expected-error {{conversion from 'class T6::C' to inaccessible base class 'class T6::A'}}
+      A* a = c; // expected-error {{cannot cast 'class T6::C' to its private base class 'class T6::A'}}
     }
   };
   
@@ -77,3 +77,14 @@
     A *a = c;
   }
 }
+
+namespace T7 {
+  class A {};
+  class B : public A {};
+  class C : private B { 
+    void f(C *c) {
+      A* a = c; // okay
+    }
+  };
+}
+
diff --git a/test/SemaCXX/access-control-check.cpp b/test/SemaCXX/access-control-check.cpp
index cf2d191..783d4de 100644
--- a/test/SemaCXX/access-control-check.cpp
+++ b/test/SemaCXX/access-control-check.cpp
@@ -11,5 +11,5 @@
 
 class N : M,P {
   N() {}
-  int PR() { return iP + PPR(); } // expected-error 2 {{access to private member of 'class P'}}
+  int PR() { return iP + PPR(); } // expected-error 2 {{private member of 'class P'}}
 };
diff --git a/test/SemaCXX/conditional-expr.cpp b/test/SemaCXX/conditional-expr.cpp
index b71133b..b961ff2 100644
--- a/test/SemaCXX/conditional-expr.cpp
+++ b/test/SemaCXX/conditional-expr.cpp
@@ -25,7 +25,7 @@
   void fn2();
 };
 struct Convertible { operator Base&(); };
-struct Priv : private Base {}; // expected-note 4 {{'private' inheritance specifier here}}
+struct Priv : private Base {}; // expected-note 4 {{declared private here}}
 struct Mid : Base {};
 struct Fin : Mid, Derived {};
 typedef void (Derived::*DFnPtr)();
@@ -111,12 +111,12 @@
 
   Priv priv;
   Fin fin;
-  (void)(i1 ? Base() : Priv()); // expected-error{{conversion from 'struct Priv' to inaccessible base class 'struct Base'}}
-  (void)(i1 ? Priv() : Base()); // expected-error{{error: conversion from 'struct Priv' to inaccessible base class 'struct Base'}}
+  (void)(i1 ? Base() : Priv()); // expected-error{{private base class}}
+  (void)(i1 ? Priv() : Base()); // expected-error{{private base class}}
   (void)(i1 ? Base() : Fin()); // expected-error{{ambiguous conversion from derived class 'struct Fin' to base class 'struct Base'}}
   (void)(i1 ? Fin() : Base()); // expected-error{{ambiguous conversion from derived class 'struct Fin' to base class 'struct Base'}}
-  (void)(i1 ? base : priv); // expected-error {{conversion from 'struct Priv' to inaccessible base class 'struct Base'}}
-  (void)(i1 ? priv : base); // expected-error {{conversion from 'struct Priv' to inaccessible base class 'struct Base'}}
+  (void)(i1 ? base : priv); // expected-error {{private base class}}
+  (void)(i1 ? priv : base); // expected-error {{private base class}}
   (void)(i1 ? base : fin); // expected-error {{ambiguous conversion from derived class 'struct Fin' to base class 'struct Base'}}
   (void)(i1 ? fin : base); // expected-error {{ambiguous conversion from derived class 'struct Fin' to base class 'struct Base'}}
 
diff --git a/test/SemaCXX/static-cast.cpp b/test/SemaCXX/static-cast.cpp
index d41b929..4818b04 100644
--- a/test/SemaCXX/static-cast.cpp
+++ b/test/SemaCXX/static-cast.cpp
@@ -4,7 +4,7 @@
 struct C1 : public virtual B {};    // Single virtual base.
 struct C2 : public virtual B {};
 struct D : public C1, public C2 {}; // Diamond
-struct E : private A {};            // Single private base. expected-note 3 {{'private' inheritance specifier here}}
+struct E : private A {};            // Single private base. expected-note 3 {{declared private here}}
 struct F : public C1 {};            // Single path to B with virtual.
 struct G1 : public B {};
 struct G2 : public B {};
@@ -56,7 +56,7 @@
   // Bad code below
 
   (void)static_cast<void*>((const int*)0); // expected-error {{static_cast from 'int const *' to 'void *' is not allowed}}
-  (void)static_cast<A*>((E*)0); // expected-error {{inaccessible base class 'struct A'}}
+  (void)static_cast<A*>((E*)0); // expected-error {{private base class 'struct A'}}
   (void)static_cast<A*>((H*)0); // expected-error {{ambiguous conversion}}
   (void)static_cast<int>((int*)0); // expected-error {{static_cast from 'int *' to 'int' is not allowed}}
   (void)static_cast<A**>((B**)0); // expected-error {{static_cast from 'struct B **' to 'struct A **' is not allowed}}
@@ -86,8 +86,8 @@
   (void)static_cast<D&>(*((A*)0)); // expected-error {{cannot cast 'struct A' to 'struct D &' via virtual base 'struct B'}}
   (void)static_cast<B*>((const A*)0); // expected-error {{static_cast from 'struct A const *' to 'struct B *' casts away constness}}
   (void)static_cast<B&>(*((const A*)0)); // expected-error {{static_cast from 'struct A const' to 'struct B &' casts away constness}}
-  (void)static_cast<E*>((A*)0); // expected-error {{cannot cast 'struct A' to 'struct E' due to inaccessible}}
-  (void)static_cast<E&>(*((A*)0)); // expected-error {{cannot cast 'struct A' to 'struct E' due to inaccessible}}
+  (void)static_cast<E*>((A*)0); // expected-error {{cannot cast private base class 'struct A' to 'struct E'}}
+  (void)static_cast<E&>(*((A*)0)); // expected-error {{cannot cast private base class 'struct A' to 'struct E'}}
   (void)static_cast<H*>((A*)0); // expected-error {{ambiguous cast from base 'struct A' to derived 'struct H':\n    struct A -> struct B -> struct G1 -> struct H\n    struct A -> struct B -> struct G2 -> struct H}}
   (void)static_cast<H&>(*((A*)0)); // expected-error {{ambiguous cast from base 'struct A' to derived 'struct H':\n    struct A -> struct B -> struct G1 -> struct H\n    struct A -> struct B -> struct G2 -> struct H}}
   (void)static_cast<E*>((B*)0); // expected-error {{static_cast from 'struct B *' to 'struct E *' is not allowed}}
diff --git a/test/SemaCXX/virtual-override.cpp b/test/SemaCXX/virtual-override.cpp
index 5e1e9b0..6f1d83f 100644
--- a/test/SemaCXX/virtual-override.cpp
+++ b/test/SemaCXX/virtual-override.cpp
@@ -29,14 +29,14 @@
 namespace T3 {
 
 struct a { };
-struct b : private a { }; // expected-note{{'private' inheritance specifier here}}
+struct b : private a { }; // expected-note{{declared private here}}
   
 class A {
   virtual a* f(); // expected-note{{overridden virtual function is here}}
 };
 
 class B : A {
-  virtual b* f(); // expected-error{{return type of virtual function 'f' is not covariant with the return type of the function it overrides (conversion from 'struct T3::b' to inaccessible base class 'struct T3::a')}}
+  virtual b* f(); // expected-error{{invalid covariant return for virtual function: 'struct T3::a' is a private base class of 'struct T3::b'}}
 };
 
 }