diff options
| author | Roman Divacky <rdivacky@FreeBSD.org> | 2010-07-13 17:21:42 +0000 |
|---|---|---|
| committer | Roman Divacky <rdivacky@FreeBSD.org> | 2010-07-13 17:21:42 +0000 |
| commit | 4ba675006b5a8edfc48b6a9bd3dcf54a70cc08f2 (patch) | |
| tree | 48b44512b5db8ced345df4a1a56b5065cf2a14d9 /test/CXX | |
| parent | d7279c4c177bca357ef96ff1379fd9bc420bfe83 (diff) | |
Notes
Diffstat (limited to 'test/CXX')
26 files changed, 550 insertions, 47 deletions
diff --git a/test/CXX/basic/basic.lookup/basic.lookup.argdep/p2.cpp b/test/CXX/basic/basic.lookup/basic.lookup.argdep/p2.cpp index 0e262f3eb1d6..0c905fbf325d 100644 --- a/test/CXX/basic/basic.lookup/basic.lookup.argdep/p2.cpp +++ b/test/CXX/basic/basic.lookup/basic.lookup.argdep/p2.cpp @@ -86,3 +86,25 @@ namespace P { } } +namespace test5 { + namespace NS { + struct A; + void foo(void (*)(A&)); + } + void bar(NS::A& a); + + void test() { + foo(&bar); + } +} + +// PR6762: __builtin_va_list should be invisible to ADL on all platforms. +void test6_function(__builtin_va_list &argv); +namespace test6 { + void test6_function(__builtin_va_list &argv); + + void test() { + __builtin_va_list args; + test6_function(args); + } +} diff --git a/test/CXX/basic/basic.lookup/basic.lookup.classref/p1.cpp b/test/CXX/basic/basic.lookup/basic.lookup.classref/p1.cpp new file mode 100644 index 000000000000..3fde0daa96cf --- /dev/null +++ b/test/CXX/basic/basic.lookup/basic.lookup.classref/p1.cpp @@ -0,0 +1,46 @@ +// RUN: %clang_cc1 -fsyntax-only -fdiagnostics-show-option -verify %s + +// C++98 [basic.lookup.classref]p1: +// In a class member access expression (5.2.5), if the . or -> token is +// immediately followed by an identifier followed by a <, the identifier must +// be looked up to determine whether the < is the beginning of a template +// argument list (14.2) or a less-than operator. The identifier is first +// looked up in the class of the object expression. If the identifier is not +// found, it is then looked up in the context of the entire postfix-expression +// and shall name a class or function template. If the lookup in the class of +// the object expression finds a template, the name is also looked up in the +// context of the entire postfix-expression and +// -- if the name is not found, the name found in the class of the object +// expression is used, otherwise +// -- if the name is found in the context of the entire postfix-expression +// and does not name a class template, the name found in the class of the +// object expression is used, otherwise +// -- if the name found is a class template, it must refer to the same +// entity as the one found in the class of the object expression, +// otherwise the program is ill-formed. + +// From PR 7247 +template<typename T> +struct set{}; // expected-note{{lookup from the current scope refers here}} +struct Value { + template<typename T> + void set(T value) {} // expected-note{{lookup in the object type 'Value' refers here}} + + void resolves_to_same() { + Value v; + v.set<double>(3.2); + } +}; +void resolves_to_different() { + { + Value v; + // The fact that the next line is a warning rather than an error is an + // extension. + v.set<double>(3.2); // expected-warning{{lookup of 'set' in member access expression is ambiguous; using member of 'Value' [-Wambiguous-member-template]}} + } + { + int set; // Non-template. + Value v; + v.set<double>(3.2); + } +} diff --git a/test/CXX/basic/basic.lookup/basic.lookup.qual/p6-0x.cpp b/test/CXX/basic/basic.lookup/basic.lookup.qual/p6-0x.cpp index 35efba571ddc..355ac4a2ecad 100644 --- a/test/CXX/basic/basic.lookup/basic.lookup.qual/p6-0x.cpp +++ b/test/CXX/basic/basic.lookup/basic.lookup.qual/p6-0x.cpp @@ -1,4 +1,7 @@ // RUN: %clang_cc1 -std=c++0x -fsyntax-only -verify %s +// XFAIL: * +// Our C++0x doesn't currently have specialized destructor name handling, +// since the specification is still in flux. struct C { typedef int I; }; diff --git a/test/CXX/basic/basic.lookup/basic.lookup.qual/p6.cpp b/test/CXX/basic/basic.lookup/basic.lookup.qual/p6.cpp index 633d5cda9963..0956de3c2a88 100644 --- a/test/CXX/basic/basic.lookup/basic.lookup.qual/p6.cpp +++ b/test/CXX/basic/basic.lookup/basic.lookup.qual/p6.cpp @@ -20,5 +20,5 @@ struct A { typedef A AB; int main() { AB *p; - p->AB::~AB(); // expected-error{{identifier 'AB' in pseudo-destructor expression does not name a type}} + p->AB::~AB(); // expected-error{{expected the class name after '~' to name a destructor}} } diff --git a/test/CXX/basic/basic.scope/basic.scope.pdecl/p9.cpp b/test/CXX/basic/basic.scope/basic.scope.pdecl/p9.cpp new file mode 100644 index 000000000000..e64b6752f082 --- /dev/null +++ b/test/CXX/basic/basic.scope/basic.scope.pdecl/p9.cpp @@ -0,0 +1,18 @@ +// RUN: %clang_cc1 -fsyntax-only -verify %s + +// Template type parameters. +typedef unsigned char T; +template<typename T = T> struct X0 { }; +template<> struct X0<unsigned char> { static const bool value = true; }; +int array0[X0<>::value? 1 : -1]; + +// Non-type template parameters. +const int N = 17; +template<int N = N> struct X1 { }; +template<> struct X1<17> { static const bool value = true; }; +int array1[X1<>::value? 1 : -1]; + +// Template template parameters. +template<template<class> class X0 = X0> struct X2 { }; +template<> struct X2<X0> { static const bool value = true; }; +int array2[X2<>::value? 1 : -1]; diff --git a/test/CXX/class.access/class.access.base/p1.cpp b/test/CXX/class.access/class.access.base/p1.cpp index 09884316f9cd..43cc99eb8b49 100644 --- a/test/CXX/class.access/class.access.base/p1.cpp +++ b/test/CXX/class.access/class.access.base/p1.cpp @@ -54,8 +54,10 @@ namespace test0 { // of the base class are accessible as protected members of the // derived class. namespace test1 { - class Base { - public: int pub; static int spub; + class Base { // expected-note 6{{member is declared here}} + public: + int pub; // expected-note{{member is declared here}} + static int spub; // expected-note{{member is declared here}} protected: int prot; static int sprot; // expected-note 4 {{declared protected here}} private: int priv; static int spriv; // expected-note 8 {{declared private here}} }; @@ -102,13 +104,15 @@ namespace test1 { // the base class are accessible as private members of the derived // class. namespace test2 { - class Base { + class Base { // expected-note 6{{member is declared here}} public: - int pub; - static int spub; + int pub; // expected-note{{member is declared here}} + static int spub; // expected-note{{member is declared here}} protected: - int prot; // expected-note {{declared protected here}} - static int sprot; // expected-note {{declared protected here}} + int prot; // expected-note {{declared protected here}} \ + // expected-note{{member is declared here}} + static int sprot; // expected-note {{declared protected here}} \ + // expected-note{{member is declared here}} private: int priv; // expected-note 4 {{declared private here}} static int spriv; // expected-note 4 {{declared private here}} diff --git a/test/CXX/class.access/class.access.base/p5.cpp b/test/CXX/class.access/class.access.base/p5.cpp index 938d9fbe9bf8..255fbfc9fc93 100644 --- a/test/CXX/class.access/class.access.base/p5.cpp +++ b/test/CXX/class.access/class.access.base/p5.cpp @@ -27,7 +27,7 @@ namespace test1 { }; struct D { - public: static int x; + public: static int x; // expected-note{{member is declared here}} static int test() { return x; } }; struct E : private D { // expected-note{{constrained by private inheritance}} @@ -45,7 +45,7 @@ namespace test1 { namespace test2 { class A { - protected: static int x; + protected: static int x; // expected-note{{member is declared here}} }; class B : private A {}; // expected-note {{private inheritance}} diff --git a/test/CXX/class.access/class.access.dcl/p1.cpp b/test/CXX/class.access/class.access.dcl/p1.cpp index 5d7905f9da81..aab5fff5ea3f 100644 --- a/test/CXX/class.access/class.access.dcl/p1.cpp +++ b/test/CXX/class.access/class.access.dcl/p1.cpp @@ -1,4 +1,4 @@ -// RUN: %clang_cc1 -fsyntax-only -verify +// RUN: %clang_cc1 -fsyntax-only -verify %s // This is just the test for [namespace.udecl]p4 with 'using' // uniformly stripped out. diff --git a/test/CXX/class.access/class.friend/p1.cpp b/test/CXX/class.access/class.friend/p1.cpp index 563ae4f63c4d..277b70bee6bd 100644 --- a/test/CXX/class.access/class.friend/p1.cpp +++ b/test/CXX/class.access/class.friend/p1.cpp @@ -6,9 +6,6 @@ // 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. -// -// FIXME: Add tests for access control when implemented. Currently we only test -// for parsing. struct S { static void f(); }; S* g() { return 0; } @@ -124,7 +121,7 @@ namespace test2 { friend struct ilist_walker_bad; X *Prev; protected: - X *getPrev() { return Prev; } + 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}} @@ -287,3 +284,25 @@ namespace test9 { 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}} + } +} diff --git a/test/CXX/class.access/class.protected/p1.cpp b/test/CXX/class.access/class.protected/p1.cpp index 6ff630c99697..778e16aa3f53 100644 --- a/test/CXX/class.access/class.protected/p1.cpp +++ b/test/CXX/class.access/class.protected/p1.cpp @@ -2,8 +2,10 @@ namespace test0 { class A { - protected: int x; // expected-note 3 {{declared}} - static int sx; // expected-note 3 {{declared}} + protected: int x; // expected-note 3 {{declared}} \ + // expected-note {{member is declared here}} + static int sx; // expected-note 3 {{declared}} \ + // expected-note {{member is declared here}} }; class B : public A { }; @@ -136,8 +138,8 @@ namespace test3 { namespace test4 { class C; class A { - protected: int x; // expected-note 2 {{declared}} - static int sx; + protected: int x; // expected-note 3 {{declared}} + static int sx; // expected-note 3{{member is declared here}} static void test(C&); }; class B : public A { @@ -174,8 +176,8 @@ namespace test4 { namespace test5 { class D; class A { - protected: int x; - static int sx; + protected: int x; // expected-note 3{{member is declared here}} + static int sx; // expected-note 3{{member is declared here}} static void test(D&); }; class B : public A { @@ -326,11 +328,12 @@ namespace test8 { } namespace test9 { - class A { - protected: int foo(); // expected-note 8 {{declared}} + class A { // expected-note {{member is declared here}} + protected: int foo(); // expected-note 8 {{declared}} \ + // expected-note {{member is declared here}} }; - class B : public A { + class B : public A { // expected-note {{member is declared here}} friend class D; }; diff --git a/test/CXX/class.access/p4.cpp b/test/CXX/class.access/p4.cpp index e8afbe7a3924..90a1449610f3 100644 --- a/test/CXX/class.access/p4.cpp +++ b/test/CXX/class.access/p4.cpp @@ -160,7 +160,7 @@ namespace test4 { private: operator Private(); // expected-note 4 {{declared private here}} public: - operator Public(); + operator Public(); // expected-note 2{{member is declared here}} }; class Derived1 : private Base { // expected-note 2 {{declared private here}} \ @@ -267,7 +267,7 @@ namespace test8 { // Don't silently upgrade forbidden-access paths to private. namespace test9 { class A { - public: static int x; + public: static int x; // expected-note {{member is declared here}} }; class B : private A { // expected-note {{constrained by private inheritance here}} }; @@ -420,3 +420,10 @@ namespace test15 { template class B<int>; // expected-note {{in instantiation}} template class B<long>; // expected-note 4 {{in instantiation}} } + +// PR7281 +namespace test16 { + class A { ~A(); }; // expected-note 2{{declared private here}} + void b() { throw A(); } // expected-error{{temporary of type 'test16::A' has private destructor}} \ + // expected-error{{exception object of type 'test16::A' has private destructor}} +} diff --git a/test/CXX/dcl.dcl/basic.namespace/namespace.udecl/p10.cpp b/test/CXX/dcl.dcl/basic.namespace/namespace.udecl/p10.cpp index 1aa163a8d8d7..27b41a755ed0 100644 --- a/test/CXX/dcl.dcl/basic.namespace/namespace.udecl/p10.cpp +++ b/test/CXX/dcl.dcl/basic.namespace/namespace.udecl/p10.cpp @@ -1,4 +1,4 @@ -// RUN: %clang -fsyntax-only -verify %s +// RUN: %clang_cc1 -fsyntax-only -verify %s namespace test0 { namespace ns0 { diff --git a/test/CXX/dcl.dcl/basic.namespace/namespace.udecl/p12.cpp b/test/CXX/dcl.dcl/basic.namespace/namespace.udecl/p12.cpp index 25371c7029b9..cc28bf6c28c4 100644 --- a/test/CXX/dcl.dcl/basic.namespace/namespace.udecl/p12.cpp +++ b/test/CXX/dcl.dcl/basic.namespace/namespace.udecl/p12.cpp @@ -111,34 +111,53 @@ namespace test3 { struct Derived1 : Base { using Base::foo; - template <int n> Opaque<2> foo() { return Opaque<2>(); } + template <int n> Opaque<2> foo() { return Opaque<2>(); } // expected-note {{invalid explicitly-specified argument for template parameter 'n'}} }; struct Derived2 : Base { - template <int n> Opaque<2> foo() { return Opaque<2>(); } + template <int n> Opaque<2> foo() { return Opaque<2>(); } // expected-note {{invalid explicitly-specified argument for template parameter 'n'}} using Base::foo; }; struct Derived3 : Base { using Base::foo; - template <class T> Opaque<3> foo() { return Opaque<3>(); } + template <class T> Opaque<3> foo() { return Opaque<3>(); } // expected-note {{invalid explicitly-specified argument for template parameter 'T'}} }; struct Derived4 : Base { - template <class T> Opaque<3> foo() { return Opaque<3>(); } + template <class T> Opaque<3> foo() { return Opaque<3>(); } // expected-note {{invalid explicitly-specified argument for template parameter 'T'}} using Base::foo; }; void test() { expect<0>(Base().foo<int>()); expect<1>(Base().foo<0>()); - expect<0>(Derived1().foo<int>()); + expect<0>(Derived1().foo<int>()); // expected-error {{no matching member function for call to 'foo'}} expect<2>(Derived1().foo<0>()); - expect<0>(Derived2().foo<int>()); + expect<0>(Derived2().foo<int>()); // expected-error {{no matching member function for call to 'foo'}} expect<2>(Derived2().foo<0>()); expect<3>(Derived3().foo<int>()); - expect<1>(Derived3().foo<0>()); + expect<1>(Derived3().foo<0>()); // expected-error {{no matching member function for call to 'foo'}} expect<3>(Derived4().foo<int>()); - expect<1>(Derived4().foo<0>()); + expect<1>(Derived4().foo<0>()); // expected-error {{no matching member function for call to 'foo'}} + } +} + +// PR7384: access control for member templates. +namespace test4 { + class Base { + protected: + template<typename T> void foo(T); + template<typename T> void bar(T); // expected-note {{declared protected here}} + }; + + struct Derived : Base { + using Base::foo; + }; + + void test() { + Derived d; + d.foo<int>(3); + d.bar<int>(3); // expected-error {{'bar' is a protected member}} } } diff --git a/test/CXX/dcl.dcl/basic.namespace/namespace.udecl/p13.cpp b/test/CXX/dcl.dcl/basic.namespace/namespace.udecl/p13.cpp index ec814b1ab97c..dd44bfc914b2 100644 --- a/test/CXX/dcl.dcl/basic.namespace/namespace.udecl/p13.cpp +++ b/test/CXX/dcl.dcl/basic.namespace/namespace.udecl/p13.cpp @@ -55,6 +55,19 @@ namespace test0 { } } +// Typedef redeclaration. +namespace rdar8018262 { + typedef void (*fp)(); + + namespace N { + typedef void (*fp)(); + } + + using N::fp; + + fp fp_1; +} + // Things to test: // member operators // conversion operators diff --git a/test/CXX/dcl.dcl/dcl.spec/dcl.constexpr/p1.cpp b/test/CXX/dcl.dcl/dcl.spec/dcl.constexpr/p1.cpp new file mode 100644 index 000000000000..cd71d55fc5ce --- /dev/null +++ b/test/CXX/dcl.dcl/dcl.spec/dcl.constexpr/p1.cpp @@ -0,0 +1,78 @@ +// RUN: %clang_cc1 -fsyntax-only -verify %s +// XFAIL: * + +struct notlit { + notlit() {} +}; +struct notlit2 { + notlit2() {} +}; + +// valid declarations +constexpr int i1 = 0; +constexpr int f1() { return 0; } +struct s1 { + constexpr static int mi = 0; +}; + +// invalid declarations +// not a definition of an object +constexpr extern int i2; // x +// not a literal type +constexpr notlit nl1; // x +// function parameters +void f2(constexpr int i) {} // x +// non-static member +struct s2 { + constexpr int mi; // x +}; +// redeclaration mismatch +constexpr int f3(); // n +int f3(); // x +int f4(); // n +constexpr int f4(); // x + +// template stuff +template <typename T> +constexpr T ft(T t) { return t; } + +// specialization can differ in constepxr +template <> +notlit ft(notlit nl) { return nl; } + +constexpr int i3 = ft(1); + +void test() { + // ignore constexpr when instantiating with non-literal + notlit2 nl2; + (void)ft(nl2); +} + +// Examples from the standard: +constexpr int square(int x); +constexpr int bufsz = 1024; + +constexpr struct pixel { // x + int x; + int y; + constexpr pixel(int); +}; + +constexpr pixel::pixel(int a) + : x(square(a)), y(square(a)) + { } + +constexpr pixel small(2); // x (no definition of square(int) yet, so can't + // constexpr-eval pixel(int)) + +constexpr int square(int x) { + return x * x; +} + +constexpr pixel large(4); // now valid + +int next(constexpr int x) { // x + return x + 1; +} + +extern constexpr int memsz; // x diff --git a/test/CXX/dcl.decl/dcl.init/dcl.init.ref/p5-cxx03-extra-copy.cpp b/test/CXX/dcl.decl/dcl.init/dcl.init.ref/p5-cxx03-extra-copy.cpp index 16394110d054..ae59598f691e 100644 --- a/test/CXX/dcl.decl/dcl.init/dcl.init.ref/p5-cxx03-extra-copy.cpp +++ b/test/CXX/dcl.decl/dcl.init/dcl.init.ref/p5-cxx03-extra-copy.cpp @@ -1,9 +1,10 @@ -// RUN: %clang_cc1 -fsyntax-only -verify %s +// RUN: %clang_cc1 -fsyntax-only -fdiagnostics-show-option -verify %s // C++03 requires that we check for a copy constructor when binding a // reference to a temporary, since we are allowed to make a copy, Even // though we don't actually make that copy, make sure that we diagnose -// cases where that copy constructor is somehow unavailable. +// cases where that copy constructor is somehow unavailable. As an +// extension, this is only a warning. struct X1 { X1(); @@ -28,6 +29,7 @@ private: template<typename T> T get_value_badly() { double *dp = 0; + // The extension doesn't extend far enough to turn this error into a warning. T *tp = dp; // expected-error{{ cannot initialize a variable of type 'int *' with an lvalue of type 'double *'}} return T(); } @@ -41,7 +43,7 @@ struct X4 { // Check for "dangerous" default arguments that could cause recursion. struct X5 { X5(); - X5(const X5&, const X5& = X5()); // expected-error{{no viable constructor copying parameter of type 'X5'}} + X5(const X5&, const X5& = X5()); // expected-warning{{no viable constructor copying parameter of type 'X5'}} }; void g1(const X1&); @@ -51,11 +53,25 @@ void g4(const X4<int>&); void g5(const X5&); void test() { - g1(X1()); // expected-error{{no viable constructor copying parameter of type 'X1'}} - g2(X2()); // expected-error{{calling a private constructor of class 'X2'}} - g3(X3()); // expected-error{{no viable constructor copying parameter of type 'X3'}} + g1(X1()); // expected-warning{{no viable constructor copying parameter of type 'X1'; C++98 requires a copy constructor when binding a reference to a temporary [-Wbind-to-temporary-copy]}} + g2(X2()); // expected-warning{{C++98 requires an accessible copy constructor for class 'X2' when binding a reference to a temporary; was private [-Wbind-to-temporary-copy]}} + g3(X3()); // expected-warning{{no viable constructor copying parameter of type 'X3'}} g4(X4<int>()); - g5(X5()); // expected-error{{no viable constructor copying parameter of type 'X5'}} + g5(X5()); // Generates a warning in the default argument. } -// Check for dangerous recursion in default arguments. +// Check that unavailable copy constructors still cause SFINAE failures. +template<int> struct int_c { }; + +template<typename T> T f(const T&); + +// Would be ambiguous with the next g(), except the instantiation failure in +// sizeof() prevents that. +template<typename T> +int &g(int_c<sizeof(f(T()))> * = 0); + +template<typename T> float &g(); + +void h() { + float &fp2 = g<X3>(); // Not ambiguous. +} diff --git a/test/CXX/dcl.decl/dcl.init/dcl.init.ref/p16-cxx0x-no-extra-copy.cpp b/test/CXX/dcl.decl/dcl.init/dcl.init.ref/p5-cxx0x-no-extra-copy.cpp index 5a342d423a2d..5cfb11a1fc1b 100644 --- a/test/CXX/dcl.decl/dcl.init/dcl.init.ref/p16-cxx0x-no-extra-copy.cpp +++ b/test/CXX/dcl.decl/dcl.init/dcl.init.ref/p5-cxx0x-no-extra-copy.cpp @@ -48,3 +48,17 @@ void test() { g3(X3()); g4(X4<int>()); } + +// Check that unavailable copy constructors do not cause SFINAE failures. +template<int> struct int_c { }; + +template<typename T> T f(const T&); + +template<typename T> +int &g(int_c<sizeof(f(T()))> * = 0); // expected-note{{candidate function [with T = X3]}} + +template<typename T> float &g(); // expected-note{{candidate function [with T = X3]}} + +void h() { + float &fp = g<X3>(); // expected-error{{call to 'g' is ambiguous}} +} diff --git a/test/CXX/except/except.spec/p14-ir.cpp b/test/CXX/except/except.spec/p14-ir.cpp new file mode 100644 index 000000000000..4d8d1f7c4018 --- /dev/null +++ b/test/CXX/except/except.spec/p14-ir.cpp @@ -0,0 +1,78 @@ +// RUN: %clang_cc1 -triple x86_64-apple-darwin10 -emit-llvm -fexceptions -o - %s | FileCheck %s + +// Copy constructor +struct X0 { + X0(); + X0(const X0 &) throw(); + X0(X0 &); +}; + +struct X1 { + X1(); + X1(const X1 &) throw(); +}; + +struct X2 : X1 { + X2(); +}; +struct X3 : X0, X1 { + X3(); +}; + +struct X4 { + X4(X4 &) throw(); +}; + +struct X5 : X0, X4 { }; + +void test(X2 x2, X3 x3, X5 x5) { + // CHECK: define linkonce_odr void @_ZN2X2C1ERKS_ + // CHECK: call void @_ZN2X2C2ERKS_({{.*}}) nounwind + // CHECK-NEXT: ret void + // CHECK-NEXT: } + X2 x2a(x2); + // CHECK: define linkonce_odr void @_ZN2X3C1ERKS_ + // CHECK: call void @_ZN2X3C2ERKS_({{.*}}) nounwind + // CHECK-NEXT: ret void + // CHECK-NEXT: } + X3 x3a(x3); + // CHECK: define linkonce_odr void @_ZN2X5C1ERS_ + // CHECK-NOT: call void @__cxa_call_unexpected + // CHECK: ret void + X5 x5a(x5); +} + +// Default constructor +struct X6 { + X6() throw(); +}; + +struct X7 { + X7(); +}; + +struct X8 : X6 { }; +struct X9 : X6, X7 { }; + +void test() { + // CHECK: define linkonce_odr void @_ZN2X8C1Ev + // CHECK: call void @_ZN2X8C2Ev({{.*}}) nounwind + // CHECK-NEXT: ret void + X8(); + + // CHECK: define linkonce_odr void @_ZN2X9C1Ev + // FIXME: check that this is the end of the line here: + // CHECK: call void @_ZN2X9C2Ev({{.*}}) + // CHECK-NEXT: ret void + X9(); + + // CHECK: define linkonce_odr void @_ZN2X9C2Ev + // CHECK: call void @_ZN2X6C2Ev({{.*}}) nounwind + // FIXME: and here: + // CHECK-NEXT: call void @_ZN2X7C2Ev({{.*}}) + // CHECK: ret void + + // CHECK: define linkonce_odr void @_ZN2X8C2Ev + // CHECK: call void @_ZN2X6C2Ev({{.*}}) nounwind + // CHECK-NEXT: ret void +} diff --git a/test/CXX/except/except.spec/p14.cpp b/test/CXX/except/except.spec/p14.cpp new file mode 100644 index 000000000000..9450b1cf80d7 --- /dev/null +++ b/test/CXX/except/except.spec/p14.cpp @@ -0,0 +1,29 @@ +// RUN: %clang_cc1 -fexceptions -verify %s +struct A { }; +struct B { }; +struct C { }; + +// Destructor +struct X0 { + virtual ~X0() throw(A); // expected-note{{overridden virtual function is here}} +}; +struct X1 { + virtual ~X1() throw(B); // expected-note{{overridden virtual function is here}} +}; +struct X2 : public X0, public X1 { }; // expected-error 2{{exception specification of overriding function is more lax than base version}} + +// Copy-assignment operator. +struct CA0 { + CA0 &operator=(const CA0&) throw(A); +}; +struct CA1 { + CA1 &operator=(const CA1&) throw(B); +}; +struct CA2 : CA0, CA1 { }; + +void test_CA() { + CA2 &(CA2::*captr1)(const CA2&) throw(A, B) = &CA2::operator=; + CA2 &(CA2::*captr2)(const CA2&) throw(A, B, C) = &CA2::operator=; + CA2 &(CA2::*captr3)(const CA2&) throw(A) = &CA2::operator=; // expected-error{{target exception specification is not superset of source}} + CA2 &(CA2::*captr4)(const CA2&) throw(B) = &CA2::operator=; // expected-error{{target exception specification is not superset of source}} +} diff --git a/test/CXX/special/class.copy/p20.cpp b/test/CXX/special/class.copy/p20.cpp new file mode 100644 index 000000000000..8dfb7ca8a068 --- /dev/null +++ b/test/CXX/special/class.copy/p20.cpp @@ -0,0 +1,46 @@ +// RUN: %clang_cc1 -fsyntax-only -verify %s + +struct ConstCopy { + ConstCopy(); + ConstCopy &operator=(const ConstCopy&); +}; + +struct NonConstCopy { + NonConstCopy(); + NonConstCopy &operator=(NonConstCopy&); +}; + +struct VirtualInheritsNonConstCopy : virtual NonConstCopy { + VirtualInheritsNonConstCopy(); + VirtualInheritsNonConstCopy &operator=(const VirtualInheritsNonConstCopy&); +}; + +struct ImplicitNonConstCopy1 : NonConstCopy { // expected-note{{the implicit copy assignment operator}} + ImplicitNonConstCopy1(); +}; + +struct ImplicitNonConstCopy2 { // expected-note{{the implicit copy assignment operator}} + ImplicitNonConstCopy2(); + NonConstCopy ncc; +}; + +struct ImplicitNonConstCopy3 { // expected-note{{the implicit copy assignment operator}} + ImplicitNonConstCopy3(); + NonConstCopy ncc_array[2][3]; +}; + +struct ImplicitNonConstCopy4 : VirtualInheritsNonConstCopy { + ImplicitNonConstCopy4(); +}; + +void test_non_const_copy(const ImplicitNonConstCopy1 &cincc1, + const ImplicitNonConstCopy2 &cincc2, + const ImplicitNonConstCopy3 &cincc3, + const ImplicitNonConstCopy4 &cincc4, + const VirtualInheritsNonConstCopy &vincc) { + (void)sizeof(ImplicitNonConstCopy1() = cincc1); // expected-error{{no viable overloaded '='}} + (void)sizeof(ImplicitNonConstCopy2() = cincc2); // expected-error{{no viable overloaded '='}} + (void)sizeof(ImplicitNonConstCopy3() = cincc3); // expected-error{{no viable overloaded '='}} + (void)sizeof(ImplicitNonConstCopy4() = cincc4); // okay + (void)sizeof(VirtualInheritsNonConstCopy() = vincc); +} diff --git a/test/CXX/special/class.copy/p9.cpp b/test/CXX/special/class.copy/p9.cpp new file mode 100644 index 000000000000..d03794420e01 --- /dev/null +++ b/test/CXX/special/class.copy/p9.cpp @@ -0,0 +1,44 @@ +// RUN: %clang_cc1 -fsyntax-only -verify %s + +struct ConstCopy { + ConstCopy(); + ConstCopy(const ConstCopy&); +}; + +struct NonConstCopy { + NonConstCopy(); + NonConstCopy(NonConstCopy&); +}; + +struct VirtualInheritsNonConstCopy : virtual NonConstCopy { + VirtualInheritsNonConstCopy(); + VirtualInheritsNonConstCopy(const VirtualInheritsNonConstCopy&); +}; + +struct ImplicitNonConstCopy1 : NonConstCopy { + ImplicitNonConstCopy1(); +}; + +struct ImplicitNonConstCopy2 { + ImplicitNonConstCopy2(); + NonConstCopy ncc; +}; + +struct ImplicitNonConstCopy3 { + ImplicitNonConstCopy3(); + NonConstCopy ncc_array[2][3]; +}; + +struct ImplicitNonConstCopy4 : VirtualInheritsNonConstCopy { + ImplicitNonConstCopy4(); +}; + +void test_non_const_copy(const ImplicitNonConstCopy1 &cincc1, + const ImplicitNonConstCopy2 &cincc2, + const ImplicitNonConstCopy3 &cincc3, + const ImplicitNonConstCopy4 &cincc4) { + (void)sizeof(ImplicitNonConstCopy1(cincc1)); // expected-error{{functional-style cast from 'ImplicitNonConstCopy1 const' to 'ImplicitNonConstCopy1' is not allowed}} + (void)sizeof(ImplicitNonConstCopy2(cincc2)); // expected-error{{functional-style cast from 'ImplicitNonConstCopy2 const' to 'ImplicitNonConstCopy2' is not allowed}} + (void)sizeof(ImplicitNonConstCopy3(cincc3)); // expected-error{{functional-style cast from 'ImplicitNonConstCopy3 const' to 'ImplicitNonConstCopy3' is not allowed}} + (void)sizeof(ImplicitNonConstCopy4(cincc4)); // expected-error{{functional-style cast from 'ImplicitNonConstCopy4 const' to 'ImplicitNonConstCopy4' is not allowed}} +} diff --git a/test/CXX/temp/temp.decls/temp.variadic/parameter-matching.cpp b/test/CXX/temp/temp.decls/temp.variadic/parameter-matching.cpp new file mode 100644 index 000000000000..7352be2d72f0 --- /dev/null +++ b/test/CXX/temp/temp.decls/temp.variadic/parameter-matching.cpp @@ -0,0 +1,21 @@ +// RUN: %clang_cc1 -std=c++0x -fsyntax-only -verify %s + +// Check for template type parameter pack (mis-)matches with template +// type parameters. +template<typename ...T> struct X0t; +template<typename ...T> struct X0t; + +template<typename ...T> struct X1t; // expected-note{{previous template type parameter pack declared here}} +template<typename T> struct X1t; // expected-error{{template type parameter conflicts with previous template type parameter pack}} + +template<typename T> struct X2t; // expected-note{{previous template type parameter declared here}} +template<typename ...T> struct X2t; // expected-error{{template type parameter pack conflicts with previous template type parameter}} + +template<template<typename ...T> class> struct X0tt; +template<template<typename ...T> class> struct X0tt; + +template<template<typename ...T> class> struct X1tt; // expected-note{{previous template type parameter pack declared here}} +template<template<typename T> class> struct X1tt; // expected-error{{template type parameter conflicts with previous template type parameter pack}} + +template<template<typename T> class> struct X2tt; // expected-note{{previous template type parameter declared here}} +template<template<typename ...T> class> struct X2tt; // expected-error{{template type parameter pack conflicts with previous template type parameter}} diff --git a/test/CXX/temp/temp.param/p2.cpp b/test/CXX/temp/temp.param/p2.cpp index 41868c5c1ac7..fed6e9c266be 100644 --- a/test/CXX/temp/temp.param/p2.cpp +++ b/test/CXX/temp/temp.param/p2.cpp @@ -14,4 +14,9 @@ template<typename T, typename X<T>::type Value> struct Y1; // A storage class shall not be specified in a template-parameter declaration. template<static int Value> struct Z; // FIXME: expect an error +// Make sure that we properly disambiguate non-type template parameters that +// start with 'class'. +class X1 { }; +template<class X1 *xptr> struct Y2 { }; + // FIXME: add the example from p2 diff --git a/test/CXX/temp/temp.spec/temp.explicit/p11.cpp b/test/CXX/temp/temp.spec/temp.explicit/p11.cpp new file mode 100644 index 000000000000..4ca54283157b --- /dev/null +++ b/test/CXX/temp/temp.spec/temp.explicit/p11.cpp @@ -0,0 +1,18 @@ +// RUN: %clang_cc1 -fsyntax-only -verify %s + +class X { + template <typename T> class Y {}; +}; + +class A { + class B {}; + class C {}; +}; + +// C++0x [temp.explicit] 14.7.2/11: +// The usual access checking rules do not apply to names used to specify +// explicit instantiations. +template class X::Y<A::B>; + +// As an extension, this rule is applied to explicit specializations as well. +template <> class X::Y<A::C> {}; diff --git a/test/CXX/temp/temp.spec/temp.explicit/p2.cpp b/test/CXX/temp/temp.spec/temp.explicit/p2.cpp index 0da316cc9cef..70d338b9f645 100644 --- a/test/CXX/temp/temp.spec/temp.explicit/p2.cpp +++ b/test/CXX/temp/temp.spec/temp.explicit/p2.cpp @@ -25,9 +25,9 @@ T X0<T>::value = 17; typedef X0<int> XInt; -template struct XInt::Inner; // expected-error{{template-id}} -template void XInt::f(); // expected-error{{template-id}} -template int XInt::value; // expected-error{{template-id}} +template struct XInt::Inner; // expected-warning{{template-id}} +template void XInt::f(); // expected-warning{{template-id}} +template int XInt::value; // expected-warning{{template-id}} namespace N { template<typename T> diff --git a/test/CXX/temp/temp.spec/temp.explicit/p9-linkage.cpp b/test/CXX/temp/temp.spec/temp.explicit/p9-linkage.cpp index e67233c37547..57b012f9a946 100644 --- a/test/CXX/temp/temp.spec/temp.explicit/p9-linkage.cpp +++ b/test/CXX/temp/temp.spec/temp.explicit/p9-linkage.cpp @@ -1,4 +1,4 @@ -// RUN: %clang_cc1 -emit-llvm -std=c++0x -o - %s | FileCheck %s +// RUN: %clang_cc1 -O1 -emit-llvm -std=c++0x -o - %s | FileCheck %s template<typename T> struct X0 { |
