summaryrefslogtreecommitdiff
path: root/test/CXX/dcl.dcl
diff options
context:
space:
mode:
Diffstat (limited to 'test/CXX/dcl.dcl')
-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
-rw-r--r--test/CXX/dcl.dcl/dcl.attr/dcl.attr.fallthrough/p1.cpp70
-rw-r--r--test/CXX/dcl.dcl/dcl.attr/dcl.attr.grammar/p2-1z.cpp16
-rw-r--r--test/CXX/dcl.dcl/dcl.attr/dcl.attr.nodiscard/p1.cpp10
-rw-r--r--test/CXX/dcl.dcl/dcl.attr/dcl.attr.nodiscard/p2.cpp29
-rw-r--r--test/CXX/dcl.dcl/dcl.attr/dcl.attr.nodiscard/p3.cpp17
-rw-r--r--test/CXX/dcl.dcl/dcl.attr/dcl.attr.unused/p1.cpp5
-rw-r--r--test/CXX/dcl.dcl/dcl.attr/dcl.attr.unused/p2.cpp17
-rw-r--r--test/CXX/dcl.dcl/dcl.attr/dcl.attr.unused/p3.cpp26
-rw-r--r--test/CXX/dcl.dcl/dcl.attr/dcl.attr.unused/p4.cpp8
-rw-r--r--test/CXX/dcl.dcl/dcl.spec/dcl.constexpr/p1.cpp29
-rw-r--r--test/CXX/dcl.dcl/dcl.spec/dcl.inline/p1.cpp8
-rw-r--r--test/CXX/dcl.dcl/dcl.spec/dcl.inline/p5.cpp15
-rw-r--r--test/CXX/dcl.dcl/dcl.spec/dcl.type/dcl.spec.auto/p2-1z.cpp47
-rw-r--r--test/CXX/dcl.dcl/dcl.spec/dcl.type/p3-0x.cpp3
-rw-r--r--test/CXX/dcl.dcl/dcl.spec/dcl.typedef/p2-0x.cpp4
24 files changed, 630 insertions, 54 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>
diff --git a/test/CXX/dcl.dcl/dcl.attr/dcl.attr.fallthrough/p1.cpp b/test/CXX/dcl.dcl/dcl.attr/dcl.attr.fallthrough/p1.cpp
new file mode 100644
index 0000000000000..e7c90339a214a
--- /dev/null
+++ b/test/CXX/dcl.dcl/dcl.attr/dcl.attr.fallthrough/p1.cpp
@@ -0,0 +1,70 @@
+// RUN: %clang_cc1 -std=c++1z -verify %s
+
+void f(int n) {
+ switch (n) {
+ case 0:
+ n += 1;
+ [[fallthrough]]; // ok
+ case 1:
+ if (n) {
+ [[fallthrough]]; // ok
+ } else {
+ return;
+ }
+ case 2:
+ for (int n = 0; n != 10; ++n)
+ [[fallthrough]]; // expected-error {{does not directly precede switch label}}
+ case 3:
+ while (true)
+ [[fallthrough]]; // expected-error {{does not directly precede switch label}}
+ case 4:
+ while (false)
+ [[fallthrough]]; // expected-error {{does not directly precede switch label}}
+ case 5:
+ do [[fallthrough]]; while (true); // expected-error {{does not directly precede switch label}}
+ case 6:
+ do [[fallthrough]]; while (false); // expected-error {{does not directly precede switch label}}
+ case 7:
+ switch (n) {
+ case 0:
+ // FIXME: This should be an error, even though the next thing we do is to
+ // fall through in an outer switch statement.
+ [[fallthrough]];
+ }
+ case 8:
+ [[fallthrough]]; // expected-error {{does not directly precede switch label}}
+ goto label;
+ label:
+ case 9:
+ n += 1;
+ case 10: // no warning, -Wimplicit-fallthrough is not enabled in this test, and does not need to
+ // be enabled for these diagnostics to be produced.
+ break;
+ }
+}
+
+[[fallthrough]] typedef int n; // expected-error {{'fallthrough' attribute cannot be applied to a declaration}}
+typedef int [[fallthrough]] n; // expected-error {{'fallthrough' attribute cannot be applied to types}}
+typedef int n [[fallthrough]]; // expected-error {{'fallthrough' attribute cannot be applied to a declaration}}
+
+enum [[fallthrough]] E {}; // expected-error {{'fallthrough' attribute cannot be applied to a declaration}}
+class [[fallthrough]] C {}; // expected-error {{'fallthrough' attribute cannot be applied to a declaration}}
+
+[[fallthrough]] // expected-error {{'fallthrough' attribute cannot be applied to a declaration}}
+void g() {
+ [[fallthrough]] int n; // expected-error {{'fallthrough' attribute cannot be applied to a declaration}}
+ [[fallthrough]] ++n; // expected-error-re {{{{^}}fallthrough attribute is only allowed on empty statements}}
+
+ switch (n) {
+ // FIXME: This should be an error.
+ [[fallthrough]];
+ return;
+
+ case 0:
+ [[fallthrough, fallthrough]]; // expected-error {{multiple times}}
+ case 1:
+ [[fallthrough(0)]]; // expected-error {{argument list}}
+ case 2:
+ break;
+ }
+}
diff --git a/test/CXX/dcl.dcl/dcl.attr/dcl.attr.grammar/p2-1z.cpp b/test/CXX/dcl.dcl/dcl.attr/dcl.attr.grammar/p2-1z.cpp
new file mode 100644
index 0000000000000..192fa12610987
--- /dev/null
+++ b/test/CXX/dcl.dcl/dcl.attr/dcl.attr.grammar/p2-1z.cpp
@@ -0,0 +1,16 @@
+// RUN: %clang_cc1 -std=c++1z -verify %s
+
+[[disable_tail_calls, noduplicate]] void f() {} // expected-warning {{unknown attribute 'disable_tail_calls'}} expected-warning {{unknown attribute 'noduplicate'}}
+
+[[using clang: disable_tail_calls, noduplicate]] void g() {} // ok
+
+[[using]] extern int n; // expected-error {{expected identifier}}
+[[using foo
+] // expected-error {{expected ':'}}
+] extern int n;
+[[using 42:]] extern int n; // expected-error {{expected identifier}}
+[[using clang:]] extern int n; // ok
+[[using blah: clang::optnone]] extern int n; // expected-error {{attribute with scope specifier cannot follow}} expected-warning {{only applies to functions}}
+
+[[using clang: unknown_attr]] extern int n; // expected-warning {{unknown attribute}}
+[[using unknown_ns: something]] extern int n; // expected-warning {{unknown attribute}}
diff --git a/test/CXX/dcl.dcl/dcl.attr/dcl.attr.nodiscard/p1.cpp b/test/CXX/dcl.dcl/dcl.attr/dcl.attr.nodiscard/p1.cpp
new file mode 100644
index 0000000000000..e7a2382412952
--- /dev/null
+++ b/test/CXX/dcl.dcl/dcl.attr/dcl.attr.nodiscard/p1.cpp
@@ -0,0 +1,10 @@
+// RUN: %clang_cc1 -fsyntax-only -std=c++1z -verify %s
+
+struct [[nodiscard]] S1 {}; // ok
+struct [[nodiscard nodiscard]] S2 {}; // expected-error {{attribute 'nodiscard' cannot appear multiple times in an attribute specifier}}
+struct [[nodiscard("Wrong")]] S3 {}; // expected-error {{'nodiscard' cannot have an argument list}}
+
+[[nodiscard]] int f();
+enum [[nodiscard]] E {};
+
+namespace [[nodiscard]] N {} // expected-warning {{'nodiscard' attribute only applies to functions, methods, enums, and classes}}
diff --git a/test/CXX/dcl.dcl/dcl.attr/dcl.attr.nodiscard/p2.cpp b/test/CXX/dcl.dcl/dcl.attr/dcl.attr.nodiscard/p2.cpp
new file mode 100644
index 0000000000000..3d4b92518810b
--- /dev/null
+++ b/test/CXX/dcl.dcl/dcl.attr/dcl.attr.nodiscard/p2.cpp
@@ -0,0 +1,29 @@
+// RUN: %clang_cc1 -fsyntax-only -std=c++1z -verify -Wc++1z-extensions %s
+// RUN: %clang_cc1 -fsyntax-only -std=c++11 -verify -DEXT -Wc++1z-extensions %s
+
+struct [[nodiscard]] S {};
+S get_s();
+S& get_s_ref();
+
+enum [[nodiscard]] E {};
+E get_e();
+
+[[nodiscard]] int get_i();
+
+void f() {
+ get_s(); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
+ get_i(); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
+ get_e(); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
+
+ // Okay, warnings are not encouraged
+ get_s_ref();
+ (void)get_s();
+ (void)get_i();
+ (void)get_e();
+}
+
+#ifdef EXT
+// expected-warning@4 {{use of the 'nodiscard' attribute is a C++1z extension}}
+// expected-warning@8 {{use of the 'nodiscard' attribute is a C++1z extension}}
+// expected-warning@11 {{use of the 'nodiscard' attribute is a C++1z extension}}
+#endif
diff --git a/test/CXX/dcl.dcl/dcl.attr/dcl.attr.nodiscard/p3.cpp b/test/CXX/dcl.dcl/dcl.attr/dcl.attr.nodiscard/p3.cpp
new file mode 100644
index 0000000000000..a3543cff7d2c9
--- /dev/null
+++ b/test/CXX/dcl.dcl/dcl.attr/dcl.attr.nodiscard/p3.cpp
@@ -0,0 +1,17 @@
+// RUN: %clang_cc1 -std=c++1z -verify %s
+
+namespace std_example {
+ struct [[nodiscard]] error_info{
+ // ...
+ };
+
+ error_info enable_missile_safety_mode();
+ void launch_missiles();
+ void test_missiles() {
+ enable_missile_safety_mode(); // expected-warning {{ignoring return value of function declared with 'nodiscard'}}
+ launch_missiles();
+ }
+
+ error_info &foo();
+ void f() { foo(); } // no warning
+}
diff --git a/test/CXX/dcl.dcl/dcl.attr/dcl.attr.unused/p1.cpp b/test/CXX/dcl.dcl/dcl.attr/dcl.attr.unused/p1.cpp
new file mode 100644
index 0000000000000..8da2ca7d6d86b
--- /dev/null
+++ b/test/CXX/dcl.dcl/dcl.attr/dcl.attr.unused/p1.cpp
@@ -0,0 +1,5 @@
+// RUN: %clang_cc1 -fsyntax-only -Wunused -std=c++1z -verify %s
+
+struct [[maybe_unused]] S1 {}; // ok
+struct [[maybe_unused maybe_unused]] S2 {}; // expected-error {{attribute 'maybe_unused' cannot appear multiple times in an attribute specifier}}
+struct [[maybe_unused("Wrong")]] S3 {}; // expected-error {{'maybe_unused' cannot have an argument list}}
diff --git a/test/CXX/dcl.dcl/dcl.attr/dcl.attr.unused/p2.cpp b/test/CXX/dcl.dcl/dcl.attr/dcl.attr.unused/p2.cpp
new file mode 100644
index 0000000000000..b539ca48ae34d
--- /dev/null
+++ b/test/CXX/dcl.dcl/dcl.attr/dcl.attr.unused/p2.cpp
@@ -0,0 +1,17 @@
+// RUN: %clang_cc1 -fsyntax-only -Wunused -std=c++1z -verify %s
+
+struct [[maybe_unused]] S {
+ int I [[maybe_unused]];
+ static int SI [[maybe_unused]]; // expected-warning {{'maybe_unused' attribute only applies to variables, functions, methods, types, enumerations, enumerators, labels, and non-static data members}}
+};
+
+enum [[maybe_unused]] E1 {
+ EnumVal [[maybe_unused]]
+};
+
+[[maybe_unused]] void unused_func([[maybe_unused]] int parm) {
+ typedef int maybe_unused_int [[maybe_unused]];
+ [[maybe_unused]] int I;
+}
+
+namespace [[maybe_unused]] N {} // expected-warning {{'maybe_unused' attribute only applies to}}
diff --git a/test/CXX/dcl.dcl/dcl.attr/dcl.attr.unused/p3.cpp b/test/CXX/dcl.dcl/dcl.attr/dcl.attr.unused/p3.cpp
new file mode 100644
index 0000000000000..a627d8331a746
--- /dev/null
+++ b/test/CXX/dcl.dcl/dcl.attr/dcl.attr.unused/p3.cpp
@@ -0,0 +1,26 @@
+// RUN: %clang_cc1 -fsyntax-only -Wunused -Wused-but-marked-unused -std=c++1z -Wc++1z-extensions -verify %s
+// RUN: %clang_cc1 -fsyntax-only -Wunused -Wused-but-marked-unused -std=c++11 -Wc++1z-extensions -verify -DEXT %s
+
+static_assert(__has_cpp_attribute(maybe_unused) == 201603, "");
+
+struct [[maybe_unused]] S {};
+
+void f() {
+ int x; // expected-warning {{unused variable}}
+ typedef int I; // expected-warning {{unused typedef 'I'}}
+
+ // Should not warn about these due to not being used.
+ [[maybe_unused]] int y;
+ typedef int maybe_unused_int [[maybe_unused]];
+
+ // Should not warn about these uses.
+ S s;
+ maybe_unused_int test;
+ y = 12;
+}
+
+#ifdef EXT
+// expected-warning@6 {{use of the 'maybe_unused' attribute is a C++1z extension}}
+// expected-warning@13 {{use of the 'maybe_unused' attribute is a C++1z extension}}
+// expected-warning@14 {{use of the 'maybe_unused' attribute is a C++1z extension}}
+#endif
diff --git a/test/CXX/dcl.dcl/dcl.attr/dcl.attr.unused/p4.cpp b/test/CXX/dcl.dcl/dcl.attr/dcl.attr.unused/p4.cpp
new file mode 100644
index 0000000000000..d4a275930d64e
--- /dev/null
+++ b/test/CXX/dcl.dcl/dcl.attr/dcl.attr.unused/p4.cpp
@@ -0,0 +1,8 @@
+// RUN: %clang_cc1 -fsyntax-only -Wunused -std=c++1z -verify %s
+// expected-no-diagnostics
+
+void f();
+[[maybe_unused]] void f();
+
+void f() {
+}
diff --git a/test/CXX/dcl.dcl/dcl.spec/dcl.constexpr/p1.cpp b/test/CXX/dcl.dcl/dcl.spec/dcl.constexpr/p1.cpp
index 35dbec93e5bb3..5a4c5c9a9d630 100644
--- a/test/CXX/dcl.dcl/dcl.spec/dcl.constexpr/p1.cpp
+++ b/test/CXX/dcl.dcl/dcl.spec/dcl.constexpr/p1.cpp
@@ -1,4 +1,6 @@
// RUN: %clang_cc1 -fsyntax-only -verify -std=c++11 %s
+// RUN: %clang_cc1 -fsyntax-only -verify -std=c++14 %s
+// RUN: %clang_cc1 -fsyntax-only -verify -std=c++1z %s
struct notlit { // expected-note {{not literal because}}
notlit() {}
@@ -26,7 +28,12 @@ void f2(constexpr int i) {} // expected-error {{function parameter cannot be con
// non-static member
struct s2 {
constexpr int mi1; // expected-error {{non-static data member cannot be constexpr; did you intend to make it const?}}
- static constexpr int mi2; // expected-error {{requires an initializer}}
+ static constexpr int mi2;
+#if __cplusplus <= 201402L
+ // expected-error@-2 {{requires an initializer}}
+#else
+ // expected-error@-4 {{default initialization of an object of const}}
+#endif
mutable constexpr int mi3 = 3; // expected-error-re {{non-static data member cannot be constexpr{{$}}}} expected-error {{'mutable' and 'const' cannot be mixed}}
};
// typedef
@@ -71,7 +78,7 @@ struct ConstexprDtor {
template <typename T> constexpr T ft(T t) { return t; }
template <typename T> T gt(T t) { return t; }
struct S {
- template<typename T> constexpr T f(); // expected-warning {{C++14}}
+ template<typename T> constexpr T f(); // expected-warning 0-1{{C++14}} expected-note 0-1{{candidate}}
template <typename T>
T g() const; // expected-note-re {{candidate template ignored: could not match 'T (){{( __attribute__\(\(thiscall\)\))?}} const' against 'char (){{( __attribute__\(\(thiscall\)\))?}}'}}
};
@@ -82,7 +89,15 @@ template <> char ft(char c) { return c; } // expected-note {{previous}}
template <> constexpr char ft(char nl); // expected-error {{constexpr declaration of 'ft<char>' follows non-constexpr declaration}}
template <> constexpr int gt(int nl) { return nl; }
template <> notlit S::f() const { return notlit(); }
-template <> constexpr int S::g() { return 0; } // expected-note {{previous}} expected-warning {{C++14}}
+#if __cplusplus >= 201402L
+// expected-error@-2 {{no function template matches}}
+#endif
+template <> constexpr int S::g() { return 0; } // expected-note {{previous}}
+#if __cplusplus < 201402L
+// expected-warning@-2 {{C++14}}
+#else
+// expected-error@-4 {{does not match any declaration in 'S'}}
+#endif
template <> int S::g() const; // expected-error {{non-constexpr declaration of 'g<int>' follows constexpr declaration}}
// specializations can drop the 'constexpr' but not the implied 'const'.
template <> char S::g() { return 0; } // expected-error {{no function template matches}}
@@ -123,3 +138,11 @@ int next(constexpr int x) { // expected-error {{function parameter cannot be con
}
extern constexpr int memsz; // expected-error {{constexpr variable declaration must be a definition}}
+
+namespace {
+ struct A {
+ static constexpr int n = 0;
+ };
+ // FIXME: We should diagnose this prior to C++17.
+ const int &r = A::n;
+}
diff --git a/test/CXX/dcl.dcl/dcl.spec/dcl.inline/p1.cpp b/test/CXX/dcl.dcl/dcl.spec/dcl.inline/p1.cpp
new file mode 100644
index 0000000000000..6db0b04a7496e
--- /dev/null
+++ b/test/CXX/dcl.dcl/dcl.spec/dcl.inline/p1.cpp
@@ -0,0 +1,8 @@
+// RUN: %clang_cc1 -std=c++1z -verify %s
+
+inline int f(); // ok
+inline int n; // ok
+
+inline typedef int t; // expected-error {{'inline' can only appear on functions and non-local variables}}
+inline struct S {}; // expected-error {{'inline' can only appear on functions and non-local variables}}
+inline struct T {} s; // ok
diff --git a/test/CXX/dcl.dcl/dcl.spec/dcl.inline/p5.cpp b/test/CXX/dcl.dcl/dcl.spec/dcl.inline/p5.cpp
new file mode 100644
index 0000000000000..0ca7bbc5fad37
--- /dev/null
+++ b/test/CXX/dcl.dcl/dcl.spec/dcl.inline/p5.cpp
@@ -0,0 +1,15 @@
+// RUN: %clang_cc1 -std=c++1z -verify %s
+
+void x() {
+ inline int f(int); // expected-error {{inline declaration of 'f' not allowed in block scope}}
+ inline int n; // expected-error {{inline declaration of 'n' not allowed in block scope}}
+ static inline int m; // expected-error {{inline declaration of 'm' not allowed in block scope}}
+}
+
+inline void g();
+struct X {
+ inline void f();
+ // FIXME: This is ill-formed per [dcl.inline]p5.
+ inline void g();
+ inline void h() {}
+};
diff --git a/test/CXX/dcl.dcl/dcl.spec/dcl.type/dcl.spec.auto/p2-1z.cpp b/test/CXX/dcl.dcl/dcl.spec/dcl.type/dcl.spec.auto/p2-1z.cpp
new file mode 100644
index 0000000000000..e41270ee3cd29
--- /dev/null
+++ b/test/CXX/dcl.dcl/dcl.spec/dcl.type/dcl.spec.auto/p2-1z.cpp
@@ -0,0 +1,47 @@
+// RUN: %clang_cc1 -std=c++1z -verify %s
+
+template<typename T, typename U> constexpr bool same = false;
+template<typename T> constexpr bool same<T, T> = true;
+
+auto a() {
+ if constexpr (false)
+ return 0;
+}
+static_assert(same<decltype(a()), void>);
+
+auto b() {
+ if constexpr (false)
+ return 0;
+ else
+ return 0.0;
+}
+static_assert(same<decltype(b()), double>);
+
+auto c() {
+ if constexpr (true)
+ return "foo";
+ else
+ return 'x';
+ if constexpr (false)
+ return 7.6;
+ else
+ return 5; // expected-error {{deduced as 'int' here but deduced as 'const char *' in earlier}}
+}
+
+template<int k> auto d() {
+ if constexpr(k == 0)
+ return 0;
+ if constexpr(k == 1)
+ return "foo";
+ else if constexpr (k == 2)
+ return 1.0;
+}
+static_assert(same<decltype(d<0>()), int>);
+static_assert(same<decltype(d<1>()), const char *>);
+static_assert(same<decltype(d<2>()), double>);
+static_assert(same<decltype(d<3>()), void>);
+
+auto e = []{ if constexpr (false) return 0; }(); // expected-error {{variable has incomplete type 'void'}}
+
+auto f = []{ if constexpr (true) return 0; }();
+static_assert(same<decltype(e), int>);
diff --git a/test/CXX/dcl.dcl/dcl.spec/dcl.type/p3-0x.cpp b/test/CXX/dcl.dcl/dcl.spec/dcl.type/p3-0x.cpp
index 39d6e706b6c1c..447f7c5d6cf38 100644
--- a/test/CXX/dcl.dcl/dcl.spec/dcl.type/p3-0x.cpp
+++ b/test/CXX/dcl.dcl/dcl.spec/dcl.type/p3-0x.cpp
@@ -18,6 +18,9 @@ void f() {
for (struct S { S(int) {} } s : arr) { // expected-error {{types may not be defined in a for range declaration}}
}
+ for (struct S { S(int) {} } s : Undeclared); // expected-error{{types may not be defined in a for range declaration}}
+ // expected-error@-1{{use of undeclared identifier 'Undeclared'}}
+
new struct T {}; // expected-error {{'T' cannot be defined in a type specifier}}
new struct A {}; // expected-error {{'A' cannot be defined in a type specifier}}
diff --git a/test/CXX/dcl.dcl/dcl.spec/dcl.typedef/p2-0x.cpp b/test/CXX/dcl.dcl/dcl.spec/dcl.typedef/p2-0x.cpp
index 20b5104f83be7..8c6f6e5ddc796 100644
--- a/test/CXX/dcl.dcl/dcl.spec/dcl.typedef/p2-0x.cpp
+++ b/test/CXX/dcl.dcl/dcl.spec/dcl.typedef/p2-0x.cpp
@@ -38,8 +38,8 @@ namespace VariableLengthArrays {
using T = int[n]; // expected-error {{variable length array declaration not allowed at file scope}}
const int m = 42;
- using U = int[m]; // expected-note {{previous definition}}
- using U = int[42]; // ok
+ using U = int[m];
+ using U = int[42]; // expected-note {{previous definition}}
using U = int; // expected-error {{type alias redefinition with different types ('int' vs 'int [42]')}}
void f() {