diff options
Diffstat (limited to 'test/CXX/drs/dr3xx.cpp')
-rw-r--r-- | test/CXX/drs/dr3xx.cpp | 1285 |
1 files changed, 1285 insertions, 0 deletions
diff --git a/test/CXX/drs/dr3xx.cpp b/test/CXX/drs/dr3xx.cpp new file mode 100644 index 0000000000000..53fc20e23fe69 --- /dev/null +++ b/test/CXX/drs/dr3xx.cpp @@ -0,0 +1,1285 @@ +// RUN: %clang_cc1 -std=c++98 %s -verify -fexceptions -fcxx-exceptions -pedantic-errors +// RUN: %clang_cc1 -std=c++11 %s -verify -fexceptions -fcxx-exceptions -pedantic-errors +// RUN: %clang_cc1 -std=c++1y %s -verify -fexceptions -fcxx-exceptions -pedantic-errors + +namespace dr300 { // dr300: yes + template<typename R, typename A> void f(R (&)(A)) {} + int g(int); + void h() { f(g); } +} + +namespace dr301 { // dr301: yes + // see also dr38 + struct S; + template<typename T> void operator+(T, T); + void operator-(S, S); + + void f() { + bool a = (void(*)(S, S))operator+<S> < + (void(*)(S, S))operator+<S>; + bool b = (void(*)(S, S))operator- < + (void(*)(S, S))operator-; + bool c = (void(*)(S, S))operator+ < + (void(*)(S, S))operator-; // expected-error {{expected '>'}} + } + + template<typename T> void f() { + typename T::template operator+<int> a; // expected-error {{typename specifier refers to a non-type template}} expected-error +{{}} + // FIXME: This shouldn't say (null). + class T::template operator+<int> b; // expected-error {{identifier followed by '<' indicates a class template specialization but (null) refers to a function template}} + enum T::template operator+<int> c; // expected-error {{expected identifier}} expected-error {{does not declare anything}} + enum T::template operator+<int>::E d; // expected-error {{qualified name refers into a specialization of function template 'T::template operator +'}} expected-error {{forward reference}} + enum T::template X<int>::E e; + T::template operator+<int>::foobar(); // expected-error {{qualified name refers into a specialization of function template 'T::template operator +'}} + T::template operator+<int>(0); // ok + } + + template<typename T> class operator&<T*> {}; // expected-error +{{}} + template<typename T> class T::operator& {}; // expected-error +{{}} + template<typename T> class S::operator&<T*> {}; // expected-error +{{}} +} + +namespace dr302 { // dr302: yes + struct A { A(); ~A(); }; +#if __cplusplus < 201103L + struct B { // expected-error {{implicit default constructor for 'dr302::B' must explicitly initialize the const member 'n'}} + const int n; // expected-note {{declared here}} + A a; + } b = B(); // expected-note {{first required here}} + // Trivial default constructor C::C() is not called here. + struct C { + const int n; + } c = C(); +#else + struct B { + const int n; // expected-note {{deleted because field 'n' of const-qualified type 'const int' would not be initialized}} + A a; + } b = B(); // expected-error {{call to implicitly-deleted default constructor}} + // C::C() is called here, because even though it's trivial, it's deleted. + struct C { + const int n; // expected-note {{deleted because field 'n' of const-qualified type 'const int' would not be initialized}} + } c = C(); // expected-error {{call to implicitly-deleted default constructor}} + struct D { + const int n = 0; + } d = D(); +#endif +} + +// dr303: na + +namespace dr304 { // dr304: yes + typedef int &a; + int n = a(); // expected-error {{requires an initializer}} + + struct S { int &b; }; + int m = S().b; +#if __cplusplus < 201103L + // expected-error@-3 {{requires an initializer}} + // expected-note@-3 {{in value-initialization}} +#else + // expected-error@-5 {{deleted}} + // expected-note@-7 {{reference}} +#endif +} + +namespace dr305 { // dr305: no + struct A { + typedef A C; + }; + void f(A *a) { + struct A {}; + a->~A(); + a->~C(); + } + typedef A B; + void g(B *b) { + b->~B(); + b->~C(); + } + void h(B *b) { + struct B {}; // expected-note {{declared here}} + b->~B(); // expected-error {{does not match}} + } + + template<typename T> struct X {}; + void i(X<int>* x) { + struct X {}; + x->~X<int>(); + x->~X(); + x->~X<char>(); // expected-error {{no member named}} + } + + // FIXME: This appears to be valid (but allowing the nested types might be a + // defect). + template<typename> struct Nested { + template<typename> struct Nested {}; + }; + void testNested(Nested<int> n) { n.~Nested<int>(); } // expected-error {{no member named}} +#if __cplusplus < 201103L + // expected-error@-2 {{ambiguous}} + // expected-note@-6 {{here}} + // expected-note@-6 {{here}} +#endif + +#if __cplusplus >= 201103L + struct Y { + template<typename T> using T1 = Y; + }; + template<typename T> using T2 = Y; + void j(Y *y) { + y->~T1<int>(); + y->~T2<int>(); + } + struct Z { + template<typename T> using T2 = T; + }; + void k(Z *z) { + // FIXME: This diagnostic is terrible. + z->~T1<int>(); // expected-error {{'T1' following the 'template' keyword does not refer to a template}} expected-error +{{}} + z->~T2<int>(); // expected-error {{no member named '~int'}} + z->~T2<Z>(); + } + + // FIXME: This is valid. + namespace Q { + template<typename A> struct R {}; + } + template<typename A> using R = Q::R<int>; + void qr(Q::R<int> x) { x.~R<char>(); } // expected-error {{no member named}} +#endif +} + +namespace dr306 { // dr306: no + // FIXME: dup 39 + // FIXME: This should be accepted. + struct A { struct B {}; }; // expected-note 2{{member}} + struct C { typedef A::B B; }; // expected-note {{member}} + struct D : A, A::B, C {}; + D::B b; // expected-error {{found in multiple base classes of different types}} +} + +// dr307: na + +namespace dr308 { // dr308: yes + // This is mostly an ABI library issue. + struct A {}; + struct B : A {}; + struct C : A {}; + struct D : B, C {}; + void f() { + try { + throw D(); + } catch (const A&) { + // unreachable + } catch (const B&) { + // get here instead + } + } +} + +// dr309: dup 485 + +namespace dr311 { // dr311: yes + namespace X { namespace Y {} } + namespace X::Y {} // expected-error {{must define each namespace separately}} + namespace X { + namespace X::Y {} // expected-error {{must define each namespace separately}} + } + // FIXME: The diagnostics here are not very good. + namespace ::dr311::X {} // expected-error 2+{{}} // expected-warning {{extra qual}} +} + +// dr312: dup 616 + +namespace dr313 { // dr313: dup 299 c++11 + struct A { operator int() const; }; + int *p = new int[A()]; +#if __cplusplus < 201103L + // FIXME: should this be available in c++98 mode? expected-error@-2 {{extension}} +#endif +} + +namespace dr314 { // dr314: dup 1710 + template<typename T> struct A { + template<typename U> struct B {}; + }; + template<typename T> struct C : public A<T>::template B<T> { + C() : A<T>::template B<T>() {} + }; +} + +// dr315: na +// dr316: sup 1004 + +namespace dr317 { // dr317: 3.5 + void f() {} // expected-note {{previous}} + inline void f(); // expected-error {{inline declaration of 'f' follows non-inline definition}} + + int g(); + int n = g(); + inline int g() { return 0; } + + int h(); + int m = h(); + int h() { return 0; } // expected-note {{previous}} + inline int h(); // expected-error {{inline declaration of 'h' follows non-inline definition}} +} + +namespace dr318 { // dr318: sup 1310 + struct A {}; + struct A::A a; +} + +namespace dr319 { // dr319: no + // FIXME: dup dr389 + // FIXME: We don't have a diagnostic for a name with linkage + // having a type without linkage. + typedef struct { + int i; + } *ps; + extern "C" void f(ps); + void g(ps); // FIXME: ill-formed, type 'ps' has no linkage + + static enum { e } a1; + enum { e2 } a2; // FIXME: ill-formed, enum type has no linkage + + enum { n1 = 1u }; + typedef int (*pa)[n1]; + pa parr; // ok, type has linkage despite using 'n1' + + template<typename> struct X {}; + + void f() { + struct A { int n; }; + extern A a; // FIXME: ill-formed + X<A> xa; + + typedef A B; + extern B b; // FIXME: ill-formed + X<B> xb; + + const int n = 1; + typedef int (*C)[n]; + extern C c; // ok + X<C> xc; + } +#if __cplusplus < 201103L + // expected-error@-12 {{uses local type 'A'}} + // expected-error@-9 {{uses local type 'A'}} +#endif +} + +namespace dr320 { // dr320: yes +#if __cplusplus >= 201103L + struct X { + constexpr X() {} + constexpr X(const X &x) : copies(x.copies + 1) {} + unsigned copies = 0; + }; + constexpr X f(X x) { return x; } + constexpr unsigned g(X x) { return x.copies; } + static_assert(f(X()).copies == g(X()) + 1, "expected one extra copy for return value"); +#endif +} + +namespace dr321 { // dr321: dup 557 + namespace N { + template<int> struct A { + template<int> struct B; + }; + template<> template<> struct A<0>::B<0>; + void f(A<0>::B<0>); + } + template<> template<> struct N::A<0>::B<0> {}; + + template<typename T> void g(T t) { f(t); } + template void g(N::A<0>::B<0>); + + namespace N { + template<typename> struct I { friend bool operator==(const I&, const I&); }; + } + N::I<int> i, j; + bool x = i == j; +} + +namespace dr322 { // dr322: yes + struct A { + template<typename T> operator T&(); + } a; + int &r = static_cast<int&>(a); + int &s = a; +} + +// dr323: no + +namespace dr324 { // dr324: yes + struct S { int n : 1; } s; // expected-note 3{{bit-field is declared here}} + int &a = s.n; // expected-error {{non-const reference cannot bind to bit-field}} + int *b = &s.n; // expected-error {{address of bit-field}} + int &c = (s.n = 0); // expected-error {{non-const reference cannot bind to bit-field}} + int *d = &(s.n = 0); // expected-error {{address of bit-field}} + int &e = true ? s.n : s.n; // expected-error {{non-const reference cannot bind to bit-field}} + int *f = &(true ? s.n : s.n); // expected-error {{address of bit-field}} + int &g = (void(), s.n); // expected-error {{non-const reference cannot bind to bit-field}} + int *h = &(void(), s.n); // expected-error {{address of bit-field}} +} + +namespace dr326 { // dr326: yes + struct S {}; + int test[__is_trivially_constructible(S, const S&) ? 1 : -1]; +} + +namespace dr327 { // dr327: dup 538 + struct A; + class A {}; + + class B; + struct B {}; +} + +namespace dr328 { // dr328: yes + struct A; // expected-note 3{{forward declaration}} + struct B { A a; }; // expected-error {{incomplete}} + template<typename> struct C { A a; }; // expected-error {{incomplete}} + A *p = new A[0]; // expected-error {{incomplete}} +} + +namespace dr329 { // dr329: 3.5 + struct B {}; + template<typename T> struct A : B { + friend void f(A a) { g(a); } + friend void h(A a) { g(a); } // expected-error {{undeclared}} + friend void i(B b) {} // expected-error {{redefinition}} expected-note {{previous}} + }; + A<int> a; + A<char> b; // expected-note {{instantiation}} + + void test() { + h(a); // expected-note {{instantiation}} + } +} + +namespace dr331 { // dr331: yes + struct A { + A(volatile A&); // expected-note {{candidate}} + } const a, b(a); // expected-error {{no matching constructor}} +} + +namespace dr332 { // dr332: dup 557 + void f(volatile void); // expected-error {{'void' as parameter must not have type qualifiers}} + void g(const void); // expected-error {{'void' as parameter must not have type qualifiers}} + void h(int n, volatile void); // expected-error {{'void' must be the first and only parameter}} +} + +namespace dr333 { // dr333: yes + int n = 0; + int f(int(n)); + int g((int(n))); + int h = f(g); +} + +namespace dr334 { // dr334: yes + template<typename T> void f() { + T x; + f((x, 123)); + } + struct S { + friend S operator,(S, int); + friend void f(S); + }; + template void f<S>(); +} + +// dr335: no + +namespace dr336 { // dr336: yes + namespace Pre { + template<class T1> class A { + template<class T2> class B { + template<class T3> void mf1(T3); + void mf2(); + }; + }; + template<> template<class X> class A<int>::B {}; + template<> template<> template<class T> void A<int>::B<double>::mf1(T t) {} // expected-error {{does not match}} + template<class Y> template<> void A<Y>::B<double>::mf2() {} // expected-error {{does not refer into a class}} + } + namespace Post { + template<class T1> class A { + template<class T2> class B { + template<class T3> void mf1(T3); + void mf2(); + }; + }; + template<> template<class X> class A<int>::B { + template<class T> void mf1(T); + }; + template<> template<> template<class T> void A<int>::B<double>::mf1(T t) {} + // FIXME: This diagnostic isn't very good. + template<class Y> template<> void A<Y>::B<double>::mf2() {} // expected-error {{does not refer into a class}} + } +} + +namespace dr337 { // dr337: yes + template<typename T> void f(T (*)[1]); + template<typename T> int &f(...); + + struct A { virtual ~A() = 0; }; + int &r = f<A>(0); + + // FIXME: The language rules here are completely broken. We cannot determine + // whether an incomplete type is abstract. See DR1640, which will probably + // supersede this one and remove this rule. + struct B; + int &s = f<B>(0); // expected-error {{of type 'void'}} + struct B { virtual ~B() = 0; }; +} + +namespace dr339 { // dr339: yes + template <int I> struct A { static const int value = I; }; + + char xxx(int); + char (&xxx(float))[2]; + + template<class T> A<sizeof(xxx((T)0))> f(T) {} // expected-note {{candidate}} + + void test() { + A<1> a = f(0); + A<2> b = f(0.0f); + A<3> c = f("foo"); // expected-error {{no matching function}} + } + + + char f(int); + int f(...); + + template <class T> struct conv_int { + static const bool value = sizeof(f(T())) == 1; + }; + + template <class T> bool conv_int2(A<sizeof(f(T()))> p); + + template<typename T> A<sizeof(f(T()))> make_A(); + + int a[conv_int<char>::value ? 1 : -1]; + bool b = conv_int2<char>(A<1>()); + A<1> c = make_A<char>(); +} + +namespace dr340 { // dr340: yes + struct A { A(int); }; + struct B { B(A, A, int); }; + int x, y; + B b(A(x), A(y), 3); +} + +namespace dr341 { // dr341: sup 1708 + namespace A { + int n; + extern "C" int &dr341_a = n; // expected-note {{previous}} expected-note {{declared with C language linkage here}} + } + namespace B { + extern "C" int &dr341_a = dr341_a; // expected-error {{redefinition}} + } + extern "C" void dr341_b(); // expected-note {{declared with C language linkage here}} +} +int dr341_a; // expected-error {{declaration of 'dr341_a' in global scope conflicts with declaration with C language linkage}} +int dr341_b; // expected-error {{declaration of 'dr341_b' in global scope conflicts with declaration with C language linkage}} +int dr341_c; // expected-note {{declared in global scope here}} +int dr341_d; // expected-note {{declared in global scope here}} +namespace dr341 { + extern "C" int dr341_c; // expected-error {{declaration of 'dr341_c' with C language linkage conflicts with declaration in global scope}} + extern "C" void dr341_d(); // expected-error {{declaration of 'dr341_d' with C language linkage conflicts with declaration in global scope}} + + namespace A { extern "C" int dr341_e; } // expected-note {{previous}} + namespace B { extern "C" void dr341_e(); } // expected-error {{redefinition of 'dr341_e' as different kind of symbol}} +} + +// dr342: na + +namespace dr343 { // dr343: no + // FIXME: dup 1710 + template<typename T> struct A { + template<typename U> struct B {}; + }; + // FIXME: In these contexts, the 'template' keyword is optional. + template<typename T> struct C : public A<T>::B<T> { // expected-error {{use 'template'}} + C() : A<T>::B<T>() {} // expected-error {{use 'template'}} + }; +} + +namespace dr344 { // dr344: dup 1435 + struct A { inline virtual ~A(); }; + struct B { friend A::~A(); }; +} + +namespace dr345 { // dr345: yes + struct A { + struct X {}; + int X; // expected-note {{here}} + }; + struct B { + struct X {}; + }; + template <class T> void f(T t) { typename T::X x; } // expected-error {{refers to non-type member 'X'}} + void f(A a, B b) { + f(b); + f(a); // expected-note {{instantiation}} + } +} + +// dr346: na + +namespace dr347 { // dr347: yes + struct base { + struct nested; + static int n; + static void f(); + void g(); + }; + + struct derived : base {}; + + struct derived::nested {}; // expected-error {{no struct named 'nested'}} + int derived::n; // expected-error {{no member named 'n'}} + void derived::f() {} // expected-error {{does not match any}} + void derived::g() {} // expected-error {{does not match any}} +} + +// dr348: na + +namespace dr349 { // dr349: no + struct A { + template <class T> operator T ***() { + int ***p = 0; + return p; // expected-error {{cannot initialize return object of type 'const int ***' with an lvalue of type 'int ***'}} + } + }; + + // FIXME: This is valid. + A a; + const int *const *const *p1 = a; // expected-note {{in instantiation of}} + + struct B { + template <class T> operator T ***() { + const int ***p = 0; + return p; + } + }; + + // FIXME: This is invalid. + B b; + const int *const *const *p2 = b; +} + +// dr351: na + +namespace dr352 { // dr352: yes + namespace example1 { + namespace A { + enum E {}; + template<typename R, typename A> void foo(E, R (*)(A)); // expected-note 2{{couldn't infer template argument 'R'}} + } + + template<typename T> void arg(T); + template<typename T> int arg(T) = delete; // expected-note {{here}} expected-error 0-1{{extension}} + + void f(A::E e) { + foo(e, &arg); // expected-error {{no matching function}} + + using A::foo; + foo<int, int>(e, &arg); // expected-error {{deleted}} + } + + int arg(int); + + void g(A::E e) { + foo(e, &arg); // expected-error {{no matching function}} + + using A::foo; + foo<int, int>(e, &arg); // ok, uses non-template + } + } + + namespace contexts { + template<int I> void f1(int (&)[I]); + template<int I> void f2(int (&)[I+1]); // expected-note {{couldn't infer}} + template<int I> void f3(int (&)[I+1], int (&)[I]); + void f() { + int a[4]; + int b[3]; + f1(a); + f2(a); // expected-error {{no matching function}} + f3(a, b); + } + + template<int I> struct S {}; + template<int I> void g1(S<I>); + template<int I> void g2(S<I+1>); // expected-note {{couldn't infer}} + template<int I> void g3(S<I+1>, S<I>); + void g() { + S<4> a; + S<3> b; + g1(a); + g2(a); // expected-error {{no matching function}} + g3(a, b); + } + + template<typename T> void h1(T = 0); // expected-note {{couldn't infer}} + template<typename T> void h2(T, T = 0); + void h() { + h1(); // expected-error {{no matching function}} + h1(0); + h1<int>(); + h2(0); + } + + template<typename T> int tmpl(T); + template<typename R, typename A> void i1(R (*)(A)); // expected-note 3{{couldn't infer}} + template<typename R, typename A> void i2(R, A, R (*)(A)); // expected-note {{not viable}} + void i() { + extern int single(int); + i1(single); + i2(0, 0, single); + + extern int ambig(float), ambig(int); + i1(ambig); // expected-error {{no matching function}} + i2(0, 0, ambig); + + extern void no_match(float), no_match(int); + i1(no_match); // expected-error {{no matching function}} + i2(0, 0, no_match); // expected-error {{no matching function}} + + i1(tmpl); // expected-error {{no matching function}} + i2(0, 0, tmpl); + } + } + + template<typename T> struct is_int; + template<> struct is_int<int> {}; + + namespace example2 { + template<typename T> int f(T (*p)(T)) { is_int<T>(); } + int g(int); + int g(char); + int i = f(g); + } + + namespace example3 { + template<typename T> int f(T, T (*p)(T)) { is_int<T>(); } + int g(int); + char g(char); + int i = f(1, g); + } + + namespace example4 { + template <class T> int f(T, T (*p)(T)) { is_int<T>(); } + char g(char); + template <class T> T g(T); + int i = f(1, g); + } + + namespace example5 { + template<int I> class A {}; + template<int I> void g(A<I+1>); // expected-note {{couldn't infer}} + template<int I> void f(A<I>, A<I+1>); + void h(A<1> a1, A<2> a2) { + g(a1); // expected-error {{no matching function}} + g<0>(a1); + f(a1, a2); + } + } +} + +// dr353 needs an IRGen test. + +namespace dr354 { // dr354: yes c++11 + // FIXME: Should we allow this in C++98 too? + struct S {}; + + template<int*> struct ptr {}; // expected-note +{{here}} + ptr<0> p0; + ptr<(int*)0> p1; + ptr<(float*)0> p2; + ptr<(int S::*)0> p3; +#if __cplusplus < 201103L + // expected-error@-5 {{does not refer to any decl}} + // expected-error@-5 {{does not refer to any decl}} + // expected-error@-5 {{does not refer to any decl}} + // expected-error@-5 {{does not refer to any decl}} +#else + // expected-error@-10 {{must be cast}} + // ok + // expected-error@-10 {{does not match}} + // expected-error@-10 {{does not match}} +#endif + + template<int*> int both(); + template<int> int both(); + int b0 = both<0>(); + int b1 = both<(int*)0>(); +#if __cplusplus < 201103L + // expected-error@-2 {{no matching function}} + // expected-note@-6 {{candidate}} + // expected-note@-6 {{candidate}} +#endif + + template<int S::*> struct ptr_mem {}; // expected-note +{{here}} + ptr_mem<0> m0; + ptr_mem<(int S::*)0> m1; + ptr_mem<(float S::*)0> m2; + ptr_mem<(int *)0> m3; +#if __cplusplus < 201103L + // expected-error@-5 {{cannot be converted}} + // expected-error@-5 {{is not a pointer to member constant}} + // expected-error@-5 {{cannot be converted}} + // expected-error@-5 {{cannot be converted}} +#else + // expected-error@-10 {{must be cast}} + // ok + // expected-error@-10 {{does not match}} + // expected-error@-10 {{does not match}} +#endif +} + +struct dr355_S; // dr355: yes +struct ::dr355_S {}; // expected-warning {{extra qualification}} +namespace dr355 { struct ::dr355_S s; } + +// dr356: na + +namespace dr357 { // dr357: yes + template<typename T> struct A { + void f() const; // expected-note {{const qualified}} + }; + template<typename T> void A<T>::f() {} // expected-error {{does not match}} + + struct B { + template<typename T> void f(); + }; + template<typename T> void B::f() const {} // expected-error {{does not match}} +} + +namespace dr358 { // dr358: yes + extern "C" void dr358_f(); + namespace N { + int var; + extern "C" void dr358_f() { var = 10; } + } +} + +namespace dr359 { // dr359: yes + // Note, the example in the DR is wrong; it doesn't contain an anonymous + // union. + struct E { + union { + struct { + int x; + } s; + } v; + + union { + struct { // expected-error {{extension}} + int x; + } s; + + struct S { // expected-error {{types cannot be declared in an anonymous union}} + int x; + } t; + + union { // expected-error {{extension}} + int u; + }; + }; + }; +} + +// dr362: na +// dr363: na + +namespace dr364 { // dr364: yes + struct S { + static void f(int); + void f(char); + }; + + void g() { + S::f('a'); // expected-error {{call to non-static}} + S::f(0); + } +} + +#if "foo" // expected-error {{invalid token}} dr366: yes +#endif + +namespace dr367 { // dr367: yes + // FIXME: These diagnostics are terrible. Don't diagnose an ill-formed global + // array as being a VLA! + int a[true ? throw 0 : 4]; // expected-error 2{{variable length array}} + int b[true ? 4 : throw 0]; + int c[true ? *new int : 4]; // expected-error 2{{variable length array}} + int d[true ? 4 : *new int]; +#if __cplusplus < 201103L + // expected-error@-4 {{variable length array}} expected-error@-4 {{constant expression}} + // expected-error@-3 {{variable length array}} expected-error@-3 {{constant expression}} +#endif +} + +namespace dr368 { // dr368: yes + template<typename T, T> struct S {}; // expected-note {{here}} + template<typename T> int f(S<T, T()> *); // expected-error {{function type}} + //template<typename T> int g(S<T, (T())> *); // FIXME: crashes clang + template<typename T> int g(S<T, true ? T() : T()> *); // expected-note {{cannot have type 'dr368::X'}} + struct X {}; + int n = g<X>(0); // expected-error {{no matching}} +} + +// dr370: na + +namespace dr372 { // dr372: no + namespace example1 { + template<typename T> struct X { + protected: + typedef T Type; // expected-note 2{{protected}} + }; + template<typename T> struct Y {}; + + // FIXME: These two are valid; deriving from T1<T> gives Z1 access to + // the protected member T1<T>::Type. + template<typename T, + template<typename> class T1, + template<typename> class T2> struct Z1 : + T1<T>, + T2<typename T1<T>::Type> {}; // expected-error {{protected}} + + template<typename T, + template<typename> class T1, + template<typename> class T2> struct Z2 : + T2<typename T1<T>::Type>, // expected-error {{protected}} + T1<T> {}; + + Z1<int, X, Y> z1; // expected-note {{instantiation of}} + Z2<int, X, Y> z2; // expected-note {{instantiation of}} + } + + namespace example2 { + struct X { + private: + typedef int Type; // expected-note {{private}} + }; + template<typename T> struct A { + typename T::Type t; // expected-error {{private}} + }; + A<X> ax; // expected-note {{instantiation of}} + } + + namespace example3 { + struct A { + protected: + typedef int N; // expected-note 2{{protected}} + }; + + template<typename T> struct B {}; + template<typename U> struct C : U, B<typename U::N> {}; // expected-error {{protected}} + template<typename U> struct D : B<typename U::N>, U {}; // expected-error {{protected}} + + C<A> x; // expected-note {{instantiation of}} + D<A> y; // expected-note {{instantiation of}} + } + + namespace example4 { + class A { + class B {}; + friend class X; + }; + + struct X : A::B { + A::B mx; + class Y { + A::B my; + }; + }; + } +} + +namespace dr373 { // dr373: no + // FIXME: This is valid. + namespace X { int dr373; } // expected-note 2{{here}} + struct dr373 { // expected-note {{here}} + void f() { + using namespace dr373::X; // expected-error {{no namespace named 'X' in 'dr373::dr373'}} + int k = dr373; // expected-error {{does not refer to a value}} + + namespace Y = dr373::X; // expected-error {{no namespace named 'X' in 'dr373::dr373'}} + k = Y::dr373; + } + }; +} + +namespace dr374 { // dr374: yes c++11 + namespace N { + template<typename T> void f(); + template<typename T> struct A { void f(); }; + } + template<> void N::f<char>() {} + template<> void N::A<char>::f() {} + template<> struct N::A<int> {}; +#if __cplusplus < 201103L + // expected-error@-4 {{extension}} expected-note@-7 {{here}} + // expected-error@-4 {{extension}} expected-note@-7 {{here}} + // expected-error@-4 {{extension}} expected-note@-8 {{here}} +#endif +} + +// dr375: dup 345 +// dr376: na + +namespace dr377 { // dr377: yes + enum E { // expected-error {{enumeration values exceed range of largest integer}} + a = -__LONG_LONG_MAX__ - 1, // expected-error 0-1{{extension}} + b = 2 * (unsigned long long)__LONG_LONG_MAX__ // expected-error 0-2{{extension}} + }; +} + +// dr378: dup 276 +// dr379: na + +namespace dr381 { // dr381: yes + struct A { + int a; + }; + struct B : virtual A {}; + struct C : B {}; + struct D : B {}; + struct E : public C, public D {}; + struct F : public A {}; + void f() { + E e; + e.B::a = 0; // expected-error {{ambiguous conversion}} + F f; + f.A::a = 1; + } +} + +namespace dr382 { // dr382: yes c++11 + // FIXME: Should we allow this in C++98 mode? + struct A { typedef int T; }; + typename A::T t; + typename dr382::A a; +#if __cplusplus < 201103L + // expected-error@-3 {{occurs outside of a template}} + // expected-error@-3 {{occurs outside of a template}} +#endif + typename A b; // expected-error {{expected a qualified name}} +} + +namespace dr383 { // dr383: yes + struct A { A &operator=(const A&); }; + struct B { ~B(); }; + union C { C &operator=(const C&); }; + union D { ~D(); }; + int check[(__is_pod(A) || __is_pod(B) || __is_pod(C) || __is_pod(D)) ? -1 : 1]; +} + +namespace dr384 { // dr384: yes + namespace N1 { + template<typename T> struct Base {}; + template<typename T> struct X { + struct Y : public Base<T> { + Y operator+(int) const; + }; + Y f(unsigned i) { return Y() + i; } + }; + } + + namespace N2 { + struct Z {}; + template<typename T> int *operator+(T, unsigned); + } + + int main() { + N1::X<N2::Z> v; + v.f(0); + } +} + +namespace dr385 { // dr385: yes + struct A { protected: void f(); }; + struct B : A { using A::f; }; + struct C : A { void g(B b) { b.f(); } }; + void h(B b) { b.f(); } + + struct D { int n; }; // expected-note {{member}} + struct E : protected D {}; // expected-note 2{{protected}} + struct F : E { friend int i(E); }; + int i(E e) { return e.n; } // expected-error {{protected base}} expected-error {{protected member}} +} + +namespace dr387 { // dr387: yes + namespace old { + template<typename T> class number { + number(int); // expected-note 2{{here}} + friend number gcd(number &x, number &y) {} + }; + + void g() { + number<double> a(3), b(4); // expected-error 2{{private}} + a = gcd(a, b); + b = gcd(3, 4); // expected-error {{undeclared}} + } + } + + namespace newer { + template <typename T> class number { + public: + number(int); + friend number gcd(number x, number y) { return 0; } + }; + + void g() { + number<double> a(3), b(4); + a = gcd(a, b); + b = gcd(3, 4); // expected-error {{undeclared}} + } + } +} + +// FIXME: dr388 needs codegen test + +namespace dr389 { // dr389: no + struct S { + typedef struct {} A; + typedef enum {} B; + typedef struct {} const C; // expected-note 0-2{{here}} + typedef enum {} const D; // expected-note 0-1{{here}} + }; + template<typename> struct T {}; + + struct WithLinkage1 {}; + enum WithLinkage2 {}; + typedef struct {} *WithLinkage3a, WithLinkage3b; + typedef enum {} WithLinkage4a, *WithLinkage4b; + typedef S::A WithLinkage5; + typedef const S::B WithLinkage6; + typedef int WithLinkage7; + typedef void (*WithLinkage8)(WithLinkage2 WithLinkage1::*, WithLinkage5 *); + typedef T<WithLinkage5> WithLinkage9; + + typedef struct {} *WithoutLinkage1; // expected-note 0-1{{here}} + typedef enum {} const WithoutLinkage2; // expected-note 0-1{{here}} + // These two types don't have linkage even though they are externally visible + // and the ODR requires them to be merged across TUs. + typedef S::C WithoutLinkage3; + typedef S::D WithoutLinkage4; + typedef void (*WithoutLinkage5)(int (WithoutLinkage3::*)(char)); + +#if __cplusplus >= 201103L + // This has linkage even though its template argument does not. + // FIXME: This is probably a defect. + typedef T<WithoutLinkage1> WithLinkage10; +#else + typedef int WithLinkage10; // dummy + + typedef T<WithLinkage1> GoodArg1; + typedef T<WithLinkage2> GoodArg2; + typedef T<WithLinkage3a> GoodArg3a; + typedef T<WithLinkage3b> GoodArg3b; + typedef T<WithLinkage4a> GoodArg4a; + typedef T<WithLinkage4b> GoodArg4b; + typedef T<WithLinkage5> GoodArg5; + typedef T<WithLinkage6> GoodArg6; + typedef T<WithLinkage7> GoodArg7; + typedef T<WithLinkage8> GoodArg8; + typedef T<WithLinkage9> GoodArg9; + + typedef T<WithoutLinkage1> BadArg1; // expected-error{{template argument uses}} + typedef T<WithoutLinkage2> BadArg2; // expected-error{{template argument uses}} + typedef T<WithoutLinkage3> BadArg3; // expected-error{{template argument uses}} + typedef T<WithoutLinkage4> BadArg4; // expected-error{{template argument uses}} + typedef T<WithoutLinkage5> BadArg5; // expected-error{{template argument uses}} +#endif + + extern WithLinkage1 withLinkage1; + extern WithLinkage2 withLinkage2; + extern WithLinkage3a withLinkage3a; + extern WithLinkage3b withLinkage3b; + extern WithLinkage4a withLinkage4a; + extern WithLinkage4b withLinkage4b; + extern WithLinkage5 withLinkage5; + extern WithLinkage6 withLinkage6; + extern WithLinkage7 withLinkage7; + extern WithLinkage8 withLinkage8; + extern WithLinkage9 withLinkage9; + extern WithLinkage10 withLinkage10; + + // FIXME: These are all ill-formed. + extern WithoutLinkage1 withoutLinkage1; + extern WithoutLinkage2 withoutLinkage2; + extern WithoutLinkage3 withoutLinkage3; + extern WithoutLinkage4 withoutLinkage4; + extern WithoutLinkage5 withoutLinkage5; + + // OK, extern "C". + extern "C" { + extern WithoutLinkage1 dr389_withoutLinkage1; + extern WithoutLinkage2 dr389_withoutLinkage2; + extern WithoutLinkage3 dr389_withoutLinkage3; + extern WithoutLinkage4 dr389_withoutLinkage4; + extern WithoutLinkage5 dr389_withoutLinkage5; + } + + // OK, defined. + WithoutLinkage1 withoutLinkageDef1; + WithoutLinkage2 withoutLinkageDef2 = WithoutLinkage2(); + WithoutLinkage3 withoutLinkageDef3 = {}; + WithoutLinkage4 withoutLinkageDef4 = WithoutLinkage4(); + WithoutLinkage5 withoutLinkageDef5; + + void use(const void *); + void use_all() { + use(&withLinkage1); use(&withLinkage2); use(&withLinkage3a); use(&withLinkage3b); + use(&withLinkage4a); use(&withLinkage4b); use(&withLinkage5); use(&withLinkage6); + use(&withLinkage7); use(&withLinkage8); use(&withLinkage9); use(&withLinkage10); + + use(&withoutLinkage1); use(&withoutLinkage2); use(&withoutLinkage3); + use(&withoutLinkage4); use(&withoutLinkage5); + + use(&dr389_withoutLinkage1); use(&dr389_withoutLinkage2); + use(&dr389_withoutLinkage3); use(&dr389_withoutLinkage4); + use(&dr389_withoutLinkage5); + + use(&withoutLinkageDef1); use(&withoutLinkageDef2); use(&withoutLinkageDef3); + use(&withoutLinkageDef4); use(&withoutLinkageDef5); + } + + void local() { + // FIXME: This is ill-formed. + extern WithoutLinkage1 withoutLinkageLocal; + } +} + +namespace dr390 { // dr390: yes + template<typename T> + struct A { + A() { f(); } // expected-warning {{call to pure virt}} + virtual void f() = 0; // expected-note {{here}} + virtual ~A() = 0; + }; + template<typename T> A<T>::~A() { T::error; } // expected-error {{cannot be used prior to}} + template<typename T> void A<T>::f() { T::error; } // ok, not odr-used + struct B : A<int> { // expected-note 2{{in instantiation of}} + void f() {} + } b; +} + +namespace dr391 { // dr391: yes c++11 + // FIXME: Should this apply to C++98 too? + class A { A(const A&); }; // expected-note 0-1{{here}} + A fa(); + const A &a = fa(); +#if __cplusplus < 201103L + // expected-error@-2 {{C++98 requires an accessible copy constructor}} +#endif + + struct B { B(const B&) = delete; }; // expected-error 0-1{{extension}} expected-note 0-1{{here}} + B fb(); + const B &b = fb(); +#if __cplusplus < 201103L + // expected-error@-2 {{deleted}} +#endif + + template<typename T> + struct C { + C(const C&) { T::error; } + }; + C<int> fc(); + const C<int> &c = fc(); +} + +// dr392 FIXME write codegen test +// dr394: na + +namespace dr395 { // dr395: yes + struct S { + template <typename T, int N>(&operator T())[N]; // expected-error {{must use a typedef}} + template <typename T, int N> operator(T (&)[N])(); // expected-error {{expected ')'}} expected-note {{to match this '('}} expected-error +{{}} + template <typename T> operator T *() const { return 0; } + template <typename T, typename U> operator T U::*() const { return 0; } + template <typename T, typename U> operator T (U::*)()() const { return 0; } // expected-error +{{}} + }; + + struct null1_t { + template <class T, class U> struct ptr_mem_fun_t { + typedef T (U::*type)(); + }; + + template <class T, class U> + operator typename ptr_mem_fun_t<T, U>::type() const { // expected-note {{couldn't infer}} + return 0; + } + } null1; + int (S::*p)() = null1; // expected-error {{no viable conversion}} + + template <typename T> using id = T; // expected-error 0-1{{extension}} + + struct T { + template <typename T, int N> operator id<T[N]> &(); + template <typename T, typename U> operator id<T (U::*)()>() const; + }; + + struct null2_t { + template<class T, class U> using ptr_mem_fun_t = T (U::*)(); // expected-error 0-1{{extension}} + template<class T, class U> operator ptr_mem_fun_t<T, U>() const { return 0; }; + } null2; + int (S::*q)() = null2; +} + +namespace dr396 { // dr396: yes + void f() { + auto int a(); // expected-error {{storage class on function}} + int (i); // expected-note {{previous}} + auto int (i); // expected-error {{redefinition}} +#if __cplusplus >= 201103L + // expected-error@-4 {{'auto' storage class}} expected-error@-2 {{'auto' storage class}} +#endif + } +} + +// dr397: sup 1823 + +namespace dr398 { // dr398: yes + namespace example1 { + struct S { + static int const I = 42; + }; + template <int N> struct X {}; + template <typename T> void f(X<T::I> *) {} + template <typename T> void f(X<T::J> *) {} + void foo() { f<S>(0); } + } + + namespace example2 { + template <int I> struct X {}; + template <template <class T> class> struct Z {}; + template <class T> void f(typename T::Y *) {} // expected-note 2{{substitution failure}} + template <class T> void g(X<T::N> *) {} // expected-note {{substitution failure}} + template <class T> void h(Z<T::template TT> *) {} // expected-note {{substitution failure}} + struct A {}; + struct B { + int Y; + }; + struct C { + typedef int N; + }; + struct D { + typedef int TT; + }; + + void test() { + f<A>(0); // expected-error {{no matching function}} + f<B>(0); // expected-error {{no matching function}} + g<C>(0); // expected-error {{no matching function}} + h<D>(0); // expected-error {{no matching function}} + } + } +} |