diff options
Diffstat (limited to 'test/CXX/drs/dr4xx.cpp')
-rw-r--r-- | test/CXX/drs/dr4xx.cpp | 1197 |
1 files changed, 1194 insertions, 3 deletions
diff --git a/test/CXX/drs/dr4xx.cpp b/test/CXX/drs/dr4xx.cpp index 1d3b94064cdd..815dbfc0b401 100644 --- a/test/CXX/drs/dr4xx.cpp +++ b/test/CXX/drs/dr4xx.cpp @@ -1,6 +1,140 @@ -// 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 -// expected-no-diagnostics +// 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 + +// FIXME: __SIZE_TYPE__ expands to 'long long' on some targets. +__extension__ typedef __SIZE_TYPE__ size_t; + +namespace std { struct type_info; } + +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 T, class U = typename T::type> 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<C>; // expected-note {{default argument}} + }; + + class D { + typedef int type; // expected-note {{private}} + friend class A<D, int>; + }; + + A<B> *b; // expected-note {{default argument}} + // FIXME: We're missing the "in instantiation of" note for the default + // argument here. + A<D> *d; + + struct E { + template<class T, class U = typename T::type> class A : public T {}; + }; + class F { + typedef int type; + friend class E; + }; + E::A<F> 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<class T, class U = typename T::type> 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<typename T> struct X {}; + typedef struct X<A::S>::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<int N> void g() { int arr[N != 1 ? 1 : -1]; } @@ -30,3 +164,1060 @@ namespace dr408 { // dr408: 3.4 template<> int R<int>::arr[2]; template void R<int>::f(); } + +namespace dr409 { // dr409: yes + template<typename T> struct A { + typedef int B; + B b1; + A::B b2; + A<T>::B b3; + A<T*>::B b4; // expected-error {{missing 'typename'}} + }; +} + +namespace dr410 { // dr410: no + template<class T> void f(T); + void g(int); + namespace M { + template<class T> void h(T); + template<class T> void i(T); + struct A { + friend void f<>(int); + friend void h<>(int); + friend void g(int); + template<class T> 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}} + + struct E {}; + struct T { // expected-note {{here}} + int a; + E e; + int b; + }; + T t1 = { 1, {}, 2 }; + T t2 = { 1, 2 }; // expected-error {{aggregate with no elements requires explicit braces}} +} + +namespace dr414 { // dr414: dup 305 + struct X {}; + void f() { + X x; + struct X {}; + x.~X(); + } +} + +namespace dr415 { // dr415: yes + template<typename T> 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<typename T> struct ptr { + T *operator->() const; + T &operator*() const; + }; + template<typename T, typename P> void test(P p) { + p->~T(); + p->T::~T(); + (*p).~T(); + (*p).T::~T(); + } + struct X {}; + template void test<int>(int*); + template void test<int>(ptr<int>); + template void test<X>(X*); + template void test<X>(ptr<X>); + + template<typename T> + void test2(T p) { + p->template Y<int>::~Y<int>(); + p->~Y<int>(); + // FIXME: This is ill-formed, but this diagnostic is terrible. We should + // reject this in the parser. + p->template ~Y<int>(); // expected-error 2{{no member named '~typename Y<int>'}} + } + template<typename T> struct Y {}; + template void test2(Y<int>*); // expected-note {{instantiation}} + template void test2(ptr<Y<int> >); // expected-note {{instantiation}} + + void test3(int *p, ptr<int> q) { + typedef int Int; + p->~Int(); + q->~Int(); + p->Int::~Int(); + q->Int::~Int(); + } + +#if __cplusplus >= 201103L + template<typename T> using id = T; + struct A { template<typename T> using id = T; }; + void test4(int *p, ptr<int> q) { + p->~id<int>(); + q->~id<int>(); + p->id<int>::~id<int>(); + q->id<int>::~id<int>(); + p->template id<int>::~id<int>(); // expected-error {{expected unqualified-id}} + q->template id<int>::~id<int>(); // expected-error {{expected unqualified-id}} + p->A::template id<int>::~id<int>(); + q->A::template id<int>::~id<int>(); + } +#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<typename T, typename U> void f() { + typedef T type; // expected-note {{prev}} + typedef U type; // expected-error {{redef}} + } + template void f<int, int>(); + template void f<int, char>(); // expected-note {{instantiation}} +} + +namespace dr423 { // dr423: yes + template<typename T> struct X { operator T&(); }; + void f(X<int> 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<typename T> operator T() const; } a; + float f = 1.0f * a; // expected-error {{ambiguous}} expected-note 5+{{built-in candidate}} + + template<typename T> struct is_float; + template<> struct is_float<float> { typedef void type; }; + + struct B { + template<typename T, typename U = typename is_float<T>::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<const D&>(b); + const D &d3 = (const D&)b; + const D &d4(b); // expected-error {{deleted}} +} + +namespace dr428 { // dr428: yes + template<typename T> T make(); + extern struct X x; // expected-note 5{{forward declaration}} + void f() { + throw void(); // expected-error {{cannot throw}} + throw make<void*>(); + throw make<const volatile void*>(); + throw x; // expected-error {{cannot throw}} + throw make<X&>(); // expected-error {{cannot throw}} + throw make<X*>(); // expected-error {{cannot throw}} + throw make<const volatile X&>(); // expected-error {{cannot throw}} + throw make<const volatile X*>(); // expected-error {{cannot throw}} + } +} + +namespace dr429 { // dr429: yes c++11 + // FIXME: This rule is obviously intended to apply to C++98 as well. + 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<typename T> T *get(); + template<typename T> struct B { + template<typename U> U *get(); + }; + }; + + template<typename T> void f(A a) { + a.get<A>()->get<T>(); + a.get<T>() + ->get<T>(); // expected-error {{use 'template'}} + a.get<T>()->template get<T>(); + a.A::get<T>(); + A::B<int> *b = a.get<A::B<int> >(); + b->get<int>(); + b->A::B<int>::get<int>(); + b->A::B<int>::get<T>(); + b->A::B<T>::get<int>(); // expected-error {{use 'template'}} + b->A::B<T>::template get<int>(); + b->A::B<T>::get<T>(); // expected-error {{use 'template'}} + b->A::B<T>::template get<T>(); + A::B<T> *c = a.get<A::B<T> >(); + c->get<int>(); // expected-error {{use 'template'}} + c->template get<int>(); + } +} + +namespace dr432 { // dr432: yes + template<typename T> struct A {}; + template<typename T> struct B : A<B> {}; // expected-error {{requires template arguments}} expected-note {{declared}} + template<typename T> struct C : A<C<T> > {}; +#if __cplusplus >= 201103L + template<typename T> struct D : decltype(A<D>()) {}; // expected-error {{requires template arguments}} expected-note {{declared}} +#endif +} + +namespace dr433 { // dr433: yes + template<class T> struct S { + void f(union U*); + }; + U *p; + template<class T> void S<T>::f(union U*) {} + + S<int> 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<typename U> struct T : U {}; // expected-error {{incomplete}} + struct S { // expected-note {{not complete}} + 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}} + 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<int> struct U { + typedef int type; + template<typename V> static void h(); + }; + template<typename T> U<sizeof(T)> g(T); + template<typename T, int N> void f(int n) { + // ok, not type dependent + g(__builtin_offsetof(A, n)).h<int>(); + g(__builtin_offsetof(T, n)).h<int>(); + // 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<int>(); // expected-error {{extension}} + g(__builtin_offsetof(A, a[N])).h<int>(); // 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<typename T = int> void f(int); // expected-error 0-1{{extension}} expected-note {{no known conversion}} + template<typename T> void g(T t) { + f<T>(t); // expected-error {{neither visible in the template definition nor found by argument-dependent lookup}} + dr448::f(t); // expected-error {{no matching function}} + } + template<typename T> 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 dr451 { // dr451: yes + const int a = 1 / 0; // expected-warning {{undefined}} + const int b = 1 / 0; // expected-warning {{undefined}} + int arr[b]; // expected-error +{{variable length arr}} +} + +namespace dr452 { // dr452: yes + struct A { + int a, b, c; + A *p; + int f(); + A() : a(f()), b(this->f() + a), c(this->a), p(this) {} + }; +} + +// dr454 FIXME write a codegen test + +namespace dr456 { // dr456: yes + // sup 903 c++11 + const int null = 0; + void *p = null; +#if __cplusplus >= 201103L + // expected-error@-2 {{cannot initialize}} +#else + // expected-warning@-4 {{null}} +#endif + + const bool f = false; + void *q = f; +#if __cplusplus >= 201103L + // expected-error@-2 {{cannot initialize}} +#else + // expected-warning@-4 {{null}} +#endif +} + +namespace dr457 { // dr457: yes + const int a = 1; + const volatile int b = 1; + int ax[a]; + int bx[b]; // expected-error +{{variable length array}} + + enum E { + ea = a, + eb = b // expected-error {{not an integral constant}} expected-note {{read of volatile-qualified}} + }; +} + +namespace dr458 { // dr458: no + struct A { + int T; + int f(); + template<typename> int g(); + }; + + template<typename> struct B : A { + int f(); + template<typename> int g(); + template<typename> int h(); + }; + + int A::f() { + return T; + } + template<typename T> + int A::g() { + return T; // FIXME: this is invalid, it finds the template parameter + } + + template<typename T> + int B<T>::f() { + return T; + } + template<typename T> template<typename U> + int B<T>::g() { + return T; + } + template<typename U> template<typename T> + int B<U>::h() { + return T; // FIXME: this is invalid, it finds the template parameter + } +} + +namespace dr460 { // dr460: yes + namespace X { namespace Q { int n; } } + namespace Y { + using X; // expected-error {{requires a qualified name}} + using dr460::X; // expected-error {{cannot refer to namespace}} + using X::Q; // expected-error {{cannot refer to namespace}} + } +} + +// dr461: na +// dr462 FIXME write a codegen test +// dr463: na +// dr464: na +// dr465: na + +namespace dr466 { // dr466: no + typedef int I; + typedef const int CI; + typedef volatile int VI; + void f(int *a, CI *b, VI *c) { + a->~I(); + a->~CI(); + a->~VI(); + a->I::~I(); + a->CI::~CI(); + a->VI::~VI(); + + a->CI::~VI(); // FIXME: This is invalid; CI and VI are not the same scalar type. + + b->~I(); + b->~CI(); + b->~VI(); + b->I::~I(); + b->CI::~CI(); + b->VI::~VI(); + + c->~I(); + c->~CI(); + c->~VI(); + c->I::~I(); + c->CI::~CI(); + c->VI::~VI(); + } +} + +namespace dr467 { // dr467: yes + int stuff(); + + int f() { + static bool done; + if (done) + goto later; + static int k = stuff(); + done = true; + later: + return k; + } + int g() { + goto later; // expected-error {{protected scope}} + int k = stuff(); // expected-note {{bypasses variable initialization}} + later: + return k; + } +} + +namespace dr468 { // dr468: yes c++11 + // FIXME: Should we allow this in C++98 too? + template<typename> struct A { + template<typename> struct B { + static int C; + }; + }; + int k = dr468::template A<int>::template B<char>::C; +#if __cplusplus < 201103L + // expected-error@-2 2{{'template' keyword outside of a template}} +#endif +} + +namespace dr469 { // dr469: no + // FIXME: The core issue here didn't really answer the question. We don't + // deduce 'const T' from a function or reference type in a class template... + template<typename T> struct X; // expected-note 2{{here}} + template<typename T> struct X<const T> {}; + X<int&> x; // expected-error {{undefined}} + X<int()> y; // expected-error {{undefined}} + + // ... but we do in a function template. GCC and EDG fail deduction of 'f' + // and the second 'h'. + template<typename T> void f(const T *); + template<typename T> void g(T *, const T * = 0); + template<typename T> void h(T *) { T::error; } + template<typename T> void h(const T *); + void i() { + f(&i); + g(&i); + h(&i); + } +} + +namespace dr470 { // dr470: yes + template<typename T> struct A { + struct B {}; + }; + template<typename T> struct C { + }; + + template struct A<int>; // expected-note {{previous}} + template struct A<int>::B; // expected-error {{duplicate explicit instantiation}} + + // ok, instantiating C<char> doesn't instantiate base class members. + template struct A<char>; + template struct C<char>; +} + +namespace dr471 { // dr471: yes + struct A { int n; }; + struct B : private virtual A {}; + struct C : protected virtual A {}; + struct D : B, C { int f() { return n; } }; + struct E : private virtual A { + using A::n; + }; + struct F : E, B { int f() { return n; } }; + struct G : virtual A { + private: + using A::n; // expected-note {{here}} + }; + struct H : B, G { int f() { return n; } }; // expected-error {{private}} +} + +namespace dr474 { // dr474: yes + namespace N { + struct S { + void f(); + }; + } + void N::S::f() { + void g(); // expected-note {{previous}} + } + int g(); + namespace N { + int g(); // expected-error {{cannot be overloaded}} + } +} + +// dr475 FIXME write a codegen test + +namespace dr477 { // dr477: 3.5 + struct A { + explicit A(); + virtual void f(); + }; + struct B { + friend explicit A::A(); // expected-error {{'explicit' is invalid in friend declarations}} + friend virtual void A::f(); // expected-error {{'virtual' is invalid in friend declarations}} + }; + explicit A::A() {} // expected-error {{can only be specified inside the class definition}} + virtual void A::f() {} // expected-error {{can only be specified inside the class definition}} +} + +namespace dr478 { // dr478: yes + struct A { virtual void f() = 0; }; // expected-note {{unimplemented}} + void f(A *a); + void f(A a[10]); // expected-error {{array of abstract class type}} +} + +namespace dr479 { // dr479: yes + struct S { + S(); + private: + S(const S&); // expected-note +{{here}} + ~S(); // expected-note +{{here}} + }; + void f() { + throw S(); + // expected-error@-1 {{temporary of type 'dr479::S' has private destructor}} + // expected-error@-2 {{calling a private constructor}} + // expected-error@-3 {{exception object of type 'dr479::S' has private destructor}} +#if __cplusplus < 201103L + // expected-error@-5 {{C++98 requires an accessible copy constructor}} +#endif + } + void g() { + S s; // expected-error {{private destructor}}} + throw s; + // expected-error@-1 {{calling a private constructor}} + // expected-error@-2 {{exception object of type 'dr479::S' has private destructor}} + } + void h() { + try { + f(); + g(); + } catch (S s) { + // expected-error@-1 {{calling a private constructor}} + // expected-error@-2 {{variable of type 'dr479::S' has private destructor}} + } + } +} + +namespace dr480 { // dr480: yes + struct A { int n; }; + struct B : A {}; + struct C : virtual B {}; + struct D : C {}; + + int A::*a = &A::n; + int D::*b = a; // expected-error {{virtual base}} + + extern int D::*c; + int A::*d = static_cast<int A::*>(c); // expected-error {{virtual base}} + + D *e; + A *f = e; + D *g = static_cast<D*>(f); // expected-error {{virtual base}} + + extern D &i; + A &j = i; + D &k = static_cast<D&>(j); // expected-error {{virtual base}} +} + +namespace dr481 { // dr481: yes + template<class T, T U> class A { T *x; }; + T *x; // expected-error {{unknown type}} + + template<class T *U> class B { T *x; }; + T *y; // ok + + struct C { + template<class T> void f(class D *p); + }; + D *z; // ok + + template<typename A = C, typename C = A> struct E { + void f() { + typedef ::dr481::C c; // expected-note {{previous}} + typedef C c; // expected-error {{different type}} + } + }; + template struct E<>; // ok + template struct E<int>; // expected-note {{instantiation of}} + + template<template<typename U_no_typo_correction> class A, + A<int> *B, + U_no_typo_correction *C> // expected-error {{unknown type}} + struct F { + U_no_typo_correction *x; // expected-error {{unknown type}} + }; + + template<template<class H *> class> struct G { + H *x; + }; + H *q; + + typedef int N; + template<N X, typename N, template<N Y> class T> struct I; + template<char*> struct J; + I<123, char*, J> *j; +} + +namespace dr482 { // dr482: 3.5 + extern int a; + void f(); + + int dr482::a = 0; // expected-warning {{extra qualification}} + void dr482::f() {} // expected-warning {{extra qualification}} + + inline namespace X { // expected-error 0-1{{C++11 feature}} + extern int b; + void g(); + struct S; + } + int dr482::b = 0; // expected-warning {{extra qualification}} + void dr482::g() {} // expected-warning {{extra qualification}} + struct dr482::S {}; // expected-warning {{extra qualification}} + + void dr482::f(); // expected-warning {{extra qualification}} + void dr482::g(); // expected-warning {{extra qualification}} + + // FIXME: The following are valid in DR482's wording, but these are bugs in + // the wording which we deliberately don't implement. + namespace N { typedef int type; } + typedef int N::type; // expected-error {{typedef declarator cannot be qualified}} + struct A { + struct B; + struct A::B {}; // expected-error {{extra qualification}} + +#if __cplusplus >= 201103L + enum class C; + enum class A::C {}; // expected-error {{extra qualification}} +#endif + }; +} + +namespace dr483 { // dr483: yes + namespace climits { + int check1[__SCHAR_MAX__ >= 127 ? 1 : -1]; + int check2[__SHRT_MAX__ >= 32767 ? 1 : -1]; + int check3[__INT_MAX__ >= 32767 ? 1 : -1]; + int check4[__LONG_MAX__ >= 2147483647 ? 1 : -1]; + int check5[__LONG_LONG_MAX__ >= 9223372036854775807 ? 1 : -1]; +#if __cplusplus < 201103L + // expected-error@-2 {{extension}} +#endif + } + namespace cstdint { + int check1[__PTRDIFF_WIDTH__ >= 16 ? 1 : -1]; + int check2[__SIG_ATOMIC_WIDTH__ >= 8 ? 1 : -1]; + int check3[__SIZE_WIDTH__ >= 16 ? 1 : -1]; + int check4[__WCHAR_WIDTH__ >= 8 ? 1 : -1]; + int check5[__WINT_WIDTH__ >= 16 ? 1 : -1]; + } +} + +namespace dr484 { // dr484: yes + struct A { + A(); + void f(); + }; + typedef const A CA; + void CA::f() { + this->~CA(); + this->CA::~A(); + this->CA::A::~A(); + } + CA::A() {} + + struct B : CA { + B() : CA() {} + void f() { return CA::f(); } + }; + + struct C; + typedef C CT; // expected-note {{here}} + struct CT {}; // expected-error {{conflicts with typedef}} + + namespace N { + struct D; + typedef D DT; // expected-note {{here}} + } + struct N::DT {}; // expected-error {{conflicts with typedef}} + + typedef struct { + S(); // expected-error {{requires a type}} + } S; +} + +namespace dr485 { // dr485: yes + namespace N { + struct S {}; + int operator+(S, S); + template<typename T> int f(S); + } + template<typename T> int f(); + + N::S s; + int a = operator+(s, s); + int b = f<int>(s); +} + +namespace dr486 { // dr486: yes + template<typename T> T f(T *); // expected-note 2{{substitution failure}} + int &f(...); + + void g(); + int n[10]; + + void h() { + int &a = f(&g); + int &b = f(&n); + f<void()>(&g); // expected-error {{no match}} + f<int[10]>(&n); // expected-error {{no match}} + } +} + +namespace dr487 { // dr487: yes + enum E { e }; + int operator+(int, E); + int i[4 + e]; // expected-error 2{{variable length array}} +} + +namespace dr488 { // dr488: yes c++11 + template <typename T> void f(T); + void f(int); + void g() { + // FIXME: It seems CWG thought this should be a SFINAE failure prior to + // allowing local types as template arguments. In C++98, we should either + // allow local types as template arguments or treat this as a SFINAE + // failure. + enum E { e }; + f(e); +#if __cplusplus < 201103L + // expected-error@-2 {{local type}} +#endif + } +} + +// dr489: na + +namespace dr490 { // dr490: yes + template<typename T> struct X {}; + + struct A { + typedef int T; + struct K {}; // expected-note {{declared}} + + int f(T); + int g(T); + int h(X<T>); + int X<T>::*i(); // expected-note {{previous}} + int K::*j(); + + template<typename T> T k(); + + operator X<T>(); + }; + + struct B { + typedef char T; + typedef int U; + friend int A::f(T); + friend int A::g(U); + friend int A::h(X<T>); + + // FIXME: Per this DR, these two are valid! That is another defect + // (no number yet...) which will eventually supersede this one. + friend int X<T>::*A::i(); // expected-error {{return type}} + friend int K::*A::j(); // expected-error {{undeclared identifier 'K'; did you mean 'A::K'?}} + + // ok, lookup finds B::T, not A::T, so return type matches + friend char A::k<T>(); + friend int A::k<U>(); + + // A conversion-type-id in a conversion-function-id is always looked up in + // the class of the conversion function first. + friend A::operator X<T>(); + }; +} + +namespace dr491 { // dr491: dup 413 + struct A {} a, b[3] = { a, {} }; + A c[2] = { a, {}, b[1] }; // expected-error {{excess elements}} +} + +// dr492 FIXME write a codegen test + +namespace dr493 { // dr493: dup 976 + struct X { + template <class T> operator const T &() const; + }; + void f() { + if (X()) { + } + } +} + +namespace dr494 { // dr494: dup 372 + class A { + class B {}; + friend class C; + }; + class C : A::B { + A::B x; + class D : A::B { + A::B y; + }; + }; +} + +namespace dr495 { // dr495: 3.5 + template<typename T> + struct S { + operator int() { return T::error; } + template<typename U> operator U(); + }; + S<int> s; + long n = s; + + template<typename T> + struct S2 { + template<typename U> operator U(); + operator int() { return T::error; } + }; + S2<int> s2; + long n2 = s2; +} + +namespace dr496 { // dr496: no + struct A { int n; }; + struct B { volatile int n; }; + int check1[ __is_trivially_copyable(const int) ? 1 : -1]; + int check2[!__is_trivially_copyable(volatile int) ? 1 : -1]; + int check3[ __is_trivially_constructible(A, const A&) ? 1 : -1]; + // FIXME: This is wrong. + int check4[ __is_trivially_constructible(B, const B&) ? 1 : -1]; + int check5[ __is_trivially_assignable(A, const A&) ? 1 : -1]; + // FIXME: This is wrong. + int check6[ __is_trivially_assignable(B, const B&) ? 1 : -1]; +} + +namespace dr497 { // dr497: yes + void before() { + struct S { + mutable int i; + }; + const S cs; // expected-error {{default initialization}} + int S::*pm = &S::i; + cs.*pm = 88; + } + + void after() { + struct S { + S() : i(0) {} + mutable int i; + }; + const S cs; + int S::*pm = &S::i; + cs.*pm = 88; // expected-error {{not assignable}} + } +} + +namespace dr499 { // dr499: yes + extern char str[]; + void f() { throw str; } +} |