1 // RUN: %clang_cc1 -std=c++11 -fsyntax-only -verify %s
2 
3 class C {
4     struct S; // expected-note {{previously declared 'private' here}}
5 public:
6 
7     struct S {}; // expected-error {{'S' redeclared with 'public' access}}
8 };
9 
10 struct S {
11     class C; // expected-note {{previously declared 'public' here}}
12 
13 private:
14     class C { }; // expected-error {{'C' redeclared with 'private' access}}
15 };
16 
17 class T {
18 protected:
19     template<typename T> struct A; // expected-note {{previously declared 'protected' here}}
20 
21 private:
22     template<typename T> struct A {}; // expected-error {{'A' redeclared with 'private' access}}
23 };
24 
25 // PR5573
26 namespace test1 {
27   class A {
28   private:
29     class X; // expected-note {{previously declared 'private' here}} \
30              // expected-note {{previous declaration is here}}
31   public:
32     class X; // expected-error {{'X' redeclared with 'public' access}} \
33              // expected-warning {{class member cannot be redeclared}}
34     class X {};
35   };
36 }
37 
38 // PR15209
39 namespace PR15209 {
40   namespace alias_templates {
41     template<typename T1, typename T2> struct U { };
42     template<typename T1> using W = U<T1, float>;
43 
44     class A {
45       typedef int I;
46       static constexpr I x = 0; // expected-note {{implicitly declared private here}}
47       static constexpr I y = 42; // expected-note {{implicitly declared private here}}
48       friend W<int>;
49     };
50 
51     template<typename T1>
52     struct U<T1, float>  {
53       int v_;
54       // the following will trigger for U<float, float> instantiation, via W<float>
UPR15209::alias_templates::U55       U() : v_(A::x) { } // expected-error {{'x' is a private member of 'PR15209::alias_templates::A'}}
56     };
57 
58     template<typename T1>
59     struct U<T1, int> {
60       int v_;
UPR15209::alias_templates::U61       U() : v_(A::y) { } // expected-error {{'y' is a private member of 'PR15209::alias_templates::A'}}
62     };
63 
64     template struct U<int, int>; // expected-note {{in instantiation of member function 'PR15209::alias_templates::U<int, int>::U' requested here}}
65 
f()66     void f()
67     {
68       W<int>();
69       // we should issue diagnostics for the following
70       W<float>(); // expected-note {{in instantiation of member function 'PR15209::alias_templates::U<float, float>::U' requested here}}
71     }
72   }
73 
74   namespace templates {
75     class A {
76       typedef int I;  // expected-note {{implicitly declared private here}}
77       static constexpr I x = 0; // expected-note {{implicitly declared private here}}
78 
79       template<int> friend struct B;
80       template<int> struct C;
81       template<template<int> class T> friend struct TT;
82       template<typename T> friend void funct(T);
83     };
84     template<A::I> struct B { };
85 
86     template<A::I> struct A::C { };
87 
88     template<template<A::I> class T> struct TT {
89       T<A::x> t;
90     };
91 
92     template struct TT<B>;
93     template<A::I> struct D { };  // expected-error {{'I' is a private member of 'PR15209::templates::A'}}
94     template struct TT<D>;
95 
96     // function template case
97     template<typename T>
funct(T)98     void funct(T)
99     {
100       (void)A::x;
101     }
102 
103     template void funct<int>(int);
104 
f()105     void f()
106     {
107       (void)A::x;  // expected-error {{'x' is a private member of 'PR15209::templates::A'}}
108     }
109   }
110 }
111 
112 namespace PR7434 {
113   namespace comment0 {
114     template <typename T> struct X;
115     namespace N {
116     class Y {
117       template<typename T> friend struct X;
118       int t; // expected-note {{here}}
119     };
120     }
121     template<typename T> struct X {
XPR7434::comment0::X122       X() { (void)N::Y().t; } // expected-error {{private}}
123     };
124     X<char> x;
125   }
126   namespace comment2 {
127     struct X;
128     namespace N {
129     class Y {
130       friend struct X;
131       int t; // expected-note {{here}}
132     };
133     }
134     struct X {
XPR7434::comment2::X135       X() { (void)N::Y().t; } // expected-error {{private}}
136     };
137   }
138 }
139 
140 namespace LocalExternVar {
141   class test {
142   private:
143     struct private_struct { // expected-note 2{{here}}
144       int x;
145     };
146     int use_private();
147   };
148 
use_private()149   int test::use_private() {
150     extern int array[sizeof(test::private_struct)]; // ok
151     return array[0];
152   }
153 
f()154   int f() {
155     extern int array[sizeof(test::private_struct)]; // expected-error {{private}}
156     return array[0];
157   }
158 
159   int array[sizeof(test::private_struct)]; // expected-error {{private}}
160 }
161 
162 namespace ThisLambdaIsNotMyFriend {
163   class A {
164     friend class D;
165     static void foo(); // expected-note {{here}}
166   };
foo()167   template <class T> void foo() {
168     []() { A::foo(); }(); // expected-error {{private}}
169   }
bar()170   void bar() { foo<void>(); }
171 }
172 
173 namespace OverloadedMemberFunctionPointer {
174   template<class T, void(T::*pMethod)()>
func0()175   void func0() {}
176 
177   template<class T, void(T::*pMethod)(int)>
func1()178   void func1() {}
179 
180   template<class T>
func2(void (* fn)())181   void func2(void(*fn)()) {} // expected-note 2 {{candidate function template not viable: no overload of 'func}}
182 
183   class C {
184   private:
185     friend void friendFunc();
186     void overloadedMethod();
187   protected:
188     void overloadedMethod(int);
189   public:
190     void overloadedMethod(int, int);
method()191     void method() {
192       func2<int>(&func0<C, &C::overloadedMethod>);
193       func2<int>(&func1<C, &C::overloadedMethod>);
194     }
195   };
196 
friendFunc()197   void friendFunc() {
198     func2<int>(&func0<C, &C::overloadedMethod>);
199     func2<int>(&func1<C, &C::overloadedMethod>);
200   }
201 
nonFriendFunc()202   void nonFriendFunc() {
203     func2<int>(&func0<C, &C::overloadedMethod>); // expected-error {{no matching function for call to 'func2'}}
204     func2<int>(&func1<C, &C::overloadedMethod>); // expected-error {{no matching function for call to 'func2'}}
205   }
206 
207   // r325321 caused an assertion failure when the following code was compiled.
208   class A {
foo1()209     template <typename Type> static bool foo1() { return true; }
210 
211   public:
init(bool c)212     void init(bool c) {
213       if (c) {
214         auto f = foo1<int>;
215       }
216     }
217   };
218 }
219