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 
foo()26   A::type foo() { } // expected-error {{'type' is a private member}}
foo()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 
test()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:
set(T & t,typename T::type v)60     template <class T> static void set(T &t, typename T::type v) {
61       t.value = v;
62     }
get(const T & t)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 
test()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(); // expected-note {{'Outer::A<B, Green>::foo' declared here}}
96   };
97 
98   class B {
99   private: typedef Green nature;
100     friend class Outer;
101   };
102 
test()103   void test() {
104     Outer::A<B, Green>::foo();
105     Outer::A<B, Blue>::foo(); // expected-error {{no member named 'foo' in 'test3::Outer::A<test3::B, test3::Blue>'; did you mean 'Outer::A<B, Green>::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 
foo(U &,typename U::type)115   template <class U> void foo(U &, typename U::type) {}
116 
test()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 
foo()131   template <A::Enum en> void A::foo() {}
132   template <A::Enum en> class A::bar {};
133 
foo()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 {
foo()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   };
check()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 
test(A & a)179   void test(A &a) {
180     if (a) return; // expected-error-re {{'operator void *(test8::A::*)(){{( __attribute__\(\(thiscall\)\))?}} 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 
test(A & a)189   void test(A &a) {
190     delete a; // expected-error {{'operator char *' is a private member of 'test9::A'}}
191   }
192 }
193