390 lines · cpp
1// RUN: %clang_cc1 -verify -emit-llvm-only %s2 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 {{declared 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 {{template 'A' cannot be referenced with the 'class' specifier}}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// PR6827256namespace 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// PR6514281namespace 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 297namespace test14 {298 template <class T> class B;299 template <class T> class A {300 friend void B<T>::foo();301 static void foo(); // expected-note {{declared private here}}302 };303 304 template <class T> class B {305 public:306 void foo() { return A<long>::foo(); } // expected-error {{'foo' is a private member of 'test14::A<long>'}}307 };308 309 template class B<int>; // expected-note {{in instantiation}}310}311 312namespace test15 {313 template <class T> class B;314 template <class T> class A {315 friend void B<T>::foo();316 317 // This shouldn't be misrecognized as a templated-scoped reference.318 template <class U> friend void B<T>::bar(U);319 320 static void foo(); // expected-note {{declared private here}}321 };322 323 template <class T> class B {324 public:325 void foo() { return A<long>::foo(); } // expected-error {{'foo' is a private member of 'test15::A<long>'}}326 };327 328 template <> class B<float> {329 public:330 void foo() { return A<float>::foo(); }331 template <class U> void bar(U u) {332 (void) A<float>::foo();333 }334 };335 336 template class B<int>; // expected-note {{in instantiation}}337}338 339namespace PR10913 {340 template<class T> class X;341 342 template<class T> void f(X<T> *x) {343 x->member = 0;344 }345 346 template<class U, class T> void f2(X<T> *x) {347 x->member = 0; // expected-error{{'member' is a protected member of 'PR10913::X<int>'}}348 }349 350 template<class T> class X {351 friend void f<T>(X<T> *x);352 friend void f2<T>(X<int> *x);353 354 protected:355 int member; // expected-note{{declared protected here}}356 };357 358 template void f(X<int> *);359 template void f2<int>(X<int> *);360 template void f2<float>(X<int> *); // expected-note{{in instantiation of function template specialization 'PR10913::f2<float, int>' requested here}}361}362 363namespace test16 {364template <class T> struct foo {}; // expected-note{{candidate ignored: not a function template}}365template <class T> class A {366 friend void foo<T>(); // expected-error{{no candidate function template was found for dependent friend function template specialization}}367};368}369 370namespace test17 {371namespace ns {372template <class T> void foo() {} // expected-note{{candidate ignored: not a member of the enclosing namespace; did you mean to explicitly qualify the specialization?}}373}374using ns::foo;375template <class T> struct A {376 friend void foo<T>() {} // expected-error{{no candidate function template was found for dependent friend function template specialization}}377};378}379 380namespace test18 {381namespace ns1 { template <class T> struct foo {}; } // expected-note{{candidate ignored: not a function template}}382namespace ns2 { void foo() {} } // expected-note{{candidate ignored: not a function template}}383using ns1::foo; // expected-note {{found by name lookup}}384using ns2::foo; // expected-note {{found by name lookup}}385 386template <class T> class A {387 friend void foo<T>() {} // expected-error {{ambiguous}} expected-error{{no candidate function template was found for dependent friend function template specialization}}388};389}390