2014-12-18 07:40:46 +08:00
// RUN: %clang_cc1 -fsyntax-only -verify %s -std=c++14
2009-05-12 06:55:49 +08:00
friend class A ; // expected-error {{'friend' used outside of class}}
void f ( ) { friend class A ; } // expected-error {{'friend' used outside of class}}
class C { friend class A ; } ;
class D { void f ( ) { friend class A ; } } ; // expected-error {{'friend' used outside of class}}
2009-12-12 04:04:54 +08:00
// PR5760
namespace test0 {
namespace ns {
void f ( int ) ;
}
struct A {
friend void ns : : f ( int a ) ;
} ;
}
2009-12-18 07:21:11 +08:00
// Test derived from LLVM's Registry.h
namespace test1 {
template < class T > struct Outer {
void foo ( T ) ;
struct Inner {
friend void Outer : : foo ( T ) ;
} ;
} ;
void test ( ) {
( void ) Outer < int > : : Inner ( ) ;
}
}
2009-12-23 08:44:38 +08:00
// PR5476
namespace test2 {
namespace foo {
void Func ( int x ) ;
}
class Bar {
friend void : : test2 : : foo : : Func ( int x ) ;
} ;
}
2009-12-23 09:09:14 +08:00
// PR5134
namespace test3 {
class Foo {
2013-06-26 07:09:30 +08:00
friend const int getInt ( int inInt = 0 ) { }
2010-07-13 16:18:22 +08:00
2009-12-23 09:09:14 +08:00
} ;
}
2010-06-09 05:27:36 +08:00
namespace test4 {
class T4A {
friend class T4B ;
public :
T4A ( class T4B * ) ;
protected :
T4B * mB ; // error here
} ;
class T4B { } ;
}
2010-10-09 12:39:54 +08:00
namespace rdar8529993 {
2011-03-05 06:45:55 +08:00
struct A { ~ A ( ) ; } ;
2010-10-09 12:39:54 +08:00
struct B : A
{
2011-03-05 06:45:55 +08:00
template < int > friend A : : ~ A ( ) ; // expected-error {{destructor cannot be declared as a template}}
2010-10-09 12:39:54 +08:00
} ;
}
2010-11-10 11:01:53 +08:00
// PR7915
namespace test5 {
struct A ;
struct A1 { friend void A ( ) ; } ;
struct B { friend void B ( ) ; } ;
}
2010-11-30 02:19:25 +08:00
// PR8479
namespace test6_1 {
class A {
public :
private :
friend class vectorA ;
A ( ) { }
} ;
class vectorA {
public :
vectorA ( int i , const A & t = A ( ) ) { }
} ;
void f ( ) {
vectorA v ( 1 ) ;
}
}
namespace test6_2 {
template < class T >
class vector {
public :
vector ( int i , const T & t = T ( ) ) { }
} ;
class A {
public :
private :
friend class vector < A > ;
A ( ) { }
} ;
void f ( ) {
vector < A > v ( 1 ) ;
}
}
2010-11-30 12:44:33 +08:00
namespace test6_3 {
template < class T >
class vector {
public :
vector ( int i ) { }
void f ( const T & t = T ( ) ) { }
} ;
class A {
public :
private :
friend void vector < A > : : f ( const A & ) ;
A ( ) { }
} ;
void f ( ) {
vector < A > v ( 1 ) ;
v . f ( ) ;
}
}
2012-03-17 03:51:19 +08:00
namespace test7 {
extern " C " {
class X {
2013-06-30 17:48:50 +08:00
friend int test7_f ( ) { return 42 ; }
2012-03-17 03:51:19 +08:00
} ;
}
}
2013-04-04 05:19:47 +08:00
// PR15485
namespace test8 {
namespace ns1 {
namespace ns2 {
template < class T > void f ( T t ) ; // expected-note {{target of using declaration}}
}
using ns2 : : f ; // expected-note {{using declaration}}
}
2016-05-24 08:01:49 +08:00
struct A { void f ( ) ; } ; // expected-note 2{{target of using declaration}}
2013-04-04 05:19:47 +08:00
struct B : public A { using A : : f ; } ; // expected-note {{using declaration}}
2016-05-24 08:01:49 +08:00
template < typename T > struct C : A { using A : : f ; } ; // expected-note {{using declaration}}
2013-04-04 05:19:47 +08:00
struct X {
template < class T > friend void ns1 : : f ( T t ) ; // expected-error {{cannot befriend target of using declaration}}
friend void B : : f ( ) ; // expected-error {{cannot befriend target of using declaration}}
2016-05-24 08:01:49 +08:00
friend void C < int > : : f ( ) ; // expected-error {{cannot befriend target of using declaration}}
2013-04-04 05:19:47 +08:00
} ;
}
2013-06-23 15:37:13 +08:00
// PR16423
namespace test9 {
class C {
} ;
struct A {
2019-01-07 14:00:46 +08:00
friend void C : : f ( int , int , int ) { } // expected-error {{friend function definition cannot be qualified with 'C::'}}
2013-06-23 15:37:13 +08:00
} ;
}
2013-07-13 04:38:49 +08:00
namespace test10 {
2013-07-18 07:53:16 +08:00
struct X { } ;
extern void f10_a ( ) ;
extern void f10_a ( X ) ;
2013-07-13 04:38:49 +08:00
struct A {
2013-07-18 07:53:16 +08:00
friend void f10_a ( ) ;
friend void f10_b ( ) ;
friend void f10_c ( ) ;
friend void f10_d ( ) ;
friend void f10_a ( X ) ;
friend void f10_b ( X ) ;
friend void f10_c ( X ) ;
friend void f10_d ( X ) ;
2013-07-13 04:38:49 +08:00
} ;
2013-07-18 07:53:16 +08:00
extern void f10_b ( ) ;
extern void f10_b ( X ) ;
2013-07-13 04:38:49 +08:00
struct B {
2013-07-18 07:53:16 +08:00
friend void f10_a ( ) ;
friend void f10_b ( ) ;
friend void f10_c ( ) ;
friend void f10_d ( ) ;
friend void f10_a ( X ) ;
friend void f10_b ( X ) ;
friend void f10_c ( X ) ;
friend void f10_d ( X ) ;
2013-07-13 04:38:49 +08:00
} ;
2013-07-18 07:53:16 +08:00
extern void f10_c ( ) ;
extern void f10_c ( X ) ;
// FIXME: Give a better diagnostic for the case where a function exists but is
// not visible.
void g ( X x ) {
f10_a ( ) ;
f10_b ( ) ;
f10_c ( ) ;
f10_d ( ) ; // expected-error {{undeclared identifier}}
: : test10 : : f10_a ( ) ;
: : test10 : : f10_b ( ) ;
: : test10 : : f10_c ( ) ;
: : test10 : : f10_d ( ) ; // expected-error {{no member named 'f10_d'}}
f10_a ( x ) ;
f10_b ( x ) ;
f10_c ( x ) ;
f10_d ( x ) ; // PR16597: expected-error {{undeclared identifier}}
: : test10 : : f10_a ( x ) ;
: : test10 : : f10_b ( x ) ;
: : test10 : : f10_c ( x ) ;
: : test10 : : f10_d ( x ) ; // expected-error {{no type named 'f10_d'}}
}
struct Y : X {
friend void f10_d ( ) ;
friend void f10_d ( X ) ;
} ;
struct Z {
operator X ( ) ;
friend void f10_d ( ) ;
friend void f10_d ( X ) ;
} ;
2019-01-07 14:00:46 +08:00
struct W {
friend void f10_d ( W ) ;
} ;
2013-07-18 07:53:16 +08:00
void g ( X x , Y y , Z z ) {
f10_d ( ) ; // expected-error {{undeclared identifier}}
: : test10 : : f10_d ( ) ; // expected-error {{no member named 'f10_d'}}
// f10_d is visible to ADL in the second and third cases.
f10_d ( x ) ; // expected-error {{undeclared identifier}}
f10_d ( y ) ;
f10_d ( z ) ;
// No ADL here.
: : test10 : : f10_d ( x ) ; // expected-error {{no type named 'f10_d'}}
: : test10 : : f10_d ( y ) ; // expected-error {{no type named 'f10_d'}}
: : test10 : : f10_d ( z ) ; // expected-error {{no type named 'f10_d'}}
}
2019-01-07 14:00:46 +08:00
void local_externs ( W w , X x , Y y ) {
extern void f10_d ( ) ; // expected-note {{candidate}}
extern void f10_d ( X ) ; // expected-note {{candidate}}
2013-07-18 07:53:16 +08:00
f10_d ( ) ;
f10_d ( x ) ;
f10_d ( y ) ;
2019-01-07 14:00:46 +08:00
f10_d ( w ) ; // expected-error {{no matching}}
2013-07-18 07:53:16 +08:00
{
int f10_d ;
f10_d ( ) ; // expected-error {{not a function}}
f10_d ( x ) ; // expected-error {{not a function}}
f10_d ( y ) ; // expected-error {{not a function}}
}
}
void i ( X x , Y y ) {
f10_d ( ) ; // expected-error {{undeclared identifier}}
f10_d ( x ) ; // expected-error {{undeclared identifier}}
f10_d ( y ) ;
}
struct C {
friend void f10_d ( ) ;
friend void f10_d ( X ) ;
} ;
void j ( X x , Y y ) {
f10_d ( ) ; // expected-error {{undeclared identifier}}
f10_d ( x ) ; // expected-error {{undeclared identifier}}
f10_d ( y ) ;
}
extern void f10_d ( ) ;
extern void f10_d ( X ) ;
void k ( X x , Y y , Z z ) {
// All OK now.
f10_d ( ) ;
f10_d ( x ) ;
: : test10 : : f10_d ( ) ;
: : test10 : : f10_d ( x ) ;
: : test10 : : f10_d ( y ) ;
: : test10 : : f10_d ( z ) ;
2013-07-13 04:38:49 +08:00
}
}
2014-05-15 02:31:48 +08:00
namespace test11 {
class __attribute__ ( ( visibility ( " hidden " ) ) ) B ;
class A {
friend class __attribute__ ( ( visibility ( " hidden " ) , noreturn ) ) B ; // expected-warning {{'noreturn' attribute only applies to functions and methods}}
} ;
}
2014-12-18 07:40:46 +08:00
namespace pr21851 {
// PR21851 was a problem where we assumed that when the friend function redecl
// lookup found a C++ method, it would necessarily have a qualifier. Below we
// have some test cases where unqualified lookup finds C++ methods without using
// qualifiers. Unfortunately, we can't exercise the case of an access check
// failure because nested classes always have access to the members of outer
// classes.
void friend_own_method ( ) {
class A {
void m ( ) { }
friend void m ( ) ;
} ;
}
void friend_enclosing_method ( ) {
class A ;
class C {
int p ;
friend class A ;
} ;
class A {
void enclosing_friend ( ) {
( void ) b - > p ;
( void ) c - > p ;
}
class B {
void b ( A * a ) {
( void ) a - > c - > p ;
}
int p ;
friend void enclosing_friend ( ) ;
} ;
B * b ;
C * c ;
} ;
}
static auto friend_file_func ( ) {
extern void file_scope_friend ( ) ;
class A {
int p ;
friend void file_scope_friend ( ) ;
} ;
return A ( ) ;
}
void file_scope_friend ( ) {
auto a = friend_file_func ( ) ;
( void ) a . p ;
}
}
2015-02-17 02:27:41 +08:00
template < typename T >
struct X_pr6954 {
operator int ( ) ;
friend void f_pr6954 ( int x ) ;
} ;
int array0_pr6954 [ sizeof ( X_pr6954 < int > ) ] ;
int array1_pr6954 [ sizeof ( X_pr6954 < float > ) ] ;
void g_pr6954 ( ) {
f_pr6954 ( 5 ) ; // expected-error{{undeclared identifier 'f_pr6954'}}
}
2016-05-24 04:03:04 +08:00
namespace tag_redecl {
namespace N {
struct X * p ;
namespace {
class K {
friend struct X ;
} ;
}
}
namespace N {
struct X ;
X * q = p ;
}
}
2016-10-21 11:15:03 +08:00
namespace default_arg {
void f ( ) ;
void f ( void * ) ; // expected-note {{previous}}
struct X {
friend void f ( int a , int b = 0 ) { }
friend void f ( void * p = 0 ) { } // expected-error {{must be the only}}
} ;
}
2018-09-10 13:32:13 +08:00
namespace PR33222 {
int f ( ) ;
template < typename T > struct X {
friend T f ( ) ;
} ;
X < int > xi ;
int g ( ) ; // expected-note {{previous}}
template < typename T > struct Y {
friend T g ( ) ; // expected-error {{return type}}
} ;
Y < float > yf ; // expected-note {{instantiation}}
2019-01-07 14:00:46 +08:00
int h ( ) ; // expected-note {{previous}}
2018-09-10 13:32:13 +08:00
template < typename T > struct Z {
2019-01-07 14:00:46 +08:00
friend T h ( ) ; // expected-error {{return type}}
2018-09-10 13:32:13 +08:00
} ;
Z < int > zi ;
Z < float > zf ; // expected-note {{instantiation}}
}
2019-01-07 14:00:46 +08:00
namespace qualified_friend_no_match {
void f ( int ) ; // expected-note {{type mismatch at 1st parameter}}
template < typename T > void f ( T * ) ; // expected-note {{could not match 'type-parameter-0-0 *' against 'double'}}
struct X {
friend void qualified_friend_no_match : : f ( double ) ; // expected-error {{friend declaration of 'f' does not match any declaration in namespace 'qualified_friend_no_match'}}
friend void qualified_friend_no_match : : g ( ) ; // expected-error {{friend declaration of 'g' does not match any declaration in namespace 'qualified_friend_no_match'}}
} ;
struct Y {
void f ( int ) ; // expected-note {{type mismatch at 1st parameter}}
template < typename T > void f ( T * ) ; // expected-note {{could not match 'type-parameter-0-0 *' against 'double'}}
} ;
struct Z {
friend void Y : : f ( double ) ; // expected-error {{friend declaration of 'f' does not match any declaration in 'qualified_friend_no_match::Y'}}
} ;
}