Home | History | Annotate | Download | only in class.access
      1 // RUN: %clang_cc1 -fsyntax-only -verify %s
      2 
      3 // C++0x [class.access]p6:
      4 //   All access controls in [class.access] affect the ability to
      5 //   access a class member name from a particular scope. For purposes
      6 //   of access control, the base-specifiers of a class and the
      7 //   definitions of class members that appear outside of the class
      8 //   definition are considered to be within the scope of that
      9 //   class. In particular, access controls apply as usual to member
     10 //   names accessed as part of a function return type, even though it
     11 //   is not possible to determine the access privileges of that use
     12 //   without first parsing the rest of the function
     13 //   declarator. Similarly, access control for implicit calls to the
     14 //   constructors, the conversion functions, or the destructor called
     15 //   to create and destroy a static data member is performed as if
     16 //   these calls appeared in the scope of the member's class.
     17 
     18 struct Public {}; struct Protected {}; struct Private {};
     19 
     20 namespace test0 {
     21   class A {
     22     typedef int type; // expected-note {{declared private here}}
     23     type foo();
     24   };
     25 
     26   A::type foo() { } // expected-error {{'type' is a private member}}
     27   A::type A::foo() { }
     28 }
     29 
     30 // conversion decls
     31 namespace test1 {
     32   class A {
     33   public:
     34     A();
     35     operator Public ();
     36     A(Public);
     37   protected:
     38     operator Protected (); // expected-note {{declared protected here}}
     39     A(Protected); // expected-note {{declared protected here}}
     40   private:
     41     operator Private (); // expected-note {{declared private here}}
     42     A(Private); // expected-note {{declared private here}}
     43   };
     44 
     45   void test() {
     46     A a;
     47     Public pub = a;
     48     Protected prot = a; // expected-error {{'operator Protected' is a protected member}}
     49     Private priv = a; // expected-error {{'operator Private' is a private member}}
     50     A apub = pub;
     51     A aprot = prot; // expected-error {{protected constructor}}
     52     A apriv = priv; // expected-error {{private constructor}}
     53   }
     54 }
     55 
     56 // PR6967
     57 namespace test2 {
     58   class A {
     59   public:
     60     template <class T> static void set(T &t, typename T::type v) {
     61       t.value = v;
     62     }
     63     template <class T> static typename T::type get(const T &t) {
     64       return t.value;
     65     }
     66   };
     67 
     68   class B {
     69     friend class A;
     70 
     71   private:
     72     typedef int type;
     73     type value;
     74   };
     75 
     76   int test() {
     77     B b;
     78     A::set(b, 0);
     79     return A::get(b);
     80   }
     81 }
     82 
     83 namespace test3 {
     84   class Green {}; class Blue {};
     85 
     86   // We have to wrap this in a class because a partial specialization
     87   // isn't actually in the context of the template.
     88   struct Outer {
     89     template <class T, class Nat> class A {
     90     };
     91   };
     92 
     93   template <class T> class Outer::A<T, typename T::nature> {
     94   public:
     95     static void foo();
     96   };
     97 
     98   class B {
     99   private: typedef Green nature;
    100     friend class Outer;
    101   };
    102 
    103   void test() {
    104     Outer::A<B, Green>::foo();
    105     Outer::A<B, Blue>::foo(); // expected-error {{no member named 'foo'}}
    106   }
    107 }
    108 
    109 namespace test4 {
    110   template <class T> class A {
    111   private: typedef int type;
    112     template <class U> friend void foo(U &, typename U::type);
    113   };
    114 
    115   template <class U> void foo(U &, typename U::type) {}
    116 
    117   void test() {
    118     A<int> a;
    119     foo(a, 0);
    120   }
    121 }
    122 
    123 // PR7644
    124 namespace test5 {
    125   class A {
    126     enum Enum { E0, E1, E2 }; // expected-note 4 {{declared private here}}
    127     template <Enum> void foo();
    128     template <Enum> class bar;
    129   };
    130 
    131   template <A::Enum en> void A::foo() {}
    132   template <A::Enum en> class A::bar {};
    133 
    134   template <A::Enum en> void foo() {} // expected-error {{'Enum' is a private member of 'test5::A'}}
    135   template <A::Enum en> class bar {}; // expected-error {{'Enum' is a private member of 'test5::A'}}
    136 
    137   class B {
    138     template <A::Enum en> void foo() {} // expected-error {{'Enum' is a private member of 'test5::A'}}
    139     template <A::Enum en> class bar {}; // expected-error {{'Enum' is a private member of 'test5::A'}}
    140   };
    141 }
    142 
    143 namespace test6 {
    144   class A {
    145   public: class public_inner {};
    146   protected: class protected_inner {};
    147   private: class private_inner {}; // expected-note {{declared private here}}
    148   };
    149 
    150   class B : A {
    151     public_inner a;
    152     protected_inner b;
    153     private_inner c; // expected-error {{'private_inner' is a private member of 'test6::A'}}
    154   };
    155 }
    156 
    157 // PR9229
    158 namespace test7 {
    159   void foo(int arg[1]);
    160   class A {
    161     void check();
    162   };
    163   class B {
    164     friend class A;
    165     A ins;
    166   };
    167   void A::check() {
    168     void foo(int arg[__builtin_offsetof(B, ins)]);
    169   }
    170 }
    171 
    172 // rdar://problem/10155256
    173 namespace test8 {
    174   class A {
    175     typedef void* (A::*UnspecifiedBoolType)() const;
    176     operator UnspecifiedBoolType() const; // expected-note {{implicitly declared private here}}
    177   };
    178 
    179   void test(A &a) {
    180     if (a) return; // expected-error {{'operator void *(class test8::A::*)(void) const' is a private member of 'test8::A'}}
    181   }
    182 }
    183 
    184 namespace test9 {
    185   class A {
    186     operator char*() const; // expected-note {{implicitly declared private here}}
    187   };
    188 
    189   void test(A &a) {
    190     delete a; // expected-error {{'operator char *' is a private member of 'test9::A'}}
    191   }
    192 }
    193