brintos

brintos / llvm-project-archived public Read only

0
0
Text · 4.9 KiB · 9a1ed46 Raw
169 lines · cpp
1// RUN: %clang_cc1 -fsyntax-only -verify %s2template<typename T> struct A {3  struct B { };4  5  friend struct B;6};7 8void f() {9  A<int>::B b;10}11 12struct C0 {13  friend struct A<int>;14};15 16namespace PR6770 {17  namespace N {18    int f1(int);19  }20  using namespace N;21 22  namespace M { 23    float f1(float);24  }25  using M::f1;26 27  template<typename T> void f1(T, T);28  template <class T>29  void f() {30    friend class f; // expected-error{{'friend' used outside of class}}31    friend class f1; // expected-error{{'friend' used outside of class}}32  }33}34 35namespace friend_redecl_inline {36// We had a bug where instantiating the foo friend declaration would check the37// defined-ness of the most recent decl while checking if the canonical decl was38// inlined.39void foo();40void bar();41template <typename T>42class C {43  friend void foo();44  friend inline void bar();45};46inline void foo() {}47inline void bar() {}48C<int> c;49}50 51namespace qualified_friend {52  void f(int); // expected-note 2{{type mismatch at 1st parameter}}53  template<typename T> void f(T*); // expected-note 2{{could not match 'T *' against 'double'}}54  template<typename T> void nondep();55 56  template<typename> struct X1 {57    friend void qualified_friend::f(double); // expected-error {{friend declaration of 'f' does not match any declaration in namespace 'qualified_friend'}}58    friend void qualified_friend::g(); // expected-error {{friend declaration of 'g' does not match any declaration in namespace 'qualified_friend'}}59  };60  template<typename T> struct X2 {61    friend void qualified_friend::f(T); // expected-error {{friend declaration of 'f' does not match any declaration in namespace 'qualified_friend'}}62  };63  X1<int> xi;64  X2<double> xd; // expected-note {{in instantiation of}}65  X2<int> x2i;66 67  struct Y {68    void f(int); // expected-note 2{{type mismatch at 1st parameter}}69    template<typename T> void f(T*); // expected-note 2{{could not match 'T *' against 'double'}}70    template<typename T> void nondep();71  };72 73  template<typename> struct Z1 {74    friend void Y::f(double); // expected-error {{friend declaration of 'f' does not match any declaration in 'qualified_friend::Y'}}75    friend void Y::g(); // expected-error {{friend declaration of 'g' does not match any declaration in 'qualified_friend::Y'}}76  };77  template<typename T> struct Z2 {78    friend void Y::f(T); // expected-error {{friend declaration of 'f' does not match any declaration in 'qualified_friend::Y'}}79  };80  Z1<int> zi;81  Z2<double> zd; // expected-note {{in instantiation of}}82  Z2<int> z2i;83 84  template<typename T>85  struct OK {86    friend void qualified_friend::f(int);87    friend void qualified_friend::f(int*);88    friend void qualified_friend::f(T*);89    friend void qualified_friend::f<T>(T*);90    friend void qualified_friend::nondep<int>();91    friend void qualified_friend::nondep<T>();92 93    friend void Y::f(int);94    friend void Y::f(int*);95    friend void Y::f(T*);96    friend void Y::f<T>(T*);97    friend void Y::nondep<int>();98    friend void Y::nondep<T>();99  };100  OK<float> ok;101}102 103namespace qualified_friend_finds_nothing {104  // FIXME: The status of this example is unclear. For now, we diagnose if the105  // qualified declaration has nothing it can redeclare, but allow qualified106  // lookup to find later-declared function templates during instantiation.107  //108  // This matches the behavior of GCC, EDG, ICC, and MSVC (except that GCC and109  // ICC bizarrely accept the instantiation of B<float>).110  namespace N {}111 112  template<typename T> struct A {113    friend void N::f(T); // expected-error {{friend declaration of 'f' does not match}}114  };115  namespace N { void f(); } // expected-note {{different number of parameters}}116 117  template<typename T> struct B {118    friend void N::f(T); // expected-error {{friend declaration of 'f' does not match}}119  };120  B<float> bf; // expected-note {{in instantiation of}}121 122  namespace N { void f(int); }123  B<int> bi; // ok?!124}125 126namespace PR37556 {127  inline namespace N { int x1, x2, y1, y2; } // expected-note 2{{previous}}128  struct X {129    friend void x1(int);130    friend void PR37556::x2(int); // expected-error {{different kind}}131  };132  template<typename T> struct Y {133    friend void y1(T);134    friend void PR37556::y2(T); // expected-error {{different kind}}135  };136  template struct Y<int>;137  template<typename T> struct Z {138    friend void z1(T);139    friend void PR37556::z2(T); // expected-error {{does not match any}}140  };141  inline namespace N { int z1, z2; }142  template struct Z<int>;143}144 145namespace PR42513_comment3 {146  template<typename X> struct T { friend auto f(X*) { return nullptr; } };147  struct X1 { friend auto f(X1*); };148  template struct T<X1>;149  int n = f((X1*)nullptr); // expected-error {{cannot initialize a variable of type 'int' with an rvalue of type 'std::nullptr_t'}}150}151 152namespace GH61851 {153namespace A {154inline namespace B {155  constexpr struct {} foo;156}157 158template <typename T>159class Bar {160  template <typename U>161  friend void foo(U &&arg) {} // no diagnostic expected162};163}164 165void foobar() {166  A::Bar<int> b;167}168}169