p1.cpp revision 00b40d3f2fb8b2f9043daf3dd4558bff98346b3c
1// RUN: %clang_cc1 -verify -emit-llvm-only %s 2 3namespace test0 { 4template <typename T> struct Num { 5 T value_; 6 7public: 8 Num(T value) : value_(value) {} 9 T get() const { return value_; } 10 11 template <typename U> struct Rep { 12 U count_; 13 Rep(U count) : count_(count) {} 14 15 friend Num operator*(const Num &a, const Rep &n) { 16 Num x = 0; 17 for (U count = n.count_; count; --count) 18 x += a; 19 return x; 20 } 21 }; 22 23 friend Num operator+(const Num &a, const Num &b) { 24 return a.value_ + b.value_; 25 } 26 27 Num& operator+=(const Num& b) { 28 value_ += b.value_; 29 return *this; 30 } 31 32 class Representation {}; 33 friend class Representation; 34}; 35 36class A { 37 template <typename T> friend bool iszero(const A &a) throw(); 38}; 39 40template <class T> class B_iterator; 41template <class T> class B { 42 friend class B_iterator<T>; 43}; 44 45int calc1() { 46 Num<int> left = -1; 47 Num<int> right = 1; 48 Num<int> result = left + right; 49 return result.get(); 50} 51 52int calc2() { 53 Num<int> x = 3; 54 Num<int>::Rep<char> n = (char) 10; 55 Num<int> result = x * n; 56 return result.get(); 57} 58} 59 60// Reduced from GNU <locale> 61namespace test1 { 62 class A { 63 bool b; // expected-note {{declared private here}} 64 template <typename T> friend bool has(const A&); 65 }; 66 template <typename T> bool has(const A &x) { 67 return x.b; 68 } 69 template <typename T> bool hasnot(const A &x) { 70 return x.b; // expected-error {{'b' is a private member of 'test1::A'}} 71 } 72} 73 74namespace test2 { 75 class A { 76 bool b; // expected-note {{declared private here}} 77 template <typename T> friend class HasChecker; 78 }; 79 template <typename T> class HasChecker { 80 bool check(A *a) { 81 return a->b; 82 } 83 }; 84 template <typename T> class HasNotChecker { 85 bool check(A *a) { 86 return a->b; // expected-error {{'b' is a private member of 'test2::A'}} 87 } 88 }; 89} 90 91namespace test3 { 92 class Bool; 93 template <class T> class User; 94 template <class T> T transform(class Bool, T); 95 96 class Bool { 97 friend class User<bool>; 98 friend bool transform<>(Bool, bool); 99 100 bool value; // expected-note 2 {{declared private here}} 101 }; 102 103 template <class T> class User { 104 static T compute(Bool b) { 105 return b.value; // expected-error {{'value' is a private member of 'test3::Bool'}} 106 } 107 }; 108 109 template <class T> T transform(Bool b, T value) { 110 if (b.value) // expected-error {{'value' is a private member of 'test3::Bool'}} 111 return value; 112 return value + 1; 113 } 114 115 template bool transform(Bool, bool); 116 template int transform(Bool, int); // expected-note {{requested here}} 117 118 template class User<bool>; 119 template class User<int>; // expected-note {{requested here}} 120} 121 122namespace test4 { 123 template <class T> class A { 124 template <class T0> friend class B; 125 bool foo(const A<T> *) const; 126 }; 127 128 template <class T> class B { 129 bool bar(const A<T> *a, const A<T> *b) { 130 return a->foo(b); 131 } 132 }; 133 134 template class B<int>; 135} 136 137namespace test5 { 138 template <class T, class U=int> class A {}; 139 template <class T> class B { 140 template <class X, class Y> friend class A; 141 }; 142 template class B<int>; 143 template class A<int>; 144} 145 146namespace Dependent { 147 template<typename T, typename Traits> class X; 148 template<typename T, typename Traits> 149 X<T, Traits> operator+(const X<T, Traits>&, const T*); 150 151 template<typename T, typename Traits> class X { 152 typedef typename Traits::value_type value_type; 153 friend X operator+<>(const X&, const value_type*); 154 }; 155} 156 157namespace test7 { 158 template <class T> class A { // expected-note {{previous definition is here}} 159 friend class B; 160 int x; // expected-note {{declared private here}} 161 }; 162 163 class B { 164 int foo(A<int> &a) { 165 return a.x; 166 } 167 }; 168 169 class C { 170 int foo(A<int> &a) { 171 return a.x; // expected-error {{'x' is a private member of 'test7::A<int>'}} 172 } 173 }; 174 175 // This shouldn't crash. 176 template <class T> class D { 177 friend class A; // expected-error {{redefinition of 'A' as different kind of symbol}} 178 }; 179 template class D<int>; 180} 181 182namespace test8 { 183 template <class N> class A { 184 static int x; 185 template <class T> friend void foo(); 186 }; 187 template class A<int>; 188 189 template <class T> void foo() { 190 A<int>::x = 0; 191 } 192 template void foo<int>(); 193} 194 195namespace test9 { 196 template <class T> class A { 197 class B; class C; 198 199 int foo(B *b) { 200 return b->x; 201 } 202 203 int foo(C *c) { 204 return c->x; // expected-error {{'x' is a private member}} 205 } 206 207 class B { 208 int x; 209 friend int A::foo(B*); 210 }; 211 212 class C { 213 int x; // expected-note {{declared private here}} 214 }; 215 }; 216 217 template class A<int>; // expected-note {{in instantiation}} 218} 219 220namespace test10 { 221 template <class T> class A; 222 template <class T> A<T> bar(const T*, const A<T>&); 223 template <class T> class A { 224 private: 225 void foo(); // expected-note {{declared private here}} 226 friend A bar<>(const T*, const A<T>&); 227 }; 228 229 template <class T> A<T> bar(const T *l, const A<T> &r) { 230 A<T> l1; 231 l1.foo(); 232 233 A<char> l2; 234 l2.foo(); // expected-error {{'foo' is a private member of 'test10::A<char>'}} 235 236 return l1; 237 } 238 239 template A<int> bar<int>(const int *, const A<int> &); // expected-note {{in instantiation}} 240} 241 242// PR6752: this shouldn't crash. 243namespace test11 { 244 struct Foo { 245 template<class A> 246 struct IteratorImpl { 247 template<class T> friend class IteratorImpl; 248 }; 249 }; 250 251 template struct Foo::IteratorImpl<int>; 252 template struct Foo::IteratorImpl<long>; 253} 254 255// PR6827 256namespace test12 { 257 template <typename T> class Foo; 258 template <typename T> Foo<T> foo(T* t){ return Foo<T>(t, true); } 259 260 template <typename T> class Foo { 261 public: 262 Foo(T*); 263 friend Foo<T> foo<T>(T*); 264 private: 265 Foo(T*, bool); // expected-note {{declared private here}} 266 }; 267 268 // Should work. 269 int globalInt; 270 Foo<int> f = foo(&globalInt); 271 272 // Shouldn't work. 273 long globalLong; 274 template <> Foo<long> foo(long *t) { 275 Foo<int> s(&globalInt, false); // expected-error {{calling a private constructor}} 276 return Foo<long>(t, true); 277 } 278} 279 280// PR6514 281namespace test13 { 282 template <int N, template <int> class Temp> 283 class Role : public Temp<N> { 284 friend class Temp<N>; 285 int x; 286 }; 287 288 template <int N> class Foo { 289 void foo(Role<N, test13::Foo> &role) { 290 (void) role.x; 291 } 292 }; 293 294 template class Foo<0>; 295} 296