diff options
Diffstat (limited to 'test/CXX/dcl.dcl')
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() { |