diff options
author | Roman Divacky <rdivacky@FreeBSD.org> | 2009-10-14 18:03:49 +0000 |
---|---|---|
committer | Roman Divacky <rdivacky@FreeBSD.org> | 2009-10-14 18:03:49 +0000 |
commit | 4c8b24812ddcd1dedaca343a6d4e76f91f398981 (patch) | |
tree | 137ebebcae16fb0ce7ab4af456992bbd8d22fced /test/CXX/class | |
parent | 5362a71c02e7d448a8ce98cf00c47e353fba5d04 (diff) |
Notes
Diffstat (limited to 'test/CXX/class')
-rw-r--r-- | test/CXX/class/class.friend/p1-ambiguous.cpp | 37 | ||||
-rw-r--r-- | test/CXX/class/class.friend/p1.cpp | 76 | ||||
-rw-r--r-- | test/CXX/class/class.friend/p2.cpp | 10 | ||||
-rw-r--r-- | test/CXX/class/class.friend/p6.cpp | 10 | ||||
-rw-r--r-- | test/CXX/class/class.local/p3.cpp | 2 | ||||
-rw-r--r-- | test/CXX/class/class.local/p4.cpp | 2 | ||||
-rw-r--r-- | test/CXX/class/class.nest/p1.cpp | 14 | ||||
-rw-r--r-- | test/CXX/class/class.nested.type/p1.cpp | 4 | ||||
-rw-r--r-- | test/CXX/class/class.union/p1.cpp | 105 |
9 files changed, 257 insertions, 3 deletions
diff --git a/test/CXX/class/class.friend/p1-ambiguous.cpp b/test/CXX/class/class.friend/p1-ambiguous.cpp new file mode 100644 index 0000000000000..a02bc53375220 --- /dev/null +++ b/test/CXX/class/class.friend/p1-ambiguous.cpp @@ -0,0 +1,37 @@ +// RUN: clang-cc -fsyntax-only -verify %s + +// Make sure that friend declarations don't introduce ambiguous +// declarations. + +// Test case courtesy of Shantonu Sen. +// Bug 4784. + +class foo; + +extern "C" { + int c_func(foo *a); +}; +int cpp_func(foo *a); + +class foo { +public: + friend int c_func(foo *a); + friend int cpp_func(foo *a); + int caller(); +private: + int x; +}; + +int c_func(foo *a) { + return a->x; +} + +int cpp_func(foo *a) { + return a->x; +} + +int foo::caller() { + c_func(this); + cpp_func(this); + return 0; +} diff --git a/test/CXX/class/class.friend/p1.cpp b/test/CXX/class/class.friend/p1.cpp new file mode 100644 index 0000000000000..7065a7e917fd7 --- /dev/null +++ b/test/CXX/class/class.friend/p1.cpp @@ -0,0 +1,76 @@ +// RUN: clang-cc -fsyntax-only -verify %s + +struct Outer { + struct Inner { + int intfield; + }; +}; + +struct Base { + void base_member(); + + typedef int Int; + Int typedeffed_member(); +}; + +struct Derived : public Base { +}; + +int myglobal; + +void global_function(); +extern "C" { + void global_c_function(); +} + +class A { + class AInner { + }; + + friend class PreDeclared; + friend class Outer::Inner; + friend int Outer::Inner::intfield; // expected-error {{ friends can only be classes or functions }} + friend int Outer::Inner::missing_field; //expected-error {{ friends can only be classes or functions }} + friend int myoperation(float); // okay + friend int myglobal; // expected-error {{ friends can only be classes or functions }} + + friend void global_function(); + friend void global_c_function(); + + friend class UndeclaredSoFar; + UndeclaredSoFar x; // expected-error {{ unknown type name 'UndeclaredSoFar' }} + + void a_member(); + friend void A::a_member(); // expected-error {{ friends cannot be members of the declaring class }} + friend void a_member(); // okay (because we ignore class scopes when looking up friends) + friend class A::AInner; // this is okay as an extension + friend class AInner; // okay, refers to ::AInner + + friend void Derived::missing_member(); // expected-error {{ no function named 'missing_member' with type 'void ()' was found in the specified scope }} + + friend void Derived::base_member(); // expected-error {{ no function named 'base_member' with type 'void ()' was found in the specified scope }} + + friend int Base::typedeffed_member(); // okay: should look through typedef + + // These test that the friend is properly not being treated as a + // member function. + friend A operator|(const A& l, const A& r); // okay + friend A operator|(const A& r); // expected-error {{ overloaded 'operator|' must be a binary operator (has 1 parameter) }} + + friend operator bool() const; // expected-error {{ must use a qualified name when declaring a conversion operator as a friend }} + + typedef void ftypedef(); + friend ftypedef typedeffed_function; // okay (because it's not declared as a member) + + class facet; + friend class facet; // should not assert + class facet {}; +}; + +A::UndeclaredSoFar y; // expected-error {{no type named 'UndeclaredSoFar' in 'class A'}} + +class PreDeclared; + +int myoperation(float f) { + return (int) f; +} diff --git a/test/CXX/class/class.friend/p2.cpp b/test/CXX/class/class.friend/p2.cpp new file mode 100644 index 0000000000000..98be2049e7566 --- /dev/null +++ b/test/CXX/class/class.friend/p2.cpp @@ -0,0 +1,10 @@ +// RUN: clang-cc -fsyntax-only -verify %s + +struct B0; + +class A { + friend class B {}; // expected-error {{cannot define a type in a friend declaration}} + friend int; // expected-error {{friends can only be classes or functions}} + friend B0; // expected-error {{must specify 'struct' to befriend}} + friend class C; // okay +}; diff --git a/test/CXX/class/class.friend/p6.cpp b/test/CXX/class/class.friend/p6.cpp new file mode 100644 index 0000000000000..2e8153c6c0471 --- /dev/null +++ b/test/CXX/class/class.friend/p6.cpp @@ -0,0 +1,10 @@ +// RUN: clang-cc -fsyntax-only -verify %s + +class A { + friend static class B; // expected-error {{'static' is invalid in friend declarations}} + friend extern class C; // expected-error {{'extern' is invalid in friend declarations}} + friend auto class D; // expected-error {{'auto' is invalid in friend declarations}} + friend register class E; // expected-error {{'register' is invalid in friend declarations}} + friend mutable class F; // expected-error {{'mutable' is invalid in friend declarations}} + friend typedef class G; // expected-error {{'typedef' is invalid in friend declarations}} +}; diff --git a/test/CXX/class/class.local/p3.cpp b/test/CXX/class/class.local/p3.cpp index d888a6d936330..9c625d18c95c2 100644 --- a/test/CXX/class/class.local/p3.cpp +++ b/test/CXX/class/class.local/p3.cpp @@ -27,4 +27,4 @@ void f3(int a) { // expected-note{{'a' declared here}} int f() { return a; } // expected-error{{reference to local variable 'a' declared in enclosed function 'f3'}} }; }; -}
\ No newline at end of file +} diff --git a/test/CXX/class/class.local/p4.cpp b/test/CXX/class/class.local/p4.cpp index 40702ad968993..f2432ec973932 100644 --- a/test/CXX/class/class.local/p4.cpp +++ b/test/CXX/class/class.local/p4.cpp @@ -7,4 +7,4 @@ void f() { static void f() { } }; -}
\ No newline at end of file +} diff --git a/test/CXX/class/class.nest/p1.cpp b/test/CXX/class/class.nest/p1.cpp new file mode 100644 index 0000000000000..bbc49f9e95e7b --- /dev/null +++ b/test/CXX/class/class.nest/p1.cpp @@ -0,0 +1,14 @@ +// RUN: clang-cc -fsyntax-only -verify %s + +class Outer { + int x; + static int sx; + + // C++0x will likely relax this rule in this specific case, but + // we'll still need to enforce it in C++03 mode. See N2253 (or + // successor). + class Inner { + static char a[sizeof(x)]; // expected-error {{ invalid use of nonstatic data member 'x' }} + static char b[sizeof(sx)]; // okay + }; +}; diff --git a/test/CXX/class/class.nested.type/p1.cpp b/test/CXX/class/class.nested.type/p1.cpp index 33bf4b4473e50..61ccd281ca937 100644 --- a/test/CXX/class/class.nested.type/p1.cpp +++ b/test/CXX/class/class.nested.type/p1.cpp @@ -1,3 +1,5 @@ +// RUN: clang-cc -fsyntax-only -verify %s + class X { public: typedef int I; @@ -8,4 +10,4 @@ public: I b; // expected-error{{unknown type name 'I'}} Y c; // expected-error{{unknown type name 'Y'}} X::Y d; -X::I e;
\ No newline at end of file +X::I e; diff --git a/test/CXX/class/class.union/p1.cpp b/test/CXX/class/class.union/p1.cpp new file mode 100644 index 0000000000000..15c2634673675 --- /dev/null +++ b/test/CXX/class/class.union/p1.cpp @@ -0,0 +1,105 @@ +// RUN: clang-cc -fsyntax-only -verify %s + +void abort() __attribute__((noreturn)); + +class Okay { + int a_; +}; + +class Virtual { + virtual void foo() { abort(); } // expected-note 3 {{because type 'class Virtual' has a virtual member function}} +}; + +class VirtualBase : virtual Okay { // expected-note 3 {{because type 'class VirtualBase' has a virtual base class}} +}; + +class Ctor { + Ctor() { abort(); } // expected-note 3 {{because type 'class Ctor' has a user-declared constructor}} +}; + +class CopyCtor { + CopyCtor(CopyCtor &cc) { abort(); } // expected-note 3 {{because type 'class CopyCtor' has a user-declared copy constructor}} +}; + +// FIXME: this should eventually trigger on the operator's declaration line +class CopyAssign { // expected-note 3 {{because type 'class CopyAssign' has a user-declared copy assignment operator}} + CopyAssign& operator=(CopyAssign& CA) { abort(); } +}; + +class Dtor { + ~Dtor() { abort(); } // expected-note 3 {{because type 'class Dtor' has a user-declared destructor}} +}; + +union U1 { + Virtual v; // expected-error {{union member 'v' has a non-trivial copy constructor}} + VirtualBase vbase; // expected-error {{union member 'vbase' has a non-trivial copy constructor}} + Ctor ctor; // expected-error {{union member 'ctor' has a non-trivial constructor}} + CopyCtor copyctor; // expected-error {{union member 'copyctor' has a non-trivial copy constructor}} + CopyAssign copyassign; // expected-error {{union member 'copyassign' has a non-trivial copy assignment operator}} + Dtor dtor; // expected-error {{union member 'dtor' has a non-trivial destructor}} + Okay okay; +}; + +union U2 { + struct { + Virtual v; // expected-note {{because type 'struct U2::<anonymous>' has a member with a non-trivial copy constructor}} + } m1; // expected-error {{union member 'm1' has a non-trivial copy constructor}} + struct { + VirtualBase vbase; // expected-note {{because type 'struct U2::<anonymous>' has a member with a non-trivial copy constructor}} + } m2; // expected-error {{union member 'm2' has a non-trivial copy constructor}} + struct { + Ctor ctor; // expected-note {{because type 'struct U2::<anonymous>' has a member with a non-trivial constructor}} + } m3; // expected-error {{union member 'm3' has a non-trivial constructor}} + struct { + CopyCtor copyctor; // expected-note {{because type 'struct U2::<anonymous>' has a member with a non-trivial copy constructor}} + } m4; // expected-error {{union member 'm4' has a non-trivial copy constructor}} + struct { + CopyAssign copyassign; // expected-note {{because type 'struct U2::<anonymous>' has a member with a non-trivial copy assignment operator}} + } m5; // expected-error {{union member 'm5' has a non-trivial copy assignment operator}} + struct { + Dtor dtor; // expected-note {{because type 'struct U2::<anonymous>' has a member with a non-trivial destructor}} + } m6; // expected-error {{union member 'm6' has a non-trivial destructor}} + struct { + Okay okay; + } m7; +}; + +union U3 { + struct s1 : Virtual { // expected-note {{because type 'struct U3::s1' has a base class with a non-trivial copy constructor}} + } m1; // expected-error {{union member 'm1' has a non-trivial copy constructor}} + struct s2 : VirtualBase { // expected-note {{because type 'struct U3::s2' has a base class with a non-trivial copy constructor}} + } m2; // expected-error {{union member 'm2' has a non-trivial copy constructor}} + struct s3 : Ctor { // expected-note {{because type 'struct U3::s3' has a base class with a non-trivial constructor}} + } m3; // expected-error {{union member 'm3' has a non-trivial constructor}} + struct s4 : CopyCtor { // expected-note {{because type 'struct U3::s4' has a base class with a non-trivial copy constructor}} + } m4; // expected-error {{union member 'm4' has a non-trivial copy constructor}} + struct s5 : CopyAssign { // expected-note {{because type 'struct U3::s5' has a base class with a non-trivial copy assignment operator}} + } m5; // expected-error {{union member 'm5' has a non-trivial copy assignment operator}} + struct s6 : Dtor { // expected-note {{because type 'struct U3::s6' has a base class with a non-trivial destructor}} + } m6; // expected-error {{union member 'm6' has a non-trivial destructor}} + struct s7 : Okay { + } m7; +}; + +template <class A, class B> struct Either { + bool tag; + union { + A a; + B b; + }; + + Either(A& a) : tag(true), a(a) {} + Either(B& b) : tag(false), b(b) {} +}; + +/* FIXME: this should work, but crashes in template code. +void fred() { + Either<int,Virtual> virt(0); + Either<int,VirtualBase> vbase(0); + Either<int,Ctor> ctor(0); + Either<int,CopyCtor> copyctor(0); + Either<int,CopyAssign> copyassign(0); + Either<int,Dtor> dtor(0); + Either<int,Okay> okay(0); +} + */ |