2010-04-10 03:03:51 +08:00
// RUN: %clang_cc1 -fsyntax-only -verify %s
2010-01-27 11:50:35 +08:00
// C++0x [class.access]p6:
// All access controls in [class.access] affect the ability to
// access a class member name from a particular scope. For purposes
// of access control, the base-specifiers of a class and the
// definitions of class members that appear outside of the class
// definition are considered to be within the scope of that
// class. In particular, access controls apply as usual to member
// names accessed as part of a function return type, even though it
// is not possible to determine the access privileges of that use
// without first parsing the rest of the function
// declarator. Similarly, access control for implicit calls to the
// constructors, the conversion functions, or the destructor called
// to create and destroy a static data member is performed as if
// these calls appeared in the scope of the member's class.
2010-02-01 11:16:54 +08:00
struct Public { } ; struct Protected { } ; struct Private { } ;
2010-01-27 11:50:35 +08:00
namespace test0 {
class A {
typedef int type ; // expected-note {{declared private here}}
type foo ( ) ;
} ;
2010-02-10 17:31:12 +08:00
A : : type foo ( ) { } // expected-error {{'type' is a private member}}
2010-01-27 11:50:35 +08:00
A : : type A : : foo ( ) { }
}
2010-02-01 11:16:54 +08:00
// conversion decls
namespace test1 {
class A {
public :
A ( ) ;
operator Public ( ) ;
A ( Public ) ;
protected :
operator Protected ( ) ; // expected-note {{declared protected here}}
A ( Protected ) ; // expected-note {{declared protected here}}
private :
operator Private ( ) ; // expected-note {{declared private here}}
A ( Private ) ; // expected-note {{declared private here}}
} ;
void test ( ) {
A a ;
Public pub = a ;
2010-02-10 17:31:12 +08:00
Protected prot = a ; // expected-error {{'operator Protected' is a protected member}}
Private priv = a ; // expected-error {{'operator Private' is a private member}}
2010-02-01 11:16:54 +08:00
A apub = pub ;
2010-02-10 17:31:12 +08:00
A aprot = prot ; // expected-error {{protected constructor}}
A apriv = priv ; // expected-error {{private constructor}}
2010-02-01 11:16:54 +08:00
}
}
2010-04-29 08:35:03 +08:00
// PR6967
namespace test2 {
class A {
public :
template < class T > static void set ( T & t , typename T : : type v ) {
t . value = v ;
}
template < class T > static typename T : : type get ( const T & t ) {
return t . value ;
}
} ;
class B {
friend class A ;
private :
typedef int type ;
type value ;
} ;
int test ( ) {
B b ;
A : : set ( b , 0 ) ;
return A : : get ( b ) ;
}
}
namespace test3 {
class Green { } ; class Blue { } ;
// We have to wrap this in a class because a partial specialization
// isn't actually in the context of the template.
struct Outer {
template < class T , class Nat > class A {
} ;
} ;
template < class T > class Outer : : A < T , typename T : : nature > {
public :
2013-10-19 08:05:00 +08:00
static void foo ( ) ; // expected-note {{'Outer::A<B, Green>::foo' declared here}}
2010-04-29 08:35:03 +08:00
} ;
class B {
private : typedef Green nature ;
friend class Outer ;
} ;
void test ( ) {
Outer : : A < B , Green > : : foo ( ) ;
2013-10-19 08:05:00 +08:00
Outer : : A < B , Blue > : : foo ( ) ; // expected-error {{no member named 'foo' in 'test3::Outer::A<test3::B, test3::Blue>'; did you mean 'Outer::A<B, Green>::foo'?}}
2010-04-29 08:35:03 +08:00
}
}
2010-04-29 09:20:45 +08:00
namespace test4 {
template < class T > class A {
private : typedef int type ;
template < class U > friend void foo ( U & , typename U : : type ) ;
} ;
template < class U > void foo ( U & , typename U : : type ) { }
void test ( ) {
A < int > a ;
foo ( a , 0 ) ;
}
}
2010-07-16 16:13:16 +08:00
// PR7644
namespace test5 {
class A {
enum Enum { E0 , E1 , E2 } ; // expected-note 4 {{declared private here}}
template < Enum > void foo ( ) ;
template < Enum > class bar ;
} ;
template < A : : Enum en > void A : : foo ( ) { }
template < A : : Enum en > class A : : bar { } ;
template < A : : Enum en > void foo ( ) { } // expected-error {{'Enum' is a private member of 'test5::A'}}
template < A : : Enum en > class bar { } ; // expected-error {{'Enum' is a private member of 'test5::A'}}
class B {
template < A : : Enum en > void foo ( ) { } // expected-error {{'Enum' is a private member of 'test5::A'}}
template < A : : Enum en > class bar { } ; // expected-error {{'Enum' is a private member of 'test5::A'}}
} ;
}
2011-02-15 15:12:36 +08:00
namespace test6 {
class A {
public : class public_inner { } ;
protected : class protected_inner { } ;
private : class private_inner { } ; // expected-note {{declared private here}}
} ;
class B : A {
public_inner a ;
protected_inner b ;
2011-12-15 08:38:15 +08:00
private_inner c ; // expected-error {{'private_inner' is a private member of 'test6::A'}}
2011-02-15 15:12:36 +08:00
} ;
}
2011-02-16 06:51:53 +08:00
// PR9229
namespace test7 {
void foo ( int arg [ 1 ] ) ;
class A {
void check ( ) ;
} ;
class B {
friend class A ;
A ins ;
} ;
void A : : check ( ) {
void foo ( int arg [ __builtin_offsetof ( B , ins ) ] ) ;
}
}
2011-09-21 16:36:56 +08:00
// rdar://problem/10155256
namespace test8 {
class A {
typedef void * ( A : : * UnspecifiedBoolType ) ( ) const ;
operator UnspecifiedBoolType ( ) const ; // expected-note {{implicitly declared private here}}
} ;
void test ( A & a ) {
2013-12-14 09:07:05 +08:00
if ( a ) return ; // expected-error-re {{'operator void *(class test8::A::*)(void){{( __attribute__\(\(thiscall\)\))?}} const' is a private member of 'test8::A'}}
2011-09-21 16:36:56 +08:00
}
}
namespace test9 {
class A {
operator char * ( ) const ; // expected-note {{implicitly declared private here}}
} ;
void test ( A & a ) {
delete a ; // expected-error {{'operator char *' is a private member of 'test9::A'}}
}
}