From 4ba8e62629200847d59473fdcbec32c71599f6b9 Mon Sep 17 00:00:00 2001 From: Richard Smith Date: Sun, 31 Aug 2014 03:06:20 +0000 Subject: [PATCH] Tests for DR525-550. git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@216834 91177308-0d34-0410-b5e6-96231b3b80d8 --- test/CXX/drs/dr5xx.cpp | 316 +++++++++++++++++++++++++++++++++++++++++ www/cxx_dr_status.html | 40 +++--- 2 files changed, 336 insertions(+), 20 deletions(-) diff --git a/test/CXX/drs/dr5xx.cpp b/test/CXX/drs/dr5xx.cpp index 0c0d451c4b..7b0c7e668d 100644 --- a/test/CXX/drs/dr5xx.cpp +++ b/test/CXX/drs/dr5xx.cpp @@ -195,6 +195,153 @@ namespace dr525 { // dr525: yes } } +namespace dr526 { // dr526: yes + template struct S {}; + template void f1(S s); + template void f2(S<(N)> s); // expected-note {{couldn't infer}} + template void f3(S<+N> s); // expected-note {{couldn't infer}} + template void g1(int (&)[N]); + template void g2(int (&)[(N)]); // expected-note {{couldn't infer}} + template 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 struct X { + typedef int type; + X::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 struct S { enum { N = 1 }; }; + template 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 struct A { + void f(T) { T::error; } + template void g(T, U) { T::error; } + struct B { typename T::error error; }; + template struct C { typename T::error error; }; + static T n; + }; + template T A::n = T::error; + + template<> void A::f(int) {} + template<> template void A::g(int, U) {} + template<> struct A::B {}; + template<> template struct A::C {}; + template<> int A::n = 0; + + void use(A a) { + a.f(a.n); + a.g(0, 0); + A::B b; + A::C c; + } + + template<> struct A { + void f(char); + template void g(char, U); + struct B; + template struct C; + static char n; + }; + + void A::f(char) {} + template void A::g(char, U) {} + struct A::B {}; + template struct A::C {}; + char A::n = 0; + } + + namespace bad { + template struct A { + void f(T) { T::error; } + template void g(T, U) { T::error; } + struct B { typename T::error error; }; + template struct C { typename T::error error; }; // expected-note {{here}} + static T n; + }; + template T A::n = T::error; + + void A::f(int) {} // expected-error {{requires 'template<>'}} + template void A::g(int, U) {} // expected-error {{should be empty}} + struct A::B {}; // expected-error {{requires 'template<>'}} + template struct A::C {}; // expected-error {{should be empty}} expected-error {{different kind of symbol}} + int A::n = 0; // expected-error {{requires 'template<>'}} + + template<> struct A { // expected-note 2{{here}} + void f(char); + template void g(char, U); + struct B; // expected-note {{here}} + template struct C; + static char n; + }; + + template<> void A::f(char) {} // expected-error {{no function template matches}} + // FIXME: This is ill-formed; -pedantic-errors should reject. + template<> template void A::g(char, U) {} // expected-warning {{extraneous template parameter list}} + template<> struct A::B {}; // expected-error {{extraneous 'template<>'}} expected-error {{does not specialize}} + // FIXME: This is ill-formed; -pedantic-errors should reject. + template<> template struct A::C {}; // expected-warning {{extraneous template parameter list}} + template<> char A::n = 0; // expected-error {{extraneous 'template<>'}} + } + + namespace nested { + template struct A { + template struct B; + }; + template<> template struct A::B { + void f(); + void g(); + template void h(); + template void i(); + }; + template<> template void A::B::f() {} + template void A::B::g() {} // expected-error {{should be empty}} + + template<> template template void A::B::h() {} + template template void A::B::i() {} // expected-error {{should be empty}} + + template<> template<> void A::B::f() {} + template<> template<> template void A::B::h() {} + template<> template<> template<> void A::B::h() {} + + template<> void A::B::f() {} // expected-error {{requires 'template<>'}} + template<> template void A::B::h() {} // expected-error {{should be empty}} + } +} + // PR8130 namespace dr532 { // dr532: 3.5 struct A { }; @@ -210,3 +357,172 @@ namespace dr532 { // dr532: 3.5 int &ir = b * a; } } + +// dr533: na + +namespace dr534 { // dr534: yes + struct S {}; + template void operator+(S, T); + template void operator+(S, T*) {} // expected-error {{function template partial spec}} +} + +namespace dr535 { // dr535: yes + class X { private: X(const X&); }; + struct A { + X x; + template 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 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 struct X { typedef int type; }; + template 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::type a; // expected-error +{{}} + X::type b; // expected-error +{{}} + X::type b; // expected-error +{{}} + + typename X::type a; + typename X::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 struct A { int n; }; + template struct B : A { int get(); }; + template<> int B::get() { return n; } + int k = B().get(); +} + +namespace dr546 { // dr546: yes + template struct A { void f(); }; + template struct A; + template void A::f() { T::error; } +} + +namespace dr547 { // d547: yes + template struct X; + template struct X {}; + template X f(T C::*) { return X(); } + + struct S { void f() const; }; + X x = f(&S::f); +} + +namespace dr548 { // dr548: dup 482 + template struct S {}; + template void f() {} + template struct dr548::S; + template void dr548::f(); +} diff --git a/www/cxx_dr_status.html b/www/cxx_dr_status.html index 6d27d00a0c..dba3275df9 100644 --- a/www/cxx_dr_status.html +++ b/www/cxx_dr_status.html @@ -675,7 +675,7 @@ 106 CD1 Creating references to references during template deduction/instantiation - Superseded by 540 + Superseded by 540 107 @@ -705,7 +705,7 @@ 111 NAD Copy constructors and cv-qualifiers - Duplicate of 535 + Duplicate of 535 112 @@ -2003,7 +2003,7 @@ of class templates 327 CD1 Use of "structure" without definition - Duplicate of 538 + Duplicate of 538 328 @@ -3197,13 +3197,13 @@ of class templates 526 CD1 Confusing aspects in the specification of non-deduced contexts - Unknown + Yes 527 CD2 Problems with linkage of types - Unknown + N/A 528 @@ -3221,13 +3221,13 @@ of class templates 530 CD1 Nontype template arguments in constant expressions - Unknown + Yes 531 C++11 Defining members of explicit specializations - Unknown + Partial 532 @@ -3239,19 +3239,19 @@ of class templates 533 NAD Special treatment for C-style header names - Unknown + N/A 534 CD1 template-names and operator-function-ids - Unknown + Yes 535 CD3 Copy construction without a copy constructor - Unknown + Yes 536 @@ -3263,7 +3263,7 @@ of class templates 537 CD1 Definition of “signature” - Unknown + N/A 538 @@ -3271,43 +3271,43 @@ of class templates Definition and usage of structure, POD-struct, POD-union, and POD class - Unknown + N/A 539 CD3 Constraints on type-specifier-seq - Unknown + Yes 540 CD1 Propagation of cv-qualifiers in reference-to-reference collapse - Unknown + Yes 541 CD2 Dependent function types - Unknown + Yes 542 CD2 Value initialization of arrays of POD-structs - Unknown + Yes 543 CD1 Value initialization and default constructors - Unknown + Yes 544 NAD Base class lookup in explicit specialization - Unknown + Yes 545 @@ -3319,7 +3319,7 @@ and POD class 546 C++11 Explicit instantiation of class template members - Unknown + Yes 547 @@ -3331,7 +3331,7 @@ and POD class 548 dup qualified-ids in declarations - Unknown + Duplicate of 482 549 -- 2.40.0