summaryrefslogtreecommitdiffstats
path: root/test/CXX
diff options
context:
space:
mode:
authorrdivacky <rdivacky@FreeBSD.org>2009-12-15 18:49:47 +0000
committerrdivacky <rdivacky@FreeBSD.org>2009-12-15 18:49:47 +0000
commit77212133072dc40f070a280af8217032f55a9eb4 (patch)
tree2fd5819f49caecc5f520219b6b9254fe94ebb138 /test/CXX
parent4b08eb6308ca90a6c08e2fc79d100821b1b1f6aa (diff)
downloadFreeBSD-src-77212133072dc40f070a280af8217032f55a9eb4.zip
FreeBSD-src-77212133072dc40f070a280af8217032f55a9eb4.tar.gz
Update clang to 91430.
Diffstat (limited to 'test/CXX')
-rw-r--r--test/CXX/basic/basic.lookup/basic.lookup.argdep/p3.cpp20
-rw-r--r--test/CXX/basic/basic.stc/basic.stc.dynamic/basic.stc.dynamic.allocation/p1.cpp44
-rw-r--r--test/CXX/basic/basic.stc/basic.stc.dynamic/basic.stc.dynamic.deallocation/p1.cpp11
-rw-r--r--test/CXX/class.access/class.access.dcl/p1.cpp199
-rw-r--r--test/CXX/class/class.mfct/class.mfct.non-static/p3.cpp93
-rw-r--r--test/CXX/dcl.dcl/basic.namespace/namespace.udecl/p10.cpp33
-rw-r--r--test/CXX/dcl.dcl/basic.namespace/namespace.udecl/p11.cpp94
-rw-r--r--test/CXX/dcl.dcl/basic.namespace/namespace.udecl/p12.cpp144
-rw-r--r--test/CXX/dcl.dcl/basic.namespace/namespace.udecl/p13.cpp63
-rw-r--r--test/CXX/dcl.dcl/basic.namespace/namespace.udecl/p3-cxx0x.cpp28
-rw-r--r--test/CXX/dcl.dcl/basic.namespace/namespace.udecl/p4.cpp212
-rw-r--r--test/CXX/dcl.dcl/basic.namespace/namespace.udecl/p8.cpp83
-rw-r--r--test/CXX/dcl.decl/dcl.init/dcl.init.list/basic.cpp5
-rw-r--r--test/CXX/dcl.decl/dcl.init/dcl.init.ref/p1.cpp14
-rw-r--r--test/CXX/dcl.decl/dcl.init/dcl.init.ref/p3.cpp3
-rw-r--r--test/CXX/dcl.decl/dcl.init/dcl.init.ref/p5-examples.cpp53
-rw-r--r--test/CXX/dcl.decl/dcl.init/dcl.init.ref/p5-var.cpp129
-rw-r--r--test/CXX/special/class.free/p6.cpp2
-rw-r--r--test/CXX/temp/temp.spec/temp.expl.spec/p17.cpp12
19 files changed, 1240 insertions, 2 deletions
diff --git a/test/CXX/basic/basic.lookup/basic.lookup.argdep/p3.cpp b/test/CXX/basic/basic.lookup/basic.lookup.argdep/p3.cpp
new file mode 100644
index 0000000..ae5590c
--- /dev/null
+++ b/test/CXX/basic/basic.lookup/basic.lookup.argdep/p3.cpp
@@ -0,0 +1,20 @@
+// RUN: clang-cc -fsyntax-only -verify %s
+
+// FIXME: embellish
+
+namespace test0 {
+ namespace A {
+ class Foo {
+ };
+
+ void foo(const Foo &foo);
+ }
+
+ class Test {
+ enum E { foo = 0 };
+
+ void test() {
+ foo(A::Foo()); // expected-error {{not a function}}
+ }
+ };
+}
diff --git a/test/CXX/basic/basic.stc/basic.stc.dynamic/basic.stc.dynamic.allocation/p1.cpp b/test/CXX/basic/basic.stc/basic.stc.dynamic/basic.stc.dynamic.allocation/p1.cpp
new file mode 100644
index 0000000..c752cec
--- /dev/null
+++ b/test/CXX/basic/basic.stc/basic.stc.dynamic/basic.stc.dynamic.allocation/p1.cpp
@@ -0,0 +1,44 @@
+// RUN: clang-cc -fsyntax-only -verify %s
+#include <stddef.h>
+
+struct A {
+ void *operator new(size_t);
+};
+
+namespace NS {
+ void *operator new(size_t);; // expected-error {{'operator new' cannot be declared inside a namespace}}
+}
+
+static void *operator new(size_t); // expected-error {{'operator new' cannot be declared static in global scope}}
+
+struct B {
+ void operator new(size_t); // expected-error {{'operator new' must return type 'void *'}}
+};
+
+struct C {
+ void *operator new(); // expected-error {{'operator new' must have at least one parameter}}
+};
+
+struct D {
+ void *operator new(bool); // expected-error {{'operator new' takes type size_t}}
+};
+
+struct E {
+ void *operator new(size_t = 0); // expected-error {{parameter of 'operator new' cannot have a default argument}}
+};
+
+struct F {
+ template<typename T> void *operator new(size_t, int);
+};
+
+struct G {
+ template<typename T> T operator new(size_t, int); // expected-error {{'operator new' cannot have a dependent return type; use 'void *' instead}}
+};
+
+struct H {
+ template<typename T> void *operator new(T, int); // expected-error {{'operator new' cannot take a dependent type as first parameter; use size_t}}
+};
+
+struct I {
+ template<typename T> void *operator new(size_t); // expected-error {{'operator new' template must have at least two parameters}}
+};
diff --git a/test/CXX/basic/basic.stc/basic.stc.dynamic/basic.stc.dynamic.deallocation/p1.cpp b/test/CXX/basic/basic.stc/basic.stc.dynamic/basic.stc.dynamic.deallocation/p1.cpp
new file mode 100644
index 0000000..04af5bc
--- /dev/null
+++ b/test/CXX/basic/basic.stc/basic.stc.dynamic/basic.stc.dynamic.deallocation/p1.cpp
@@ -0,0 +1,11 @@
+// RUN: clang-cc -fsyntax-only -verify %s
+
+struct A {
+ void operator delete(void*);
+};
+
+namespace NS {
+ void operator delete(void *); // expected-error {{'operator delete' cannot be declared inside a namespace}}
+}
+
+static void operator delete(void *); // expected-error {{'operator delete' cannot be declared static in global scope}}
diff --git a/test/CXX/class.access/class.access.dcl/p1.cpp b/test/CXX/class.access/class.access.dcl/p1.cpp
new file mode 100644
index 0000000..043a9bf
--- /dev/null
+++ b/test/CXX/class.access/class.access.dcl/p1.cpp
@@ -0,0 +1,199 @@
+// RUN: clang-cc -fsyntax-only -verify
+
+// This is just the test for [namespace.udecl]p4 with 'using'
+// uniformly stripped out.
+
+// C++03 [namespace.udecl]p4:
+// A using-declaration used as a member-declaration shall refer to a
+// member of a base class of the class being defined, shall refer to
+// a member of an anonymous union that is a member of a base class
+// of the class being defined, or shall refer to an enumerator for
+// an enumeration type that is a member of a base class of the class
+// being defined.
+
+// There is no directly analogous paragraph in C++0x, and the feature
+// works sufficiently differently there that it needs a separate test.
+
+namespace test0 {
+ namespace NonClass {
+ typedef int type;
+ struct hiding {};
+ int hiding;
+ static union { double union_member; };
+ enum tagname { enumerator };
+ }
+
+ class Test0 {
+ NonClass::type; // expected-error {{not a class}} expected-warning {{access declarations are deprecated}}
+ NonClass::hiding; // expected-error {{not a class}} expected-warning {{access declarations are deprecated}}
+ NonClass::union_member; // expected-error {{not a class}} expected-warning {{access declarations are deprecated}}
+ NonClass::enumerator; // expected-error {{not a class}} expected-warning {{access declarations are deprecated}}
+ };
+}
+
+struct Opaque0 {};
+
+namespace test1 {
+ struct A {
+ typedef int type;
+ struct hiding {}; // expected-note {{previous use is here}}
+ Opaque0 hiding;
+ union { double union_member; };
+ enum tagname { enumerator };
+ };
+
+ struct B : A {
+ A::type; // expected-warning {{access declarations are deprecated}}
+ A::hiding; // expected-warning {{access declarations are deprecated}}
+ A::union_member; // expected-warning {{access declarations are deprecated}}
+ A::enumerator; // expected-warning {{access declarations are deprecated}}
+ A::tagname; // expected-warning {{access declarations are deprecated}}
+
+ void test0() {
+ type t = 0;
+ }
+
+ void test1() {
+ typedef struct A::hiding local;
+ struct hiding _ = local();
+ }
+
+ void test2() {
+ union hiding _; // expected-error {{tag type that does not match previous}}
+ }
+
+ void test3() {
+ char array[sizeof(union_member) == sizeof(double) ? 1 : -1];
+ }
+
+ void test4() {
+ enum tagname _ = enumerator;
+ }
+
+ void test5() {
+ Opaque0 _ = hiding;
+ }
+ };
+}
+
+namespace test2 {
+ struct A {
+ typedef int type;
+ struct hiding {}; // expected-note {{previous use is here}}
+ int hiding;
+ union { double union_member; };
+ enum tagname { enumerator };
+ };
+
+ template <class T> struct B : A {
+ A::type; // expected-warning {{access declarations are deprecated}}
+ A::hiding; // expected-warning {{access declarations are deprecated}}
+ A::union_member; // expected-warning {{access declarations are deprecated}}
+ A::enumerator; // expected-warning {{access declarations are deprecated}}
+ A::tagname; // expected-warning {{access declarations are deprecated}}
+
+ void test0() {
+ type t = 0;
+ }
+
+ void test1() {
+ typedef struct A::hiding local;
+ struct hiding _ = local();
+ }
+
+ void test2() {
+ union hiding _; // expected-error {{tag type that does not match previous}}
+ }
+
+ void test3() {
+ char array[sizeof(union_member) == sizeof(double) ? 1 : -1];
+ }
+
+ void test4() {
+ enum tagname _ = enumerator;
+ }
+
+ void test5() {
+ Opaque0 _ = hiding;
+ }
+ };
+}
+
+namespace test3 {
+ struct hiding {};
+
+ template <class T> struct A {
+ typedef int type; // expected-note {{target of using declaration}}
+ struct hiding {};
+ Opaque0 hiding;
+ union { double union_member; };
+ enum tagname { enumerator }; // expected-note {{target of using declaration}}
+ };
+
+ template <class T> struct B : A<T> {
+ A<T>::type; // expected-error {{dependent using declaration resolved to type without 'typename'}} // expected-warning {{access declarations are deprecated}}
+ A<T>::hiding; // expected-warning {{access declarations are deprecated}}
+ A<T>::union_member; // expected-warning {{access declarations are deprecated}}
+ A<T>::enumerator; // expected-warning {{access declarations are deprecated}}
+ A<T>::tagname; // expected-error {{dependent using declaration resolved to type without 'typename'}} // expected-warning {{access declarations are deprecated}}
+
+ // FIXME: re-enable these when the various bugs involving tags are fixed
+#if 0
+ void test1() {
+ typedef struct A<T>::hiding local;
+ struct hiding _ = local();
+ }
+
+ void test2() {
+ typedef struct A<T>::hiding local;
+ union hiding _ = local();
+ }
+#endif
+
+ void test3() {
+ char array[sizeof(union_member) == sizeof(double) ? 1 : -1];
+ }
+
+#if 0
+ void test4() {
+ enum tagname _ = enumerator;
+ }
+#endif
+
+ void test5() {
+ Opaque0 _ = hiding;
+ }
+ };
+
+ template struct B<int>; // expected-note {{in instantiation}}
+}
+
+namespace test4 {
+ struct Base {
+ int foo();
+ };
+
+ struct Unrelated {
+ int foo();
+ };
+
+ struct Subclass : Base {
+ };
+
+ namespace InnerNS {
+ int foo();
+ }
+
+ // We should be able to diagnose these without instantiation.
+ template <class T> struct C : Base {
+ InnerNS::foo; // expected-error {{not a class}} expected-warning {{access declarations are deprecated}}
+ Base::bar; // expected-error {{no member named 'bar'}} expected-warning {{access declarations are deprecated}}
+ Unrelated::foo; // expected-error {{not a base class}} expected-warning {{access declarations are deprecated}}
+ C::foo; // legal in C++03 // expected-warning {{access declarations are deprecated}}
+ Subclass::foo; // legal in C++03 // expected-warning {{access declarations are deprecated}}
+
+ int bar(); //expected-note {{target of using declaration}}
+ C::bar; // expected-error {{refers to its own class}} expected-warning {{access declarations are deprecated}}
+ };
+}
+
diff --git a/test/CXX/class/class.mfct/class.mfct.non-static/p3.cpp b/test/CXX/class/class.mfct/class.mfct.non-static/p3.cpp
new file mode 100644
index 0000000..b90661d
--- /dev/null
+++ b/test/CXX/class/class.mfct/class.mfct.non-static/p3.cpp
@@ -0,0 +1,93 @@
+// RUN: clang-cc -fsyntax-only -verify %s
+
+// [class.mfct.non-static]p3:
+// When an id-expression (5.1) that is not part of a class member
+// access syntax (5.2.5) and not used to form a pointer to member
+// (5.3.1) is used in the body of a non-static member function of
+// class X, if name lookup (3.4.1) resolves the name in the
+// id-expression to a non-static non-type member of some class C,
+// the id-expression is transformed into a class member access
+// expression (5.2.5) using (*this) (9.3.2) as the
+// postfix-expression to the left of the . operator. [ Note: if C is
+// not X or a base class of X, the class member access expression is
+// ill-formed. --end note] Similarly during name lookup, when an
+// unqualified-id (5.1) used in the definition of a member function
+// for class X resolves to a static member, an enumerator or a
+// nested type of class X or of a base class of X, the
+// unqualified-id is transformed into a qualified-id (5.1) in which
+// the nested-name-specifier names the class of the member function.
+
+namespace test0 {
+ class A {
+ int data_member;
+ int instance_method();
+ static int static_method();
+
+ bool test() {
+ return data_member + instance_method() < static_method();
+ }
+ };
+}
+
+namespace test1 {
+ struct Opaque1 {}; struct Opaque2 {}; struct Opaque3 {};
+
+ struct A {
+ void foo(Opaque1); // expected-note {{candidate}}
+ void foo(Opaque2); // expected-note {{candidate}}
+ void test();
+ };
+
+ struct B : A {
+
+ };
+
+ void A::test() {
+ B::foo(Opaque1());
+ B::foo(Opaque2());
+ B::foo(Opaque3()); // expected-error {{no matching member function}}
+ }
+}
+
+namespace test2 {
+ class Unrelated {
+ void foo();
+ };
+
+ template <class T> struct B;
+ template <class T> struct C;
+
+ template <class T> struct A {
+ void foo();
+
+ void test0() {
+ Unrelated::foo(); // expected-error {{call to non-static member function without an object argument}}
+ }
+
+ void test1() {
+ B<T>::foo();
+ }
+
+ static void test2() {
+ B<T>::foo(); // expected-error {{call to non-static member function without an object argument}}
+ }
+
+ void test3() {
+ C<T>::foo(); // expected-error {{no member named 'foo'}}
+ }
+ };
+
+ template <class T> struct B : A<T> {
+ };
+
+ template <class T> struct C {
+ };
+
+ int test() {
+ A<int> a;
+ a.test0(); // no instantiation note here, decl is ill-formed
+ a.test1();
+ a.test2(); // expected-note {{in instantiation}}
+ a.test3(); // expected-note {{in instantiation}}
+ }
+}
diff --git a/test/CXX/dcl.dcl/basic.namespace/namespace.udecl/p10.cpp b/test/CXX/dcl.dcl/basic.namespace/namespace.udecl/p10.cpp
new file mode 100644
index 0000000..00d109e
--- /dev/null
+++ b/test/CXX/dcl.dcl/basic.namespace/namespace.udecl/p10.cpp
@@ -0,0 +1,33 @@
+// RUN: clang -fsyntax-only -verify %s
+
+namespace test0 {
+ namespace ns0 {
+ class tag;
+ int tag();
+ }
+
+ namespace ns1 {
+ using ns0::tag;
+ }
+
+ namespace ns2 {
+ using ns0::tag;
+ }
+
+ using ns1::tag;
+ using ns2::tag;
+}
+
+// PR 5752
+namespace test1 {
+ namespace ns {
+ void foo();
+ }
+
+ using ns::foo;
+ void foo(int);
+
+ namespace ns {
+ using test1::foo;
+ }
+}
diff --git a/test/CXX/dcl.dcl/basic.namespace/namespace.udecl/p11.cpp b/test/CXX/dcl.dcl/basic.namespace/namespace.udecl/p11.cpp
new file mode 100644
index 0000000..b4302d5
--- /dev/null
+++ b/test/CXX/dcl.dcl/basic.namespace/namespace.udecl/p11.cpp
@@ -0,0 +1,94 @@
+// RUN: clang-cc -fsyntax-only -verify %s
+
+// C++03 [namespace.udecl]p11:
+// If a function declaration in namespace scope or block scope has
+// the same name and the same parameter types as a function
+// introduced by a using-declaration, the program is
+// ill-formed. [Note: two using-declarations may introduce functions
+// with the same name and the same parameter types. If, for a call
+// to an unqualified function name, function overload resolution
+// selects the functions introduced by such using-declarations, the
+// function call is ill-formed.
+
+namespace test0 {
+ namespace ns { void foo(); } // expected-note {{target of using declaration}}
+ int foo(); // expected-note {{conflicting declaration}}
+ using ns::foo; // expected-error {{target of using declaration conflicts with declaration already in scope}}
+}
+
+namespace test1 {
+ namespace ns { void foo(); } // expected-note {{target of using declaration}}
+ using ns::foo; //expected-note {{using declaration}}
+ int foo(); // expected-error {{declaration conflicts with target of using declaration already in scope}}
+}
+
+namespace test2 {
+ namespace ns { void foo(); } // expected-note 2 {{target of using declaration}}
+ void test0() {
+ int foo(); // expected-note {{conflicting declaration}}
+ using ns::foo; // expected-error {{target of using declaration conflicts with declaration already in scope}}
+ }
+
+ void test1() {
+ using ns::foo; //expected-note {{using declaration}}
+ int foo(); // expected-error {{declaration conflicts with target of using declaration already in scope}}
+ }
+}
+
+namespace test3 {
+ namespace ns { void foo(); } // expected-note 2 {{target of using declaration}}
+ class Test0 {
+ void test() {
+ int foo(); // expected-note {{conflicting declaration}}
+ using ns::foo; // expected-error {{target of using declaration conflicts with declaration already in scope}}
+ }
+ };
+
+ class Test1 {
+ void test() {
+ using ns::foo; //expected-note {{using declaration}}
+ int foo(); // expected-error {{declaration conflicts with target of using declaration already in scope}}
+ }
+ };
+}
+
+namespace test4 {
+ namespace ns { void foo(); } // expected-note 2 {{target of using declaration}}
+ template <typename> class Test0 {
+ void test() {
+ int foo(); // expected-note {{conflicting declaration}}
+ using ns::foo; // expected-error {{target of using declaration conflicts with declaration already in scope}}
+ }
+ };
+
+ template <typename> class Test1 {
+ void test() {
+ using ns::foo; //expected-note {{using declaration}}
+ int foo(); // expected-error {{declaration conflicts with target of using declaration already in scope}}
+ }
+ };
+}
+
+// FIXME: we should be able to diagnose both of these, but we can't.
+// ...I'm actually not sure why we can diagnose either of them; it's
+// probably a bug.
+namespace test5 {
+ namespace ns { void foo(int); } // expected-note {{target of using declaration}}
+ template <typename T> class Test0 {
+ void test() {
+ int foo(T);
+ using ns::foo;
+ }
+ };
+
+ template <typename T> class Test1 {
+ void test() {
+ using ns::foo; // expected-note {{using declaration}}
+ int foo(T); // expected-error {{declaration conflicts with target of using declaration already in scope}}
+ }
+ };
+
+ template class Test0<int>;
+ template class Test1<int>; // expected-note {{in instantiation of member function}}
+}
+
diff --git a/test/CXX/dcl.dcl/basic.namespace/namespace.udecl/p12.cpp b/test/CXX/dcl.dcl/basic.namespace/namespace.udecl/p12.cpp
new file mode 100644
index 0000000..4cbe1be
--- /dev/null
+++ b/test/CXX/dcl.dcl/basic.namespace/namespace.udecl/p12.cpp
@@ -0,0 +1,144 @@
+// RUN: clang-cc -fsyntax-only -verify %s
+
+// C++03 [namespace.udecl]p12:
+// When a using-declaration brings names from a base class into a
+// derived class scope, member functions in the derived class
+// override and/or hide member functions with the same name and
+// parameter types in a base class (rather than conflicting).
+
+template <unsigned n> struct Opaque {};
+template <unsigned n> void expect(Opaque<n> _) {}
+
+// PR5727
+// This just shouldn't crash.
+namespace test0 {
+ template<typename> struct RefPtr { };
+ template<typename> struct PtrHash {
+ static void f() { }
+ };
+ template<typename T> struct PtrHash<RefPtr<T> > : PtrHash<T*> {
+ using PtrHash<T*>::f;
+ static void f() { f(); }
+ };
+}
+
+// Simple hiding.
+namespace test1 {
+ struct Base {
+ Opaque<0> foo(Opaque<0>);
+ Opaque<0> foo(Opaque<1>);
+ Opaque<0> foo(Opaque<2>);
+ };
+
+ // using before decls
+ struct Test0 : Base {
+ using Base::foo;
+ Opaque<1> foo(Opaque<1>);
+ Opaque<1> foo(Opaque<3>);
+
+ void test0() { Opaque<0> _ = foo(Opaque<0>()); }
+ void test1() { Opaque<1> _ = foo(Opaque<1>()); }
+ void test2() { Opaque<0> _ = foo(Opaque<2>()); }
+ void test3() { Opaque<1> _ = foo(Opaque<3>()); }
+ };
+
+ // using after decls
+ struct Test1 : Base {
+ Opaque<1> foo(Opaque<1>);
+ Opaque<1> foo(Opaque<3>);
+ using Base::foo;
+
+ void test0() { Opaque<0> _ = foo(Opaque<0>()); }
+ void test1() { Opaque<1> _ = foo(Opaque<1>()); }
+ void test2() { Opaque<0> _ = foo(Opaque<2>()); }
+ void test3() { Opaque<1> _ = foo(Opaque<3>()); }
+ };
+
+ // using between decls
+ struct Test2 : Base {
+ Opaque<1> foo(Opaque<0>);
+ using Base::foo;
+ Opaque<1> foo(Opaque<2>);
+ Opaque<1> foo(Opaque<3>);
+
+ void test0() { Opaque<1> _ = foo(Opaque<0>()); }
+ void test1() { Opaque<0> _ = foo(Opaque<1>()); }
+ void test2() { Opaque<1> _ = foo(Opaque<2>()); }
+ void test3() { Opaque<1> _ = foo(Opaque<3>()); }
+ };
+}
+
+// Crazy dependent hiding.
+namespace test2 {
+ struct Base {
+ void foo(int);
+ };
+
+ template <typename T> struct Derived1 : Base {
+ using Base::foo;
+ void foo(T);
+
+ void testUnresolved(int i) { foo(i); }
+ };
+
+ void test0(int i) {
+ Derived1<int> d1;
+ d1.foo(i);
+ d1.testUnresolved(i);
+ }
+
+ // Same thing, except with the order of members reversed.
+ template <typename T> struct Derived2 : Base {
+ void foo(T);
+ using Base::foo;
+
+ void testUnresolved(int i) { foo(i); }
+ };
+
+ void test1(int i) {
+ Derived2<int> d2;
+ d2.foo(i);
+ d2.testUnresolved(i);
+ }
+}
+
+// Hiding of member templates.
+namespace test3 {
+ struct Base {
+ template <class T> Opaque<0> foo() { return Opaque<0>(); }
+ template <int n> Opaque<1> foo() { return Opaque<1>(); }
+ };
+
+ struct Derived1 : Base {
+ using Base::foo;
+ template <int n> Opaque<2> foo() { return Opaque<2>(); }
+ };
+
+ struct Derived2 : Base {
+ template <int n> Opaque<2> foo() { return Opaque<2>(); }
+ using Base::foo;
+ };
+
+ struct Derived3 : Base {
+ using Base::foo;
+ template <class T> Opaque<3> foo() { return Opaque<3>(); }
+ };
+
+ struct Derived4 : Base {
+ template <class T> Opaque<3> foo() { return Opaque<3>(); }
+ using Base::foo;
+ };
+
+ void test() {
+ expect<0>(Base().foo<int>());
+ expect<1>(Base().foo<0>());
+ expect<0>(Derived1().foo<int>());
+ expect<2>(Derived1().foo<0>());
+ expect<0>(Derived2().foo<int>());
+ expect<2>(Derived2().foo<0>());
+ expect<3>(Derived3().foo<int>());
+ expect<1>(Derived3().foo<0>());
+ expect<3>(Derived4().foo<int>());
+ expect<1>(Derived4().foo<0>());
+ }
+}
diff --git a/test/CXX/dcl.dcl/basic.namespace/namespace.udecl/p13.cpp b/test/CXX/dcl.dcl/basic.namespace/namespace.udecl/p13.cpp
new file mode 100644
index 0000000..1a05aae
--- /dev/null
+++ b/test/CXX/dcl.dcl/basic.namespace/namespace.udecl/p13.cpp
@@ -0,0 +1,63 @@
+// RUN: clang-cc -fsyntax-only -verify %s
+
+// C++03 [namespace.udecl]p3:
+// For the purpose of overload resolution, the functions which are
+// introduced by a using-declaration into a derived class will be
+// treated as though they were members of the derived class. In
+// particular, the implicit this parameter shall be treated as if it
+// were a pointer to the derived class rather than to the base
+// class. This has no effect on the type of the function, and in all
+// other respects the function remains a member of the base class.
+
+namespace test0 {
+ struct Opaque0 {};
+ struct Opaque1 {};
+
+ struct Base {
+ Opaque0 test0(int*);
+ Opaque0 test1(const int*);
+ Opaque0 test2(int*);
+ Opaque0 test3(int*) const;
+ };
+
+ struct Derived : Base {
+ using Base::test0;
+ Opaque1 test0(const int*);
+
+ using Base::test1;
+ Opaque1 test1(int*);
+
+ using Base::test2;
+ Opaque1 test2(int*) const;
+
+ using Base::test3;
+ Opaque1 test3(int*);
+ };
+
+ void test0() {
+ Opaque0 a = Derived().test0((int*) 0);
+ Opaque1 b = Derived().test0((const int*) 0);
+ }
+
+ void test1() {
+ Opaque1 a = Derived().test1((int*) 0);
+ Opaque0 b = Derived().test1((const int*) 0);
+ }
+
+ void test2() {
+ Opaque0 a = ((Derived*) 0)->test2((int*) 0);
+ Opaque1 b = ((const Derived*) 0)->test2((int*) 0);
+ }
+
+ void test3() {
+ Opaque1 a = ((Derived*) 0)->test3((int*) 0);
+ Opaque0 b = ((const Derived*) 0)->test3((int*) 0);
+ }
+}
+
+// Things to test:
+// member operators
+// conversion operators
+// call operators
+// call-surrogate conversion operators
+// everything, but in dependent contexts
diff --git a/test/CXX/dcl.dcl/basic.namespace/namespace.udecl/p3-cxx0x.cpp b/test/CXX/dcl.dcl/basic.namespace/namespace.udecl/p3-cxx0x.cpp
index d701f88..8257330 100644
--- a/test/CXX/dcl.dcl/basic.namespace/namespace.udecl/p3-cxx0x.cpp
+++ b/test/CXX/dcl.dcl/basic.namespace/namespace.udecl/p3-cxx0x.cpp
@@ -1,4 +1,4 @@
-// RUN: clang-cc -fsyntax-only -verify %s
+// RUN: clang-cc -std=c++0x -fsyntax-only -verify %s
// C++0x N2914.
struct B {
@@ -18,3 +18,29 @@ class D2 : public B {
using B::x;
using C::g; // expected-error{{using declaration refers into 'C::', which is not a base class of 'D2'}}
};
+
+namespace test1 {
+ struct Base {
+ int foo();
+ };
+
+ struct Unrelated {
+ int foo();
+ };
+
+ struct Subclass : Base {
+ };
+
+ namespace InnerNS {
+ int foo();
+ }
+
+ // We should be able to diagnose these without instantiation.
+ template <class T> struct C : Base {
+ using InnerNS::foo; // expected-error {{not a class}}
+ using Base::bar; // expected-error {{no member named 'bar'}}
+ using Unrelated::foo; // expected-error {{not a base class}}
+ using C::foo; // expected-error {{refers to its own class}}
+ using Subclass::foo; // expected-error {{not a base class}}
+ };
+}
diff --git a/test/CXX/dcl.dcl/basic.namespace/namespace.udecl/p4.cpp b/test/CXX/dcl.dcl/basic.namespace/namespace.udecl/p4.cpp
new file mode 100644
index 0000000..bf314c4
--- /dev/null
+++ b/test/CXX/dcl.dcl/basic.namespace/namespace.udecl/p4.cpp
@@ -0,0 +1,212 @@
+// RUN: clang-cc -fsyntax-only -verify %s
+
+// C++03 [namespace.udecl]p4:
+// A using-declaration used as a member-declaration shall refer to a
+// member of a base class of the class being defined, shall refer to
+// a member of an anonymous union that is a member of a base class
+// of the class being defined, or shall refer to an enumerator for
+// an enumeration type that is a member of a base class of the class
+// being defined.
+
+// There is no directly analogous paragraph in C++0x, and the feature
+// works sufficiently differently there that it needs a separate test.
+
+namespace test0 {
+ namespace NonClass {
+ typedef int type;
+ struct hiding {};
+ int hiding;
+ static union { double union_member; };
+ enum tagname { enumerator };
+ }
+
+ class Test0 {
+ using NonClass::type; // expected-error {{not a class}}
+ using NonClass::hiding; // expected-error {{not a class}}
+ using NonClass::union_member; // expected-error {{not a class}}
+ using NonClass::enumerator; // expected-error {{not a class}}
+ };
+}
+
+struct Opaque0 {};
+
+namespace test1 {
+ struct A {
+ typedef int type;
+ struct hiding {}; // expected-note {{previous use is here}}
+ Opaque0 hiding;
+ union { double union_member; };
+ enum tagname { enumerator };
+ };
+
+ struct B : A {
+ using A::type;
+ using A::hiding;
+ using A::union_member;
+ using A::enumerator;
+ using A::tagname;
+
+ void test0() {
+ type t = 0;
+ }
+
+ void test1() {
+ typedef struct A::hiding local;
+ struct hiding _ = local();
+ }
+
+ void test2() {
+ union hiding _; // expected-error {{tag type that does not match previous}}
+ }
+
+ void test3() {
+ char array[sizeof(union_member) == sizeof(double) ? 1 : -1];
+ }
+
+ void test4() {
+ enum tagname _ = enumerator;
+ }
+
+ void test5() {
+ Opaque0 _ = hiding;
+ }
+ };
+}
+
+namespace test2 {
+ struct A {
+ typedef int type;
+ struct hiding {}; // expected-note {{previous use is here}}
+ int hiding;
+ union { double union_member; };
+ enum tagname { enumerator };
+ };
+
+ template <class T> struct B : A {
+ using A::type;
+ using A::hiding;
+ using A::union_member;
+ using A::enumerator;
+ using A::tagname;
+
+ void test0() {
+ type t = 0;
+ }
+
+ void test1() {
+ typedef struct A::hiding local;
+ struct hiding _ = local();
+ }
+
+ void test2() {
+ union hiding _; // expected-error {{tag type that does not match previous}}
+ }
+
+ void test3() {
+ char array[sizeof(union_member) == sizeof(double) ? 1 : -1];
+ }
+
+ void test4() {
+ enum tagname _ = enumerator;
+ }
+
+ void test5() {
+ Opaque0 _ = hiding;
+ }
+ };
+}
+
+namespace test3 {
+ struct hiding {};
+
+ template <class T> struct A {
+ typedef int type; // expected-note {{target of using declaration}}
+ struct hiding {};
+ Opaque0 hiding; // expected-note {{target of using declaration}}
+ union { double union_member; }; // expected-note {{target of using declaration}}
+ enum tagname { enumerator }; // expected-note 2 {{target of using declaration}}
+ };
+
+ template <class T> struct B : A<T> {
+ using A<T>::type; // expected-error {{dependent using declaration resolved to type without 'typename'}}
+ using A<T>::hiding;
+ using A<T>::union_member;
+ using A<T>::enumerator;
+ using A<T>::tagname; // expected-error {{dependent using declaration resolved to type without 'typename'}}
+
+ // FIXME: re-enable these when the various bugs involving tags are fixed
+#if 0
+ void test1() {
+ typedef struct A<T>::hiding local;
+ struct hiding _ = local();
+ }
+
+ void test2() {
+ typedef struct A<T>::hiding local;
+ union hiding _ = local();
+ }
+#endif
+
+ void test3() {
+ char array[sizeof(union_member) == sizeof(double) ? 1 : -1];
+ }
+
+#if 0
+ void test4() {
+ enum tagname _ = enumerator;
+ }
+#endif
+
+ void test5() {
+ Opaque0 _ = hiding;
+ }
+ };
+
+ template struct B<int>; // expected-note {{in instantiation}}
+
+ template <class T> struct C : A<T> {
+ using typename A<T>::type;
+ using typename A<T>::hiding; // expected-error {{'typename' keyword used on a non-type}}
+ using typename A<T>::union_member; // expected-error {{'typename' keyword used on a non-type}}
+ using typename A<T>::enumerator; // expected-error {{'typename' keyword used on a non-type}}
+
+ void test6() {
+ type t = 0;
+ }
+
+ void test7() {
+ Opaque0 _ = hiding; // expected-error {{expected '(' for function-style cast or type construction}}
+ }
+ };
+
+ template struct C<int>; // expected-note {{in instantiation}}
+}
+
+namespace test4 {
+ struct Base {
+ int foo();
+ };
+
+ struct Unrelated {
+ int foo();
+ };
+
+ struct Subclass : Base {
+ };
+
+ namespace InnerNS {
+ int foo();
+ }
+
+ // We should be able to diagnose these without instantiation.
+ template <class T> struct C : Base {
+ using InnerNS::foo; // expected-error {{not a class}}
+ using Base::bar; // expected-error {{no member named 'bar'}}
+ using Unrelated::foo; // expected-error {{not a base class}}
+ using C::foo; // legal in C++03
+ using Subclass::foo; // legal in C++03
+
+ int bar(); //expected-note {{target of using declaration}}
+ using C::bar; // expected-error {{refers to its own class}}
+ };
+}
diff --git a/test/CXX/dcl.dcl/basic.namespace/namespace.udecl/p8.cpp b/test/CXX/dcl.dcl/basic.namespace/namespace.udecl/p8.cpp
new file mode 100644
index 0000000..bf0f330
--- /dev/null
+++ b/test/CXX/dcl.dcl/basic.namespace/namespace.udecl/p8.cpp
@@ -0,0 +1,83 @@
+// RUN: clang-cc -fsyntax-only -verify %s
+
+struct Opaque0 {};
+struct Opaque1 {};
+
+// Redeclarations are okay in a namespace.
+namespace test0 {
+ namespace ns {
+ void foo(Opaque0); // expected-note 2 {{candidate function}}
+ }
+
+ using ns::foo;
+ using ns::foo;
+
+ void test0() {
+ foo(Opaque1()); // expected-error {{no matching function for call}}
+ }
+
+ namespace ns {
+ void foo(Opaque1);
+ }
+
+ void test1() {
+ foo(Opaque1()); // expected-error {{no matching function for call}}
+ }
+
+ using ns::foo;
+
+ void test2() {
+ foo(Opaque1());
+ }
+
+ using ns::foo;
+}
+
+// Make sure we handle transparent contexts the same way.
+namespace test1 {
+ namespace ns {
+ void foo(Opaque0); // expected-note 2 {{candidate function}}
+ }
+
+ extern "C++" {
+ using ns::foo;
+ }
+
+ void test0() {
+ foo(Opaque1()); // expected-error {{no matching function for call}}
+ }
+
+ namespace ns {
+ void foo(Opaque1);
+ }
+
+ void test1() {
+ foo(Opaque1()); // expected-error {{no matching function for call}}
+ }
+
+ extern "C++" {
+ using ns::foo;
+ }
+
+ void test2() {
+ foo(Opaque1());
+ }
+}
+
+// Make sure we detect invalid redeclarations that can't be detected
+// until template instantiation.
+namespace test2 {
+ template <class T> struct Base {
+ typedef Base type;
+ void foo();
+ };
+
+ template <class T> struct Derived : Base<T> {
+ // These are invalid redeclarations, detectable only after
+ // instantiation.
+ using Base<T>::foo; // expected-note {{previous using decl}}
+ using Base<T>::type::foo; //expected-error {{redeclaration of using decl}}
+ };
+
+ template struct Derived<int>; // expected-note {{in instantiation of template class}}
+}
diff --git a/test/CXX/dcl.decl/dcl.init/dcl.init.list/basic.cpp b/test/CXX/dcl.decl/dcl.init/dcl.init.list/basic.cpp
new file mode 100644
index 0000000..f62b425
--- /dev/null
+++ b/test/CXX/dcl.decl/dcl.init/dcl.init.list/basic.cpp
@@ -0,0 +1,5 @@
+// RUN: clang-cc -fsyntax-only -verify %s
+
+void f0() {
+ int &ir = { 17 }; // expected-error{{reference to type 'int' cannot bind to an initializer list}}
+}
diff --git a/test/CXX/dcl.decl/dcl.init/dcl.init.ref/p1.cpp b/test/CXX/dcl.decl/dcl.init/dcl.init.ref/p1.cpp
new file mode 100644
index 0000000..66fa2d1
--- /dev/null
+++ b/test/CXX/dcl.decl/dcl.init/dcl.init.ref/p1.cpp
@@ -0,0 +1,14 @@
+// RUN: clang-cc -fsyntax-only -verify -std=c++0x %s
+int g(int);
+void f() {
+ int i;
+ int& r = i;
+ r = 1;
+ int* p = &r;
+ int &rr=r;
+ int (&rg)(int) = g;
+ rg(i);
+ int a[3];
+ int (&ra)[3] = a;
+ ra[1] = i;
+}
diff --git a/test/CXX/dcl.decl/dcl.init/dcl.init.ref/p3.cpp b/test/CXX/dcl.decl/dcl.init/dcl.init.ref/p3.cpp
new file mode 100644
index 0000000..54840f5
--- /dev/null
+++ b/test/CXX/dcl.decl/dcl.init/dcl.init.ref/p3.cpp
@@ -0,0 +1,3 @@
+// RUN: clang-cc -fsyntax-only -verify %s
+int& r1; // expected-error{{declaration of reference variable 'r1' requires an initializer}}
+extern int& r2;
diff --git a/test/CXX/dcl.decl/dcl.init/dcl.init.ref/p5-examples.cpp b/test/CXX/dcl.decl/dcl.init/dcl.init.ref/p5-examples.cpp
new file mode 100644
index 0000000..5d34345
--- /dev/null
+++ b/test/CXX/dcl.decl/dcl.init/dcl.init.ref/p5-examples.cpp
@@ -0,0 +1,53 @@
+// RUN: clang-cc -ast-dump %s 2>&1 | FileCheck %s
+
+// CHECK: example0
+void example0() {
+ double d = 2.0;
+ // CHECK: double &rd =
+ // CHECK-NEXT: DeclRefExpr
+ double &rd = d;
+ // CHECK: double const &rcd =
+ // CHECK-NEXT: ImplicitCastExpr{{.*}}'double const' <NoOp>
+ const double &rcd = d;
+}
+
+struct A { };
+struct B : A { } b;
+
+// CHECK: example1
+void example1() {
+ // CHECK: struct A &ra =
+ // CHECK: ImplicitCastExpr{{.*}}'struct A' <DerivedToBase> lvalue
+ A &ra = b;
+ // CHECK: struct A const &rca =
+ // CHECK: ImplicitCastExpr{{.*}}'struct A const' <NoOp>
+ // CHECK: ImplicitCastExpr{{.*}}'struct A' <DerivedToBase>
+ const A& rca = b;
+}
+
+extern B f();
+
+struct X {
+ operator B();
+} x;
+
+// CHECK: example2
+void example2() {
+ // CHECK: struct A const &rca =
+ // CHECK: ImplicitCastExpr{{.*}}'struct A const' <NoOp>
+ // CHECK: ImplicitCastExpr{{.*}}'struct A' <DerivedToBase>
+ // CHECK: CallExpr{{.*}}struct B
+ const A &rca = f();
+ // CHECK: struct A const &r =
+ // CHECK: ImplicitCastExpr{{.*}}'struct A const' <NoOp>
+ // CHECK: ImplicitCastExpr{{.*}}'struct A' <DerivedToBase>
+ // CHECK: CXXMemberCallExpr{{.*}}'struct B'
+ const A& r = x;
+}
+
+// CHECK: example3
+void example3() {
+ // CHECK: double const &rcd2 =
+ // CHECK: ImplicitCastExpr{{.*}}<IntegralToFloating>
+ const double& rcd2 = 2;
+}
diff --git a/test/CXX/dcl.decl/dcl.init/dcl.init.ref/p5-var.cpp b/test/CXX/dcl.decl/dcl.init/dcl.init.ref/p5-var.cpp
new file mode 100644
index 0000000..5fa1fff
--- /dev/null
+++ b/test/CXX/dcl.decl/dcl.init/dcl.init.ref/p5-var.cpp
@@ -0,0 +1,129 @@
+// RUN: clang-cc -fsyntax-only -verify %s
+
+struct Base { }; // expected-note{{candidate function}}
+struct Derived : Base { }; // expected-note{{candidate function}}
+struct Unrelated { };
+struct Derived2 : Base { };
+struct Diamond : Derived, Derived2 { };
+
+struct ConvertibleToBaseRef {
+ operator Base&() const;
+};
+
+struct ConvertibleToDerivedRef {
+ operator Derived&() const;
+};
+
+struct ConvertibleToBothDerivedRef {
+ operator Derived&(); // expected-note{{candidate function}}
+ operator Derived2&(); // expected-note{{candidate function}}
+};
+
+struct ConvertibleToIntRef {
+ operator int&();
+};
+
+struct ConvertibleToBase {
+ operator Base() const;
+};
+
+struct ConvertibleToDerived {
+ operator Derived() const;
+};
+
+struct ConvertibleToBothDerived {
+ operator Derived(); // expected-note{{candidate function}}
+ operator Derived2(); // expected-note{{candidate function}}
+};
+
+struct ConvertibleToInt {
+ operator int();
+};
+
+template<typename T> T create();
+
+// First bullet: lvalue references binding to lvalues (the simple cases).
+void bind_lvalue_to_lvalue(Base b, Derived d,
+ const Base bc, const Derived dc,
+ Diamond diamond,
+ int i) {
+ // Reference-compatible
+ Base &br1 = b;
+ Base &br2 = d;
+ Derived &dr1 = d;
+ Derived &dr2 = b; // expected-error{{non-const lvalue reference to type 'struct Derived' cannot bind to a value of unrelated type 'struct Base'}}
+ Base &br3 = bc; // expected-error{{drops qualifiers}}
+ Base &br4 = dc; // expected-error{{drops qualifiers}}
+ Base &br5 = diamond; // expected-error{{ambiguous conversion from derived class 'struct Diamond' to base class 'struct Base'}}
+ int &ir = i;
+ long &lr = i; // expected-error{{non-const lvalue reference to type 'long' cannot bind to a value of unrelated type 'int'}}
+}
+
+void bind_lvalue_quals(volatile Base b, volatile Derived d,
+ volatile const Base bvc, volatile const Derived dvc,
+ volatile const int ivc) {
+ volatile Base &bvr1 = b;
+ volatile Base &bvr2 = d;
+ volatile Base &bvr3 = bvc; // expected-error{{binding of reference to type 'struct Base volatile' to a value of type 'struct Base const volatile' drops qualifiers}}
+ volatile Base &bvr4 = dvc; // expected-error{{binding of reference to type 'struct Base volatile' to a value of type 'struct Derived const volatile' drops qualifiers}}
+
+ volatile int &ir = ivc; // expected-error{{binding of reference to type 'int volatile' to a value of type 'int const volatile' drops qualifiers}}
+}
+
+void bind_lvalue_to_rvalue() {
+ Base &br1 = Base(); // expected-error{{non-const lvalue reference to type 'struct Base' cannot bind to a temporary of type 'struct Base'}}
+ Base &br2 = Derived(); // expected-error{{non-const lvalue reference to type 'struct Base' cannot bind to a temporary of type 'struct Derived'}}
+
+ int &ir = 17; // expected-error{{non-const lvalue reference to type 'int' cannot bind to a temporary of type 'int'}}
+}
+
+void bind_lvalue_to_unrelated(Unrelated ur) {
+ Base &br1 = ur; // expected-error{{non-const lvalue reference to type 'struct Base' cannot bind to a value of unrelated type 'struct Unrelated'}}
+}
+
+void bind_lvalue_to_conv_lvalue() {
+ // Not reference-related, but convertible
+ Base &nbr1 = ConvertibleToBaseRef();
+ Base &nbr2 = ConvertibleToDerivedRef();
+ Derived &ndr1 = ConvertibleToDerivedRef();
+ int &ir = ConvertibleToIntRef();
+}
+
+void bind_lvalue_to_conv_lvalue_ambig(ConvertibleToBothDerivedRef both) {
+ Derived &dr1 = both;
+ Base &br1 = both; // expected-error{{error: conversion from 'struct ConvertibleToBothDerivedRef' to 'struct Base' is ambiguous}}
+}
+
+struct IntBitfield {
+ int i : 17; // expected-note{{bit-field is declared here}}
+};
+
+void test_bitfield(IntBitfield ib) {
+ int & ir1 = (ib.i); // expected-error{{non-const reference cannot bind to bit-field 'i'}}
+}
+
+// Second bullet: const lvalue reference binding to an rvalue with
+// similar type (both of which are class types).
+void bind_const_lvalue_to_rvalue() {
+ const Base &br1 = create<Base>();
+ const Base &br2 = create<Derived>();
+ const Derived &dr1 = create<Base>(); // expected-error{{no viable conversion}}
+
+ const Base &br3 = create<const Base>();
+ const Base &br4 = create<const Derived>();
+
+ const Base &br5 = create<const volatile Base>(); // expected-error{{binding of reference to type 'struct Base const' to a value of type 'struct Base const volatile' drops qualifiers}}
+ const Base &br6 = create<const volatile Derived>(); // expected-error{{binding of reference to type 'struct Base const' to a value of type 'struct Derived const volatile' drops qualifiers}}
+
+ const int &ir = create<int>();
+}
+
+// Second bullet: const lvalue reference binds to the result of a conversion.
+void bind_const_lvalue_to_class_conv_temporary() {
+ const Base &br1 = ConvertibleToBase();
+ const Base &br2 = ConvertibleToDerived();
+}
+void bind_lvalue_to_conv_rvalue_ambig(ConvertibleToBothDerived both) {
+ const Derived &dr1 = both;
+ const Base &br1 = both; // expected-error{{error: conversion from 'struct ConvertibleToBothDerived' to 'struct Base const' is ambiguous}}
+}
diff --git a/test/CXX/special/class.free/p6.cpp b/test/CXX/special/class.free/p6.cpp
index 8334817..b082b85 100644
--- a/test/CXX/special/class.free/p6.cpp
+++ b/test/CXX/special/class.free/p6.cpp
@@ -2,7 +2,7 @@
#include <stddef.h>
struct A {
- void operator delete(size_t) {
+ void operator delete(void*) {
(void)this; // expected-error {{invalid use of 'this' outside of a nonstatic member function}}
}
void operator delete[](void*) {
diff --git a/test/CXX/temp/temp.spec/temp.expl.spec/p17.cpp b/test/CXX/temp/temp.spec/temp.expl.spec/p17.cpp
index 883cb71..0665304 100644
--- a/test/CXX/temp/temp.spec/temp.expl.spec/p17.cpp
+++ b/test/CXX/temp/temp.spec/temp.expl.spec/p17.cpp
@@ -10,3 +10,15 @@ template<> template<> class A<int>::B<double>;
template<> template<> void A<char>::B<char>::mf();
template<> void A<char>::B<int>::mf(); // expected-error{{requires 'template<>'}}
+
+namespace test1 {
+ template <class> class A {
+ static int foo;
+ static int bar;
+ };
+ typedef A<int> AA;
+
+ template <> int AA::foo = 0; // expected-error {{cannot use typedef}}
+ int AA::bar = 1; // expected-error {{cannot use typedef}} expected-error {{template specialization requires 'template<>'}}
+ int A<float>::bar = 2; // expected-error {{template specialization requires 'template<>'}}
+}
OpenPOWER on IntegriCloud