diff options
Diffstat (limited to 'test/CXX/drs')
-rw-r--r-- | test/CXX/drs/dr0xx.cpp | 1040 | ||||
-rw-r--r-- | test/CXX/drs/dr1xx.cpp | 1011 | ||||
-rw-r--r-- | test/CXX/drs/dr2xx.cpp | 726 | ||||
-rw-r--r-- | test/CXX/drs/dr4xx.cpp | 32 |
4 files changed, 2809 insertions, 0 deletions
diff --git a/test/CXX/drs/dr0xx.cpp b/test/CXX/drs/dr0xx.cpp new file mode 100644 index 0000000..265a52d --- /dev/null +++ b/test/CXX/drs/dr0xx.cpp @@ -0,0 +1,1040 @@ +// RUN: %clang_cc1 -std=c++98 %s -verify -fexceptions -fcxx-exceptions -pedantic-errors -Wno-bind-to-temporary-copy +// 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 dr1 { // dr1: no + namespace X { extern "C" void dr1_f(int a = 1); } + namespace Y { extern "C" void dr1_f(int a = 2); } + using X::dr1_f; using Y::dr1_f; + void g() { + dr1_f(0); + // FIXME: This should be rejected, due to the ambiguous default argument. + dr1_f(); + } + namespace X { + using Y::dr1_f; + void h() { + dr1_f(0); + // FIXME: This should be rejected, due to the ambiguous default argument. + dr1_f(); + } + } + + namespace X { + void z(int); + } + void X::z(int = 1) {} // expected-note {{previous}} + namespace X { + void z(int = 2); // expected-error {{redefinition of default argument}} + } +} + +namespace dr3 { // dr3: yes + template<typename T> struct A {}; + template<typename T> void f(T) { A<T> a; } // expected-note {{implicit instantiation}} + template void f(int); + template<> struct A<int> {}; // expected-error {{explicit specialization of 'dr3::A<int>' after instantiation}} +} + +namespace dr4 { // dr4: yes + extern "C" { + static void dr4_f(int) {} + static void dr4_f(float) {} + void dr4_g(int) {} // expected-note {{previous}} + void dr4_g(float) {} // expected-error {{conflicting types}} + } +} + +namespace dr5 { // dr5: yes + struct A {} a; + struct B { + B(const A&); + B(const B&); + }; + const volatile B b = a; + + struct C { C(C&); }; + struct D : C {}; + struct E { operator D&(); } e; + const C c = e; +} + +namespace dr7 { // dr7: yes + class A { public: ~A(); }; + class B : virtual private A {}; // expected-note 2 {{declared private here}} + class C : public B {} c; // expected-error 2 {{inherited virtual base class 'dr7::A' has private destructor}} \ + // expected-note {{implicit default constructor for 'dr7::C' first required here}} \ + // expected-note {{implicit destructor for 'dr7::C' first required here}} + class VeryDerivedC : public B, virtual public A {} vdc; + + class X { ~X(); }; // expected-note {{here}} + class Y : X { ~Y() {} }; // expected-error {{private destructor}} + + namespace PR16370 { // This regressed the first time DR7 was fixed. + struct S1 { virtual ~S1(); }; + struct S2 : S1 {}; + struct S3 : S2 {}; + struct S4 : virtual S2 {}; + struct S5 : S3, S4 { + S5(); + ~S5(); + }; + S5::S5() {} + } +} + +namespace dr8 { // dr8: dup 45 + class A { + struct U; + static const int k = 5; + void f(); + template<typename, int, void (A::*)()> struct T; + + T<U, k, &A::f> *g(); + }; + A::T<A::U, A::k, &A::f> *A::g() { return 0; } +} + +namespace dr9 { // dr9: yes + struct B { + protected: + int m; // expected-note {{here}} + friend int R1(); + }; + struct N : protected B { // expected-note 2{{protected}} + friend int R2(); + } n; + int R1() { return n.m; } // expected-error {{protected base class}} expected-error {{protected member}} + int R2() { return n.m; } +} + +namespace dr10 { // dr10: dup 45 + class A { + struct B { + A::B *p; + }; + }; +} + +namespace dr11 { // dr11: yes + template<typename T> struct A : T { + using typename T::U; + U u; + }; + template<typename T> struct B : T { + using T::V; + V v; // expected-error {{unknown type name}} + }; + struct X { typedef int U; }; + A<X> ax; +} + +namespace dr12 { // dr12: sup 239 + enum E { e }; + E &f(E, E = e); + void g() { + int &f(int, E = e); + // Under DR12, these call two different functions. + // Under DR239, they call the same function. + int &b = f(e); + int &c = f(1); + } +} + +namespace dr14 { // dr14: yes + namespace X { extern "C" int dr14_f(); } + namespace Y { extern "C" int dr14_f(); } + using namespace X; + using namespace Y; + int k = dr14_f(); + + class C { + int k; + friend int Y::dr14_f(); + } c; + namespace Z { + extern "C" int dr14_f() { return c.k; } + } + + namespace X { typedef int T; typedef int U; } // expected-note {{candidate}} + namespace Y { typedef int T; typedef long U; } // expected-note {{candidate}} + T t; // ok, same type both times + U u; // expected-error {{ambiguous}} +} + +namespace dr15 { // dr15: yes + template<typename T> void f(int); // expected-note {{previous}} + template<typename T> void f(int = 0); // expected-error {{default arguments cannot be added}} +} + +namespace dr16 { // dr16: yes + class A { // expected-note {{here}} + void f(); // expected-note {{here}} + friend class C; + }; + class B : A {}; // expected-note 4{{here}} + class C : B { + void g() { + f(); // expected-error {{private member}} expected-error {{private base}} + A::f(); // expected-error {{private member}} expected-error {{private base}} + } + }; +} + +namespace dr17 { // dr17: yes + class A { + int n; + int f(); + struct C; + }; + struct B : A {} b; + int A::f() { return b.n; } + struct A::C : A { + int g() { return n; } + }; +} + +namespace dr18 { // dr18: yes + typedef void Void; + void f(Void); // expected-error {{empty parameter list defined with a typedef of 'void'}} +} + +namespace dr19 { // dr19: yes + struct A { + int n; // expected-note {{here}} + }; + struct B : protected A { // expected-note {{here}} + }; + struct C : B {} c; + struct D : B { + int get1() { return c.n; } // expected-error {{protected member}} + int get2() { return ((A&)c).n; } // ok, A is an accessible base of B from here + }; +} + +namespace dr20 { // dr20: yes + class X { + public: + X(); + private: + X(const X&); // expected-note {{here}} + }; + X f(); + X x = f(); // expected-error {{private}} +} + +namespace dr21 { // dr21: yes + template<typename T> struct A; + struct X { + template<typename T = int> friend struct A; // expected-error {{default template argument not permitted on a friend template}} + template<typename T = int> friend struct B; // expected-error {{default template argument not permitted on a friend template}} + }; +} + +namespace dr22 { // dr22: sup 481 + template<typename dr22_T = dr22_T> struct X; // expected-error {{unknown type name 'dr22_T'}} + typedef int T; + template<typename T = T> struct Y; +} + +namespace dr23 { // dr23: yes + template<typename T> void f(T, T); // expected-note {{candidate}} + template<typename T> void f(T, int); // expected-note {{candidate}} + void g() { f(0, 0); } // expected-error {{ambiguous}} +} + +// dr24: na + +namespace dr25 { // dr25: yes + struct A { + void f() throw(int); + }; + void (A::*f)() throw (int); + void (A::*g)() throw () = f; // expected-error {{is not superset of source}} + void (A::*g2)() throw () = 0; + void (A::*h)() throw (int, char) = f; + void (A::*i)() throw () = &A::f; // expected-error {{is not superset of source}} + void (A::*i2)() throw () = 0; + void (A::*j)() throw (int, char) = &A::f; + void x() { + // FIXME: Don't produce the second error here. + g2 = f; // expected-error {{is not superset}} expected-error {{incompatible}} + h = f; + i2 = &A::f; // expected-error {{is not superset}} expected-error {{incompatible}} + j = &A::f; + } +} + +namespace dr26 { // dr26: yes + struct A { A(A, const A & = A()); }; // expected-error {{must pass its first argument by reference}} + struct B { + B(); // expected-note {{candidate}} + B(const B &, B = B()); // expected-error {{no matching constructor}} expected-note {{candidate}} expected-note {{here}} + }; +} + +namespace dr27 { // dr27: yes + enum E { e } n; + E &m = true ? n : n; +} + +// dr28: na + +namespace dr29 { // dr29: 3.4 + void dr29_f0(); // expected-note {{here}} + void g0() { void dr29_f0(); } + extern "C++" void g0_cxx() { void dr29_f0(); } + extern "C" void g0_c() { void dr29_f0(); } // expected-error {{different language linkage}} + + extern "C" void dr29_f1(); // expected-note {{here}} + void g1() { void dr29_f1(); } + extern "C" void g1_c() { void dr29_f1(); } + extern "C++" void g1_cxx() { void dr29_f1(); } // expected-error {{different language linkage}} + + void g2() { void dr29_f2(); } // expected-note {{here}} + extern "C" void dr29_f2(); // expected-error {{different language linkage}} + + extern "C" void g3() { void dr29_f3(); } // expected-note {{here}} + extern "C++" void dr29_f3(); // expected-error {{different language linkage}} + + extern "C++" void g4() { void dr29_f4(); } // expected-note {{here}} + extern "C" void dr29_f4(); // expected-error {{different language linkage}} + + extern "C" void g5(); + extern "C++" void dr29_f5(); + void g5() { + void dr29_f5(); // ok, g5 is extern "C" but we're not inside the linkage-specification here. + } + + extern "C++" void g6(); + extern "C" void dr29_f6(); + void g6() { + void dr29_f6(); // ok, g6 is extern "C" but we're not inside the linkage-specification here. + } + + extern "C" void g7(); + extern "C++" void dr29_f7(); // expected-note {{here}} + extern "C" void g7() { + void dr29_f7(); // expected-error {{different language linkage}} + } + + extern "C++" void g8(); + extern "C" void dr29_f8(); // expected-note {{here}} + extern "C++" void g8() { + void dr29_f8(); // expected-error {{different language linkage}} + } +} + +namespace dr30 { // dr30: sup 468 c++11 + struct A { + template<int> static int f(); + } a, *p = &a; + int x = A::template f<0>(); + int y = a.template f<0>(); + int z = p->template f<0>(); +#if __cplusplus < 201103L + // FIXME: It's not clear whether DR468 applies to C++98 too. + // expected-error@-5 {{'template' keyword outside of a template}} + // expected-error@-5 {{'template' keyword outside of a template}} + // expected-error@-5 {{'template' keyword outside of a template}} +#endif +} + +namespace dr31 { // dr31: yes + class X { + private: + void operator delete(void*); // expected-note {{here}} + }; + // We would call X::operator delete if X() threw (even though it can't, + // and even though we allocated the X using ::operator delete). + X *p = new X; // expected-error {{private}} +} + +// dr32: na + +namespace dr33 { // dr33: yes + namespace X { struct S; void f(void (*)(S)); } // expected-note {{candidate}} + namespace Y { struct T; void f(void (*)(T)); } // expected-note {{candidate}} + void g(X::S); + template<typename Z> Z g(Y::T); + void h() { f(&g); } // expected-error {{ambiguous}} +} + +// dr34: na +// dr35: dup 178 +// dr37: sup 475 + +namespace dr38 { // dr38: yes + template<typename T> struct X {}; + template<typename T> X<T> operator+(X<T> a, X<T> b) { return a; } + template X<int> operator+<int>(X<int>, X<int>); +} + +namespace dr39 { // dr39: no + namespace example1 { + struct A { int &f(int); }; + struct B : A { + using A::f; + float &f(float); + } b; + int &r = b.f(0); + } + + namespace example2 { + struct A { + int &x(int); // expected-note {{found}} + static int &y(int); // expected-note {{found}} + }; + struct V { + int &z(int); + }; + struct B : A, virtual V { + using A::x; // expected-note {{found}} + float &x(float); + using A::y; // expected-note {{found}} + static float &y(float); + using V::z; + float &z(float); + }; + struct C : A, B, virtual V {} c; + int &x = c.x(0); // expected-error {{found in multiple base classes}} + // FIXME: This is valid, because we find the same static data member either way. + int &y = c.y(0); // expected-error {{found in multiple base classes}} + int &z = c.z(0); + } + + namespace example3 { + struct A { static int f(); }; + struct B : virtual A { using A::f; }; + struct C : virtual A { using A::f; }; + struct D : B, C {} d; + int k = d.f(); + } + + namespace example4 { + struct A { int n; }; // expected-note {{found}} + struct B : A {}; + struct C : A {}; + struct D : B, C { int f() { return n; } }; // expected-error {{found in multiple base-class}} + } + + namespace PR5916 { + // FIXME: This is valid. + struct A { int n; }; // expected-note +{{found}} + struct B : A {}; + struct C : A {}; + struct D : B, C {}; + int k = sizeof(D::n); // expected-error {{found in multiple base}} expected-error {{unknown type name}} +#if __cplusplus >= 201103L + decltype(D::n) n; // expected-error {{found in multiple base}} +#endif + } +} + +// dr40: na + +namespace dr41 { // dr41: yes + struct S f(S); +} + +namespace dr42 { // dr42: yes + struct A { static const int k = 0; }; + struct B : A { static const int k = A::k; }; +} + +// dr43: na + +namespace dr44 { // dr44: yes + struct A { + template<int> void f(); + template<> void f<0>(); // expected-error {{explicit specialization of 'f' in class scope}} + }; +} + +namespace dr45 { // dr45: yes + class A { + class B {}; + class C : B {}; + C c; + }; +} + +namespace dr46 { // dr46: yes + template<typename> struct A { template<typename> struct B {}; }; + template template struct A<int>::B<int>; // expected-error {{expected unqualified-id}} +} + +namespace dr47 { // dr47: no + template<typename T> struct A { + friend void f() { T t; } + }; + A<int> a; + A<float> b; +#if __cplusplus < 201103L + // expected-error@-5 {{redefinition}} expected-note@-5 {{previous}} + // expected-note@-3 {{instantiation of}} +#else + void f(); + // FIXME: We should produce some kind of error here. C++11 [temp.friend]p4 + // says we instantiate 'f' when it's odr-used, but that doesn't imply that + // this is valid; we still have multiple definitions of 'f' even if we never + // instantiate any of them. + void g() { f(); } +#endif +} + +namespace dr48 { // dr48: yes + namespace { + struct S { + static const int m = 0; + static const int n = 0; + static const int o = 0; + }; + } + int a = S::m; + // FIXME: We should produce a 'has internal linkage but is not defined' + // diagnostic for 'S::n'. + const int &b = S::n; + const int S::o; + const int &c = S::o; +} + +namespace dr49 { // dr49: yes + template<int*> struct A {}; // expected-note {{here}} + int k; +#if __has_feature(cxx_constexpr) + constexpr +#endif + int *const p = &k; + A<&k> a; + A<p> b; // expected-error {{must have its address taken}} +#if __cplusplus < 201103L + // expected-error@-2 {{internal linkage}} + // expected-note@-5 {{here}} +#endif +} + +namespace dr50 { // dr50: yes + struct X; // expected-note {{forward}} + extern X *p; + X *q = (X*)p; + X *r = static_cast<X*>(p); + X *s = const_cast<X*>(p); + X *t = reinterpret_cast<X*>(p); + X *u = dynamic_cast<X*>(p); // expected-error {{incomplete}} +} + +namespace dr51 { // dr51: yes + struct A {}; + struct B : A {}; + struct S { + operator A&(); + operator B&(); + } s; + A &a = s; +} + +namespace dr52 { // dr52: yes + struct A { int n; }; // expected-note {{here}} + struct B : private A {} b; // expected-note 2{{private}} + // FIXME: This first diagnostic is very strangely worded, and seems to be bogus. + int k = b.A::n; // expected-error {{'A' is a private member of 'dr52::A'}} + // expected-error@-1 {{cannot cast 'struct B' to its private base}} +} + +namespace dr53 { // dr53: yes + int n = 0; + enum E { e } x = static_cast<E>(n); +} + +namespace dr54 { // dr54: yes + struct A { int a; } a; + struct V { int v; } v; + struct B : private A, virtual V { int b; } b; // expected-note 6{{private here}} + + A &sab = static_cast<A&>(b); // expected-error {{private base}} + A *spab = static_cast<A*>(&b); // expected-error {{private base}} + int A::*smab = static_cast<int A::*>(&B::b); // expected-error {{private base}} + B &sba = static_cast<B&>(a); // expected-error {{private base}} + B *spba = static_cast<B*>(&a); // expected-error {{private base}} + int B::*smba = static_cast<int B::*>(&A::a); // expected-error {{private base}} + + V &svb = static_cast<V&>(b); + V *spvb = static_cast<V*>(&b); + int V::*smvb = static_cast<int V::*>(&B::b); // expected-error {{virtual base}} + B &sbv = static_cast<B&>(v); // expected-error {{virtual base}} + B *spbv = static_cast<B*>(&v); // expected-error {{virtual base}} + int B::*smbv = static_cast<int B::*>(&V::v); // expected-error {{virtual base}} + + A &cab = (A&)(b); + A *cpab = (A*)(&b); + int A::*cmab = (int A::*)(&B::b); + B &cba = (B&)(a); + B *cpba = (B*)(&a); + int B::*cmba = (int B::*)(&A::a); + + V &cvb = (V&)(b); + V *cpvb = (V*)(&b); + int V::*cmvb = (int V::*)(&B::b); // expected-error {{virtual base}} + B &cbv = (B&)(v); // expected-error {{virtual base}} + B *cpbv = (B*)(&v); // expected-error {{virtual base}} + int B::*cmbv = (int B::*)(&V::v); // expected-error {{virtual base}} +} + +namespace dr55 { // dr55: yes + enum E { e = 5 }; + int test[(e + 1 == 6) ? 1 : -1]; +} + +namespace dr56 { // dr56: yes + struct A { + typedef int T; // expected-note {{previous}} + typedef int T; // expected-error {{redefinition}} + }; + struct B { + struct X; + typedef X X; // expected-note {{previous}} + typedef X X; // expected-error {{redefinition}} + }; +} + +namespace dr58 { // dr58: yes + // FIXME: Ideally, we should have a CodeGen test for this. +#if __cplusplus >= 201103L + enum E1 { E1_0 = 0, E1_1 = 1 }; + enum E2 { E2_0 = 0, E2_m1 = -1 }; + struct X { E1 e1 : 1; E2 e2 : 1; }; + static_assert(X{E1_1, E2_m1}.e1 == 1, ""); + static_assert(X{E1_1, E2_m1}.e2 == -1, ""); +#endif +} + +namespace dr59 { // dr59: yes + template<typename T> struct convert_to { operator T() const; }; + struct A {}; // expected-note 2{{volatile qualifier}} + struct B : A {}; // expected-note 2{{volatile qualifier}} +#if __cplusplus >= 201103L // move constructors + // expected-note@-3 2{{volatile qualifier}} + // expected-note@-3 2{{volatile qualifier}} +#endif + + A a1 = convert_to<A>(); + A a2 = convert_to<A&>(); + A a3 = convert_to<const A>(); + A a4 = convert_to<const volatile A>(); // expected-error {{no viable}} + A a5 = convert_to<const volatile A&>(); // expected-error {{no viable}} + + B b1 = convert_to<B>(); + B b2 = convert_to<B&>(); + B b3 = convert_to<const B>(); + B b4 = convert_to<const volatile B>(); // expected-error {{no viable}} + B b5 = convert_to<const volatile B&>(); // expected-error {{no viable}} + + int n1 = convert_to<int>(); + int n2 = convert_to<int&>(); + int n3 = convert_to<const int>(); + int n4 = convert_to<const volatile int>(); + int n5 = convert_to<const volatile int&>(); +} + +namespace dr60 { // dr60: yes + void f(int &); + int &f(...); + const int k = 0; + int &n = f(k); +} + +namespace dr61 { // dr61: yes + struct X { + static void f(); + } x; + struct Y { + static void f(); + static void f(int); + } y; + // This is (presumably) valid, because x.f does not refer to an overloaded + // function name. + void (*p)() = &x.f; + void (*q)() = &y.f; // expected-error {{cannot create a non-constant pointer to member function}} + void (*r)() = y.f; // expected-error {{cannot create a non-constant pointer to member function}} +} + +namespace dr62 { // dr62: yes + struct A { + struct { int n; } b; + }; + template<typename T> struct X {}; + template<typename T> T get() { return get<T>(); } + template<typename T> int take(T) { return 0; } + + X<A> x1; + A a = get<A>(); + + typedef struct { } *NoNameForLinkagePtr; +#if __cplusplus < 201103L + // expected-note@-2 5{{here}} +#endif + NoNameForLinkagePtr noNameForLinkagePtr; + + struct Danger { + NoNameForLinkagePtr p; + }; + + X<NoNameForLinkagePtr> x2; + X<const NoNameForLinkagePtr> x3; + NoNameForLinkagePtr p1 = get<NoNameForLinkagePtr>(); + NoNameForLinkagePtr p2 = get<const NoNameForLinkagePtr>(); + int n1 = take(noNameForLinkagePtr); +#if __cplusplus < 201103L + // expected-error@-6 {{uses unnamed type}} + // expected-error@-6 {{uses unnamed type}} + // expected-error@-6 {{uses unnamed type}} + // expected-error@-6 {{uses unnamed type}} + // expected-error@-6 {{uses unnamed type}} +#endif + + X<Danger> x4; + + void f() { + struct NoLinkage {}; + X<NoLinkage> a; + X<const NoLinkage> b; + get<NoLinkage>(); + get<const NoLinkage>(); + X<void (*)(NoLinkage A::*)> c; + X<int NoLinkage::*> d; +#if __cplusplus < 201103L + // expected-error@-7 {{uses local type}} + // expected-error@-7 {{uses local type}} + // expected-error@-7 {{uses local type}} + // expected-error@-7 {{uses local type}} + // expected-error@-7 {{uses local type}} + // expected-error@-7 {{uses local type}} +#endif + } +} + +namespace dr63 { // dr63: yes + template<typename T> struct S { typename T::error e; }; + extern S<int> *p; + void *q = p; +} + +namespace dr64 { // dr64: yes + template<class T> void f(T); + template<class T> void f(T*); + template<> void f(int*); + template<> void f<int>(int*); + template<> void f(int); +} + +// dr65: na + +namespace dr66 { // dr66: no + namespace X { + int f(int n); // expected-note 2{{candidate}} + } + using X::f; + namespace X { + int f(int n = 0); + int f(int, int); + } + // FIXME: The first two calls here should be accepted. + int a = f(); // expected-error {{no matching function}} + int b = f(1); + int c = f(1, 2); // expected-error {{no matching function}} +} + +// dr67: na + +namespace dr68 { // dr68: yes + template<typename T> struct X {}; + struct ::dr68::X<int> x1; + struct ::dr68::template X<int> x2; +#if __cplusplus < 201103L + // expected-error@-2 {{'template' keyword outside of a template}} +#endif + struct Y { + friend struct X<int>; + friend struct ::dr68::X<char>; + friend struct ::dr68::template X<double>; +#if __cplusplus < 201103L + // expected-error@-2 {{'template' keyword outside of a template}} +#endif + }; + template<typename> + struct Z { + friend struct ::dr68::template X<double>; + friend typename ::dr68::X<double>; +#if __cplusplus < 201103L + // expected-error@-2 {{C++11 extension}} +#endif + }; +} + +namespace dr69 { // dr69: yes + template<typename T> static void f() {} + // FIXME: Should we warn here? + inline void g() { f<int>(); } + // FIXME: This should be rejected, per [temp.explicit]p11. + extern template void f<char>(); +#if __cplusplus < 201103L + // expected-error@-2 {{C++11 extension}} +#endif + template<void(*)()> struct Q {}; + Q<&f<int> > q; +#if __cplusplus < 201103L + // expected-error@-2 {{internal linkage}} expected-note@-11 {{here}} +#endif +} + +namespace dr70 { // dr70: yes + template<int> struct A {}; + template<int I, int J> int f(int (&)[I + J], A<I>, A<J>); + int arr[7]; + int k = f(arr, A<3>(), A<4>()); +} + +// dr71: na +// dr72: dup 69 + +#if __cplusplus >= 201103L +namespace dr73 { // dr73: no + // The resolution to dr73 is unworkable. Consider: + int a, b; + static_assert(&a + 1 != &b, ""); +} +#endif + +namespace dr74 { // dr74: yes + enum E { k = 5 }; + int (*p)[k] = new int[k][k]; +} + +namespace dr75 { // dr75: yes + struct S { + static int n = 0; // expected-error {{non-const}} + }; +} + +namespace dr76 { // dr76: yes + const volatile int n = 1; + int arr[n]; // expected-error +{{variable length array}} +} + +namespace dr77 { // dr77: yes + struct A { + struct B {}; + friend struct B; + }; +} + +namespace dr78 { // dr78: sup ???? + // Under DR78, this is valid, because 'k' has static storage duration, so is + // zero-initialized. + const int k; // expected-error {{default initialization of an object of const}} +} + +// dr79: na + +namespace dr80 { // dr80: yes + struct A { + int A; + }; + struct B { + static int B; // expected-error {{same name as its class}} + }; + struct C { + int C; // expected-note {{hidden by}} + // FIXME: These diagnostics aren't very good. + C(); // expected-error {{must use 'struct' tag to refer to}} expected-error {{expected member name}} + }; + struct D { + D(); + int D; // expected-error {{same name as its class}} + }; +} + +// dr81: na +// dr82: dup 48 + +namespace dr83 { // dr83: yes + int &f(const char*); + char &f(char *); + int &k = f("foo"); +} + +namespace dr84 { // dr84: yes + struct B; + struct A { operator B() const; }; + struct C {}; + struct B { + B(B&); // expected-note {{candidate}} + B(C); + operator C() const; + }; + A a; + // Cannot use B(C) / operator C() pair to construct the B from the B temporary + // here. + B b = a; // expected-error {{no viable}} +} + +namespace dr85 { // dr85: yes + struct A { + struct B; + struct B {}; // expected-note{{previous declaration is here}} + struct B; // expected-error{{class member cannot be redeclared}} + + union U; + union U {}; // expected-note{{previous declaration is here}} + union U; // expected-error{{class member cannot be redeclared}} + +#if __cplusplus >= 201103L + enum E1 : int; + enum E1 : int { e1 }; // expected-note{{previous declaration is here}} + enum E1 : int; // expected-error{{class member cannot be redeclared}} + + enum class E2; + enum class E2 { e2 }; // expected-note{{previous declaration is here}} + enum class E2; // expected-error{{class member cannot be redeclared}} +#endif + }; + + template <typename T> + struct C { + struct B {}; // expected-note{{previous declaration is here}} + struct B; // expected-error{{class member cannot be redeclared}} + }; +} + +// dr86: dup 446 + +namespace dr87 { // dr87: no + template<typename T> struct X {}; + // FIXME: This is invalid. + X<void() throw()> x; + // ... but this is valid. + X<void(void() throw())> y; +} + +namespace dr88 { // dr88: yes + template<typename T> struct S { + static const int a = 1; + static const int b; + }; + // FIXME: This diagnostic is pretty bad. + template<> const int S<int>::a = 4; // expected-error {{redefinition}} expected-note {{previous}} + template<> const int S<int>::b = 4; +} + +// dr89: na + +namespace dr90 { // dr90: yes + struct A { + template<typename T> friend void dr90_f(T); + }; + struct B : A { + template<typename T> friend void dr90_g(T); + struct C {}; + union D {}; + }; + struct E : B {}; + struct F : B::C {}; + + void test() { + dr90_f(A()); + dr90_f(B()); + dr90_f(B::C()); // expected-error {{undeclared identifier}} + dr90_f(B::D()); // expected-error {{undeclared identifier}} + dr90_f(E()); + dr90_f(F()); // expected-error {{undeclared identifier}} + + dr90_g(A()); // expected-error {{undeclared identifier}} + dr90_g(B()); + dr90_g(B::C()); + dr90_g(B::D()); + dr90_g(E()); + dr90_g(F()); // expected-error {{undeclared identifier}} + } +} + +namespace dr91 { // dr91: yes + union U { friend int f(U); }; + int k = f(U()); +} + +// dr93: na + +namespace dr94 { // dr94: yes + struct A { static const int n = 5; }; + int arr[A::n]; +} + +namespace dr95 { // dr95: yes + struct A; + struct B; + namespace N { + class C { + friend struct A; + friend struct B; + static void f(); // expected-note {{here}} + }; + struct A *p; // dr95::A, not dr95::N::A. + } + A *q = N::p; // ok, same type + struct B { void f() { N::C::f(); } }; // expected-error {{private}} +} + +namespace dr96 { // dr96: no + struct A { + void f(int); + template<typename T> int f(T); + template<typename T> struct S {}; + } a; + template<template<typename> class X> struct B {}; + + template<typename T> + void test() { + int k1 = a.template f<int>(0); + // FIXME: This is ill-formed, because 'f' is not a template-id and does not + // name a class template. + // FIXME: What about alias templates? + int k2 = a.template f(1); + A::template S<int> s; + B<A::template S> b; + } +} + +namespace dr97 { // dr97: yes + struct A { + static const int a = false; + static const int b = !a; + }; +} + +namespace dr98 { // dr98: yes + void test(int n) { + switch (n) { + try { // expected-note 2{{bypasses}} + case 0: // expected-error {{protected}} + x: + throw n; + } catch (...) { // expected-note 2{{bypasses}} + case 1: // expected-error {{protected}} + y: + throw n; + } + case 2: + goto x; // expected-error {{protected}} + case 3: + goto y; // expected-error {{protected}} + } + } +} + +namespace dr99 { // dr99: sup 214 + template<typename T> void f(T&); + template<typename T> int &f(const T&); + const int n = 0; + int &r = f(n); +} diff --git a/test/CXX/drs/dr1xx.cpp b/test/CXX/drs/dr1xx.cpp new file mode 100644 index 0000000..7045148 --- /dev/null +++ b/test/CXX/drs/dr1xx.cpp @@ -0,0 +1,1011 @@ +// RUN: %clang_cc1 -std=c++98 -triple x86_64-unknown-unknown %s -verify -fexceptions -fcxx-exceptions -pedantic-errors +// RUN: %clang_cc1 -std=c++11 -triple x86_64-unknown-unknown %s -verify -fexceptions -fcxx-exceptions -pedantic-errors +// RUN: %clang_cc1 -std=c++1y -triple x86_64-unknown-unknown %s -verify -fexceptions -fcxx-exceptions -pedantic-errors + +namespace dr100 { // dr100: yes + template<const char *> struct A {}; // expected-note {{declared here}} + template<const char (&)[4]> struct B {}; // expected-note {{declared here}} + A<"foo"> a; // expected-error {{does not refer to any declaration}} + B<"bar"> b; // expected-error {{does not refer to any declaration}} +} + +namespace dr101 { // dr101: yes + extern "C" void dr101_f(); + typedef unsigned size_t; + namespace X { + extern "C" void dr101_f(); + typedef unsigned size_t; + } + using X::dr101_f; + using X::size_t; +} + +namespace dr102 { // dr102: yes + namespace A { + template<typename T> T f(T a, T b) { return a + b; } // expected-error {{neither visible in the template definition nor found by argument-dependent lookup}} + } + namespace B { + struct S {}; + } + B::S operator+(B::S, B::S); // expected-note {{should be declared prior to the call site or in namespace 'dr102::B'}} + template B::S A::f(B::S, B::S); // expected-note {{in instantiation of}} +} + +// dr103: na +// dr104 FIXME: add codegen test +// dr105: na + +namespace dr106 { // dr106: sup 540 + typedef int &r1; + typedef r1 &r1; + typedef const r1 r1; + typedef const r1 &r1; + + typedef const int &r2; + typedef r2 &r2; + typedef const r2 r2; + typedef const r2 &r2; +} + +namespace dr107 { // dr107: yes + struct S {}; + extern "C" S operator+(S, S) { return S(); } +} + +namespace dr108 { // dr108: yes + template<typename T> struct A { + struct B { typedef int X; }; + B::X x; // expected-error {{missing 'typename'}} + struct C : B { X x; }; // expected-error {{unknown type name}} + }; + template<> struct A<int>::B { int X; }; +} + +namespace dr109 { // dr109: yes + struct A { template<typename T> void f(T); }; + template<typename T> struct B : T { + using T::template f; // expected-error {{using declaration can not refer to a template}} + void g() { this->f<int>(123); } // expected-error {{use 'template'}} + }; +} + +namespace dr111 { // dr111: dup 535 + struct A { A(); A(volatile A&, int = 0); A(A&, const char * = "foo"); }; + struct B : A { B(); }; // expected-note +{{would lose const qualifier}} expected-note {{requires 0 arguments}} + const B b1; + B b2(b1); // expected-error {{no matching constructor}} +} + +namespace dr112 { // dr112: yes + struct T { int n; }; + typedef T Arr[1]; + + const T a1[1] = {}; + volatile T a2[1] = {}; + const Arr a3 = {}; + volatile Arr a4 = {}; + template<const volatile T*> struct X {}; + X<a1> x1; + X<a2> x2; + X<a3> x3; + X<a4> x4; +#if __cplusplus < 201103L + // expected-error@-5 {{internal linkage}} expected-note@-10 {{here}} + // expected-error@-4 {{internal linkage}} expected-note@-9 {{here}} +#else + // FIXME: Test this somehow. +#endif +} + +namespace dr113 { // dr113: yes + extern void (*p)(); + void f() { + no_such_function(); // expected-error {{undeclared}} + p(); + } + void g(); + void (*p)() = &g; +} + +namespace dr114 { // dr114: yes + struct A { + virtual void f(int) = 0; // expected-note {{unimplemented}} + }; + struct B : A { + template<typename T> void f(T); + void g() { f(0); } + } b; // expected-error {{abstract}} +} + +namespace dr115 { // dr115: yes + template<typename T> int f(T); // expected-note +{{}} + template<typename T> int g(T); // expected-note +{{}} + template<typename T> int g(T, int); // expected-note +{{}} + + int k1 = f(&f); // expected-error {{no match}} + int k2 = f(&f<int>); + int k3 = f(&g<int>); // expected-error {{no match}} + + void h() { + (void)&f; // expected-error {{address of overloaded function 'f' cannot be cast to type 'void'}} + (void)&f<int>; + (void)&g<int>; // expected-error {{address of overloaded function 'g' cannot be cast to type 'void'}} + + &f; // expected-error {{reference to overloaded function could not be resolved}} + &f<int>; // expected-warning {{unused}} + &g<int>; // expected-error {{reference to overloaded function could not be resolved}} + } + + struct S { + template<typename T> static int f(T); + template<typename T> static int g(T); + template<typename T> static int g(T, int); + } s; + + int k4 = f(&s.f); // expected-error {{non-constant pointer to member}} + int k5 = f(&s.f<int>); + int k6 = f(&s.g<int>); // expected-error {{non-constant pointer to member}} + + void i() { + (void)&s.f; // expected-error {{non-constant pointer to member}} + (void)&s.f<int>; + (void)&s.g<int>; // expected-error {{non-constant pointer to member}} + + &s.f; // expected-error {{non-constant pointer to member}} + &s.f<int>; // expected-warning {{unused}} + &s.g<int>; // expected-error {{non-constant pointer to member}} + } + + struct T { + template<typename T> int f(T); + template<typename T> int g(T); + template<typename T> int g(T, int); + } t; + + int k7 = f(&s.f); // expected-error {{non-constant pointer to member}} + int k8 = f(&s.f<int>); + int k9 = f(&s.g<int>); // expected-error {{non-constant pointer to member}} + + void j() { + (void)&s.f; // expected-error {{non-constant pointer to member}} + (void)&s.f<int>; + (void)&s.g<int>; // expected-error {{non-constant pointer to member}} + + &s.f; // expected-error {{non-constant pointer to member}} + &s.f<int>; // expected-warning {{unused}} + &s.g<int>; // expected-error {{non-constant pointer to member}} + } + +#if __cplusplus >= 201103L + // Special case kicks in only if a template argument list is specified. + template<typename T=int> void with_default(); // expected-note +{{}} + int k10 = f(&with_default); // expected-error {{no matching function}} + int k11 = f(&with_default<>); + void k() { + (void)&with_default; // expected-error {{overloaded function}} + (void)&with_default<>; + &with_default; // expected-error {{overloaded function}} + &with_default<>; // expected-warning {{unused}} + } +#endif +} + +namespace dr116 { // dr116: yes + template<int> struct A {}; + template<int N> void f(A<N>) {} // expected-note {{previous}} + template<int M> void f(A<M>) {} // expected-error {{redefinition}} + template<typename T> void f(A<sizeof(T)>) {} // expected-note {{previous}} + template<typename U> void f(A<sizeof(U)>) {} // expected-error {{redefinition}} +} + +// dr117: na +// dr118 FIXME: add codegen test +// dr119: na +// dr120: na + +namespace dr121 { // dr121: yes + struct X { + template<typename T> struct Y {}; + }; + template<typename T> struct Z { + X::Y<T> x; + T::Y<T> y; // expected-error +{{}} + }; + Z<X> z; +} + +namespace dr122 { // dr122: yes + template<typename T> void f(); + void g() { f<int>(); } +} + +// dr123: na +// dr124: dup 201 + +// dr125: yes +struct dr125_A { struct dr125_B {}; }; // expected-note {{here}} +dr125_A::dr125_B dr125_C(); +namespace dr125_B { dr125_A dr125_C(); } +namespace dr125 { + struct X { + friend dr125_A::dr125_B (::dr125_C)(); // ok + friend dr125_A (::dr125_B::dr125_C)(); // ok + friend dr125_A::dr125_B::dr125_C(); // expected-error {{did you mean the constructor name 'dr125_B'?}} + // expected-warning@-1 {{missing exception specification}} +#if __cplusplus >= 201103L + // expected-error@-3 {{follows constexpr declaration}} expected-note@-10 {{here}} +#endif + }; +} + +namespace dr126 { // dr126: no + struct C {}; + struct D : C {}; + struct E : private C { friend class A; friend class B; }; + struct F : protected C {}; + struct G : C {}; + struct H : D, G {}; + + struct A { + virtual void cp() throw(C*); + virtual void dp() throw(C*); + virtual void ep() throw(C*); // expected-note {{overridden}} + virtual void fp() throw(C*); // expected-note {{overridden}} + virtual void gp() throw(C*); + virtual void hp() throw(C*); // expected-note {{overridden}} + + virtual void cr() throw(C&); + virtual void dr() throw(C&); + virtual void er() throw(C&); // expected-note {{overridden}} + virtual void fr() throw(C&); // expected-note {{overridden}} + virtual void gr() throw(C&); + virtual void hr() throw(C&); // expected-note {{overridden}} + + virtual void pv() throw(void*); // expected-note {{overridden}} + +#if __cplusplus >= 201103L + virtual void np() throw(C*); // expected-note {{overridden}} + virtual void npm() throw(int C::*); // expected-note {{overridden}} + virtual void nr() throw(C&); // expected-note {{overridden}} +#endif + + virtual void ref1() throw(C *const&); + virtual void ref2() throw(C *); + + virtual void v() throw(int); + virtual void w() throw(const int); + virtual void x() throw(int*); + virtual void y() throw(const int*); + virtual void z() throw(int); // expected-note {{overridden}} + }; + struct B : A { + virtual void cp() throw(C*); + virtual void dp() throw(D*); + virtual void ep() throw(E*); // expected-error {{more lax}} + virtual void fp() throw(F*); // expected-error {{more lax}} + virtual void gp() throw(G*); + virtual void hp() throw(H*); // expected-error {{more lax}} + + virtual void cr() throw(C&); + virtual void dr() throw(D&); + virtual void er() throw(E&); // expected-error {{more lax}} + virtual void fr() throw(F&); // expected-error {{more lax}} + virtual void gr() throw(G&); + virtual void hr() throw(H&); // expected-error {{more lax}} + + virtual void pv() throw(C*); // expected-error {{more lax}} FIXME: This is valid. + +#if __cplusplus >= 201103L + using nullptr_t = decltype(nullptr); + virtual void np() throw(nullptr_t*); // expected-error {{more lax}} FIXME: This is valid. + virtual void npm() throw(nullptr_t*); // expected-error {{more lax}} FIXME: This is valid. + virtual void nr() throw(nullptr_t&); // expected-error {{more lax}} This is not. +#endif + + virtual void ref1() throw(D *const &); + virtual void ref2() throw(D *); + + virtual void v() throw(const int); + virtual void w() throw(int); + virtual void x() throw(const int*); // FIXME: 'const int*' is not allowed by A::h. + virtual void y() throw(int*); // ok + virtual void z() throw(long); // expected-error {{more lax}} + }; +} + +namespace dr127 { // dr127: yes + __extension__ typedef __decltype(sizeof(0)) size_t; + template<typename T> struct A { + A() throw(int); + void *operator new(size_t, const char * = 0); + void operator delete(void *, const char *) { T::error; } // expected-error 2{{no members}} + void operator delete(void *) { T::error; } + }; + A<void> *p = new A<void>; // expected-note {{instantiat}} + A<int> *q = new ("") A<int>; // expected-note {{instantiat}} +} + +namespace dr128 { // dr128: yes + enum E1 { e1 } x = e1; + enum E2 { e2 } y = static_cast<E2>(x), z = static_cast<E2>(e1); +} + +// dr129: dup 616 +// dr130: na + +namespace dr131 { // dr131: yes + const char *a_with_\u0e8c = "\u0e8c"; + const char *b_with_\u0e8d = "\u0e8d"; + const char *c_with_\u0e8e = "\u0e8e"; +#if __cplusplus < 201103L + // expected-error@-4 {{expected ';'}} expected-error@-2 {{expected ';'}} +#endif +} + +namespace dr132 { // dr132: no + void f() { + extern struct {} x; // ok + extern struct S {} y; // FIXME: This is invalid. + } + static enum { E } e; +} + +// dr133: dup 87 +// dr134: na + +namespace dr135 { // dr135: yes + struct A { + A f(A a) { return a; } + friend A g(A a) { return a; } + static A h(A a) { return a; } + }; +} + +namespace dr136 { // dr136: 3.4 + void f(int, int, int = 0); // expected-note {{previous declaration is here}} + void g(int, int, int); // expected-note {{previous declaration is here}} + struct A { + friend void f(int, int = 0, int); // expected-error {{friend declaration specifying a default argument must be the only declaration}} + friend void g(int, int, int = 0); // expected-error {{friend declaration specifying a default argument must be the only declaration}} + friend void h(int, int, int = 0); // expected-error {{friend declaration specifying a default argument must be a definition}} + friend void i(int, int, int = 0) {} // expected-note {{previous declaration is here}} + friend void j(int, int, int = 0) {} + operator int(); + }; + void i(int, int, int); // expected-error {{friend declaration specifying a default argument must be the only declaration}} + void q() { + j(A(), A()); // ok, has default argument + } + extern "C" void k(int, int, int, int); // expected-note {{previous declaration is here}} + namespace NSA { + struct A { + friend void dr136::k(int, int, int, int = 0); // expected-error {{friend declaration specifying a default argument must be the only declaration}} \ + // expected-note {{previous declaration is here}} + }; + } + namespace NSB { + struct A { + friend void dr136::k(int, int, int = 0, int); // expected-error {{friend declaration specifying a default argument must be the only declaration}} + }; + } + struct B { + void f(int); // expected-note {{previous declaration is here}} + }; + struct C { + friend void B::f(int = 0); // expected-error {{friend declaration specifying a default argument must be the only declaration}} + }; +} + +namespace dr137 { // dr137: yes + extern void *p; + extern const void *cp; + extern volatile void *vp; + extern const volatile void *cvp; + int *q = static_cast<int*>(p); + int *qc = static_cast<int*>(cp); // expected-error {{casts away qualifiers}} + int *qv = static_cast<int*>(vp); // expected-error {{casts away qualifiers}} + int *qcv = static_cast<int*>(cvp); // expected-error {{casts away qualifiers}} + const int *cq = static_cast<const int*>(p); + const int *cqc = static_cast<const int*>(cp); + const int *cqv = static_cast<const int*>(vp); // expected-error {{casts away qualifiers}} + const int *cqcv = static_cast<const int*>(cvp); // expected-error {{casts away qualifiers}} + const volatile int *cvq = static_cast<const volatile int*>(p); + const volatile int *cvqc = static_cast<const volatile int*>(cp); + const volatile int *cvqv = static_cast<const volatile int*>(vp); + const volatile int *cvqcv = static_cast<const volatile int*>(cvp); +} + +namespace dr139 { // dr139: yes + namespace example1 { + typedef int f; // expected-note {{previous}} + struct A { + friend void f(A &); // expected-error {{different kind of symbol}} + }; + } + + namespace example2 { + typedef int f; + namespace N { + struct A { + friend void f(A &); + operator int(); + void g(A a) { int i = f(a); } // ok, f is typedef not friend function + }; + } + } +} + +namespace dr140 { // dr140: yes + void f(int *const) {} // expected-note {{previous}} + void f(int[3]) {} // expected-error {{redefinition}} + void g(const int); + void g(int n) { n = 2; } +} + +namespace dr141 { // dr141: yes + template<typename T> void f(); + template<typename T> struct S { int n; }; + struct A : S<int> { + template<typename T> void f(); + template<typename T> struct S {}; + } a; + struct B : S<int> {} b; + void g() { + a.f<int>(); + (void)a.S<int>::n; // expected-error {{no member named 'n'}} +#if __cplusplus < 201103L + // expected-error@-2 {{ambiguous}} + // expected-note@-11 {{lookup from the current scope}} + // expected-note@-9 {{lookup in the object type}} +#endif + b.f<int>(); // expected-error {{no member}} expected-error +{{}} + (void)b.S<int>::n; + } + template<typename T> struct C { + T t; + void g() { + t.f<int>(); // expected-error {{use 'template'}} + } + void h() { + (void)t.S<int>::n; // ok + } + void i() { + (void)t.S<int>(); // ok! + } + }; + void h() { C<B>().h(); } // ok + struct X { + template<typename T> void S(); + }; + void i() { C<X>().i(); } // ok!! +} + +namespace dr142 { // dr142: yes + class B { // expected-note +{{here}} + public: + int mi; // expected-note +{{here}} + static int si; // expected-note +{{here}} + }; + class D : private B { // expected-note +{{here}} + }; + class DD : public D { + void f(); + }; + void DD::f() { + mi = 3; // expected-error {{private base class}} expected-error {{private member}} + si = 3; // expected-error {{private member}} + B b_old; // expected-error {{private member}} + dr142::B b; + b.mi = 3; + b.si = 3; + B::si = 3; // expected-error {{private member}} + dr142::B::si = 3; + B *bp1_old = this; // expected-error {{private member}} expected-error {{private base class}} + dr142::B *bp1 = this; // expected-error {{private base class}} + B *bp2_old = (B*)this; // expected-error 2{{private member}} + dr142::B *bp2 = (dr142::B*)this; + bp2->mi = 3; + } +} + +namespace dr143 { // dr143: yes + namespace A { struct X; } + namespace B { void f(A::X); } + namespace A { + struct X { friend void B::f(X); }; + } + void g(A::X x) { + f(x); // expected-error {{undeclared identifier 'f'}} + } +} + +namespace dr145 { // dr145: yes + void f(bool b) { + ++b; // expected-warning {{deprecated}} + b++; // expected-warning {{deprecated}} + } +} + +namespace dr147 { // dr147: no + namespace example1 { + template<typename> struct A { + template<typename T> A(T); + }; + // FIXME: This appears to be valid, and EDG and G++ accept. + template<> template<> A<int>::A<int>(int) {} // expected-error {{out-of-line constructor for 'A' cannot have template arguments}} + } + namespace example2 { + struct A { A(); }; + struct B : A { B(); }; + A::A a1; // expected-error {{is a constructor}} + B::A a2; + } + namespace example3 { + template<typename> struct A { + template<typename T> A(T); + static A a; + }; + template<> A<int>::A<int>(A<int>::a); // expected-error {{is a constructor}} + } +} + +namespace dr148 { // dr148: yes + struct A { int A::*p; }; + int check1[__is_pod(int(A::*)) ? 1 : -1]; + int check2[__is_pod(A) ? 1 : -1]; +} + +// dr149: na + +namespace dr151 { // dr151: yes + struct X {}; + typedef int X::*p; +#if __cplusplus < 201103L +#define fold(x) (__builtin_constant_p(0) ? (x) : (x)) +#else +#define fold +#endif + int check[fold(p() == 0) ? 1 : -1]; +#undef fold +} + +namespace dr152 { // dr152: yes + struct A { + A(); // expected-note {{not viable}} + explicit A(const A&); + }; + A a1 = A(); // expected-error {{no matching constructor}} + A a2((A())); +} + +// dr153: na + +namespace dr154 { // dr154: yes + union { int a; }; // expected-error {{must be declared 'static'}} + namespace { + union { int b; }; + } + static union { int c; }; +} + +namespace dr155 { // dr155: dup 632 + struct S { int n; } s = { { 1 } }; // expected-warning {{braces around scalar initializer}} +} + +namespace dr159 { // dr159: no + namespace X { void f(); } + void f(); + // FIXME: This should be accepted. + void dr159::f() {} // expected-error {{extra qualification}} + void dr159::X::f() {} +} + +// dr160: na + +namespace dr161 { // dr161: yes + class A { + protected: + struct B { int n; } b; // expected-note 2{{here}} + static B bs; + void f(); // expected-note {{here}} + static void sf(); + }; + struct C : A {}; + struct D : A { + void g(C c) { + (void)b.n; + B b1; + C::B b2; // ok, accessible as a member of A + (void)&C::b; // expected-error {{protected}} + (void)&C::bs; + (void)c.b; // expected-error {{protected}} + (void)c.bs; + f(); + sf(); + c.f(); // expected-error {{protected}} + c.sf(); + A::f(); + D::f(); + A::sf(); + C::sf(); + D::sf(); + } + }; +} + +namespace dr162 { // dr162: no + struct A { + char &f(char); + static int &f(int); + + void g() { + int &a = (&A::f)(0); // FIXME: expected-error {{could not be resolved}} + char &b = (&A::f)('0'); // expected-error {{could not be resolved}} + } + }; + + int &c = (&A::f)(0); // FIXME: expected-error {{could not be resolved}} + char &d = (&A::f)('0'); // expected-error {{could not be resolved}} +} + +// dr163: na + +namespace dr164 { // dr164: yes + void f(int); + template <class T> int g(T t) { return f(t); } + + enum E { e }; + int f(E); + + int k = g(e); +} + +namespace dr165 { // dr165: no + namespace N { + struct A { friend struct B; }; + void f() { void g(); } + } + // FIXME: dr1477 says this is ok, dr165 says it's ill-formed + struct N::B {}; + // FIXME: dr165 says this is ill-formed, but the argument in dr1477 says it's ok + void N::g() {} +} + +namespace dr166 { // dr166: yes + namespace A { class X; } + + template<typename T> int f(T t) { return t.n; } + int g(A::X); + template<typename T> int h(T t) { return t.n; } // expected-error {{private}} + int i(A::X); + + namespace A { + class X { + friend int f<X>(X); + friend int dr166::g(X); + friend int h(X); + friend int i(X); + int n; // expected-note 2{{here}} + }; + + int h(X x) { return x.n; } + int i(X x) { return x.n; } + } + + template int f(A::X); + int g(A::X x) { return x.n; } + template int h(A::X); // expected-note {{instantiation}} + int i(A::X x) { return x.n; } // expected-error {{private}} +} + +// dr167: sup 1012 + +namespace dr168 { // dr168: no + extern "C" typedef int (*p)(); + extern "C++" typedef int (*q)(); + struct S { + static int f(); + }; + p a = &S::f; // FIXME: this should fail. + q b = &S::f; +} + +namespace dr169 { // dr169: yes + template<typename> struct A { int n; }; + struct B { + template<typename> struct C; + template<typename> void f(); + template<typename> static int n; // expected-error 0-1{{extension}} + }; + struct D : A<int>, B { + using A<int>::n; + using B::C<int>; // expected-error {{using declaration can not refer to a template specialization}} + using B::f<int>; // expected-error {{using declaration can not refer to a template specialization}} + using B::n<int>; // expected-error {{using declaration can not refer to a template specialization}} + }; +} + +namespace { // dr171: yes + int dr171a; +} +int dr171b; // expected-note {{here}} +namespace dr171 { + extern "C" void dr171a(); + extern "C" void dr171b(); // expected-error {{conflicts}} +} + +namespace dr172 { // dr172: yes + enum { zero }; + int check1[-1 < zero ? 1 : -1]; + + enum { x = -1, y = (unsigned int)-1 }; + int check2[sizeof(x) > sizeof(int) ? 1 : -1]; + + enum { a = (unsigned int)-1 / 2 }; + int check3a[sizeof(a) == sizeof(int) ? 1 : -1]; + int check3b[-a < 0 ? 1 : -1]; + + enum { b = (unsigned int)-1 / 2 + 1 }; + int check4a[sizeof(b) == sizeof(unsigned int) ? 1 : -1]; + int check4b[-b > 0 ? 1 : -1]; + + enum { c = (unsigned long)-1 / 2 }; + int check5a[sizeof(c) == sizeof(long) ? 1 : -1]; + int check5b[-c < 0 ? 1 : -1]; + + enum { d = (unsigned long)-1 / 2 + 1 }; + int check6a[sizeof(d) == sizeof(unsigned long) ? 1 : -1]; + int check6b[-d > 0 ? 1 : -1]; + + enum { e = (unsigned long long)-1 / 2 }; // expected-error 0-1{{extension}} + int check7a[sizeof(e) == sizeof(long) ? 1 : -1]; // expected-error 0-1{{extension}} + int check7b[-e < 0 ? 1 : -1]; + + enum { f = (unsigned long long)-1 / 2 + 1 }; // expected-error 0-1{{extension}} + int check8a[sizeof(f) == sizeof(unsigned long) ? 1 : -1]; // expected-error 0-1{{extension}} + int check8b[-f > 0 ? 1 : -1]; +} + +namespace dr173 { // dr173: yes + int check[('0' + 1 == '1' && '0' + 2 == '2' && '0' + 3 == '3' && + '0' + 4 == '4' && '0' + 5 == '5' && '0' + 6 == '6' && + '0' + 7 == '7' && '0' + 8 == '8' && '0' + 9 == '9') ? 1 : -1]; +} + +// dr174: sup 1012 + +namespace dr175 { // dr175: yes + struct A {}; // expected-note {{here}} + struct B : private A {}; // expected-note {{constrained by private inheritance}} + struct C : B { + A a; // expected-error {{private}} + dr175::A b; + }; +} + +namespace dr176 { // dr176: yes + template<typename T> class Y; + template<> class Y<int> { + void f() { + typedef Y A; // expected-note {{here}} + typedef Y<char> A; // expected-error {{different types ('Y<char>' vs 'Y<int>')}} + } + }; + + template<typename T> struct Base {}; // expected-note 2{{found}} + template<typename T> struct Derived : public Base<T> { + void f() { + typedef typename Derived::template Base<T> A; + typedef typename Derived::Base A; + } + }; + template struct Derived<int>; + + template<typename T> struct Derived2 : Base<int>, Base<char> { + typename Derived2::Base b; // expected-error {{found in multiple base classes}} + typename Derived2::Base<double> d; + }; + + template<typename T> class X { // expected-note {{here}} + X *p1; + X<T> *p2; + X<int> *p3; + dr176::X *p4; // expected-error {{requires template arguments}} + }; +} + +namespace dr177 { // dr177: yes + struct B {}; + struct A { + A(A &); // expected-note {{not viable: expects an l-value}} + A(const B &); + }; + B b; + A a = b; // expected-error {{no viable constructor copying variable}} +} + +namespace dr178 { // dr178: yes + int check[int() == 0 ? 1 : -1]; +#if __cplusplus >= 201103L + static_assert(int{} == 0, ""); + struct S { int a, b; }; + static_assert(S{1}.b == 0, ""); + struct T { constexpr T() : n() {} int n; }; + static_assert(T().n == 0, ""); + struct U : S { constexpr U() : S() {} }; + static_assert(U().b == 0, ""); +#endif +} + +namespace dr179 { // dr179: yes + void f(); + int n = &f - &f; // expected-error {{arithmetic on pointers to the function type 'void ()'}} +} + +namespace dr180 { // dr180: yes + template<typename T> struct X : T, T::some_base { + X() : T::some_type_that_might_be_T(), T::some_base() {} + friend class T::some_class; + void f() { + enum T::some_enum e; + } + }; +} + +namespace dr181 { // dr181: yes + namespace X { + template <template X<class T> > struct A { }; // expected-error +{{}} + template <template X<class T> > void f(A<X>) { } // expected-error +{{}} + } + + namespace Y { + template <template <class T> class X> struct A { }; + template <template <class T> class X> void f(A<X>) { } + } +} + +namespace dr182 { // dr182: yes + template <class T> struct C { + void f(); + void g(); + }; + + template <class T> void C<T>::f() {} + template <class T> void C<T>::g() {} + + class A { + class B {}; // expected-note {{here}} + void f(); + }; + + template void C<A::B>::f(); + template <> void C<A::B>::g(); // expected-error {{private}} + + void A::f() { + C<B> cb; + cb.f(); + } +} + +namespace dr183 { // dr183: sup 382 + template<typename T> struct A {}; + template<typename T> struct B { + typedef int X; + }; + template<> struct A<int> { + typename B<int>::X x; + }; +} + +namespace dr184 { // dr184: yes + template<typename T = float> struct B {}; + + template<template<typename TT = float> class T> struct A { + void f(); + void g(); + }; + + template<template<typename TT> class T> void A<T>::f() { // expected-note {{here}} + T<> t; // expected-error {{too few template arguments}} + } + + template<template<typename TT = char> class T> void A<T>::g() { + T<> t; + typedef T<> X; + typedef T<char> X; + } + + void h() { A<B>().g(); } +} + +// dr185 FIXME: add codegen test + +namespace dr187 { // dr187: sup 481 + const int Z = 1; + template<int X = Z, int Z = X> struct A; + typedef A<> T; + typedef A<1, 1> T; +} + +namespace dr188 { // dr188: yes + char c[10]; + int check[sizeof(0, c) == 10 ? 1 : -1]; +} + +// dr190 FIXME: add codegen test for tbaa + +// dr193 FIXME: add codegen test + +namespace dr194 { // dr194: yes + struct A { + A(); + void A(); // expected-error {{has the same name as its class}} expected-error {{constructor cannot have a return type}} + }; + struct B { + void B(); // expected-error {{has the same name as its class}} expected-error {{constructor cannot have a return type}} + B(); + }; + struct C { + inline explicit C(int) {} + }; +} + +namespace dr195 { // dr195: yes + void f(); + int *p = (int*)&f; // expected-error 0-1{{extension}} + void (*q)() = (void(*)())&p; // expected-error 0-1{{extension}} +} + +namespace dr197 { // dr197: yes + char &f(char); + + template <class T> void g(T t) { + char &a = f(1); + char &b = f(T(1)); // expected-error {{unrelated type 'int'}} + char &c = f(t); // expected-error {{unrelated type 'int'}} + } + + void f(int); + + enum E { e }; + int &f(E); + + void h() { + g('a'); + g(2); + g(e); // expected-note {{in instantiation of}} + } +} + +namespace dr198 { // dr198: yes + struct A { + int n; + struct B { + int m[sizeof(n)]; +#if __cplusplus < 201103L + // expected-error@-2 {{invalid use of non-static data member}} +#endif + int f() { return n; } + // expected-error@-1 {{use of non-static data member 'n' of 'A' from nested type 'B'}} + }; + struct C; + struct D; + }; + struct A::C { + int m[sizeof(n)]; +#if __cplusplus < 201103L + // expected-error@-2 {{invalid use of non-static data member}} +#endif + int f() { return n; } + // expected-error@-1 {{use of non-static data member 'n' of 'A' from nested type 'C'}} + }; + struct A::D : A { + int m[sizeof(n)]; +#if __cplusplus < 201103L + // expected-error@-2 {{invalid use of non-static data member}} +#endif + int f() { return n; } + }; +} + +// dr199 FIXME: add codegen test diff --git a/test/CXX/drs/dr2xx.cpp b/test/CXX/drs/dr2xx.cpp new file mode 100644 index 0000000..2c32a9e --- /dev/null +++ b/test/CXX/drs/dr2xx.cpp @@ -0,0 +1,726 @@ +// 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 + +// PR13819 -- __SIZE_TYPE__ is incompatible. +// REQUIRES: LP64 + +#if __cplusplus < 201103L +#define fold(x) (__builtin_constant_p(x) ? (x) : (x)) +#else +#define fold +#endif + +namespace dr200 { // dr200: dup 214 + template <class T> T f(int); + template <class T, class U> T f(U) = delete; // expected-error 0-1{{extension}} + + void g() { + f<int>(1); + } +} + +// dr201 FIXME: write codegen test + +namespace dr202 { // dr202: yes + template<typename T> T f(); + template<int (*g)()> struct X { + int arr[fold(g == &f<int>) ? 1 : -1]; + }; + template struct X<f>; +} + +// FIXME (export) dr204: no + +namespace dr206 { // dr206: yes + struct S; // expected-note 2{{declaration}} + template<typename T> struct Q { S s; }; // expected-error {{incomplete}} + template<typename T> void f() { S s; } // expected-error {{incomplete}} +} + +namespace dr207 { // dr207: yes + class A { + protected: + static void f() {} + }; + class B : A { + public: + using A::f; + void g() { + A::f(); + f(); + } + }; +} + +// dr208 FIXME: write codegen test + +namespace dr209 { // dr209: yes + class A { + void f(); // expected-note {{here}} + }; + class B { + friend void A::f(); // expected-error {{private}} + }; +} + +// dr210 FIXME: write codegen test + +namespace dr211 { // dr211: yes + struct A { + A() try { + throw 0; + } catch (...) { + return; // expected-error {{return in the catch of a function try block of a constructor}} + } + }; +} + +namespace dr213 { // dr213: yes + template <class T> struct A : T { + void h(T t) { + char &r1 = f(t); + int &r2 = g(t); // expected-error {{undeclared}} + } + }; + struct B { + int &f(B); + int &g(B); // expected-note {{in dependent base class}} + }; + char &f(B); + + template void A<B>::h(B); // expected-note {{instantiation}} +} + +namespace dr214 { // dr214: yes + template<typename T, typename U> T checked_cast(U from) { U::error; } + template<typename T, typename U> T checked_cast(U *from); + class C {}; + void foo(int *arg) { checked_cast<const C *>(arg); } + + template<typename T> T f(int); + template<typename T, typename U> T f(U) { T::error; } + void g() { + f<int>(1); + } +} + +namespace dr215 { // dr215: yes + template<typename T> class X { + friend void T::foo(); + int n; + }; + struct Y { + void foo() { (void)+X<Y>().n; } + }; +} + +namespace dr216 { // dr216: no + // FIXME: Should reject this: 'f' has linkage but its type does not, + // and 'f' is odr-used but not defined in this TU. + typedef enum { e } *E; + void f(E); + void g(E e) { f(e); } + + struct S { + // FIXME: Should reject this: 'f' has linkage but its type does not, + // and 'f' is odr-used but not defined in this TU. + typedef enum { e } *E; + void f(E); + }; + void g(S s, S::E e) { s.f(e); } +} + +namespace dr217 { // dr217: yes + template<typename T> struct S { + void f(int); + }; + template<typename T> void S<T>::f(int = 0) {} // expected-error {{default arguments cannot be added}} +} + +namespace dr218 { // dr218: yes + namespace A { + struct S {}; + void f(S); + } + namespace B { + struct S {}; + void f(S); + } + + struct C { + int f; + void test1(A::S as) { f(as); } // expected-error {{called object type 'int'}} + void test2(A::S as) { void f(); f(as); } // expected-error {{too many arguments}} expected-note {{}} + void test3(A::S as) { using A::f; f(as); } // ok + void test4(A::S as) { using B::f; f(as); } // ok + void test5(A::S as) { int f; f(as); } // expected-error {{called object type 'int'}} + void test6(A::S as) { struct f {}; (void) f(as); } // expected-error {{no matching conversion}} expected-note +{{}} + }; + + namespace D { + struct S {}; + struct X { void operator()(S); } f; + } + void testD(D::S ds) { f(ds); } // expected-error {{undeclared identifier}} + + namespace E { + struct S {}; + struct f { f(S); }; + } + void testE(E::S es) { f(es); } // expected-error {{undeclared identifier}} + + namespace F { + struct S { + template<typename T> friend void f(S, T) {} + }; + } + void testF(F::S fs) { f(fs, 0); } + + namespace G { + namespace X { + int f; + struct A {}; + } + namespace Y { + template<typename T> void f(T); + struct B {}; + } + template<typename A, typename B> struct C {}; + } + void testG(G::C<G::X::A, G::Y::B> gc) { f(gc); } +} + +// dr219: na +// dr220: na + +namespace dr221 { // dr221: yes + struct A { + A &operator=(int&); + A &operator+=(int&); + static A &operator=(A&, double&); // expected-error {{cannot be a static member}} + static A &operator+=(A&, double&); // expected-error {{cannot be a static member}} + friend A &operator=(A&, char&); // expected-error {{must be a non-static member function}} + friend A &operator+=(A&, char&); + }; + A &operator=(A&, float&); // expected-error {{must be a non-static member function}} + A &operator+=(A&, float&); + + void test(A a, int n, char c, float f) { + a = n; + a += n; + a = c; + a += c; + a = f; + a += f; + } +} + +// dr222 is a mystery -- it lists no changes to the standard, and yet was +// apparently both voted into the WP and acted upon by the editor. + +// dr223: na + +namespace dr224 { // dr224: no + namespace example1 { + template <class T> class A { + typedef int type; + A::type a; + A<T>::type b; + A<T*>::type c; // expected-error {{missing 'typename'}} + ::dr224::example1::A<T>::type d; + + class B { + typedef int type; + + A::type a; + A<T>::type b; + A<T*>::type c; // expected-error {{missing 'typename'}} + ::dr224::example1::A<T>::type d; + + B::type e; + A<T>::B::type f; + A<T*>::B::type g; // expected-error {{missing 'typename'}} + typename A<T*>::B::type h; + }; + }; + + template <class T> class A<T*> { + typedef int type; + A<T*>::type a; + A<T>::type b; // expected-error {{missing 'typename'}} + }; + + template <class T1, class T2, int I> struct B { + typedef int type; + B<T1, T2, I>::type b1; + B<T2, T1, I>::type b2; // expected-error {{missing 'typename'}} + + typedef T1 my_T1; + static const int my_I = I; + static const int my_I2 = I+0; + static const int my_I3 = my_I; + B<my_T1, T2, my_I>::type b3; // FIXME: expected-error {{missing 'typename'}} + B<my_T1, T2, my_I2>::type b4; // expected-error {{missing 'typename'}} + B<my_T1, T2, my_I3>::type b5; // FIXME: expected-error {{missing 'typename'}} + }; + } + + namespace example2 { + template <int, typename T> struct X { typedef T type; }; + template <class T> class A { + static const int i = 5; + X<i, int>::type w; // FIXME: expected-error {{missing 'typename'}} + X<A::i, char>::type x; // FIXME: expected-error {{missing 'typename'}} + X<A<T>::i, double>::type y; // FIXME: expected-error {{missing 'typename'}} + X<A<T*>::i, long>::type z; // expected-error {{missing 'typename'}} + int f(); + }; + template <class T> int A<T>::f() { + return i; + } + } +} + +// dr225: yes +template<typename T> void dr225_f(T t) { dr225_g(t); } // expected-error {{call to function 'dr225_g' that is neither visible in the template definition nor found by argument-dependent lookup}} +void dr225_g(int); // expected-note {{should be declared prior to the call site}} +template void dr225_f(int); // expected-note {{in instantiation of}} + +namespace dr226 { // dr226: no + template<typename T = void> void f() {} +#if __cplusplus < 201103L + // expected-error@-2 {{extension}} + // FIXME: This appears to be wrong: default arguments for function templates + // are listed as a defect (in c++98) not an extension. EDG accepts them in + // strict c++98 mode. +#endif + template<typename T> struct S { + template<typename U = void> void g(); +#if __cplusplus < 201103L + // expected-error@-2 {{extension}} +#endif + template<typename U> struct X; + template<typename U> void h(); + }; + template<typename T> template<typename U> void S<T>::g() {} + template<typename T> template<typename U = void> struct S<T>::X {}; // expected-error {{cannot add a default template arg}} + template<typename T> template<typename U = void> void S<T>::h() {} // expected-error {{cannot add a default template arg}} + + template<typename> void friend_h(); + struct A { + // FIXME: This is ill-formed. + template<typename=void> struct friend_B; + // FIXME: f, h, and i are ill-formed. + // f is ill-formed because it is not a definition. + // h and i are ill-formed because they are not the only declarations of the + // function in the translation unit. + template<typename=void> void friend_f(); + template<typename=void> void friend_g() {} + template<typename=void> void friend_h() {} + template<typename=void> void friend_i() {} +#if __cplusplus < 201103L + // expected-error@-5 {{extension}} expected-error@-4 {{extension}} + // expected-error@-4 {{extension}} expected-error@-3 {{extension}} +#endif + }; + template<typename> void friend_i(); + + template<typename=void, typename X> void foo(X) {} + template<typename=void, typename X> struct Foo {}; // expected-error {{missing a default argument}} expected-note {{here}} +#if __cplusplus < 201103L + // expected-error@-3 {{extension}} +#endif + + template<typename=void, typename X, typename, typename Y> int foo(X, Y); + template<typename, typename X, typename=void, typename Y> int foo(X, Y); + int x = foo(0, 0); +#if __cplusplus < 201103L + // expected-error@-4 {{extension}} + // expected-error@-4 {{extension}} +#endif +} + +void dr227(bool b) { // dr227: yes + if (b) + int n; + else + int n; +} + +namespace dr228 { // dr228: yes + template <class T> struct X { + void f(); + }; + template <class T> struct Y { + void g(X<T> x) { x.template X<T>::f(); } + }; +} + +namespace dr229 { // dr229: yes + template<typename T> void f(); + template<typename T> void f<T*>() {} // expected-error {{function template partial specialization}} + template<> void f<int>() {} +} + +namespace dr231 { // dr231: yes + namespace outer { + namespace inner { + int i; // expected-note {{here}} + } + void f() { using namespace inner; } + int j = i; // expected-error {{undeclared identifier 'i'; did you mean 'inner::i'?}} + } +} + +// dr234: na +// dr235: na + +namespace dr236 { // dr236: yes + void *p = int(); +#if __cplusplus < 201103L + // expected-warning@-2 {{null pointer}} +#else + // expected-error@-4 {{cannot initialize}} +#endif +} + +namespace dr237 { // dr237: dup 470 + template<typename T> struct A { void f() { T::error; } }; + template<typename T> struct B : A<T> {}; + template struct B<int>; // ok +} + +namespace dr239 { // dr239: yes + namespace NS { + class T {}; + void f(T); + float &g(T, int); + } + NS::T parm; + int &g(NS::T, float); + int main() { + f(parm); + float &r = g(parm, 1); + extern int &g(NS::T, float); + int &s = g(parm, 1); + } +} + +// dr240: dup 616 + +namespace dr241 { // dr241: yes + namespace A { + struct B {}; + template <int X> void f(); // expected-note 2{{candidate}} + template <int X> void g(B); + } + namespace C { + template <class T> void f(T t); // expected-note 2{{candidate}} + template <class T> void g(T t); // expected-note {{candidate}} + } + void h(A::B b) { + f<3>(b); // expected-error {{undeclared identifier}} + g<3>(b); // expected-error {{undeclared identifier}} + A::f<3>(b); // expected-error {{no matching}} + A::g<3>(b); + C::f<3>(b); // expected-error {{no matching}} + C::g<3>(b); // expected-error {{no matching}} + using C::f; + using C::g; + f<3>(b); // expected-error {{no matching}} + g<3>(b); + } +} + +namespace dr243 { // dr243: yes + struct B; + struct A { + A(B); // expected-note {{candidate}} + }; + struct B { + operator A() = delete; // expected-error 0-1{{extension}} expected-note {{candidate}} + } b; + A a1(b); + A a2 = b; // expected-error {{ambiguous}} +} + +namespace dr244 { // dr244: no + struct B {}; struct D : B {}; // expected-note {{here}} + + D D_object; + typedef B B_alias; + B* B_ptr = &D_object; + + void f() { + D_object.~B(); // expected-error {{expression does not match the type}} + D_object.B::~B(); + B_ptr->~B(); + B_ptr->~B_alias(); + B_ptr->B_alias::~B(); + // This is valid under DR244. + B_ptr->B_alias::~B_alias(); // FIXME: expected-error {{expected the class name after '~' to name a destructor}} + B_ptr->dr244::~B(); // expected-error {{refers to a member in namespace}} + B_ptr->dr244::~B_alias(); // expected-error {{refers to a member in namespace}} + } +} + +namespace dr245 { // dr245: yes + struct S { + enum E {}; // expected-note {{here}} + class E *p; // expected-error {{does not match previous declaration}} + }; +} + +namespace dr246 { // dr246: yes + struct S { + S() try { // expected-note {{try block}} + throw 0; +X: ; + } catch (int) { + goto X; // expected-error {{protected scope}} + } + }; +} + +namespace dr247 { // dr247: yes + struct A {}; + struct B : A { + void f(); + void f(int); + }; + void (A::*f)() = (void (A::*)())&B::f; + + struct C { + void f(); + void f(int); + }; + struct D : C {}; + void (C::*g)() = &D::f; + void (D::*h)() = &D::f; + + struct E { + void f(); + }; + struct F : E { + using E::f; + void f(int); + }; + void (F::*i)() = &F::f; +} + +namespace dr248 { // dr248: yes c++11 + // FIXME: Should this also apply to c++98 mode? This was a DR against C++98. + int \u040d\u040e = 0; +#if __cplusplus < 201103L + // FIXME: expected-error@-2 {{expected ';'}} +#endif +} + +namespace dr249 { // dr249: yes + template<typename T> struct X { void f(); }; + template<typename T> void X<T>::f() {} +} + +namespace dr250 { // dr250: yes + typedef void (*FPtr)(double x[]); + + template<int I> void f(double x[]); + FPtr fp = &f<3>; + + template<int I = 3> void g(double x[]); // expected-error 0-1{{extension}} + FPtr gp = &g<>; +} + +namespace dr252 { // dr252: yes + struct A { + void operator delete(void*); // expected-note {{found}} + }; + struct B { + void operator delete(void*); // expected-note {{found}} + }; + struct C : A, B { + virtual ~C(); + }; + C::~C() {} // expected-error {{'operator delete' found in multiple base classes}} + + struct D { + void operator delete(void*, int); // expected-note {{here}} + virtual ~D(); + }; + D::~D() {} // expected-error {{no suitable member 'operator delete'}} + + struct E { + void operator delete(void*, int); + void operator delete(void*) = delete; // expected-error 0-1{{extension}} expected-note {{here}} + virtual ~E(); + }; + E::~E() {} // expected-error {{deleted}} + + struct F { + // If both functions are available, the first one is a placement delete. + void operator delete(void*, __SIZE_TYPE__); + void operator delete(void*) = delete; // expected-error 0-1{{extension}} expected-note {{here}} + virtual ~F(); + }; + F::~F() {} // expected-error {{deleted}} + + struct G { + void operator delete(void*, __SIZE_TYPE__); + virtual ~G(); + }; + G::~G() {} +} + +namespace dr254 { // dr254: yes + template<typename T> struct A { + typedef typename T::type type; // ok even if this is a typedef-name, because + // it's not an elaborated-type-specifier + typedef struct T::type foo; // expected-error {{elaborated type refers to a typedef}} + }; + struct B { struct type {}; }; + struct C { typedef struct {} type; }; // expected-note {{here}} + A<B>::type n; + A<C>::type n; // expected-note {{instantiation of}} +} + +// dr256: dup 624 + +namespace dr257 { // dr257: yes + struct A { A(int); }; // expected-note {{here}} + struct B : virtual A { + B() {} + virtual void f() = 0; + }; + struct C : B { + C() {} + }; + struct D : B { + D() {} // expected-error {{must explicitly initialize the base class 'dr257::A'}} + void f(); + }; +} + +namespace dr258 { // dr258: yes + struct A { + void f(const int); + template<typename> void g(int); + float &h() const; + }; + struct B : A { + using A::f; + using A::g; + using A::h; + int &f(int); + template<int> int &g(int); // expected-note {{candidate}} + int &h(); + } b; + int &w = b.f(0); + int &x = b.g<int>(0); // expected-error {{no match}} + int &y = b.h(); + float &z = const_cast<const B&>(b).h(); + + struct C { + virtual void f(const int) = 0; + }; + struct D : C { + void f(int); + } d; + + struct E { + virtual void f() = 0; // expected-note {{unimplemented}} + }; + struct F : E { + void f() const {} + } f; // expected-error {{abstract}} +} + +namespace dr259 { // dr259: yes c++11 + template<typename T> struct A {}; + template struct A<int>; // expected-note {{previous}} + template struct A<int>; // expected-error {{duplicate explicit instantiation}} + + // FIXME: We only apply this DR in C++11 mode. + template<> struct A<float>; + template struct A<float>; +#if __cplusplus < 201103L + // expected-error@-2 {{extension}} expected-note@-3 {{here}} +#endif + + template struct A<char>; // expected-note {{here}} + template<> struct A<char>; // expected-error {{explicit specialization of 'dr259::A<char>' after instantiation}} + + template<> struct A<double>; + template<> struct A<double>; + template<> struct A<double> {}; // expected-note {{here}} + template<> struct A<double> {}; // expected-error {{redefinition}} + + template<typename T> struct B; // expected-note {{here}} + template struct B<int>; // expected-error {{undefined}} + + template<> struct B<float>; + template struct B<float>; +#if __cplusplus < 201103L + // expected-error@-2 {{extension}} expected-note@-3 {{here}} +#endif +} + +namespace dr261 { // dr261: no +#pragma clang diagnostic push +#pragma clang diagnostic warning "-Wused-but-marked-unused" + + // FIXME: This is ill-formed, with a diagnostic required, because operator new + // and operator delete are inline and odr-used, but not defined in this + // translation unit. + // We're also missing the -Wused-but-marked-unused diagnostic here. + struct A { + inline void *operator new(__SIZE_TYPE__) __attribute__((unused)); + inline void operator delete(void*) __attribute__((unused)); + A() {} + }; + + // FIXME: These are ill-formed, with a required diagnostic, for the same + // reason. + struct B { + inline void operator delete(void*) __attribute__((unused)); + ~B() {} + }; + struct C { + inline void operator delete(void*) __attribute__((unused)); + virtual ~C() {} + }; + + struct D { + inline void operator delete(void*) __attribute__((unused)); + }; + void h() { C::operator delete(0); } // expected-warning {{marked unused but was used}} + +#pragma clang diagnostic pop +} + +namespace dr262 { // dr262: yes + int f(int = 0, ...); + int k = f(); + int l = f(0); + int m = f(0, 0); +} + +namespace dr263 { // dr263: yes + struct X {}; + struct Y { +#if __cplusplus < 201103L + friend X::X() throw(); + friend X::~X() throw(); +#else + friend constexpr X::X() noexcept; + friend X::~X(); +#endif + Y::Y(); // expected-error {{extra qualification}} + Y::~Y(); // expected-error {{extra qualification}} + }; +} + +// dr265: dup 353 +// dr266: na +// dr269: na +// dr270: na diff --git a/test/CXX/drs/dr4xx.cpp b/test/CXX/drs/dr4xx.cpp new file mode 100644 index 0000000..1d3b940 --- /dev/null +++ b/test/CXX/drs/dr4xx.cpp @@ -0,0 +1,32 @@ +// 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 + +namespace dr408 { // dr408: 3.4 + template<int N> void g() { int arr[N != 1 ? 1 : -1]; } + template<> void g<2>() { } + + template<typename T> struct S { + static int i[]; + void f(); + }; + template<typename T> int S<T>::i[] = { 1 }; + + template<typename T> void S<T>::f() { + g<sizeof (i) / sizeof (int)>(); + } + template<> int S<int>::i[] = { 1, 2 }; + template void S<int>::f(); // uses g<2>(), not g<1>(). + + + template<typename T> struct R { + static int arr[]; + void f(); + }; + template<typename T> int R<T>::arr[1]; + template<typename T> void R<T>::f() { + int arr[sizeof(arr) != sizeof(int) ? 1 : -1]; + } + template<> int R<int>::arr[2]; + template void R<int>::f(); +} |