summaryrefslogtreecommitdiff
path: root/test/CXX/dcl.dcl/basic.namespace/namespace.udecl
diff options
context:
space:
mode:
Diffstat (limited to 'test/CXX/dcl.dcl/basic.namespace/namespace.udecl')
-rw-r--r--test/CXX/dcl.dcl/basic.namespace/namespace.udecl/p12.cpp32
-rw-r--r--test/CXX/dcl.dcl/basic.namespace/namespace.udecl/p15.cpp81
-rw-r--r--test/CXX/dcl.dcl/basic.namespace/namespace.udecl/p18.cpp77
-rw-r--r--test/CXX/dcl.dcl/basic.namespace/namespace.udecl/p3-cxx0x.cpp46
-rw-r--r--test/CXX/dcl.dcl/basic.namespace/namespace.udecl/p3.cpp82
-rw-r--r--test/CXX/dcl.dcl/basic.namespace/namespace.udecl/p4.cpp28
-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.cpp4
-rw-r--r--test/CXX/dcl.dcl/basic.namespace/namespace.udecl/p8-cxx0x.cpp27
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>