diff options
Diffstat (limited to 'test/CXX/dcl.dcl/basic.namespace/namespace.udecl')
-rw-r--r-- | test/CXX/dcl.dcl/basic.namespace/namespace.udecl/p12.cpp | 32 | ||||
-rw-r--r-- | test/CXX/dcl.dcl/basic.namespace/namespace.udecl/p15.cpp | 81 | ||||
-rw-r--r-- | test/CXX/dcl.dcl/basic.namespace/namespace.udecl/p18.cpp | 77 | ||||
-rw-r--r-- | test/CXX/dcl.dcl/basic.namespace/namespace.udecl/p3-cxx0x.cpp | 46 | ||||
-rw-r--r-- | test/CXX/dcl.dcl/basic.namespace/namespace.udecl/p3.cpp | 82 | ||||
-rw-r--r-- | test/CXX/dcl.dcl/basic.namespace/namespace.udecl/p4.cpp | 28 | ||||
-rw-r--r-- | test/CXX/dcl.dcl/basic.namespace/namespace.udecl/p6-cxx11.cpp (renamed from test/CXX/dcl.dcl/basic.namespace/namespace.udecl/p6-cxx0x.cpp) | 3 | ||||
-rw-r--r-- | test/CXX/dcl.dcl/basic.namespace/namespace.udecl/p7.cpp | 4 | ||||
-rw-r--r-- | test/CXX/dcl.dcl/basic.namespace/namespace.udecl/p8-cxx0x.cpp | 27 |
9 files changed, 331 insertions, 49 deletions
diff --git a/test/CXX/dcl.dcl/basic.namespace/namespace.udecl/p12.cpp b/test/CXX/dcl.dcl/basic.namespace/namespace.udecl/p12.cpp index cc28bf6c28c4c..ce43720cb2d3e 100644 --- a/test/CXX/dcl.dcl/basic.namespace/namespace.udecl/p12.cpp +++ b/test/CXX/dcl.dcl/basic.namespace/namespace.udecl/p12.cpp @@ -1,3 +1,5 @@ +// RUN: %clang_cc1 -fsyntax-only -verify -std=c++98 %s +// RUN: %clang_cc1 -fsyntax-only -verify -std=c++11 %s // RUN: %clang_cc1 -fsyntax-only -verify %s // C++03 [namespace.udecl]p12: @@ -161,3 +163,33 @@ namespace test4 { d.bar<int>(3); // expected-error {{'bar' is a protected member}} } } + +namespace test5 { + struct Derived; + struct Base { + void operator=(const Derived&); + }; + struct Derived : Base { + // Hidden by implicit derived class operator. + using Base::operator=; + }; + void f(Derived d) { + d = d; + } +} + +#if __cplusplus >= 201103L +namespace test6 { + struct Derived; + struct Base { + void operator=(Derived&&); + }; + struct Derived : Base { + // Hidden by implicit derived class operator. + using Base::operator=; + }; + void f(Derived d) { + d = Derived(); + } +} +#endif diff --git a/test/CXX/dcl.dcl/basic.namespace/namespace.udecl/p15.cpp b/test/CXX/dcl.dcl/basic.namespace/namespace.udecl/p15.cpp new file mode 100644 index 0000000000000..3e04d5094ac19 --- /dev/null +++ b/test/CXX/dcl.dcl/basic.namespace/namespace.udecl/p15.cpp @@ -0,0 +1,81 @@ +// RUN: %clang_cc1 -std=c++11 -verify %s + +struct B1 { // expected-note 2{{candidate}} + B1(int); // expected-note {{candidate}} +}; + +struct B2 { // expected-note 2{{candidate}} + B2(int); // expected-note {{candidate}} +}; + +struct D1 : B1, B2 { // expected-note 2{{candidate}} + using B1::B1; // expected-note 3{{inherited here}} + using B2::B2; // expected-note 3{{inherited here}} +}; +D1 d1(0); // expected-error {{ambiguous}} + +struct D2 : B1, B2 { + using B1::B1; + using B2::B2; + D2(int); +}; +D2 d2(0); // ok + + +// The emergent behavior of implicit special members is a bit odd when +// inheriting from multiple base classes. +namespace default_ctor { + struct C; + struct D; + + struct A { // expected-note 4{{candidate}} + A(); // expected-note {{candidate}} + + A(C &&); // expected-note {{candidate}} + C &operator=(C&&); // expected-note {{candidate}} + + A(D &&); // expected-note {{candidate}} + D &operator=(D&&); // expected-note {{candidate}} + }; + + struct B { // expected-note 4{{candidate}} + B(); // expected-note {{candidate}} + + B(C &&); // expected-note {{candidate}} + C &operator=(C&&); // expected-note {{candidate}} + + B(D &&); // expected-note {{candidate}} + D &operator=(D&&); // expected-note {{candidate}} + }; + + struct C : A, B { + using A::A; + using A::operator=; + using B::B; + using B::operator=; + }; + struct D : A, B { + using A::A; // expected-note 5{{inherited here}} + using A::operator=; + using B::B; // expected-note 5{{inherited here}} + using B::operator=; + + D(int); + D(const D&); // expected-note {{candidate}} + D &operator=(const D&); // expected-note {{candidate}} + }; + + C c; + void f(C c) { + C c2(static_cast<C&&>(c)); + c = static_cast<C&&>(c); + } + + // D does not declare D(), D(D&&), nor operator=(D&&), so the base class + // versions are inherited. + D d; // expected-error {{ambiguous}} + void f(D d) { + D d2(static_cast<D&&>(d)); // expected-error {{ambiguous}} + d = static_cast<D&&>(d); // expected-error {{ambiguous}} + } +} diff --git a/test/CXX/dcl.dcl/basic.namespace/namespace.udecl/p18.cpp b/test/CXX/dcl.dcl/basic.namespace/namespace.udecl/p18.cpp new file mode 100644 index 0000000000000..b9fca4bd5b616 --- /dev/null +++ b/test/CXX/dcl.dcl/basic.namespace/namespace.udecl/p18.cpp @@ -0,0 +1,77 @@ +// RUN: %clang_cc1 -std=c++11 -verify %s + +struct Public {} public_; +struct Protected {} protected_; +struct Private {} private_; + +class A { +public: + A(Public); + void f(Public); + +protected: + A(Protected); // expected-note {{protected here}} + void f(Protected); + +private: + A(Private); // expected-note 4{{private here}} + void f(Private); // expected-note {{private here}} + + friend void Friend(); +}; + +class B : private A { + using A::A; // ok + using A::f; // expected-error {{private member}} + + void f() { + B a(public_); + B b(protected_); + B c(private_); // expected-error {{private}} + } + + B(Public p, int) : B(p) {} + B(Protected p, int) : B(p) {} + B(Private p, int) : B(p) {} // expected-error {{private}} +}; + +class C : public B { + C(Public p) : B(p) {} + // There is no access check on the conversion from derived to base here; + // protected constructors of A act like protected constructors of B. + C(Protected p) : B(p) {} + C(Private p) : B(p) {} // expected-error {{private}} +}; + +void Friend() { + // There is no access check on the conversion from derived to base here. + B a(public_); + B b(protected_); + B c(private_); +} + +void NonFriend() { + B a(public_); + B b(protected_); // expected-error {{protected}} + B c(private_); // expected-error {{private}} +} + +namespace ProtectedAccessFromMember { +namespace a { + struct ES { + private: + ES(const ES &) = delete; + protected: + ES(const char *); + }; +} +namespace b { + struct DES : a::ES { + DES *f(); + private: + using a::ES::ES; + }; +} +b::DES *b::DES::f() { return new b::DES("foo"); } + +} diff --git a/test/CXX/dcl.dcl/basic.namespace/namespace.udecl/p3-cxx0x.cpp b/test/CXX/dcl.dcl/basic.namespace/namespace.udecl/p3-cxx0x.cpp deleted file mode 100644 index f61437ead6e49..0000000000000 --- a/test/CXX/dcl.dcl/basic.namespace/namespace.udecl/p3-cxx0x.cpp +++ /dev/null @@ -1,46 +0,0 @@ -// RUN: %clang_cc1 -std=c++11 -fsyntax-only -verify %s -// C++0x N2914. - -struct B { - void f(char); - void g(char); - enum E { e }; - union { int x; }; -}; - -class C { - int g(); -}; - -class D2 : public B { - using B::f; - using B::e; - using B::x; - using C::g; // expected-error{{using declaration refers into 'C::', which is not a base class of 'D2'}} -}; - -namespace test1 { - struct Base { - int foo(); - }; - - struct Unrelated { - int foo(); - }; - - struct Subclass : Base { - }; - - namespace InnerNS { - int foo(); - } - - // We should be able to diagnose these without instantiation. - template <class T> struct C : Base { - using InnerNS::foo; // expected-error {{not a class}} - using Base::bar; // expected-error {{no member named 'bar'}} - using Unrelated::foo; // expected-error {{not a base class}} - using C::foo; // expected-error {{refers to its own class}} - using Subclass::foo; // expected-error {{not a base class}} - }; -} diff --git a/test/CXX/dcl.dcl/basic.namespace/namespace.udecl/p3.cpp b/test/CXX/dcl.dcl/basic.namespace/namespace.udecl/p3.cpp new file mode 100644 index 0000000000000..6c505a55c2afc --- /dev/null +++ b/test/CXX/dcl.dcl/basic.namespace/namespace.udecl/p3.cpp @@ -0,0 +1,82 @@ +// RUN: %clang_cc1 -std=c++98 -fsyntax-only -verify %s +// RUN: %clang_cc1 -std=c++11 -fsyntax-only -verify %s +// RUN: %clang_cc1 -fsyntax-only -verify %s + +struct B { + void f(char); + void g(char); + enum E { e }; + union { int x; }; + + enum class EC { ec }; // expected-warning 0-1 {{C++11}} + + void f2(char); + void g2(char); + enum E2 { e2 }; + union { int x2; }; +}; + +class C { + int g(); +}; + +struct D : B {}; + +class D2 : public B { + using B::f; + using B::E; + using B::e; + using B::x; + using C::g; // expected-error{{using declaration refers into 'C::', which is not a base class of 'D2'}} + + // These are valid in C++98 but not in C++11. + using D::f2; + using D::E2; + using D::e2; + using D::x2; +#if __cplusplus >= 201103L + // expected-error@-5 {{using declaration refers into 'D::', which is not a base class of 'D2'}} + // expected-error@-5 {{using declaration refers into 'D::', which is not a base class of 'D2'}} + // expected-error@-5 {{using declaration refers into 'D::', which is not a base class of 'D2'}} + // expected-error@-5 {{using declaration refers into 'D::', which is not a base class of 'D2'}} +#endif + + using B::EC; + using B::EC::ec; // expected-error {{not a class}} expected-warning 0-1 {{C++11}} +}; + +namespace test1 { + struct Base { + int foo(); + }; + + struct Unrelated { + int foo(); + }; + + struct Subclass : Base { + }; + + namespace InnerNS { + int foo(); + } + + struct B : Base { + }; + + // We should be able to diagnose these without instantiation. + template <class T> struct C : Base { + using InnerNS::foo; // expected-error {{not a class}} + using Base::bar; // expected-error {{no member named 'bar'}} + using Unrelated::foo; // expected-error {{not a base class}} + + // In C++98, it's hard to see that these are invalid, because indirect + // references to base class members are permitted. + using C::foo; + using Subclass::foo; +#if __cplusplus >= 201103L + // expected-error@-3 {{refers to its own class}} + // expected-error@-3 {{not a base class}} +#endif + }; +} diff --git a/test/CXX/dcl.dcl/basic.namespace/namespace.udecl/p4.cpp b/test/CXX/dcl.dcl/basic.namespace/namespace.udecl/p4.cpp index a43d9e019ed33..781a1a1824e93 100644 --- a/test/CXX/dcl.dcl/basic.namespace/namespace.udecl/p4.cpp +++ b/test/CXX/dcl.dcl/basic.namespace/namespace.udecl/p4.cpp @@ -1,4 +1,5 @@ // RUN: %clang_cc1 -fsyntax-only -verify %s +// RUN: %clang_cc1 -fsyntax-only -verify -std=c++11 %s // C++03 [namespace.udecl]p4: // A using-declaration used as a member-declaration shall refer to a @@ -206,8 +207,33 @@ namespace test4 { using Unrelated::foo; // expected-error {{not a base class}} using C::foo; // legal in C++03 using Subclass::foo; // legal in C++03 +#if __cplusplus >= 201103L + // expected-error@-3 {{refers to its own class}} + // expected-error@-3 {{refers into 'Subclass::', which is not a base class}} +#endif - int bar(); //expected-note {{target of using declaration}} + int bar(); +#if __cplusplus < 201103L + // expected-note@-2 {{target of using declaration}} +#endif using C::bar; // expected-error {{refers to its own class}} }; } + +namespace test5 { + struct B; + struct A { + A(const B&); + B &operator=(const B&); + }; + struct B : A { +#if __cplusplus >= 201103L + using A::A; +#endif + using A::operator=; + }; + void test(B b) { + B b2(b); + b2 = b; + } +} diff --git a/test/CXX/dcl.dcl/basic.namespace/namespace.udecl/p6-cxx0x.cpp b/test/CXX/dcl.dcl/basic.namespace/namespace.udecl/p6-cxx11.cpp index c2fb95902454d..97b2953b90312 100644 --- a/test/CXX/dcl.dcl/basic.namespace/namespace.udecl/p6-cxx0x.cpp +++ b/test/CXX/dcl.dcl/basic.namespace/namespace.udecl/p6-cxx11.cpp @@ -1,8 +1,7 @@ // RUN: %clang_cc1 -fsyntax-only -verify %s -// C++0x N2914. namespace A { namespace B { } } -using A::B; // expected-error{{using declaration cannot refer to namespace}} +using A::B; // expected-error{{using declaration cannot refer to a namespace}} diff --git a/test/CXX/dcl.dcl/basic.namespace/namespace.udecl/p7.cpp b/test/CXX/dcl.dcl/basic.namespace/namespace.udecl/p7.cpp new file mode 100644 index 0000000000000..6c9379fac27fd --- /dev/null +++ b/test/CXX/dcl.dcl/basic.namespace/namespace.udecl/p7.cpp @@ -0,0 +1,4 @@ +// RUN: %clang_cc1 -std=c++11 -verify %s + +enum class EC { ec }; +using EC::ec; // expected-error {{using declaration cannot refer to a scoped enumerator}} diff --git a/test/CXX/dcl.dcl/basic.namespace/namespace.udecl/p8-cxx0x.cpp b/test/CXX/dcl.dcl/basic.namespace/namespace.udecl/p8-cxx0x.cpp index ebe5388d65acc..6c63f061ab0f1 100644 --- a/test/CXX/dcl.dcl/basic.namespace/namespace.udecl/p8-cxx0x.cpp +++ b/test/CXX/dcl.dcl/basic.namespace/namespace.udecl/p8-cxx0x.cpp @@ -7,14 +7,41 @@ struct X { int i; static int a; + enum E { e }; }; using X::i; // expected-error{{using declaration cannot refer to class member}} using X::s; // expected-error{{using declaration cannot refer to class member}} +using X::e; // expected-error{{using declaration cannot refer to class member}} +using X::E::e; // expected-error{{using declaration cannot refer to class member}} expected-warning 0-1{{C++11}} +#if __cplusplus < 201103L +// expected-note@-3 {{use a const variable}} +// expected-note@-3 {{use a const variable}} +// CXX98-NOT: fix-it:"{{.*}}":{[[@LINE-5]]: +// CXX98-NOT: fix-it:"{{.*}}":{[[@LINE-5]]: +#else +// expected-note@-8 {{use a constexpr variable}} +// expected-note@-8 {{use a constexpr variable}} +// CXX11: fix-it:"{{.*}}":{[[@LINE-10]]:1-[[@LINE-10]]:6}:"constexpr auto e = " +// CXX11: fix-it:"{{.*}}":{[[@LINE-10]]:1-[[@LINE-10]]:6}:"constexpr auto e = " +#endif void f() { using X::i; // expected-error{{using declaration cannot refer to class member}} using X::s; // expected-error{{using declaration cannot refer to class member}} + using X::e; // expected-error{{using declaration cannot refer to class member}} + using X::E::e; // expected-error{{using declaration cannot refer to class member}} expected-warning 0-1{{C++11}} +#if __cplusplus < 201103L + // expected-note@-3 {{use a const variable}} + // expected-note@-3 {{use a const variable}} + // CXX98-NOT: fix-it:"{{.*}}":{[[@LINE-5]]: + // CXX98-NOT: fix-it:"{{.*}}":{[[@LINE-5]]: +#else + // expected-note@-8 {{use a constexpr variable}} + // expected-note@-8 {{use a constexpr variable}} + // CXX11: fix-it:"{{.*}}":{[[@LINE-10]]:3-[[@LINE-10]]:8}:"constexpr auto e = " + // CXX11: fix-it:"{{.*}}":{[[@LINE-10]]:3-[[@LINE-10]]:8}:"constexpr auto e = " +#endif } template <typename T> |