summaryrefslogtreecommitdiff
path: root/test/CXX/class
diff options
context:
space:
mode:
authorRoman Divacky <rdivacky@FreeBSD.org>2009-10-14 18:03:49 +0000
committerRoman Divacky <rdivacky@FreeBSD.org>2009-10-14 18:03:49 +0000
commit4c8b24812ddcd1dedaca343a6d4e76f91f398981 (patch)
tree137ebebcae16fb0ce7ab4af456992bbd8d22fced /test/CXX/class
parent5362a71c02e7d448a8ce98cf00c47e353fba5d04 (diff)
Notes
Diffstat (limited to 'test/CXX/class')
-rw-r--r--test/CXX/class/class.friend/p1-ambiguous.cpp37
-rw-r--r--test/CXX/class/class.friend/p1.cpp76
-rw-r--r--test/CXX/class/class.friend/p2.cpp10
-rw-r--r--test/CXX/class/class.friend/p6.cpp10
-rw-r--r--test/CXX/class/class.local/p3.cpp2
-rw-r--r--test/CXX/class/class.local/p4.cpp2
-rw-r--r--test/CXX/class/class.nest/p1.cpp14
-rw-r--r--test/CXX/class/class.nested.type/p1.cpp4
-rw-r--r--test/CXX/class/class.union/p1.cpp105
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);
+}
+ */