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