aboutsummaryrefslogtreecommitdiff
path: root/test/CXX/drs/dr4xx.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'test/CXX/drs/dr4xx.cpp')
-rw-r--r--test/CXX/drs/dr4xx.cpp1197
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; }
+}