diff options
Diffstat (limited to 'test/CXX/drs')
-rw-r--r-- | test/CXX/drs/dr0xx.cpp | 40 | ||||
-rw-r--r-- | test/CXX/drs/dr10xx.cpp | 21 | ||||
-rw-r--r-- | test/CXX/drs/dr13xx.cpp | 3 | ||||
-rw-r--r-- | test/CXX/drs/dr14xx.cpp | 3 | ||||
-rw-r--r-- | test/CXX/drs/dr15xx.cpp | 7 | ||||
-rw-r--r-- | test/CXX/drs/dr16xx.cpp | 19 | ||||
-rw-r--r-- | test/CXX/drs/dr18xx.cpp | 24 | ||||
-rw-r--r-- | test/CXX/drs/dr1xx.cpp | 7 | ||||
-rw-r--r-- | test/CXX/drs/dr2xx.cpp | 46 | ||||
-rw-r--r-- | test/CXX/drs/dr3xx.cpp | 40 | ||||
-rw-r--r-- | test/CXX/drs/dr412.cpp | 3 | ||||
-rw-r--r-- | test/CXX/drs/dr4xx.cpp | 19 | ||||
-rw-r--r-- | test/CXX/drs/dr5xx.cpp | 785 | ||||
-rw-r--r-- | test/CXX/drs/dr6xx.cpp | 349 | ||||
-rw-r--r-- | test/CXX/drs/dr9xx.cpp | 3 |
15 files changed, 1313 insertions, 56 deletions
diff --git a/test/CXX/drs/dr0xx.cpp b/test/CXX/drs/dr0xx.cpp index 29e1720..5b34cc3 100644 --- a/test/CXX/drs/dr0xx.cpp +++ b/test/CXX/drs/dr0xx.cpp @@ -1,6 +1,7 @@ // RUN: %clang_cc1 -std=c++98 %s -verify -fexceptions -fcxx-exceptions -pedantic-errors -Wno-bind-to-temporary-copy // RUN: %clang_cc1 -std=c++11 %s -verify -fexceptions -fcxx-exceptions -pedantic-errors -// RUN: %clang_cc1 -std=c++1y %s -verify -fexceptions -fcxx-exceptions -pedantic-errors +// RUN: %clang_cc1 -std=c++14 %s -verify -fexceptions -fcxx-exceptions -pedantic-errors +// RUN: %clang_cc1 -std=c++1z %s -verify -fexceptions -fcxx-exceptions -pedantic-errors namespace dr1 { // dr1: no namespace X { extern "C" void dr1_f(int a = 1); } @@ -520,17 +521,28 @@ namespace dr48 { // dr48: yes } namespace dr49 { // dr49: yes - template<int*> struct A {}; // expected-note {{here}} + template<int*> struct A {}; // expected-note 0-2{{here}} int k; #if __has_feature(cxx_constexpr) constexpr #endif - int *const p = &k; + int *const p = &k; // expected-note 0-2{{here}} A<&k> a; - A<p> b; // expected-error {{must have its address taken}} + A<p> b; +#if __cplusplus <= 201402L + // expected-error@-2 {{must have its address taken}} +#endif +#if __cplusplus < 201103L + // expected-error@-5 {{internal linkage}} +#endif + int *q = &k; + A<q> c; #if __cplusplus < 201103L - // expected-error@-2 {{internal linkage}} - // expected-note@-5 {{here}} + // expected-error@-2 {{must have its address taken}} +#else + // expected-error@-4 {{constant expression}} + // expected-note@-5 {{read of non-constexpr}} + // expected-note@-7 {{declared here}} #endif } @@ -822,7 +834,7 @@ namespace dr70 { // dr70: yes namespace dr73 { // dr73: no // The resolution to dr73 is unworkable. Consider: int a, b; - static_assert(&a + 1 != &b, ""); + static_assert(&a + 1 != &b, ""); // expected-error {{not an integral constant expression}} } #endif @@ -852,7 +864,7 @@ namespace dr77 { // dr77: yes namespace dr78 { // dr78: sup ???? // Under DR78, this is valid, because 'k' has static storage duration, so is // zero-initialized. - const int k; // expected-error {{default initialization of an object of const}} + const int k; // expected-error {{default initialization of an object of const}} expected-note{{add an explicit initializer to initialize 'k'}} } // dr79: na @@ -994,6 +1006,10 @@ namespace dr92 { // dr92: yes g(q); // expected-error {{is not superset}} } + // Prior to C++17, this is OK because the exception specification is not + // considered in this context. In C++17, we *do* perform an implicit + // conversion (which performs initialization), but we convert to the type of + // the template parameter, which does not include the exception specification. template<void() throw()> struct X {}; X<&f> xp; // ok } @@ -1051,18 +1067,18 @@ namespace dr98 { // dr98: yes void test(int n) { switch (n) { try { // expected-note 2{{bypasses}} - case 0: // expected-error {{protected}} + case 0: // expected-error {{cannot jump}} x: throw n; } catch (...) { // expected-note 2{{bypasses}} - case 1: // expected-error {{protected}} + case 1: // expected-error {{cannot jump}} y: throw n; } case 2: - goto x; // expected-error {{protected}} + goto x; // expected-error {{cannot jump}} case 3: - goto y; // expected-error {{protected}} + goto y; // expected-error {{cannot jump}} } } } diff --git a/test/CXX/drs/dr10xx.cpp b/test/CXX/drs/dr10xx.cpp index 64c71b2..a1d7ef6 100644 --- a/test/CXX/drs/dr10xx.cpp +++ b/test/CXX/drs/dr10xx.cpp @@ -1,6 +1,7 @@ // RUN: %clang_cc1 -std=c++98 %s -verify -fexceptions -fcxx-exceptions -pedantic-errors // RUN: %clang_cc1 -std=c++11 %s -verify -fexceptions -fcxx-exceptions -pedantic-errors -// RUN: %clang_cc1 -std=c++1y %s -verify -fexceptions -fcxx-exceptions -pedantic-errors +// RUN: %clang_cc1 -std=c++14 %s -verify -fexceptions -fcxx-exceptions -pedantic-errors +// RUN: %clang_cc1 -std=c++1z %s -verify -fexceptions -fcxx-exceptions -pedantic-errors // expected-no-diagnostics @@ -13,6 +14,24 @@ namespace std { }; } +namespace dr1048 { // dr1048: 3.6 + struct A {}; + const A f(); + A g(); + typedef const A CA; +#if __cplusplus >= 201103L + // ok: we deduce non-const A in each case. + A &&a = [] (int n) { + while (1) switch (n) { + case 0: return f(); + case 1: return g(); + case 2: return A(); + case 3: return CA(); + } + } (0); +#endif +} + namespace dr1070 { // dr1070: 3.5 #if __cplusplus >= 201103L struct A { diff --git a/test/CXX/drs/dr13xx.cpp b/test/CXX/drs/dr13xx.cpp index 5827291..29b39cb 100644 --- a/test/CXX/drs/dr13xx.cpp +++ b/test/CXX/drs/dr13xx.cpp @@ -1,6 +1,7 @@ // RUN: %clang_cc1 -std=c++98 %s -verify -fexceptions -fcxx-exceptions -pedantic-errors // RUN: %clang_cc1 -std=c++11 %s -verify -fexceptions -fcxx-exceptions -pedantic-errors -// RUN: %clang_cc1 -std=c++1y %s -verify -fexceptions -fcxx-exceptions -pedantic-errors +// RUN: %clang_cc1 -std=c++14 %s -verify -fexceptions -fcxx-exceptions -pedantic-errors +// RUN: %clang_cc1 -std=c++1z %s -verify -fexceptions -fcxx-exceptions -pedantic-errors namespace dr1346 { // dr1346: 3.5 auto a(1); // expected-error 0-1{{extension}} diff --git a/test/CXX/drs/dr14xx.cpp b/test/CXX/drs/dr14xx.cpp index 8de1b8d..e931924 100644 --- a/test/CXX/drs/dr14xx.cpp +++ b/test/CXX/drs/dr14xx.cpp @@ -1,6 +1,7 @@ // RUN: %clang_cc1 -std=c++98 %s -verify -fexceptions -fcxx-exceptions -pedantic-errors // RUN: %clang_cc1 -std=c++11 %s -verify -fexceptions -fcxx-exceptions -pedantic-errors -// RUN: %clang_cc1 -std=c++1y %s -verify -fexceptions -fcxx-exceptions -pedantic-errors +// RUN: %clang_cc1 -std=c++14 %s -verify -fexceptions -fcxx-exceptions -pedantic-errors +// RUN: %clang_cc1 -std=c++1z %s -verify -fexceptions -fcxx-exceptions -pedantic-errors #if __cplusplus < 201103L // expected-no-diagnostics diff --git a/test/CXX/drs/dr15xx.cpp b/test/CXX/drs/dr15xx.cpp index 66618c1..d7c2b92 100644 --- a/test/CXX/drs/dr15xx.cpp +++ b/test/CXX/drs/dr15xx.cpp @@ -1,16 +1,17 @@ // RUN: %clang_cc1 -std=c++98 -triple x86_64-unknown-unknown %s -verify -fexceptions -fcxx-exceptions -pedantic-errors // RUN: %clang_cc1 -std=c++11 -triple x86_64-unknown-unknown %s -verify -fexceptions -fcxx-exceptions -pedantic-errors -// RUN: %clang_cc1 -std=c++1y -triple x86_64-unknown-unknown %s -verify -fexceptions -fcxx-exceptions -pedantic-errors +// RUN: %clang_cc1 -std=c++14 -triple x86_64-unknown-unknown %s -verify -fexceptions -fcxx-exceptions -pedantic-errors +// RUN: %clang_cc1 -std=c++1z -triple x86_64-unknown-unknown %s -verify -fexceptions -fcxx-exceptions -pedantic-errors // expected-no-diagnostics -namespace DR1550 { // dr1550: yes +namespace dr1550 { // dr1550: yes int f(bool b, int n) { return (b ? (throw 0) : n) + (b ? n : (throw 0)); } } -namespace DR1560 { // dr1560: 3.5 +namespace dr1560 { // dr1560: 3.5 void f(bool b, int n) { (b ? throw 0 : n) = (b ? n : throw 0) = 0; } diff --git a/test/CXX/drs/dr16xx.cpp b/test/CXX/drs/dr16xx.cpp new file mode 100644 index 0000000..62040f1 --- /dev/null +++ b/test/CXX/drs/dr16xx.cpp @@ -0,0 +1,19 @@ +// RUN: %clang_cc1 -std=c++98 -triple x86_64-unknown-unknown %s -verify -fexceptions -fcxx-exceptions -pedantic-errors +// RUN: %clang_cc1 -std=c++11 -triple x86_64-unknown-unknown %s -verify -fexceptions -fcxx-exceptions -pedantic-errors +// RUN: %clang_cc1 -std=c++14 -triple x86_64-unknown-unknown %s -verify -fexceptions -fcxx-exceptions -pedantic-errors +// RUN: %clang_cc1 -std=c++1z -triple x86_64-unknown-unknown %s -verify -fexceptions -fcxx-exceptions -pedantic-errors + +#if __cplusplus < 201103L +// expected-no-diagnostics +#endif + +namespace dr1684 { // dr1684: 3.6 +#if __cplusplus >= 201103L + struct NonLiteral { // expected-note {{because}} + NonLiteral(); + constexpr int f() { return 0; } // expected-warning 0-1{{will not be implicitly 'const'}} + }; + constexpr int f(NonLiteral &) { return 0; } + constexpr int f(NonLiteral) { return 0; } // expected-error {{not a literal type}} +#endif +} diff --git a/test/CXX/drs/dr18xx.cpp b/test/CXX/drs/dr18xx.cpp new file mode 100644 index 0000000..bc72b67 --- /dev/null +++ b/test/CXX/drs/dr18xx.cpp @@ -0,0 +1,24 @@ +// RUN: %clang_cc1 -std=c++98 -triple x86_64-unknown-unknown %s -verify -fexceptions -fcxx-exceptions -pedantic-errors +// RUN: %clang_cc1 -std=c++11 -triple x86_64-unknown-unknown %s -verify -fexceptions -fcxx-exceptions -pedantic-errors +// RUN: %clang_cc1 -std=c++14 -triple x86_64-unknown-unknown %s -verify -fexceptions -fcxx-exceptions -pedantic-errors +// RUN: %clang_cc1 -std=c++1z -triple x86_64-unknown-unknown %s -verify -fexceptions -fcxx-exceptions -pedantic-errors + +#if __cplusplus < 201103L +// expected-no-diagnostics +#endif + +void dr1891() { // dr1891: 3.6 +#if __cplusplus >= 201103L + int n; + auto a = []{}; // expected-note 2{{candidate}} + auto b = [=]{ return n; }; // expected-note 2{{candidate}} + typedef decltype(a) A; + typedef decltype(b) B; + + static_assert(!__has_trivial_constructor(A), ""); + static_assert(!__has_trivial_constructor(B), ""); + + A x; // expected-error {{no matching constructor}} + B y; // expected-error {{no matching constructor}} +#endif +} diff --git a/test/CXX/drs/dr1xx.cpp b/test/CXX/drs/dr1xx.cpp index 6aff43c..cc6c5af 100644 --- a/test/CXX/drs/dr1xx.cpp +++ b/test/CXX/drs/dr1xx.cpp @@ -1,10 +1,11 @@ // RUN: %clang_cc1 -std=c++98 -triple x86_64-unknown-unknown %s -verify -fexceptions -fcxx-exceptions -pedantic-errors // RUN: %clang_cc1 -std=c++11 -triple x86_64-unknown-unknown %s -verify -fexceptions -fcxx-exceptions -pedantic-errors -// RUN: %clang_cc1 -std=c++1y -triple x86_64-unknown-unknown %s -verify -fexceptions -fcxx-exceptions -pedantic-errors +// RUN: %clang_cc1 -std=c++14 -triple x86_64-unknown-unknown %s -verify -fexceptions -fcxx-exceptions -pedantic-errors +// RUN: %clang_cc1 -std=c++1z -triple x86_64-unknown-unknown %s -verify -fexceptions -fcxx-exceptions -pedantic-errors namespace dr100 { // dr100: yes - template<const char *> struct A {}; // expected-note {{declared here}} - template<const char (&)[4]> struct B {}; // expected-note {{declared here}} + template<const char *> struct A {}; // expected-note 0-1{{declared here}} + template<const char (&)[4]> struct B {}; // expected-note 0-1{{declared here}} A<"foo"> a; // expected-error {{does not refer to any declaration}} B<"bar"> b; // expected-error {{does not refer to any declaration}} } diff --git a/test/CXX/drs/dr2xx.cpp b/test/CXX/drs/dr2xx.cpp index bb9af9f..bb1f13a 100644 --- a/test/CXX/drs/dr2xx.cpp +++ b/test/CXX/drs/dr2xx.cpp @@ -1,6 +1,7 @@ // RUN: %clang_cc1 -std=c++98 %s -verify -fexceptions -fcxx-exceptions -pedantic-errors // RUN: %clang_cc1 -std=c++11 %s -verify -fexceptions -fcxx-exceptions -pedantic-errors -// RUN: %clang_cc1 -std=c++1y %s -verify -fexceptions -fcxx-exceptions -pedantic-errors +// RUN: %clang_cc1 -std=c++14 %s -verify -fexceptions -fcxx-exceptions -pedantic-errors +// RUN: %clang_cc1 -std=c++1z %s -verify -fexceptions -fcxx-exceptions -pedantic-errors // PR13819 -- __SIZE_TYPE__ is incompatible. typedef __SIZE_TYPE__ size_t; // expected-error 0-1 {{extension}} @@ -195,8 +196,8 @@ namespace dr218 { // dr218: yes // dr220: na namespace dr221 { // dr221: yes - struct A { - A &operator=(int&); + struct A { // expected-note 2-4{{candidate}} + A &operator=(int&); // expected-note 2{{candidate}} A &operator+=(int&); static A &operator=(A&, double&); // expected-error {{cannot be a static member}} static A &operator+=(A&, double&); // expected-error {{cannot be a static member}} @@ -209,9 +210,9 @@ namespace dr221 { // dr221: yes void test(A a, int n, char c, float f) { a = n; a += n; - a = c; + a = c; // expected-error {{no viable}} a += c; - a = f; + a = f; // expected-error {{no viable}} a += f; } } @@ -466,7 +467,7 @@ namespace dr243 { // dr243: yes A a2 = b; // expected-error {{ambiguous}} } -namespace dr244 { // dr244: 3.5 +namespace dr244 { // dr244: partial struct B {}; struct D : B {}; // expected-note {{here}} D D_object; @@ -484,6 +485,28 @@ namespace dr244 { // dr244: 3.5 B_ptr->dr244::~B(); // expected-error {{refers to a member in namespace}} B_ptr->dr244::~B_alias(); // expected-error {{refers to a member in namespace}} } + + namespace N { + template<typename T> struct E {}; + typedef E<int> F; + } + void g(N::F f) { + typedef N::F G; + f.~G(); + f.G::~E(); + f.G::~F(); // expected-error {{expected the class name after '~' to name a destructor}} + f.G::~G(); + // This is technically ill-formed; E is looked up in 'N::' and names the + // class template, not the injected-class-name of the class. But that's + // probably a bug in the standard. + f.N::F::~E(); + // This is valid; we look up the second F in the same scope in which we + // found the first one, that is, 'N::'. + f.N::F::~F(); // FIXME: expected-error {{expected the class name after '~' to name a destructor}} + // This is technically ill-formed; G is looked up in 'N::' and is not found; + // as above, this is probably a bug in the standard. + f.N::F::~G(); + } } namespace dr245 { // dr245: yes @@ -499,7 +522,7 @@ namespace dr246 { // dr246: yes throw 0; X: ; } catch (int) { - goto X; // expected-error {{protected scope}} + goto X; // expected-error {{cannot jump}} } }; } @@ -968,12 +991,11 @@ namespace dr289 { // dr289: yes namespace dr294 { // dr294: no void f() throw(int); int main() { - // FIXME: we reject this for the wrong reason, because we don't implement - // dr87 yet. - (void)static_cast<void (*)() throw()>(f); // expected-error {{not superset}} - void (*p)() throw() = f; // expected-error {{not superset}} - + (void)static_cast<void (*)() throw()>(f); // FIXME: ill-formed (void)static_cast<void (*)() throw(int)>(f); // FIXME: ill-formed + + void (*p)() throw() = f; // expected-error {{not superset}} + void (*q)() throw(int) = f; } } diff --git a/test/CXX/drs/dr3xx.cpp b/test/CXX/drs/dr3xx.cpp index 53fc20e..cea4d64 100644 --- a/test/CXX/drs/dr3xx.cpp +++ b/test/CXX/drs/dr3xx.cpp @@ -1,6 +1,7 @@ // RUN: %clang_cc1 -std=c++98 %s -verify -fexceptions -fcxx-exceptions -pedantic-errors // RUN: %clang_cc1 -std=c++11 %s -verify -fexceptions -fcxx-exceptions -pedantic-errors -// RUN: %clang_cc1 -std=c++1y %s -verify -fexceptions -fcxx-exceptions -pedantic-errors +// RUN: %clang_cc1 -std=c++14 %s -verify -fexceptions -fcxx-exceptions -pedantic-errors +// RUN: %clang_cc1 -std=c++1z %s -verify -fexceptions -fcxx-exceptions -pedantic-errors namespace dr300 { // dr300: yes template<typename R, typename A> void f(R (&)(A)) {} @@ -181,9 +182,15 @@ namespace dr308 { // dr308: yes namespace dr311 { // dr311: yes namespace X { namespace Y {} } - namespace X::Y {} // expected-error {{must define each namespace separately}} + namespace X::Y {} +#if __cplusplus <= 201402L + // expected-error@-2 {{define each namespace separately}} +#endif namespace X { - namespace X::Y {} // expected-error {{must define each namespace separately}} + namespace X::Y {} +#if __cplusplus <= 201402L + // expected-error@-2 {{define each namespace separately}} +#endif } // FIXME: The diagnostics here are not very good. namespace ::dr311::X {} // expected-error 2+{{}} // expected-warning {{extra qual}} @@ -199,7 +206,7 @@ namespace dr313 { // dr313: dup 299 c++11 #endif } -namespace dr314 { // dr314: dup 1710 +namespace dr314 { // FIXME 314: dup 1710 template<typename T> struct A { template<typename U> struct B {}; }; @@ -322,6 +329,7 @@ namespace dr324 { // dr324: yes int *f = &(true ? s.n : s.n); // expected-error {{address of bit-field}} int &g = (void(), s.n); // expected-error {{non-const reference cannot bind to bit-field}} int *h = &(void(), s.n); // expected-error {{address of bit-field}} + int *i = &++s.n; // expected-error {{address of bit-field}} } namespace dr326 { // dr326: yes @@ -365,7 +373,7 @@ namespace dr331 { // dr331: yes } const a, b(a); // expected-error {{no matching constructor}} } -namespace dr332 { // dr332: dup 557 +namespace dr332 { // dr332: dup 577 void f(volatile void); // expected-error {{'void' as parameter must not have type qualifiers}} void g(const void); // expected-error {{'void' as parameter must not have type qualifiers}} void h(int n, volatile void); // expected-error {{'void' must be the first and only parameter}} @@ -497,7 +505,7 @@ namespace dr341 { // dr342: na -namespace dr343 { // dr343: no +namespace dr343 { // FIXME 343: no // FIXME: dup 1710 template<typename T> struct A { template<typename U> struct B {}; @@ -697,7 +705,7 @@ namespace dr354 { // dr354: yes c++11 // FIXME: Should we allow this in C++98 too? struct S {}; - template<int*> struct ptr {}; // expected-note +{{here}} + template<int*> struct ptr {}; // expected-note 0-4{{here}} ptr<0> p0; ptr<(int*)0> p1; ptr<(float*)0> p2; @@ -707,11 +715,16 @@ namespace dr354 { // dr354: yes c++11 // expected-error@-5 {{does not refer to any decl}} // expected-error@-5 {{does not refer to any decl}} // expected-error@-5 {{does not refer to any decl}} -#else +#elif __cplusplus <= 201402L // expected-error@-10 {{must be cast}} // ok // expected-error@-10 {{does not match}} // expected-error@-10 {{does not match}} +#else + // expected-error@-15 {{conversion from 'int' to 'int *' is not allowed}} + // ok + // expected-error@-15 {{'float *' is not implicitly convertible to 'int *'}} + // expected-error@-15 {{'int dr354::S::*' is not implicitly convertible to 'int *'}} #endif template<int*> int both(); @@ -724,7 +737,7 @@ namespace dr354 { // dr354: yes c++11 // expected-note@-6 {{candidate}} #endif - template<int S::*> struct ptr_mem {}; // expected-note +{{here}} + template<int S::*> struct ptr_mem {}; // expected-note 0-4{{here}} ptr_mem<0> m0; ptr_mem<(int S::*)0> m1; ptr_mem<(float S::*)0> m2; @@ -734,11 +747,16 @@ namespace dr354 { // dr354: yes c++11 // expected-error@-5 {{is not a pointer to member constant}} // expected-error@-5 {{cannot be converted}} // expected-error@-5 {{cannot be converted}} -#else +#elif __cplusplus <= 201402L // expected-error@-10 {{must be cast}} // ok // expected-error@-10 {{does not match}} // expected-error@-10 {{does not match}} +#else + // expected-error@-15 {{conversion from 'int' to 'int dr354::S::*' is not allowed}} + // ok + // expected-error@-15 {{'float dr354::S::*' is not implicitly convertible to 'int dr354::S::*'}} + // expected-error@-15 {{'int *' is not implicitly convertible to 'int dr354::S::*'}} #endif } @@ -1201,7 +1219,7 @@ namespace dr391 { // dr391: yes c++11 namespace dr395 { // dr395: yes struct S { - template <typename T, int N>(&operator T())[N]; // expected-error {{must use a typedef}} + template <typename T, int N>(&operator T())[N]; // expected-error {{cannot specify any part of a return type}} template <typename T, int N> operator(T (&)[N])(); // expected-error {{expected ')'}} expected-note {{to match this '('}} expected-error +{{}} template <typename T> operator T *() const { return 0; } template <typename T, typename U> operator T U::*() const { return 0; } diff --git a/test/CXX/drs/dr412.cpp b/test/CXX/drs/dr412.cpp index cb33e20..39cdd61 100644 --- a/test/CXX/drs/dr412.cpp +++ b/test/CXX/drs/dr412.cpp @@ -1,6 +1,7 @@ // RUN: %clang_cc1 -std=c++98 %s -verify -fexceptions -fcxx-exceptions -pedantic-errors -DNOEXCEPT="throw()" -DBAD_ALLOC="throw(std::bad_alloc)" // RUN: %clang_cc1 -std=c++11 %s -verify -fexceptions -fcxx-exceptions -pedantic-errors -DNOEXCEPT=noexcept -DBAD_ALLOC= -// RUN: %clang_cc1 -std=c++1y %s -verify -fexceptions -fcxx-exceptions -pedantic-errors -DNOEXCEPT=noexcept -DBAD_ALLOC= +// RUN: %clang_cc1 -std=c++14 %s -verify -fexceptions -fcxx-exceptions -pedantic-errors -DNOEXCEPT=noexcept -DBAD_ALLOC= +// RUN: %clang_cc1 -std=c++1z %s -verify -fexceptions -fcxx-exceptions -pedantic-errors -DNOEXCEPT=noexcept -DBAD_ALLOC= // dr412: yes // lwg404: yes diff --git a/test/CXX/drs/dr4xx.cpp b/test/CXX/drs/dr4xx.cpp index 815dbfc..42c6774 100644 --- a/test/CXX/drs/dr4xx.cpp +++ b/test/CXX/drs/dr4xx.cpp @@ -1,6 +1,7 @@ // RUN: env ASAN_OPTIONS=detect_stack_use_after_return=0 %clang_cc1 -std=c++98 %s -verify -fexceptions -fcxx-exceptions -pedantic-errors // RUN: env ASAN_OPTIONS=detect_stack_use_after_return=0 %clang_cc1 -std=c++11 %s -verify -fexceptions -fcxx-exceptions -pedantic-errors -// RUN: env ASAN_OPTIONS=detect_stack_use_after_return=0 %clang_cc1 -std=c++1y %s -verify -fexceptions -fcxx-exceptions -pedantic-errors +// RUN: env ASAN_OPTIONS=detect_stack_use_after_return=0 %clang_cc1 -std=c++14 %s -verify -fexceptions -fcxx-exceptions -pedantic-errors +// RUN: env ASAN_OPTIONS=detect_stack_use_after_return=0 %clang_cc1 -std=c++1z %s -verify -fexceptions -fcxx-exceptions -pedantic-errors // FIXME: __SIZE_TYPE__ expands to 'long long' on some targets. __extension__ typedef __SIZE_TYPE__ size_t; @@ -501,15 +502,15 @@ namespace dr436 { // dr436: yes void f(); // expected-error {{redefinition}} } -namespace dr437 { // dr437: no +namespace dr437 { // dr437: sup 1308 // This is superseded by 1308, which is in turn superseded by 1330, // which restores this rule. - template<typename U> struct T : U {}; // expected-error {{incomplete}} - struct S { // expected-note {{not complete}} + template<typename U> struct T : U {}; + struct S { void f() throw(S); - void g() throw(T<S>); // expected-note {{in instantiation of}} - struct U; // expected-note {{forward}} - void h() throw(U); // expected-error {{incomplete}} + void g() throw(T<S>); + struct U; + void h() throw(U); struct U {}; }; } @@ -755,7 +756,7 @@ namespace dr467 { // dr467: yes return k; } int g() { - goto later; // expected-error {{protected scope}} + goto later; // expected-error {{cannot jump}} int k = stuff(); // expected-note {{bypasses variable initialization}} later: return k; @@ -1201,7 +1202,7 @@ namespace dr497 { // dr497: yes struct S { mutable int i; }; - const S cs; // expected-error {{default initialization}} + const S cs; // expected-error {{default initialization}} expected-note {{add an explicit initializer}} int S::*pm = &S::i; cs.*pm = 88; } diff --git a/test/CXX/drs/dr5xx.cpp b/test/CXX/drs/dr5xx.cpp index 0c0d451..5bf085f 100644 --- a/test/CXX/drs/dr5xx.cpp +++ b/test/CXX/drs/dr5xx.cpp @@ -1,6 +1,13 @@ // RUN: %clang_cc1 -std=c++98 %s -verify -fexceptions -fcxx-exceptions -pedantic-errors // RUN: %clang_cc1 -std=c++11 %s -verify -fexceptions -fcxx-exceptions -pedantic-errors -// RUN: %clang_cc1 -std=c++1y %s -verify -fexceptions -fcxx-exceptions -pedantic-errors +// RUN: %clang_cc1 -std=c++14 %s -verify -fexceptions -fcxx-exceptions -pedantic-errors +// RUN: %clang_cc1 -std=c++1z %s -verify -fexceptions -fcxx-exceptions -pedantic-errors + +// FIXME: This is included to avoid a diagnostic with no source location +// pointing at the implicit operator new. We can't match such a diagnostic +// with -verify. +__extension__ typedef __SIZE_TYPE__ size_t; +void *operator new(size_t); // expected-warning 0-1{{missing exception spec}} expected-note{{candidate}} namespace dr500 { // dr500: dup 372 class D; @@ -195,6 +202,153 @@ namespace dr525 { // dr525: yes } } +namespace dr526 { // dr526: yes + template<int> struct S {}; + template<int N> void f1(S<N> s); + template<int N> void f2(S<(N)> s); // expected-note {{couldn't infer}} + template<int N> void f3(S<+N> s); // expected-note {{couldn't infer}} + template<int N> void g1(int (&)[N]); + template<int N> void g2(int (&)[(N)]); // expected-note {{couldn't infer}} + template<int N> void g3(int (&)[+N]); // expected-note {{couldn't infer}} + + void test(int (&a)[3], S<3> s) { + f1(s); + f2(s); // expected-error {{no matching}} + f3(s); // expected-error {{no matching}} + g1(a); + g2(a); // expected-error {{no matching}} + g3(a); // expected-error {{no matching}} + } + + template<int N> struct X { + typedef int type; + X<N>::type v1; + X<(N)>::type v2; // expected-error {{missing 'typename'}} + X<+N>::type v3; // expected-error {{missing 'typename'}} + }; +} + +namespace dr527 { // dr527: na + // This DR is meaningless. It removes a required diagnostic from the case + // where a not-externally-visible object is odr-used but not defined, which + // requires a diagnostic for a different reason. + extern struct { int x; } a; // FIXME: We should reject this, per dr389. + static struct { int x; } b; + extern "C" struct { int x; } c; + namespace { extern struct { int x; } d; } + typedef struct { int x; } *P; + struct E { static P e; }; // FIXME: We should reject this, per dr389. + namespace { struct F { static P f; }; } + + int ax = a.x, bx = b.x, cx = c.x, dx = d.x, ex = E::e->x, fx = F::f->x; +} + +namespace dr530 { // dr530: yes + template<int*> struct S { enum { N = 1 }; }; + template<void(*)()> struct T { enum { N = 1 }; }; + int n; + void f(); + int a[S<&n>::N]; + int b[T<&f>::N]; +} + +namespace dr531 { // dr531: partial + namespace good { + template<typename T> struct A { + void f(T) { T::error; } + template<typename U> void g(T, U) { T::error; } + struct B { typename T::error error; }; + template<typename U> struct C { typename T::error error; }; + static T n; + }; + template<typename T> T A<T>::n = T::error; + + template<> void A<int>::f(int) {} + template<> template<typename U> void A<int>::g(int, U) {} + template<> struct A<int>::B {}; + template<> template<typename U> struct A<int>::C {}; + template<> int A<int>::n = 0; + + void use(A<int> a) { + a.f(a.n); + a.g(0, 0); + A<int>::B b; + A<int>::C<int> c; + } + + template<> struct A<char> { + void f(char); + template<typename U> void g(char, U); + struct B; + template<typename U> struct C; + static char n; + }; + + void A<char>::f(char) {} + template<typename U> void A<char>::g(char, U) {} + struct A<char>::B {}; + template<typename U> struct A<char>::C {}; + char A<char>::n = 0; + } + + namespace bad { + template<typename T> struct A { + void f(T) { T::error; } + template<typename U> void g(T, U) { T::error; } + struct B { typename T::error error; }; + template<typename U> struct C { typename T::error error; }; // expected-note {{here}} + static T n; + }; + template<typename T> T A<T>::n = T::error; + + void A<int>::f(int) {} // expected-error {{requires 'template<>'}} + template<typename U> void A<int>::g(int, U) {} // expected-error {{should be empty}} + struct A<int>::B {}; // expected-error {{requires 'template<>'}} + template<typename U> struct A<int>::C {}; // expected-error {{should be empty}} expected-error {{different kind of symbol}} + int A<int>::n = 0; // expected-error {{requires 'template<>'}} + + template<> struct A<char> { // expected-note 2{{here}} + void f(char); + template<typename U> void g(char, U); + struct B; // expected-note {{here}} + template<typename U> struct C; + static char n; + }; + + template<> void A<char>::f(char) {} // expected-error {{no function template matches}} + // FIXME: This is ill-formed; -pedantic-errors should reject. + template<> template<typename U> void A<char>::g(char, U) {} // expected-warning {{extraneous template parameter list}} + template<> struct A<char>::B {}; // expected-error {{extraneous 'template<>'}} expected-error {{does not specialize}} + // FIXME: This is ill-formed; -pedantic-errors should reject. + template<> template<typename U> struct A<char>::C {}; // expected-warning {{extraneous template parameter list}} + template<> char A<char>::n = 0; // expected-error {{extraneous 'template<>'}} + } + + namespace nested { + template<typename T> struct A { + template<typename U> struct B; + }; + template<> template<typename U> struct A<int>::B { + void f(); + void g(); + template<typename V> void h(); + template<typename V> void i(); + }; + template<> template<typename U> void A<int>::B<U>::f() {} + template<typename U> void A<int>::B<U>::g() {} // expected-error {{should be empty}} + + template<> template<typename U> template<typename V> void A<int>::B<U>::h() {} + template<typename U> template<typename V> void A<int>::B<U>::i() {} // expected-error {{should be empty}} + + template<> template<> void A<int>::B<int>::f() {} + template<> template<> template<typename V> void A<int>::B<int>::h() {} + template<> template<> template<> void A<int>::B<int>::h<int>() {} + + template<> void A<int>::B<char>::f() {} // expected-error {{requires 'template<>'}} + template<> template<typename V> void A<int>::B<char>::h() {} // expected-error {{should be empty}} + } +} + // PR8130 namespace dr532 { // dr532: 3.5 struct A { }; @@ -210,3 +364,632 @@ namespace dr532 { // dr532: 3.5 int &ir = b * a; } } + +// dr533: na + +namespace dr534 { // dr534: yes + struct S {}; + template<typename T> void operator+(S, T); + template<typename T> void operator+<T*>(S, T*) {} // expected-error {{function template partial spec}} +} + +namespace dr535 { // dr535: yes + class X { private: X(const X&); }; + struct A { + X x; + template<typename T> A(T&); + }; + struct B : A { + X y; + B(volatile A&); + }; + + extern A a1; + A a2(a1); // ok, uses constructor template + + extern volatile B b1; + B b2(b1); // ok, uses converting constructor + + void f() { throw a1; } + +#if __cplusplus >= 201103L + struct C { + constexpr C() : n(0) {} + template<typename T> constexpr C(T&t) : n(t.n == 0 ? throw 0 : 0) {} + int n; + }; + constexpr C c() { return C(); } + // ok, copy is elided + constexpr C x = c(); +#endif +} + +// dr537: na +// dr538: na + +// dr539: yes +const dr539( // expected-error {{requires a type specifier}} + const a) { // expected-error {{unknown type name 'a'}} + const b; // expected-error {{requires a type specifier}} + new const; // expected-error {{expected a type}} + try {} catch (const n) {} // expected-error {{unknown type name 'n'}} + try {} catch (const) {} // expected-error {{expected a type}} + if (const n = 0) {} // expected-error {{requires a type specifier}} + switch (const n = 0) {} // expected-error {{requires a type specifier}} + while (const n = 0) {} // expected-error {{requires a type specifier}} + for (const n = 0; // expected-error {{requires a type specifier}} + const m = 0; ) {} // expected-error {{requires a type specifier}} + sizeof(const); // expected-error {{requires a type specifier}} + struct S { + const n; // expected-error {{requires a type specifier}} + operator const(); // expected-error {{expected a type}} + }; +#if __cplusplus >= 201103L + int arr[3]; + // FIXME: The extra braces here are to avoid the parser getting too + // badly confused when recovering here. We should fix this recovery. + { for (const n // expected-error {{unknown type name 'n'}} expected-note {{}} + : arr) ; {} } // expected-error +{{}} + (void) [](const) {}; // expected-error {{requires a type specifier}} + (void) [](const n) {}; // expected-error {{unknown type name 'n'}} + enum E : const {}; // expected-error {{expected a type}} + using T = const; // expected-error {{expected a type}} + auto f() -> const; // expected-error {{expected a type}} +#endif +} + +namespace dr540 { // dr540: yes + typedef int &a; + typedef const a &a; // expected-warning {{has no effect}} + typedef const int &b; + typedef b &b; + typedef const a &c; // expected-note {{previous}} expected-warning {{has no effect}} + typedef const b &c; // expected-error {{different}} expected-warning {{has no effect}} +} + +namespace dr541 { // dr541: yes + template<int> struct X { typedef int type; }; + template<typename T> struct S { + int f(T); + + int g(int); + T g(bool); + + int h(); + int h(T); + + void x() { + // These are type-dependent expressions, even though we could + // determine that all calls have type 'int'. + X<sizeof(f(0))>::type a; // expected-error +{{}} + X<sizeof(g(0))>::type b; // expected-error +{{}} + X<sizeof(h(0))>::type b; // expected-error +{{}} + + typename X<sizeof(f(0))>::type a; + typename X<sizeof(h(0))>::type b; + } + }; +} + +namespace dr542 { // dr542: yes +#if __cplusplus >= 201103L + struct A { A() = delete; int n; }; + A a[32] = {}; // ok, constructor not called + + struct B { + int n; + private: + B() = default; + }; + B b[32] = {}; // ok, constructor not called +#endif +} + +namespace dr543 { // dr543: yes + // In C++98+DR543, this is valid because value-initialization doesn't call a + // trivial default constructor, so we never notice that defining the + // constructor would be ill-formed. + // + // In C++11+DR543, this is ill-formed, because the default constructor is + // deleted, and value-initialization *does* call a deleted default + // constructor, even if it is trivial. + struct A { + const int n; + }; + A a = A(); +#if __cplusplus >= 201103L + // expected-error@-2 {{deleted}} + // expected-note@-5 {{would not be initialized}} +#endif +} + +namespace dr544 { // dr544: yes + int *n; + + template<class T> struct A { int n; }; + template<class T> struct B : A<T> { int get(); }; + template<> int B<int>::get() { return n; } + int k = B<int>().get(); +} + +namespace dr546 { // dr546: yes + template<typename T> struct A { void f(); }; + template struct A<int>; + template<typename T> void A<T>::f() { T::error; } +} + +namespace dr547 { // dr547: yes + // When targeting the MS x86 ABI, the type of a member function includes a + // __thiscall qualifier. This is non-conforming, but we still implement + // the intent of dr547 +#if defined(_M_IX86) || (defined(__MINGW32__) && !defined(__MINGW64__)) +#define THISCALL __thiscall +#else +#define THISCALL +#endif + + template<typename T> struct X; + template<typename T> struct X<THISCALL T() const> {}; + template<typename T, typename C> X<T> f(T C::*) { return X<T>(); } + + struct S { void f() const; }; + X<THISCALL void() const> x = f(&S::f); + +#undef THISCALL +} + +namespace dr548 { // dr548: dup 482 + template<typename T> struct S {}; + template<typename T> void f() {} + template struct dr548::S<int>; + template void dr548::f<int>(); +} + +namespace dr551 { // dr551: yes c++11 + // FIXME: This obviously should apply in C++98 mode too. + template<typename T> void f() {} + template inline void f<int>(); +#if __cplusplus >= 201103L + // expected-error@-2 {{cannot be 'inline'}} +#endif + + template<typename T> inline void g() {} + template inline void g<int>(); +#if __cplusplus >= 201103L + // expected-error@-2 {{cannot be 'inline'}} +#endif + + template<typename T> struct X { + void f() {} + }; + template inline void X<int>::f(); +#if __cplusplus >= 201103L + // expected-error@-2 {{cannot be 'inline'}} +#endif +} + +namespace dr552 { // dr552: yes + template<typename T, typename T::U> struct X {}; + struct Y { typedef int U; }; + X<Y, 0> x; +} + +struct dr553_class { + friend void *operator new(size_t, dr553_class); +}; +namespace dr553 { + dr553_class c; + // Contrary to the apparent intention of the DR, operator new is not actually + // looked up with a lookup mechanism that performs ADL; the standard says it + // "is looked up in global scope", where it is not visible. + void *p = new (c) int; // expected-error {{no matching function}} + + struct namespace_scope { + friend void *operator new(size_t, namespace_scope); // expected-error {{cannot be declared inside a namespace}} + }; +} + +// dr556: na + +namespace dr557 { // dr557: yes + template<typename T> struct S { + friend void f(S<T> *); + friend void g(S<S<T> > *); + }; + void x(S<int> *p, S<S<int> > *q) { + f(p); + g(q); + } +} + +namespace dr558 { // dr558: yes + wchar_t a = L'\uD7FF'; + wchar_t b = L'\xD7FF'; + wchar_t c = L'\uD800'; // expected-error {{invalid universal character}} + wchar_t d = L'\xD800'; + wchar_t e = L'\uDFFF'; // expected-error {{invalid universal character}} + wchar_t f = L'\xDFFF'; + wchar_t g = L'\uE000'; + wchar_t h = L'\xE000'; +} + +template<typename> struct dr559 { typedef int T; dr559::T u; }; // dr559: yes + +namespace dr561 { // dr561: yes + template<typename T> void f(int); + template<typename T> void g(T t) { + f<T>(t); + } + namespace { + struct S {}; + template<typename T> static void f(S); + } + void h(S s) { + g(s); + } +} + +namespace dr564 { // dr564: yes + extern "C++" void f(int); + void f(int); // ok + extern "C++" { extern int n; } + int n; // ok +} + +namespace dr565 { // dr565: yes + namespace N { + template<typename T> int f(T); // expected-note {{target}} + } + using N::f; // expected-note {{using}} + template<typename T> int f(T*); + template<typename T> void f(T); + template<typename T, int = 0> int f(T); // expected-error 0-1{{extension}} + template<typename T> int f(T, int = 0); + template<typename T> int f(T); // expected-error {{conflicts with}} +} + +namespace dr566 { // dr566: yes +#if __cplusplus >= 201103L + int check[int(-3.99) == -3 ? 1 : -1]; +#endif +} + +// dr567: na + +namespace dr568 { // dr568: yes c++11 + // FIXME: This is a DR issue against C++98, so should probably apply there + // too. + struct x { int y; }; + class trivial : x { + x y; + public: + int n; + }; + int check_trivial[__is_trivial(trivial) ? 1 : -1]; + + struct std_layout { + std_layout(); + std_layout(const std_layout &); + ~std_layout(); + private: + int n; + }; + int check_std_layout[__is_standard_layout(std_layout) ? 1 : -1]; + + struct aggregate { + int x; + int y; + trivial t; + std_layout sl; + }; + aggregate aggr = {}; + + void f(...); + void g(trivial t) { f(t); } +#if __cplusplus < 201103L + // expected-error@-2 {{non-POD}} +#endif + + void jump() { + goto x; +#if __cplusplus < 201103L + // expected-error@-2 {{cannot jump}} + // expected-note@+2 {{non-POD}} +#endif + trivial t; + x: ; + } +} + +namespace dr569 { // dr569: yes c++11 + // FIXME: This is a DR issue against C++98, so should probably apply there + // too. + ;;;;; +#if __cplusplus < 201103L + // expected-error@-2 {{C++11 extension}} +#endif +} + +namespace dr570 { // dr570: dup 633 + int n; + int &r = n; // expected-note {{previous}} + int &r = n; // expected-error {{redefinition}} +} + +namespace dr571 { // dr571 unknown + // FIXME: Add a codegen test. + typedef int &ir; + int n; + const ir r = n; // expected-warning {{has no effect}} FIXME: Test if this has internal linkage. +} + +namespace dr572 { // dr572: yes + enum E { a = 1, b = 2 }; + int check[a + b == 3 ? 1 : -1]; +} + +namespace dr573 { // dr573: no + void *a; + int *b = reinterpret_cast<int*>(a); + void (*c)() = reinterpret_cast<void(*)()>(a); + void *d = reinterpret_cast<void*>(c); +#if __cplusplus < 201103L + // expected-error@-3 {{extension}} + // expected-error@-3 {{extension}} +#endif + void f() { delete a; } // expected-error {{cannot delete}} + int n = d - a; // expected-error {{arithmetic on pointers to void}} + // FIXME: This is ill-formed. + template<void*> struct S; + template<int*> struct T; +} + +namespace dr574 { // dr574: yes + struct A { + A &operator=(const A&) const; // expected-note {{does not match because it is const}} + }; + struct B { + B &operator=(const B&) volatile; // expected-note {{nearly matches}} + }; +#if __cplusplus >= 201103L + struct C { + C &operator=(const C&) &; // expected-note {{not viable}} expected-note {{nearly matches}} expected-note {{here}} + }; + struct D { + D &operator=(const D&) &&; // expected-note {{not viable}} expected-note {{nearly matches}} expected-note {{here}} + }; + void test(C c, D d) { + c = c; + C() = c; // expected-error {{no viable}} + d = d; // expected-error {{no viable}} + D() = d; + } +#endif + struct Test { + friend A &A::operator=(const A&); // expected-error {{does not match}} + friend B &B::operator=(const B&); // expected-error {{does not match}} +#if __cplusplus >= 201103L + // FIXME: We shouldn't produce the 'cannot overload' diagnostics here. + friend C &C::operator=(const C&); // expected-error {{does not match}} expected-error {{cannot overload}} + friend D &D::operator=(const D&); // expected-error {{does not match}} expected-error {{cannot overload}} +#endif + }; +} + +namespace dr575 { // dr575: yes + template<typename T, typename U = typename T::type> void a(T); void a(...); // expected-error 0-1{{extension}} + template<typename T, typename T::type U = 0> void b(T); void b(...); // expected-error 0-1{{extension}} + template<typename T, int U = T::value> void c(T); void c(...); // expected-error 0-1{{extension}} + template<typename T> void d(T, int = T::value); void d(...); // expected-error {{cannot be used prior to '::'}} + void x() { + a(0); + b(0); + c(0); + d(0); // expected-note {{in instantiation of default function argument}} + } + + template<typename T = int&> void f(T* = 0); // expected-error 0-1{{extension}} + template<typename T = int> void f(T = 0); // expected-error 0-1{{extension}} + void g() { f<>(); } + + template<typename T> T &h(T *); + template<typename T> T *h(T *); + void *p = h((void*)0); +} + +namespace dr576 { // dr576: yes + typedef void f() {} // expected-error {{function definition declared 'typedef'}} + void f(typedef int n); // expected-error {{invalid storage class}} + void f(char c) { typedef int n; } +} + +namespace dr577 { // dr577: yes + typedef void V; + typedef const void CV; + void a(void); + void b(const void); // expected-error {{qualifiers}} + void c(V); + void d(CV); // expected-error {{qualifiers}} + void (*e)(void) = c; + void (*f)(const void); // expected-error {{qualifiers}} + void (*g)(V) = a; + void (*h)(CV); // expected-error {{qualifiers}} + template<typename T> void i(T); // expected-note 2{{requires 1 arg}} + template<typename T> void j(void (*)(T)); // expected-note 2{{argument may not have 'void' type}} + void k() { + a(); + c(); + i<void>(); // expected-error {{no match}} + i<const void>(); // expected-error {{no match}} + j<void>(0); // expected-error {{no match}} + j<const void>(0); // expected-error {{no match}} + } +} + +namespace dr580 { // dr580: no + class C; + struct A { static C c; }; + struct B { static C c; }; + class C { + C(); // expected-note {{here}} + ~C(); // expected-note {{here}} + + typedef int I; // expected-note {{here}} + template<int> struct X; + template<int> friend struct Y; + template<int> void f(); + template<int> friend void g(); + friend struct A; + }; + + template<C::I> struct C::X {}; + template<C::I> struct Y {}; + template<C::I> struct Z {}; // FIXME: should reject, accepted because C befriends A! + + template<C::I> void C::f() {} + template<C::I> void g() {} + template<C::I> void h() {} // expected-error {{private}} + + C A::c; + C B::c; // expected-error 2{{private}} +} + +// dr582: na + +namespace dr583 { // dr583: no + // see n3624 + int *p; + // FIXME: These are all ill-formed. + bool b1 = p < 0; + bool b2 = p > 0; + bool b3 = p <= 0; + bool b4 = p >= 0; +} + +// dr584: na + +namespace dr585 { // dr585: yes + template<typename> struct T; + struct A { + friend T; // expected-error {{requires a type specifier}} expected-error {{can only be classes or functions}} + // FIXME: It's not clear whether the standard allows this or what it means, + // but the DR585 writeup suggests it as an alternative. + template<typename U> friend T<U>; // expected-error {{must use an elaborated type}} + }; + template<template<typename> class T> struct B { + friend T; // expected-error {{requires a type specifier}} expected-error {{can only be classes or functions}} + template<typename U> friend T<U>; // expected-error {{must use an elaborated type}} + }; +} + +// dr586: na + +namespace dr587 { // dr587: yes + template<typename T> void f(bool b, const T x, T y) { + const T *p = &(b ? x : y); + } + struct S {}; + template void f(bool, const int, int); + template void f(bool, const S, S); +} + +namespace dr588 { // dr588: yes + struct A { int n; }; // expected-note {{ambiguous}} + template<typename T> int f() { + struct S : A, T { int f() { return n; } } s; + int a = s.f(); + int b = s.n; // expected-error {{found in multiple}} + } + struct B { int n; }; // expected-note {{ambiguous}} + int k = f<B>(); // expected-note {{here}} +} + +namespace dr589 { // dr589: yes + struct B { }; + struct D : B { }; + D f(); + extern const B &b; + bool a; + const B *p = &(a ? f() : b); // expected-error {{temporary}} + const B *q = &(a ? D() : b); // expected-error {{temporary}} +} + +namespace dr590 { // dr590: yes + template<typename T> struct A { + struct B { + struct C { + A<T>::B::C f(A<T>::B::C); // ok, no 'typename' required. + }; + }; + }; + template<typename T> typename A<T>::B::C A<T>::B::C::f(A<T>::B::C) {} +} + +namespace dr591 { // dr591: no + template<typename T> struct A { + typedef int M; + struct B { + typedef void M; + struct C; + }; + }; + + template<typename T> struct A<T>::B::C : A<T> { + // FIXME: Should find member of non-dependent base class A<T>. + M m; // expected-error {{incomplete type 'M' (aka 'void'}} + }; +} + +// dr592: na +// dr593 needs an IRGen test. +// dr594: na + +namespace dr595 { // dr595: dup 1330 + template<class T> struct X { + void f() throw(T) {} + }; + struct S { + X<S> xs; + }; +} + +// dr597: na + +namespace dr598 { // dr598: yes + namespace N { + void f(int); + void f(char); + // Not found by ADL. + void g(void (*)(int)); + void h(void (*)(int)); + + namespace M { + struct S {}; + int &h(void (*)(S)); + } + void i(M::S); + void i(); + } + int &g(void(*)(char)); + int &r = g(N::f); + int &s = h(N::f); // expected-error {{undeclared}} + int &t = h(N::i); +} + +namespace dr599 { // dr599: partial + typedef int Fn(); + struct S { operator void*(); }; + struct T { operator Fn*(); }; + struct U { operator int*(); operator void*(); }; // expected-note 2{{conversion}} + struct V { operator int*(); operator Fn*(); }; + void f(void *p, void (*q)(), S s, T t, U u, V v) { + delete p; // expected-error {{cannot delete}} + delete q; // expected-error {{cannot delete}} + delete s; // expected-error {{cannot delete}} + delete t; // expected-error {{cannot delete}} + // FIXME: This is valid, but is rejected due to a non-conforming GNU + // extension allowing deletion of pointers to void. + delete u; // expected-error {{ambiguous}} + delete v; + } +} diff --git a/test/CXX/drs/dr6xx.cpp b/test/CXX/drs/dr6xx.cpp new file mode 100644 index 0000000..988c8f4 --- /dev/null +++ b/test/CXX/drs/dr6xx.cpp @@ -0,0 +1,349 @@ +// RUN: %clang_cc1 -std=c++98 %s -verify -fexceptions -fcxx-exceptions -pedantic-errors +// RUN: %clang_cc1 -std=c++11 %s -verify -fexceptions -fcxx-exceptions -pedantic-errors +// RUN: %clang_cc1 -std=c++14 %s -verify -fexceptions -fcxx-exceptions -pedantic-errors +// RUN: %clang_cc1 -std=c++1z %s -verify -fexceptions -fcxx-exceptions -pedantic-errors + +namespace std { struct type_info {}; } + +namespace dr601 { // dr601: yes +#if __cplusplus >= 201103L +#define MAX __LLONG_MAX__ +#else +#define MAX __LONG_MAX__ +#endif + +#if 0x8000 < -1 +#error 0x8000 should be signed +#endif + +#if MAX > 0xFFFFFFFF && 0x80000000 < -1 +#error 0x80000000 should be signed +#endif + +#if __INT_MAX__ == 0x7FFFFFFF +_Static_assert(0x80000000 < -1, "0x80000000 should be unsigned"); // expected-error {{C11}} +#endif + +#if MAX > 0xFFFFFFFFFFFFFFFF && 0x8000000000000000 < -1 +#error 0x8000000000000000 should be signed +#endif + +#if __cplusplus >= 201103L && __LLONG_MAX__ == 0x7FFFFFFFFFFFFFFF +static_assert(0x8000000000000000 < -1, "0x8000000000000000 should be unsigned"); // expected-error {{C11}} +#endif + +#undef MAX +} + +namespace dr602 { // dr602: yes + template<class T> struct A { + template<class U> friend struct A; + }; + + template<class T> struct B { + class C { + template<class U> friend struct B; + typedef int type; + }; + typename C::type ct; // ok, befriended + }; + B<int> b; +} + +namespace dr603 { // dr603: yes + template<unsigned char> struct S {}; + typedef S<'\001'> S1; + typedef S<(1ul << __CHAR_BIT__) + 1> S1; +#if __cplusplus >= 201103L + // expected-error@-2 {{cannot be narrowed}} +#endif +} + +// dr604: na +// dr605 needs IRGen test + +namespace dr606 { // dr606: yes +#if __cplusplus >= 201103L + template<typename T> struct S {}; + template<typename T> void f(S<T> &&); // expected-note {{no known conversion from 'S<int>' to 'S<int> &&'}} + template<typename T> void g(T &&); + template<typename T> void h(const T &&); // expected-note {{no known conversion from 'S<int>' to 'const dr606::S<int> &&'}} + + void test(S<int> s) { + f(s); // expected-error {{no match}} + g(s); + h(s); // expected-error {{no match}} + + g(test); + h(test); // ok, an rvalue reference can bind to a function lvalue + } +#endif +} + +namespace dr608 { // dr608: yes + struct A { virtual void f(); }; + struct B : A {}; + struct C : A { void f(); }; + struct D : B, C {}; +} + +int dr610[-0u == 0u ? 1 : -1]; // dr610: yes + +namespace dr611 { // dr611: yes + int k; + struct S { int &r; } s = { k ? k : k }; +} + +// dr612: na + +namespace dr613 { // dr613: yes c++11 + // see also n2253 + struct A { int n; static void f(); }; + int f(int); + struct B { virtual void f(); }; + B &g(int); + + int an1 = sizeof(A::n); + int an2 = sizeof(A::n + 1); // valid per dr850 + int an3 = sizeof A::n; + int an4 = sizeof(f(A::n)); + int an5 = sizeof(g(A::n)); + const std::type_info &an6 = typeid(A::n); + const std::type_info &an7 = typeid(A::n + 1); + const std::type_info &an8 = typeid(f(A::n)); + const std::type_info &an9 = typeid(g(A::n)); // expected-error {{non-static}} +#if __cplusplus < 201103L + // expected-error@-10 {{non-static}} + // expected-error@-10 {{non-static}} + // expected-error@-10 {{non-static}} + // expected-error@-10 {{non-static}} + // expected-error@-10 {{non-static}} + // expected-error@-10 {{non-static}} + // expected-error@-10 {{non-static}} + // expected-error@-10 {{non-static}} +#endif + + void A::f() { + int an1 = sizeof n; + const std::type_info &an2 = typeid(n + 1); +#if __cplusplus < 201103L + // expected-error@-3 {{static}} + // expected-error@-3 {{static}} +#endif + const std::type_info &an3 = typeid(g(n)); // expected-error {{static}} + } +} + +int dr614_a[(-1) / 2 == 0 ? 1 : -1]; // dr614: yes +int dr614_b[(-1) % 2 == -1 ? 1 : -1]; + +namespace dr615 { // dr615: yes + int f(); + static int n = f(); +} + +namespace dr616 { // dr616: no +#if __cplusplus >= 201103L + struct S { int n; } s; + // FIXME: These should all be 'int &&' + using T = decltype(S().n); // expected-note 2{{previous}} + using T = decltype(static_cast<S&&>(s).n); + using T = decltype(S().*&S::n); + using T = decltype(static_cast<S&&>(s).*&S::n); // expected-error {{different type}} + using T = int&&; // expected-error {{different type}} +#endif +} + +namespace dr618 { // dr618: yes +#if (unsigned)-1 > 0 +#error wrong +#endif +} + +namespace dr619 { // dr619: yes + extern int x[10]; + struct S { static int x[10]; }; + + int x[]; + _Static_assert(sizeof(x) == sizeof(int) * 10, ""); // expected-error {{C11}} + extern int x[]; + _Static_assert(sizeof(x) == sizeof(int) * 10, ""); // expected-error {{C11}} + + int S::x[]; + _Static_assert(sizeof(S::x) == sizeof(int) * 10, ""); // expected-error {{C11}} + + void f() { + extern int x[]; + sizeof(x); // expected-error {{incomplete}} + } +} + +// dr620: dup 568 + +namespace dr621 { + template<typename T> T f(); + template<> int f() {} // expected-note {{previous}} + template<> int f<int>() {} // expected-error {{redefinition}} +} + +// dr623: na +// FIXME: Add documentation saying we allow invalid pointer values. + +// dr624 needs an IRGen check. + +namespace dr625 { // dr625: yes + template<typename T> struct A {}; + A<auto> x = A<int>(); // expected-error {{'auto' not allowed in template argument}} expected-error 0-1{{extension}} + void f(int); + void (*p)(auto) = f; // expected-error {{'auto' not allowed in function prototype}} expected-error 0-1{{extension}} +} + +namespace dr626 { // dr626: yes +#define STR(x) #x + char c[2] = STR(c); // ok, type matches + wchar_t w[2] = STR(w); // expected-error {{initializing wide char array with non-wide string literal}} +} + +namespace dr627 { // dr627: yes + void f() { + true a = 0; // expected-error +{{}} expected-warning {{unused}} + } +} + +// dr628: na + +namespace dr629 { // dr629: yes + typedef int T; + int n = 1; + void f() { + auto T = 2; +#if __cplusplus < 201103L + // expected-error@-2 {{expected unqualified-id}} +#else + // expected-note@-4 {{previous}} +#endif + + auto T(n); +#if __cplusplus >= 201103L + // expected-error@-2 {{redefinition of 'T'}} +#endif + } +} + +namespace dr630 { // dr630: yes +const bool MB_EQ_WC = + ' ' == L' ' && '\t' == L'\t' && '\v' == L'\v' && '\r' == L'\r' && + '\n' == L'\n' && // + 'a' == L'a' && 'b' == L'b' && 'c' == L'c' && 'd' == L'd' && 'e' == L'e' && + 'f' == L'f' && 'g' == L'g' && 'h' == L'h' && 'i' == L'i' && 'j' == L'j' && + 'k' == L'k' && 'l' == L'l' && 'm' == L'm' && 'n' == L'n' && 'o' == L'o' && + 'p' == L'p' && 'q' == L'q' && 'r' == L'r' && 's' == L's' && 't' == L't' && + 'u' == L'u' && 'v' == L'v' && 'w' == L'w' && 'x' == L'x' && 'y' == L'y' && + 'z' == L'z' && // + 'A' == L'A' && 'B' == L'B' && 'C' == L'C' && 'D' == L'D' && 'E' == L'E' && + 'F' == L'F' && 'G' == L'G' && 'H' == L'H' && 'I' == L'I' && 'J' == L'J' && + 'K' == L'K' && 'L' == L'L' && 'M' == L'M' && 'N' == L'N' && 'O' == L'O' && + 'P' == L'P' && 'Q' == L'Q' && 'R' == L'R' && 'S' == L'S' && 'T' == L'T' && + 'U' == L'U' && 'V' == L'V' && 'W' == L'W' && 'X' == L'X' && 'Y' == L'Y' && + 'Z' == L'Z' && // + '0' == L'0' && '1' == L'1' && '2' == L'2' && '3' == L'3' && '4' == L'4' && + '5' == L'5' && '6' == L'6' && '7' == L'7' && '8' == L'8' && + '9' == L'9' && // + '_' == L'_' && '{' == L'{' && '}' == L'}' && '[' == L'[' && ']' == L']' && + '#' == L'#' && '(' == L'(' && ')' == L')' && '<' == L'<' && '>' == L'>' && + '%' == L'%' && ':' == L':' && ';' == L';' && '.' == L'.' && '?' == L'?' && + '*' == L'*' && '+' == L'+' && '-' == L'-' && '/' == L'/' && '^' == L'^' && + '&' == L'&' && '|' == L'|' && '~' == L'~' && '!' == L'!' && '=' == L'=' && + ',' == L',' && '\\' == L'\\' && '"' == L'"' && '\'' == L'\''; +#if __STDC_MB_MIGHT_NEQ_WC__ +#ifndef __FreeBSD__ // PR22208, FreeBSD expects us to give a bad (but conforming) answer here. +_Static_assert(!MB_EQ_WC, "__STDC_MB_MIGHT_NEQ_WC__ but all basic source characters have same representation"); // expected-error {{C11}} +#endif +#else +_Static_assert(MB_EQ_WC, "!__STDC_MB_MIGHT_NEQ_WC__ but some character differs"); // expected-error {{C11}} +#endif +} + +// dr631: na + +namespace dr632 { // dr632: yes + struct S { int n; } s = {{5}}; // expected-warning {{braces}} +} + +// dr633: na +// see also n2993 + +namespace dr634 { // dr634: yes + struct S { S(); S(const S&); virtual void f(); ~S(); }; + int f(...); + char f(int); + template<typename T> int (&g(T))[sizeof f(T())]; + int (&a)[sizeof(int)] = g(S()); + int (&b)[1] = g(0); + int k = f(S()); // expected-error {{cannot pass}} +} + +namespace dr635 { // dr635: yes + template<typename T> struct A { A(); ~A(); }; + template<typename T> A<T>::A<T>() {} // expected-error {{cannot have template arguments}} + template<typename T> A<T>::~A<T>() {} + + template<typename T> struct B { B(); ~B(); }; + template<typename T> B<T>::B() {} + template<typename T> B<T>::~B() {} + + struct C { template<typename T> C(); C(); }; + template<typename T> C::C() {} + C::C() {} + template<> C::C<int>() {} // expected-error {{constructor name}} expected-error {{unqualified-id}} + /*FIXME: needed for error recovery:*/; + + template<typename T> struct D { template<typename U> D(); D(); }; + template<typename T> D<T>::D() {} // expected-note {{previous}} + template<typename T> template<typename U> D<T>::D() {} + template<typename T> D<T>::D<T>() {} // expected-error {{redefinition}} expected-error {{cannot have template arg}} +} + +namespace dr637 { // dr637: yes + void f(int i) { + i = ++i + 1; + i = i++ + 1; // expected-warning {{unsequenced}} + } +} + +namespace dr638 { // dr638: no + template<typename T> struct A { + struct B; + void f(); + void g(); + struct C { + void h(); + }; + }; + + class X { + typedef int type; + template<class T> friend struct A<T>::B; // expected-warning {{not supported}} + template<class T> friend void A<T>::f(); // expected-warning {{not supported}} + template<class T> friend void A<T>::g(); // expected-warning {{not supported}} + template<class T> friend void A<T>::C::h(); // expected-warning {{not supported}} + }; + + template<> struct A<int> { + X::type a; // FIXME: private + struct B { + X::type b; // ok + }; + int f() { X::type c; } // FIXME: private + void g() { X::type d; } // ok + struct D { + void h() { X::type e; } // FIXME: private + }; + }; +} + +namespace dr639 { // dr639: yes + void f(int i) { + void((i = 0) + (i = 0)); // expected-warning {{unsequenced}} + } +} diff --git a/test/CXX/drs/dr9xx.cpp b/test/CXX/drs/dr9xx.cpp index 40dc282..4bcd656 100644 --- a/test/CXX/drs/dr9xx.cpp +++ b/test/CXX/drs/dr9xx.cpp @@ -1,6 +1,7 @@ // RUN: %clang_cc1 -std=c++98 %s -verify -fexceptions -fcxx-exceptions -pedantic-errors // RUN: %clang_cc1 -std=c++11 %s -verify -fexceptions -fcxx-exceptions -pedantic-errors -// RUN: %clang_cc1 -std=c++1y %s -verify -fexceptions -fcxx-exceptions -pedantic-errors +// RUN: %clang_cc1 -std=c++14 %s -verify -fexceptions -fcxx-exceptions -pedantic-errors +// RUN: %clang_cc1 -std=c++1z %s -verify -fexceptions -fcxx-exceptions -pedantic-errors #if __cplusplus < 201103L // expected-no-diagnostics |