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