17002f4c03c2d0544f4e8bea8d3a5636519081e35John McCall// RUN: %clang_cc1 -fsyntax-only -verify %s
22f514480c448708ec382a684cf5e035d3a827ec8John McCall
32f514480c448708ec382a684cf5e035d3a827ec8John McCall// C++0x [class.access]p6:
42f514480c448708ec382a684cf5e035d3a827ec8John McCall//   All access controls in [class.access] affect the ability to
52f514480c448708ec382a684cf5e035d3a827ec8John McCall//   access a class member name from a particular scope. For purposes
62f514480c448708ec382a684cf5e035d3a827ec8John McCall//   of access control, the base-specifiers of a class and the
72f514480c448708ec382a684cf5e035d3a827ec8John McCall//   definitions of class members that appear outside of the class
82f514480c448708ec382a684cf5e035d3a827ec8John McCall//   definition are considered to be within the scope of that
92f514480c448708ec382a684cf5e035d3a827ec8John McCall//   class. In particular, access controls apply as usual to member
102f514480c448708ec382a684cf5e035d3a827ec8John McCall//   names accessed as part of a function return type, even though it
112f514480c448708ec382a684cf5e035d3a827ec8John McCall//   is not possible to determine the access privileges of that use
122f514480c448708ec382a684cf5e035d3a827ec8John McCall//   without first parsing the rest of the function
132f514480c448708ec382a684cf5e035d3a827ec8John McCall//   declarator. Similarly, access control for implicit calls to the
142f514480c448708ec382a684cf5e035d3a827ec8John McCall//   constructors, the conversion functions, or the destructor called
152f514480c448708ec382a684cf5e035d3a827ec8John McCall//   to create and destroy a static data member is performed as if
162f514480c448708ec382a684cf5e035d3a827ec8John McCall//   these calls appeared in the scope of the member's class.
172f514480c448708ec382a684cf5e035d3a827ec8John McCall
18b13b737a2450167c82e148590e8019b839ce6b98John McCallstruct Public {}; struct Protected {}; struct Private {};
19b13b737a2450167c82e148590e8019b839ce6b98John McCall
202f514480c448708ec382a684cf5e035d3a827ec8John McCallnamespace test0 {
212f514480c448708ec382a684cf5e035d3a827ec8John McCall  class A {
222f514480c448708ec382a684cf5e035d3a827ec8John McCall    typedef int type; // expected-note {{declared private here}}
232f514480c448708ec382a684cf5e035d3a827ec8John McCall    type foo();
242f514480c448708ec382a684cf5e035d3a827ec8John McCall  };
252f514480c448708ec382a684cf5e035d3a827ec8John McCall
266b2accb4793e16b2e93a8c2589f5df702231f17aJohn McCall  A::type foo() { } // expected-error {{'type' is a private member}}
272f514480c448708ec382a684cf5e035d3a827ec8John McCall  A::type A::foo() { }
282f514480c448708ec382a684cf5e035d3a827ec8John McCall}
29b13b737a2450167c82e148590e8019b839ce6b98John McCall
30b13b737a2450167c82e148590e8019b839ce6b98John McCall// conversion decls
31b13b737a2450167c82e148590e8019b839ce6b98John McCallnamespace test1 {
32b13b737a2450167c82e148590e8019b839ce6b98John McCall  class A {
33b13b737a2450167c82e148590e8019b839ce6b98John McCall  public:
34b13b737a2450167c82e148590e8019b839ce6b98John McCall    A();
35b13b737a2450167c82e148590e8019b839ce6b98John McCall    operator Public ();
36b13b737a2450167c82e148590e8019b839ce6b98John McCall    A(Public);
37b13b737a2450167c82e148590e8019b839ce6b98John McCall  protected:
38b13b737a2450167c82e148590e8019b839ce6b98John McCall    operator Protected (); // expected-note {{declared protected here}}
39b13b737a2450167c82e148590e8019b839ce6b98John McCall    A(Protected); // expected-note {{declared protected here}}
40b13b737a2450167c82e148590e8019b839ce6b98John McCall  private:
41b13b737a2450167c82e148590e8019b839ce6b98John McCall    operator Private (); // expected-note {{declared private here}}
42b13b737a2450167c82e148590e8019b839ce6b98John McCall    A(Private); // expected-note {{declared private here}}
43b13b737a2450167c82e148590e8019b839ce6b98John McCall  };
44b13b737a2450167c82e148590e8019b839ce6b98John McCall
45b13b737a2450167c82e148590e8019b839ce6b98John McCall  void test() {
46b13b737a2450167c82e148590e8019b839ce6b98John McCall    A a;
47b13b737a2450167c82e148590e8019b839ce6b98John McCall    Public pub = a;
486b2accb4793e16b2e93a8c2589f5df702231f17aJohn McCall    Protected prot = a; // expected-error {{'operator Protected' is a protected member}}
496b2accb4793e16b2e93a8c2589f5df702231f17aJohn McCall    Private priv = a; // expected-error {{'operator Private' is a private member}}
50b13b737a2450167c82e148590e8019b839ce6b98John McCall    A apub = pub;
516b2accb4793e16b2e93a8c2589f5df702231f17aJohn McCall    A aprot = prot; // expected-error {{protected constructor}}
526b2accb4793e16b2e93a8c2589f5df702231f17aJohn McCall    A apriv = priv; // expected-error {{private constructor}}
53b13b737a2450167c82e148590e8019b839ce6b98John McCall  }
54b13b737a2450167c82e148590e8019b839ce6b98John McCall}
55f5813826802c2e76cdc13cae834ebfd4518d74a6John McCall
56f5813826802c2e76cdc13cae834ebfd4518d74a6John McCall// PR6967
57f5813826802c2e76cdc13cae834ebfd4518d74a6John McCallnamespace test2 {
58f5813826802c2e76cdc13cae834ebfd4518d74a6John McCall  class A {
59f5813826802c2e76cdc13cae834ebfd4518d74a6John McCall  public:
60f5813826802c2e76cdc13cae834ebfd4518d74a6John McCall    template <class T> static void set(T &t, typename T::type v) {
61f5813826802c2e76cdc13cae834ebfd4518d74a6John McCall      t.value = v;
62f5813826802c2e76cdc13cae834ebfd4518d74a6John McCall    }
63f5813826802c2e76cdc13cae834ebfd4518d74a6John McCall    template <class T> static typename T::type get(const T &t) {
64f5813826802c2e76cdc13cae834ebfd4518d74a6John McCall      return t.value;
65f5813826802c2e76cdc13cae834ebfd4518d74a6John McCall    }
66f5813826802c2e76cdc13cae834ebfd4518d74a6John McCall  };
67f5813826802c2e76cdc13cae834ebfd4518d74a6John McCall
68f5813826802c2e76cdc13cae834ebfd4518d74a6John McCall  class B {
69f5813826802c2e76cdc13cae834ebfd4518d74a6John McCall    friend class A;
70f5813826802c2e76cdc13cae834ebfd4518d74a6John McCall
71f5813826802c2e76cdc13cae834ebfd4518d74a6John McCall  private:
72f5813826802c2e76cdc13cae834ebfd4518d74a6John McCall    typedef int type;
73f5813826802c2e76cdc13cae834ebfd4518d74a6John McCall    type value;
74f5813826802c2e76cdc13cae834ebfd4518d74a6John McCall  };
75f5813826802c2e76cdc13cae834ebfd4518d74a6John McCall
76f5813826802c2e76cdc13cae834ebfd4518d74a6John McCall  int test() {
77f5813826802c2e76cdc13cae834ebfd4518d74a6John McCall    B b;
78f5813826802c2e76cdc13cae834ebfd4518d74a6John McCall    A::set(b, 0);
79f5813826802c2e76cdc13cae834ebfd4518d74a6John McCall    return A::get(b);
80f5813826802c2e76cdc13cae834ebfd4518d74a6John McCall  }
81f5813826802c2e76cdc13cae834ebfd4518d74a6John McCall}
82f5813826802c2e76cdc13cae834ebfd4518d74a6John McCall
83f5813826802c2e76cdc13cae834ebfd4518d74a6John McCallnamespace test3 {
84f5813826802c2e76cdc13cae834ebfd4518d74a6John McCall  class Green {}; class Blue {};
85f5813826802c2e76cdc13cae834ebfd4518d74a6John McCall
86f5813826802c2e76cdc13cae834ebfd4518d74a6John McCall  // We have to wrap this in a class because a partial specialization
87f5813826802c2e76cdc13cae834ebfd4518d74a6John McCall  // isn't actually in the context of the template.
88f5813826802c2e76cdc13cae834ebfd4518d74a6John McCall  struct Outer {
89f5813826802c2e76cdc13cae834ebfd4518d74a6John McCall    template <class T, class Nat> class A {
90f5813826802c2e76cdc13cae834ebfd4518d74a6John McCall    };
91f5813826802c2e76cdc13cae834ebfd4518d74a6John McCall  };
92f5813826802c2e76cdc13cae834ebfd4518d74a6John McCall
93f5813826802c2e76cdc13cae834ebfd4518d74a6John McCall  template <class T> class Outer::A<T, typename T::nature> {
94f5813826802c2e76cdc13cae834ebfd4518d74a6John McCall  public:
95b5c7768a74936d4e2c7a484570a638cb74702d8bKaelyn Uhrain    static void foo(); // expected-note {{'Outer::A<B, Green>::foo' declared here}}
96f5813826802c2e76cdc13cae834ebfd4518d74a6John McCall  };
97f5813826802c2e76cdc13cae834ebfd4518d74a6John McCall
98f5813826802c2e76cdc13cae834ebfd4518d74a6John McCall  class B {
99f5813826802c2e76cdc13cae834ebfd4518d74a6John McCall  private: typedef Green nature;
100f5813826802c2e76cdc13cae834ebfd4518d74a6John McCall    friend class Outer;
101f5813826802c2e76cdc13cae834ebfd4518d74a6John McCall  };
102f5813826802c2e76cdc13cae834ebfd4518d74a6John McCall
103f5813826802c2e76cdc13cae834ebfd4518d74a6John McCall  void test() {
104f5813826802c2e76cdc13cae834ebfd4518d74a6John McCall    Outer::A<B, Green>::foo();
105b5c7768a74936d4e2c7a484570a638cb74702d8bKaelyn Uhrain    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'?}}
106f5813826802c2e76cdc13cae834ebfd4518d74a6John McCall  }
107f5813826802c2e76cdc13cae834ebfd4518d74a6John McCall}
1087576a65d25f3d604cec57e357b17ead8b3bbfa16John McCall
1097576a65d25f3d604cec57e357b17ead8b3bbfa16John McCallnamespace test4 {
1107576a65d25f3d604cec57e357b17ead8b3bbfa16John McCall  template <class T> class A {
1117576a65d25f3d604cec57e357b17ead8b3bbfa16John McCall  private: typedef int type;
1127576a65d25f3d604cec57e357b17ead8b3bbfa16John McCall    template <class U> friend void foo(U &, typename U::type);
1137576a65d25f3d604cec57e357b17ead8b3bbfa16John McCall  };
1147576a65d25f3d604cec57e357b17ead8b3bbfa16John McCall
1157576a65d25f3d604cec57e357b17ead8b3bbfa16John McCall  template <class U> void foo(U &, typename U::type) {}
1167576a65d25f3d604cec57e357b17ead8b3bbfa16John McCall
1177576a65d25f3d604cec57e357b17ead8b3bbfa16John McCall  void test() {
1187576a65d25f3d604cec57e357b17ead8b3bbfa16John McCall    A<int> a;
1197576a65d25f3d604cec57e357b17ead8b3bbfa16John McCall    foo(a, 0);
1207576a65d25f3d604cec57e357b17ead8b3bbfa16John McCall  }
1217576a65d25f3d604cec57e357b17ead8b3bbfa16John McCall}
122c9068d7dd94d439cec66c421115d15303e481025John McCall
123c9068d7dd94d439cec66c421115d15303e481025John McCall// PR7644
124c9068d7dd94d439cec66c421115d15303e481025John McCallnamespace test5 {
125c9068d7dd94d439cec66c421115d15303e481025John McCall  class A {
126c9068d7dd94d439cec66c421115d15303e481025John McCall    enum Enum { E0, E1, E2 }; // expected-note 4 {{declared private here}}
127c9068d7dd94d439cec66c421115d15303e481025John McCall    template <Enum> void foo();
128c9068d7dd94d439cec66c421115d15303e481025John McCall    template <Enum> class bar;
129c9068d7dd94d439cec66c421115d15303e481025John McCall  };
130c9068d7dd94d439cec66c421115d15303e481025John McCall
131c9068d7dd94d439cec66c421115d15303e481025John McCall  template <A::Enum en> void A::foo() {}
132c9068d7dd94d439cec66c421115d15303e481025John McCall  template <A::Enum en> class A::bar {};
133c9068d7dd94d439cec66c421115d15303e481025John McCall
134c9068d7dd94d439cec66c421115d15303e481025John McCall  template <A::Enum en> void foo() {} // expected-error {{'Enum' is a private member of 'test5::A'}}
135c9068d7dd94d439cec66c421115d15303e481025John McCall  template <A::Enum en> class bar {}; // expected-error {{'Enum' is a private member of 'test5::A'}}
136c9068d7dd94d439cec66c421115d15303e481025John McCall
137c9068d7dd94d439cec66c421115d15303e481025John McCall  class B {
138c9068d7dd94d439cec66c421115d15303e481025John McCall    template <A::Enum en> void foo() {} // expected-error {{'Enum' is a private member of 'test5::A'}}
139c9068d7dd94d439cec66c421115d15303e481025John McCall    template <A::Enum en> class bar {}; // expected-error {{'Enum' is a private member of 'test5::A'}}
140c9068d7dd94d439cec66c421115d15303e481025John McCall  };
141c9068d7dd94d439cec66c421115d15303e481025John McCall}
142b25b295fdfc443bdf060e860a21f6f01d9fbdc18John McCall
143b25b295fdfc443bdf060e860a21f6f01d9fbdc18John McCallnamespace test6 {
144b25b295fdfc443bdf060e860a21f6f01d9fbdc18John McCall  class A {
145b25b295fdfc443bdf060e860a21f6f01d9fbdc18John McCall  public: class public_inner {};
146b25b295fdfc443bdf060e860a21f6f01d9fbdc18John McCall  protected: class protected_inner {};
147b25b295fdfc443bdf060e860a21f6f01d9fbdc18John McCall  private: class private_inner {}; // expected-note {{declared private here}}
148b25b295fdfc443bdf060e860a21f6f01d9fbdc18John McCall  };
149b25b295fdfc443bdf060e860a21f6f01d9fbdc18John McCall
150b25b295fdfc443bdf060e860a21f6f01d9fbdc18John McCall  class B : A {
151b25b295fdfc443bdf060e860a21f6f01d9fbdc18John McCall    public_inner a;
152b25b295fdfc443bdf060e860a21f6f01d9fbdc18John McCall    protected_inner b;
1532fe9b7fb07dff15dd15dd8755a9a9e6de0fe46fcRichard Trieu    private_inner c; // expected-error {{'private_inner' is a private member of 'test6::A'}}
154b25b295fdfc443bdf060e860a21f6f01d9fbdc18John McCall  };
155b25b295fdfc443bdf060e860a21f6f01d9fbdc18John McCall}
1564bfd680597862e437fcba739dce58531d0b15d6eJohn McCall
1574bfd680597862e437fcba739dce58531d0b15d6eJohn McCall// PR9229
1584bfd680597862e437fcba739dce58531d0b15d6eJohn McCallnamespace test7 {
1594bfd680597862e437fcba739dce58531d0b15d6eJohn McCall  void foo(int arg[1]);
1604bfd680597862e437fcba739dce58531d0b15d6eJohn McCall  class A {
1614bfd680597862e437fcba739dce58531d0b15d6eJohn McCall    void check();
1624bfd680597862e437fcba739dce58531d0b15d6eJohn McCall  };
1634bfd680597862e437fcba739dce58531d0b15d6eJohn McCall  class B {
1644bfd680597862e437fcba739dce58531d0b15d6eJohn McCall    friend class A;
1654bfd680597862e437fcba739dce58531d0b15d6eJohn McCall    A ins;
1664bfd680597862e437fcba739dce58531d0b15d6eJohn McCall  };
1674bfd680597862e437fcba739dce58531d0b15d6eJohn McCall  void A::check() {
1684bfd680597862e437fcba739dce58531d0b15d6eJohn McCall    void foo(int arg[__builtin_offsetof(B, ins)]);
1694bfd680597862e437fcba739dce58531d0b15d6eJohn McCall  }
1704bfd680597862e437fcba739dce58531d0b15d6eJohn McCall}
171ca82a82082edc982a1fb5fcfef2dd2c8cf9bc824John McCall
172ca82a82082edc982a1fb5fcfef2dd2c8cf9bc824John McCall// rdar://problem/10155256
173ca82a82082edc982a1fb5fcfef2dd2c8cf9bc824John McCallnamespace test8 {
174ca82a82082edc982a1fb5fcfef2dd2c8cf9bc824John McCall  class A {
175ca82a82082edc982a1fb5fcfef2dd2c8cf9bc824John McCall    typedef void* (A::*UnspecifiedBoolType)() const;
176ca82a82082edc982a1fb5fcfef2dd2c8cf9bc824John McCall    operator UnspecifiedBoolType() const; // expected-note {{implicitly declared private here}}
177ca82a82082edc982a1fb5fcfef2dd2c8cf9bc824John McCall  };
178ca82a82082edc982a1fb5fcfef2dd2c8cf9bc824John McCall
179ca82a82082edc982a1fb5fcfef2dd2c8cf9bc824John McCall  void test(A &a) {
180651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines    if (a) return; // expected-error-re {{'operator void *(test8::A::*)(){{( __attribute__\(\(thiscall\)\))?}} const' is a private member of 'test8::A'}}
181ca82a82082edc982a1fb5fcfef2dd2c8cf9bc824John McCall  }
182ca82a82082edc982a1fb5fcfef2dd2c8cf9bc824John McCall}
183ca82a82082edc982a1fb5fcfef2dd2c8cf9bc824John McCall
184ca82a82082edc982a1fb5fcfef2dd2c8cf9bc824John McCallnamespace test9 {
185ca82a82082edc982a1fb5fcfef2dd2c8cf9bc824John McCall  class A {
186ca82a82082edc982a1fb5fcfef2dd2c8cf9bc824John McCall    operator char*() const; // expected-note {{implicitly declared private here}}
187ca82a82082edc982a1fb5fcfef2dd2c8cf9bc824John McCall  };
188ca82a82082edc982a1fb5fcfef2dd2c8cf9bc824John McCall
189ca82a82082edc982a1fb5fcfef2dd2c8cf9bc824John McCall  void test(A &a) {
190ca82a82082edc982a1fb5fcfef2dd2c8cf9bc824John McCall    delete a; // expected-error {{'operator char *' is a private member of 'test9::A'}}
191ca82a82082edc982a1fb5fcfef2dd2c8cf9bc824John McCall  }
192ca82a82082edc982a1fb5fcfef2dd2c8cf9bc824John McCall}
193