From: Richard Smith Date: Mon, 17 Mar 2014 08:20:10 +0000 (+0000) Subject: Tests for DR400-450. X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=7d6c15cd93913b1e96cd0acc279275fded64b088;p=clang Tests for DR400-450. git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@204033 91177308-0d34-0410-b5e6-96231b3b80d8 --- diff --git a/test/CXX/drs/dr412.cpp b/test/CXX/drs/dr412.cpp new file mode 100644 index 0000000000..a09062b794 --- /dev/null +++ b/test/CXX/drs/dr412.cpp @@ -0,0 +1,19 @@ +// 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= + +// dr412: yes +// lwg404: yes +// lwg2340: yes + +typedef __SIZE_TYPE__ size_t; +namespace std { struct bad_alloc {}; } +int x; +inline void* operator new(size_t) BAD_ALLOC; // expected-error {{cannot be declared 'inline'}} +inline void* operator new[](size_t) BAD_ALLOC; // expected-error {{cannot be declared 'inline'}} +inline void operator delete(void*) NOEXCEPT; // expected-error {{cannot be declared 'inline'}} +inline void operator delete[](void*) NOEXCEPT; // expected-error {{cannot be declared 'inline'}} +#if __cplusplus >= 201402L +inline void operator delete(void*, size_t) NOEXCEPT; // expected-error {{cannot be declared 'inline'}} +inline void operator delete[](void*, size_t) NOEXCEPT; // expected-error {{cannot be declared 'inline'}} +#endif diff --git a/test/CXX/drs/dr4xx.cpp b/test/CXX/drs/dr4xx.cpp index f295431125..e6a2370938 100644 --- a/test/CXX/drs/dr4xx.cpp +++ b/test/CXX/drs/dr4xx.cpp @@ -2,6 +2,135 @@ // 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 +namespace dr400 { // dr400: yes + struct A { int a; struct a {}; }; // expected-note 2{{conflicting}} expected-note {{ambiguous}} + struct B { int a; struct a {}; }; // expected-note 2{{target}} expected-note {{ambiguous}} + struct C : A, B { using A::a; struct a b; }; + struct D : A, B { using A::a; using B::a; struct a b; }; // expected-error 2{{conflicts}} + struct E : A, B { struct a b; }; // expected-error {{found in multiple base classes}} +} + +namespace dr401 { // dr401: yes + template class A : public T {}; // expected-error {{protected}} expected-error 2{{private}} + + class B { + protected: + typedef int type; // expected-note {{protected}} + }; + + class C { + typedef int type; // expected-note {{private}} + friend class A; // expected-note {{default argument}} + }; + + class D { + typedef int type; // expected-note {{private}} + friend class A; + }; + + A *b; // expected-note {{default argument}} + // FIXME: We're missing the "in instantiation of" note for the default + // argument here. + A *d; + + struct E { + template class A : public T {}; + }; + class F { + typedef int type; + friend class E; + }; + E::A eaf; // ok, default argument is in befriended context + + // FIXME: Why do we get different diagnostics in C++11 onwards here? We seem + // to not treat the default template argument as a SFINAE context in C++98. + template void f(T) {} + void g(B b) { f(b); } +#if __cplusplus < 201103L + // expected-error@-3 0-1{{extension}} expected-error@-3 {{protected}} expected-note@-3 {{instantiation}} + // expected-note@-3 {{substituting}} +#else + // expected-error@-5 {{no matching}} expected-note@-6 {{protected}} +#endif +} + +namespace dr403 { // dr403: yes + namespace A { + struct S {}; + int f(void*); + } + template struct X {}; + typedef struct X::X XS; + XS *p; + int k = f(p); // ok, finds A::f, even though type XS is a typedef-name + // referring to an elaborated-type-specifier naming a + // injected-class-name, which is about as far from a + // template-id as we can make it. +} + +// dr404: na +// (NB: also sup 594) + +namespace dr406 { // dr406: yes + typedef struct { + static int n; // expected-error {{static data member 'n' not allowed in anonymous struct}} + } A; +} + +namespace dr407 { // dr407: no + struct S; + typedef struct S S; + void f() { + struct S *p; + { + typedef struct S S; // expected-note {{here}} + struct S *p; // expected-error {{refers to a typedef}} + } + } + struct S {}; + + namespace UsingDir { + namespace A { + struct S {}; // expected-note {{found}} + } + namespace B { + typedef int S; // expected-note {{found}} + } + namespace C { + using namespace A; + using namespace B; + struct S s; // expected-error {{ambiguous}} + } + namespace D { + // FIXME: This is valid. + using A::S; + typedef struct S S; // expected-note {{here}} + struct S s; // expected-error {{refers to a typedef}} + } + namespace E { + // FIXME: The standard doesn't say whether this is valid. + typedef A::S S; + using A::S; + struct S s; + } + namespace F { + typedef A::S S; // expected-note {{here}} + } + // FIXME: The standard doesn't say what to do in these cases, but + // our behavior should not depend on the order of the using-directives. + namespace G { + using namespace A; + using namespace F; + struct S s; + } + namespace H { + using namespace F; + using namespace A; + struct S s; // expected-error {{refers to a typedef}} + } + } +} + namespace dr408 { // dr408: 3.4 template void g() { int arr[N != 1 ? 1 : -1]; } template<> void g<2>() { } @@ -31,6 +160,447 @@ namespace dr408 { // dr408: 3.4 template void R::f(); } +namespace dr409 { // dr409: yes + template struct A { + typedef int B; + B b1; + A::B b2; + A::B b3; + A::B b4; // expected-error {{missing 'typename'}} + }; +} + +namespace dr410 { // dr410: no + template void f(T); + void g(int); + namespace M { + template void h(T); + template void i(T); + struct A { + friend void f<>(int); + friend void h<>(int); + friend void g(int); + template void i(T); + friend void i<>(int); + private: + static void z(); // expected-note {{private}} + }; + + template<> void h(int) { A::z(); } + // FIXME: This should be ill-formed. The member A::i<> is befriended, + // not this function. + template<> void i(int) { A::z(); } + } + template<> void f(int) { M::A::z(); } + void g(int) { M::A::z(); } // expected-error {{private}} +} + +// dr412 is in its own file. + +namespace dr413 { // dr413: yes + struct S { + int a; + int : 17; + int b; + }; + S s = { 1, 2, 3 }; // expected-error {{excess elements}} +} + +namespace dr414 { // dr414: dup 305 + struct X {}; + void f() { + X x; + struct X {}; + x.~X(); + } +} + +namespace dr415 { // dr415: yes + template void f(T, ...) { T::error; } + void f(int, int); + void g() { f(0, 0); } // ok +} + +namespace dr416 { // dr416: yes + extern struct A a; + int &operator+(const A&, const A&); + int &k = a + a; + struct A { float &operator+(A&); }; + float &f = a + a; +} + +namespace dr417 { // dr417: no + struct A; + struct dr417::A {}; // expected-warning {{extra qualification}} + struct B { struct X; }; + struct C : B {}; + struct C::X {}; // expected-error {{no struct named 'X' in 'dr417::C'}} + struct B::X { struct Y; }; + struct C::X::Y {}; // ok! + namespace N { + struct D; + struct E; + struct F; + struct H; + } + // FIXME: This is ill-formed. + using N::D; + struct dr417::D {}; // expected-warning {{extra qualification}} + using namespace N; + struct dr417::E {}; // expected-warning {{extra qualification}} expected-error {{no struct named 'E'}} + struct N::F {}; + struct G; + using N::H; + namespace M { + struct dr417::G {}; // expected-error {{namespace 'M' does not enclose}} + struct dr417::H {}; // expected-error {{namespace 'M' does not enclose}} + } +} + +namespace dr420 { // dr420: yes + template struct ptr { + T *operator->() const; + T &operator*() const; + }; + template void test(P p) { + p->~T(); + p->T::~T(); + (*p).~T(); + (*p).T::~T(); + } + struct X {}; + template void test(int*); + template void test(ptr); + template void test(X*); + template void test(ptr); + + template + void test2(T p) { + p->template Y::~Y(); + p->~Y(); + // FIXME: This is ill-formed, but this diagnostic is terrible. We should + // reject this in the parser. + p->template ~Y(); // expected-error 2{{no member named '~typename Y'}} + } + template struct Y {}; + template void test2(Y*); // expected-note {{instantiation}} + template void test2(ptr >); // expected-note {{instantiation}} + + void test3(int *p, ptr q) { + typedef int Int; + p->~Int(); + q->~Int(); + p->Int::~Int(); + q->Int::~Int(); + } + +#if __cplusplus >= 201103L + template using id = T; + struct A { template using id = T; }; + void test4(int *p, ptr q) { + p->~id(); + q->~id(); + p->id::~id(); + q->id::~id(); + p->template id::~id(); // expected-error {{expected unqualified-id}} + q->template id::~id(); // expected-error {{expected unqualified-id}} + p->A::template id::~id(); + q->A::template id::~id(); + } +#endif +} + +namespace dr421 { // dr421: yes + struct X { X(); int n; int &r; }; + int *p = &X().n; // expected-error {{taking the address of a temporary}} + int *q = &X().r; +} + +namespace dr422 { // dr422: yes + template void f() { + typedef T type; // expected-note {{prev}} + typedef U type; // expected-error {{redef}} + } + template void f(); + template void f(); // expected-note {{instantiation}} +} + +namespace dr423 { // dr423: yes + template struct X { operator T&(); }; + void f(X x) { x += 1; } +} + +namespace dr424 { // dr424: yes + struct A { + typedef int N; // expected-note {{previous}} + typedef int N; // expected-error {{redefinition}} + + struct X; + typedef X X; // expected-note {{previous}} + struct X {}; + + struct X *p; + struct A::X *q; + X *r; + + typedef X X; // expected-error {{redefinition}} + }; + struct B { + typedef int N; + }; + struct C : B { + typedef int N; // expected-note {{previous}} + typedef int N; // expected-error {{redefinition}} + }; +} + +namespace dr425 { // dr425: yes + struct A { template operator T() const; } a; + float f = 1.0f * a; // expected-error {{ambiguous}} expected-note 5+{{built-in candidate}} + + template struct is_float; + template<> struct is_float { typedef void type; }; + + struct B { + template::type> operator T() const; // expected-error 0-1{{extension}} + } b; + float g = 1.0f * b; // ok +} + +namespace dr427 { // dr427: yes + struct B {}; + struct D : public B { + D(B &) = delete; // expected-error 0-1{{extension}} expected-note {{deleted}} + }; + + extern D d1; + B &b = d1; + const D &d2 = static_cast(b); + const D &d3 = (const D&)b; + const D &d4(b); // expected-error {{deleted}} +} + +namespace dr428 { // dr428: yes + template T make(); + extern struct X x; // expected-note 5{{forward declaration}} + void f() { + throw void(); // expected-error {{cannot throw}} + throw make(); + throw make(); + throw x; // expected-error {{cannot throw}} + throw make(); // expected-error {{cannot throw}} + throw make(); // expected-error {{cannot throw}} + throw make(); // expected-error {{cannot throw}} + throw make(); // expected-error {{cannot throw}} + } +} + +namespace dr429 { // dr429: yes c++11 + // FIXME: This rule is obviously intended to apply to C++98 as well. + typedef __SIZE_TYPE__ size_t; + struct A { + static void *operator new(size_t, size_t); + static void operator delete(void*, size_t); + } *a = new (0) A; +#if __cplusplus >= 201103L + // expected-error@-2 {{'new' expression with placement arguments refers to non-placement 'operator delete'}} + // expected-note@-4 {{here}} +#endif + struct B { + static void *operator new(size_t, size_t); + static void operator delete(void*); + static void operator delete(void*, size_t); + } *b = new (0) B; // ok, second delete is not a non-placement deallocation function +} + +namespace dr430 { // dr430: yes c++11 + // resolved by n2239 + // FIXME: This should apply in C++98 too. + void f(int n) { + int a[] = { n++, n++, n++ }; +#if __cplusplus < 201103L + // expected-warning@-2 {{multiple unsequenced modifications to 'n'}} +#endif + } +} + +namespace dr431 { // dr431: yes + struct A { + template T *get(); + template struct B { + template U *get(); + }; + }; + + template void f(A a) { + a.get()->get(); + a.get() + ->get(); // expected-error {{use 'template'}} + a.get()->template get(); + a.A::get(); + A::B *b = a.get >(); + b->get(); + b->A::B::get(); + b->A::B::get(); + b->A::B::get(); // expected-error {{use 'template'}} + b->A::B::template get(); + b->A::B::get(); // expected-error {{use 'template'}} + b->A::B::template get(); + A::B *c = a.get >(); + c->get(); // expected-error {{use 'template'}} + c->template get(); + } +} + +namespace dr432 { // dr432: yes + template struct A {}; + template struct B : A {}; // expected-error {{requires template arguments}} expected-note {{declared}} + template struct C : A > {}; +#if __cplusplus >= 201103L + template struct D : decltype(A()) {}; // expected-error {{requires template arguments}} expected-note {{declared}} +#endif +} + +namespace dr433 { // dr433: yes + template struct S { + void f(union U*); + }; + U *p; + template void S::f(union U*) {} + + S s; +} + +namespace dr434 { // dr434: yes + void f() { + const int ci = 0; + int *pi = 0; + const int *&rpci = pi; // expected-error {{cannot bind}} + rpci = &ci; + *pi = 1; + } +} + +// dr435: na + +namespace dr436 { // dr436: yes + enum E { f }; // expected-note {{previous}} + void f(); // expected-error {{redefinition}} +} + +namespace dr437 { // dr437: no + // This is superseded by 1308, which is in turn superseded by 1330, + // which restores this rule. + template struct T : U {}; // expected-error {{incomplete}} + struct S { // expected-note {{not complete}} + void f() throw(S); + void g() throw(T); // expected-note {{in instantiation of}} + struct U; // expected-note {{forward}} + void h() throw(U); // expected-error {{incomplete}} + struct U {}; + }; +} + +// dr438 FIXME write a codegen test +// dr439 FIXME write a codegen test +// dr441 FIXME write a codegen test +// dr442: sup 348 +// dr443: na + +namespace dr444 { // dr444: yes + struct D; + struct B { // expected-note {{candidate is the implicit copy}} expected-note 0-1 {{implicit move}} + D &operator=(D &) = delete; // expected-error 0-1{{extension}} expected-note {{deleted}} + }; + struct D : B { // expected-note {{candidate is the implicit}} expected-note 0-1 {{implicit move}} + using B::operator=; + } extern d; + void f() { + d = d; // expected-error {{deleted}} + } +} + +namespace dr445 { // dr445: yes + class A { void f(); }; // expected-note {{private}} + struct B { + friend void A::f(); // expected-error {{private}} + }; +} + +namespace dr446 { // dr446: yes + struct C; + struct A { + A(); + A(const A&) = delete; // expected-error 0-1{{extension}} expected-note +{{deleted}} + A(const C&); + }; + struct C : A {}; + void f(A a, bool b, C c) { + void(b ? a : a); + b ? A() : a; // expected-error {{deleted}} + b ? a : A(); // expected-error {{deleted}} + b ? A() : A(); // expected-error {{deleted}} + + void(b ? a : c); + b ? a : C(); // expected-error {{deleted}} + b ? c : A(); // expected-error {{deleted}} + b ? A() : C(); // expected-error {{deleted}} + } +} + +namespace dr447 { // dr447: yes + struct A { int n; int a[4]; }; + template struct U { + typedef int type; + template static void h(); + }; + template U g(T); + template void f(int n) { + // ok, not type dependent + g(__builtin_offsetof(A, n)).h(); + g(__builtin_offsetof(T, n)).h(); + // value dependent if first argument is a dependent type + U<__builtin_offsetof(A, n)>::type a; + U<__builtin_offsetof(T, n)>::type b; // expected-error +{{}} expected-warning 0+{{}} + // as an extension, we allow the member-designator to include array indices + g(__builtin_offsetof(A, a[0])).h(); // expected-error {{extension}} + g(__builtin_offsetof(A, a[N])).h(); // expected-error {{extension}} + U<__builtin_offsetof(A, a[0])>::type c; // expected-error {{extension}} + U<__builtin_offsetof(A, a[N])>::type d; // expected-error {{extension}} expected-error +{{}} expected-warning 0+{{}} + } +} + +namespace dr448 { // dr448: yes + template void f(int); // expected-error 0-1{{extension}} expected-note {{no known conversion}} + template void g(T t) { + f(t); // expected-error {{neither visible in the template definition nor found by argument-dependent lookup}} + dr448::f(t); // expected-error {{no matching function}} + } + template void f(T); // expected-note {{should be declared prior to the call site}} + namespace HideFromADL { struct X {}; } + template void g(int); // ok + template void g(HideFromADL::X); // expected-note {{instantiation of}} +} + +// dr449: na + +namespace dr450 { // dr450: yes + typedef int A[3]; + void f1(const A &); + void f2(A &); // expected-note +{{not viable}} + struct S { A n; }; + void g() { + f1(S().n); + f2(S().n); // expected-error {{no match}}} + } +#if __cplusplus >= 201103L + void h() { + f1(A{}); + f2(A{}); // expected-error {{no match}} + } +#endif +} + namespace dr482 { // dr482: 3.5 extern int a; void f(); diff --git a/www/cxx_dr_status.html b/www/cxx_dr_status.html index 590163a660..0681e4be42 100644 --- a/www/cxx_dr_status.html +++ b/www/cxx_dr_status.html @@ -555,7 +555,7 @@ 86 CD1 Lifetime of temporaries in query expressions - Duplicate of 446 + Duplicate of 446 87 @@ -2441,13 +2441,13 @@ of class templates 400 CD1 Using-declarations and the "struct hack" - Unknown + Yes 401 CD1 When is access for template parameter default arguments checked? - Unknown + Yes 402 @@ -2459,13 +2459,13 @@ of class templates 403 CD1 Reference to a type as a template-id - Unknown + Yes 404 CD1 Unclear reference to construction with non-trivial constructor - Unknown + N/A 405 @@ -2477,13 +2477,13 @@ of class templates 406 CD1 Static data member in class with name for linkage purposes - Unknown + Yes 407 C++11 Named class with associated typedef: two names or one? - Unknown + No 408 @@ -2495,13 +2495,13 @@ of class templates 409 CD1 Obsolete paragraph missed by changes for issue 224 - Unknown + Yes 410 CD1 Paragraph missed in changes for issue 166 - Unknown + No 411 @@ -2513,37 +2513,37 @@ of class templates 412 NAD Can a replacement allocation function be inline? - Unknown + Yes 413 CD1 Definition of "empty class" - Unknown + Yes 414 CD1 Multiple types found on destructor lookup - Unknown + Duplicate of 305 415 CD1 Template deduction does not cause instantiation - Unknown + Yes 416 CD1 Class must be complete to allow operator lookup? - Unknown + Yes 417 CD1 Using derived-class qualified name in out-of-class nested class definition - Unknown + No 418 @@ -2561,37 +2561,37 @@ of class templates 420 CD1 postfixexpression->scalar_type_dtor() inconsistent - Unknown + Yes 421 CD1 Is rvalue.field an rvalue? - Unknown + Yes 422 NAD Is a typedef redeclaration allowed with a template type that might be the same? - Unknown + Yes 423 NAD Can a conversion be done on the left operand of a compound assignment? - Unknown + Yes 424 CD1 Wording problem with issue 56 resolution on redeclaring typedefs in class scope - Unknown + Yes 425 CD1 Set of candidates for overloaded built-in operator with float operand - Unknown + Yes 426 @@ -2603,67 +2603,67 @@ of class templates 427 CD1 static_cast ambiguity: conversion versus cast to derived - Unknown + Yes 428 CD1 Mention of expression with reference type - Unknown + Yes 429 CD1 Matching deallocation function chosen based on syntax or signature? - Unknown + Yes (C++11 onwards) 430 CD1 Ordering of expression evaluation in initializer list - Unknown + Yes (C++11 onwards) 431 C++11 Defect in wording in 14.2 - Unknown + Yes 432 CD1 Is injected class name visible in base class specifier list? - Unknown + Yes 433 CD1 Do elaborated type specifiers in templates inject into enclosing namespace scope? - Unknown + Yes 434 NAD Unclear suppression of standard conversions while binding reference to lvalue - Unknown + Yes 435 NAD Change "declararation or definition" to "declaration" - Unknown + N/A 436 CD1 Problem in example in 9.6 paragraph 4 - Unknown + Yes 437 CD1 Is type of class allowed in member function exception specification? - Unknown + No 438 @@ -2693,55 +2693,55 @@ of class templates 442 CD1 Incorrect use of null pointer constant in description of delete operator - Unknown + Superseded by 348 443 CD1 Wording nit in description of lifetime of temporaries - Unknown + N/A 444 NAD Overriding and the generated copy assignment operator - Unknown + Yes 445 NAD Wording issue on friend declarations - Unknown + Yes 446 CD1 Does an lvalue-to-rvalue conversion on the "?" operator produce a temporary? - Unknown + Yes 447 CD1 Is offsetof type-dependent? - Unknown + Yes 448 C++11 Set of template functions in call with dependent explicit argument - Unknown + Yes 449 NAD Consistency in use of hyphen with names of "non" entities - Unknown + N/A 450 CD1 Binding a reference to const to a cv-qualified array rvalue - Unknown + Yes 451