From 222e2a7620e6520ffaf4fc4e69d79c18da31542e Mon Sep 17 00:00:00 2001 From: "Zancanaro; Carlo" Date: Mon, 24 Sep 2012 09:58:17 +1000 Subject: Add the clang library to the repo (with some of my changes, too). --- clang/test/CXX/class.access/class.friend/p1.cpp | 356 +++++++++++++++++++++ clang/test/CXX/class.access/class.friend/p11.cpp | 19 ++ .../CXX/class.access/class.friend/p2-cxx03.cpp | 13 + .../CXX/class.access/class.friend/p3-cxx0x.cpp | 29 ++ clang/test/CXX/class.access/class.friend/p6.cpp | 20 ++ 5 files changed, 437 insertions(+) create mode 100644 clang/test/CXX/class.access/class.friend/p1.cpp create mode 100644 clang/test/CXX/class.access/class.friend/p11.cpp create mode 100644 clang/test/CXX/class.access/class.friend/p2-cxx03.cpp create mode 100644 clang/test/CXX/class.access/class.friend/p3-cxx0x.cpp create mode 100644 clang/test/CXX/class.access/class.friend/p6.cpp (limited to 'clang/test/CXX/class.access/class.friend') diff --git a/clang/test/CXX/class.access/class.friend/p1.cpp b/clang/test/CXX/class.access/class.friend/p1.cpp new file mode 100644 index 0000000..68ff83f --- /dev/null +++ b/clang/test/CXX/class.access/class.friend/p1.cpp @@ -0,0 +1,356 @@ +// RUN: %clang_cc1 -fsyntax-only -verify %s + +// C++'0x [class.friend] p1: +// A friend of a class is a function or class that is given permission to use +// the private and protected member names from the class. A class specifies +// its friends, if any, by way of friend declarations. Such declarations give +// special access rights to the friends, but they do not make the nominated +// friends members of the befriending class. + +struct S { static void f(); }; +S* g() { return 0; } + +struct X { + friend struct S; + friend S* g(); +}; + +void test1() { + S s; + g()->f(); + S::f(); + X::g(); // expected-error{{no member named 'g' in 'X'}} + X::S x_s; // expected-error{{no member named 'S' in 'X'}} + X x; + x.g(); // expected-error{{no member named 'g' in 'X'}} +} + +// Test that we recurse through namespaces to find already declared names, but +// new names are declared within the enclosing namespace. +namespace N { + struct X { + friend struct S; + friend S* g(); + + friend struct S2; + friend struct S2* g2(); + }; + + struct S2 { static void f2(); }; + S2* g2() { return 0; } + + void test() { + g()->f(); + S s; + S::f(); + X::g(); // expected-error{{no member named 'g' in 'N::X'}} + X::S x_s; // expected-error{{no member named 'S' in 'N::X'}} + X x; + x.g(); // expected-error{{no member named 'g' in 'N::X'}} + + g2(); + S2 s2; + ::g2(); // expected-error{{no member named 'g2' in the global namespace}} + ::S2 g_s2; // expected-error{{no member named 'S2' in the global namespace}} + X::g2(); // expected-error{{no member named 'g2' in 'N::X'}} + X::S2 x_s2; // expected-error{{no member named 'S2' in 'N::X'}} + x.g2(); // expected-error{{no member named 'g2' in 'N::X'}} + } +} + +namespace test0 { + class ClassFriend { + void test(); + }; + + class MemberFriend { + void test(); + }; + + void declared_test(); + + class Class { + static void member(); // expected-note 2 {{declared private here}} + + friend class ClassFriend; + friend class UndeclaredClassFriend; + + friend void undeclared_test(); + friend void declared_test(); + friend void MemberFriend::test(); + }; + + void declared_test() { + Class::member(); + } + + void undeclared_test() { + Class::member(); + } + + void unfriended_test() { + Class::member(); // expected-error {{'member' is a private member of 'test0::Class'}} + } + + void ClassFriend::test() { + Class::member(); + } + + void MemberFriend::test() { + Class::member(); + } + + class UndeclaredClassFriend { + void test() { + Class::member(); + } + }; + + class ClassNonFriend { + void test() { + Class::member(); // expected-error {{'member' is a private member of 'test0::Class'}} + } + }; +} + +// Make sure that friends have access to inherited protected members. +namespace test2 { + struct X; + + class ilist_half_node { + friend struct ilist_walker_bad; + X *Prev; + protected: + X *getPrev() { return Prev; } // expected-note{{member is declared here}} + }; + + class ilist_node : private ilist_half_node { // expected-note {{declared private here}} expected-note {{constrained by private inheritance here}} + friend struct ilist_walker; + X *Next; + X *getNext() { return Next; } // expected-note {{declared private here}} + }; + + struct X : ilist_node {}; + + struct ilist_walker { + static X *getPrev(X *N) { return N->getPrev(); } + static X *getNext(X *N) { return N->getNext(); } + }; + + struct ilist_walker_bad { + static X *getPrev(X *N) { return N->getPrev(); } // \ + // expected-error {{'getPrev' is a private member of 'test2::ilist_half_node'}} \ + // expected-error {{cannot cast 'test2::X' to its private base class 'test2::ilist_half_node'}} + + static X *getNext(X *N) { return N->getNext(); } // \ + // expected-error {{'getNext' is a private member of 'test2::ilist_node'}} + }; +} + +namespace test3 { + class A { protected: int x; }; // expected-note {{declared protected here}} + + class B : public A { + friend int foo(B*); + }; + + int foo(B *p) { + return p->x; + } + + int foo(const B *p) { + return p->x; // expected-error {{'x' is a protected member of 'test3::A'}} + } +} + +namespace test3a { + class A { protected: int x; }; + + class B : public A { + friend int foo(B*); + }; + + int foo(B * const p) { + return p->x; + } +} + +namespace test4 { + template class Holder { + T object; + friend bool operator==(Holder &a, Holder &b) { + return a.object == b.object; // expected-error {{invalid operands to binary expression}} + } + }; + + struct Inequal {}; + bool test() { + Holder a, b; + return a == b; // expected-note {{requested here}} + } +} + + +// PR6174 +namespace test5 { + namespace ns { + class A; + } + + class ns::A { + private: int x; + friend class B; + }; + + namespace ns { + class B { + int test(A *p) { return p->x; } + }; + } +} + +// PR6207 +namespace test6 { + struct A {}; + + struct B { + friend A::A(); + friend A::~A(); + friend A &A::operator=(const A&); + }; +} + +namespace test7 { + template struct X { + X(); + ~X(); + void foo(); + void bar(); + }; + + class A { + friend void X::foo(); + friend X::X(); + friend X::X(const X&); + + private: + A(); // expected-note 2 {{declared private here}} + }; + + template<> void X::foo() { + A a; + } + + template<> void X::bar() { + A a; // expected-error {{calling a private constructor}} + } + + template<> X::X() { + A a; + } + + template<> X::~X() { + A a; // expected-error {{calling a private constructor}} + } +} + +// Return types, parameters and default arguments to friend functions. +namespace test8 { + class A { + typedef int I; // expected-note 4 {{declared private here}} + static const I x = 0; // expected-note {{implicitly declared private here}} + friend I f(I i); + template friend I g(I i); + }; + + const A::I A::x; + A::I f(A::I i = A::x) {} + template A::I g(A::I i) { + T t; + } + template A::I g(A::I i); + + A::I f2(A::I i = A::x) {} // expected-error 3 {{is a private member of}} + template A::I g2(A::I i) { // expected-error 2 {{is a private member of}} + T t; + } + template A::I g2(A::I i); +} + +// PR6885 +namespace test9 { + class B { + friend class test9; + }; +} + +// PR7230 +namespace test10 { + extern "C" void f(void); + extern "C" void g(void); + + namespace NS { + class C { + void foo(void); // expected-note {{declared private here}} + friend void test10::f(void); + }; + static C* bar; + } + + void f(void) { + NS::bar->foo(); + } + + void g(void) { + NS::bar->foo(); // expected-error {{private member}} + } +} + +// PR8705 +namespace test11 { + class A { + void test0(int); + void test1(int); + void test2(int); + void test3(int); + }; + + class B { + typedef int private_type; // expected-note 2 {{implicitly declared private here}} + friend void A::test0(int); + friend void A::test1(int); + }; + + void A::test0(B::private_type x) {} + void A::test1(int x = B::private_type()) {} + void A::test2(B::private_type x) {} // expected-error {{'private_type' is a private member of 'test11::B'}} + void A::test3(int x = B::private_type()) {} // expected-error {{'private_type' is a private member of 'test11::B'}} +} + + +// PR9221 +namespace test12 { + struct A { + void foo(); + }; + class B : private A { + friend void A::foo(); + void *mem; + }; + void A::foo() { + void *var = static_cast(this)->mem; + } +} + +namespace PR9103 { + struct base { + protected: + static void foo(void) {} + }; + + struct cls: base { + friend void bar(void) { + base::foo(); + } + }; +} diff --git a/clang/test/CXX/class.access/class.friend/p11.cpp b/clang/test/CXX/class.access/class.friend/p11.cpp new file mode 100644 index 0000000..a05b2d2 --- /dev/null +++ b/clang/test/CXX/class.access/class.friend/p11.cpp @@ -0,0 +1,19 @@ +// RUN: %clang_cc1 -fsyntax-only -verify %s + +// rdar://problem/8540720 +namespace test0 { + void foo() { + void bar(); + class A { + friend void bar(); + }; + } +} + +namespace test1 { + void foo() { + class A { + friend void bar(); // expected-error {{no matching function found in local scope}} + }; + } +} diff --git a/clang/test/CXX/class.access/class.friend/p2-cxx03.cpp b/clang/test/CXX/class.access/class.friend/p2-cxx03.cpp new file mode 100644 index 0000000..f8cabfd --- /dev/null +++ b/clang/test/CXX/class.access/class.friend/p2-cxx03.cpp @@ -0,0 +1,13 @@ +// RUN: %clang_cc1 -fsyntax-only -verify %s +template +class X0 { + friend T; // expected-warning{{non-class friend type 'T' is a C++11 extension}} +}; + +class X1 { }; +enum E1 { }; +X0 x0a; +X0 x0b; +X0 x0c; +X0 x0d; + diff --git a/clang/test/CXX/class.access/class.friend/p3-cxx0x.cpp b/clang/test/CXX/class.access/class.friend/p3-cxx0x.cpp new file mode 100644 index 0000000..00fc0a3 --- /dev/null +++ b/clang/test/CXX/class.access/class.friend/p3-cxx0x.cpp @@ -0,0 +1,29 @@ +// RUN: %clang_cc1 -fsyntax-only -std=c++11 -verify %s +template +class X0 { + friend T; +}; + +class Y1 { }; +enum E1 { }; +X0 x0a; +X0 x0b; +X0 x0c; +X0 x0d; + +template +class X1 { + friend typename T::type; // expected-error{{no type named 'type' in 'Y1'}} +}; + +struct Y2 { + struct type { }; +}; + +struct Y3 { + typedef int type; +}; + +X1 x1a; +X1 x1b; +X1 x1c; // expected-note{{in instantiation of template class 'X1' requested here}} diff --git a/clang/test/CXX/class.access/class.friend/p6.cpp b/clang/test/CXX/class.access/class.friend/p6.cpp new file mode 100644 index 0000000..7f7d909 --- /dev/null +++ b/clang/test/CXX/class.access/class.friend/p6.cpp @@ -0,0 +1,20 @@ +// RUN: %clang_cc1 -fsyntax-only -verify %s + +void f1(); + +struct X { + void f2(); +}; + +struct Y { + friend void ::f1() { } // expected-error{{friend function definition cannot be qualified with '::'}} + friend void X::f2() { } // expected-error{{friend function definition cannot be qualified with 'X::'}} +}; + +void local() { + void f(); + + struct Local { + friend void f() { } // expected-error{{friend function cannot be defined in a local class}} + }; +} -- cgit v1.2.3