147 lines · cpp
1// RUN: %clang_cc1 -fsyntax-only -std=c++17 -pedantic -verify %s2// RUN: %clang_cc1 -fsyntax-only -std=c++20 -Wc++17-compat-pedantic -verify %s -Wno-defaulted-function-deleted3 4struct A {};5int (A::*pa)() const&;6int use_pa = (A().*pa)();7#if __cplusplus <= 201703L8 // expected-warning@-2 {{invoking a pointer to a 'const &' member function on an rvalue is a C++20 extension}}9#else10 // expected-warning@-4 {{invoking a pointer to a 'const &' member function on an rvalue is incompatible with C++ standards before C++20}}11#endif12 13struct B {14 void b() {15 (void) [=, this] {};16#if __cplusplus <= 201703L17 // expected-warning@-2 {{explicit capture of 'this' with a capture default of '=' is a C++20 extension}}18#else19 // expected-warning@-4 {{explicit capture of 'this' with a capture default of '=' is incompatible with C++ standards before C++20}}20#endif21 }22 23 int n : 5 = 0;24#if __cplusplus <= 201703L25 // expected-warning@-2 {{default member initializer for bit-field is a C++20 extension}}26#else27 // expected-warning@-4 {{default member initializer for bit-field is incompatible with C++ standards before C++20}}28#endif29};30 31auto Lambda = []{};32decltype(Lambda) AnotherLambda;33#if __cplusplus <= 201703L34 // expected-error@-2 {{no matching constructor}} expected-note@-3 2{{candidate}}35#else36 // expected-warning@-4 {{default construction of lambda is incompatible with C++ standards before C++20}}37#endif38 39void copy_lambda() { Lambda = Lambda; }40#if __cplusplus <= 201703L41 // expected-error@-2 {{deleted}} expected-note@-10 {{lambda}}42#else43 // expected-warning@-4 {{assignment of lambda is incompatible with C++ standards before C++20}}44#endif45 46struct DefaultDeleteWrongTypeBase {47 DefaultDeleteWrongTypeBase(DefaultDeleteWrongTypeBase&);48};49struct DefaultDeleteWrongType : DefaultDeleteWrongTypeBase {50 DefaultDeleteWrongType(const DefaultDeleteWrongType&) = default;51#if __cplusplus <= 201703L52 // expected-error@-2 {{a member or base requires it to be non-const}}53#else54 // expected-warning@-4 {{explicitly defaulting this copy constructor with a type different from the implicit type is incompatible with C++ standards before C++20}}55#endif56};57 58void ForRangeInit() {59 for (int arr[3] = {1, 2, 3}; int n : arr) {}60#if __cplusplus <= 201703L61 // expected-warning@-2 {{range-based for loop initialization statements are a C++20 extension}}62#else63 // expected-warning@-4 {{range-based for loop initialization statements are incompatible with C++ standards before C++20}}64#endif65}66 67struct ConstexprVirtual {68 virtual constexpr void f() {}69#if __cplusplus <= 201703L70 // expected-error@-2 {{virtual function cannot be constexpr}}71#else72 // expected-warning@-4 {{virtual constexpr functions are incompatible with C++ standards before C++20}}73#endif74};75 76struct C { int x, y, z; };77static auto [cx, cy, cz] = C();78#if __cplusplus <= 201703L79 // expected-warning@-2 {{structured binding declaration declared 'static' is a C++20 extension}}80#else81 // expected-warning@-4 {{structured binding declaration declared 'static' is incompatible with C++ standards before C++20}}82#endif83void f() {84 static thread_local auto [cx, cy, cz] = C();85#if __cplusplus <= 201703L86 // expected-warning@-2 {{structured binding declaration declared 'static' is a C++20 extension}}87 // expected-warning@-3 {{structured binding declaration declared 'thread_local' is a C++20 extension}}88#else89 // expected-warning@-5 {{structured binding declaration declared 'static' is incompatible with C++ standards before C++20}}90 // expected-warning@-6 {{structured binding declaration declared 'thread_local' is incompatible with C++ standards before C++20}}91#endif92}93 94struct DefaultedComparisons {95 bool operator==(const DefaultedComparisons&) const = default;96 bool operator!=(const DefaultedComparisons&) const = default;97#if __cplusplus <= 201703L98 // expected-warning@-3 {{defaulted comparison operators are a C++20 extension}}99 // expected-warning@-3 {{defaulted comparison operators are a C++20 extension}}100#else101 // expected-warning@-6 {{defaulted comparison operators are incompatible with C++ standards before C++20}}102 // expected-warning@-6 {{defaulted comparison operators are incompatible with C++ standards before C++20}}103#endif104 bool operator<=>(const DefaultedComparisons&) const = default;105#if __cplusplus <= 201703L106 // expected-error@-2 {{'operator<=' cannot be the name of a variable or data member}} expected-error@-2 0+{{}} expected-warning@-2 {{}}107#else108 // expected-warning@-4 {{'<=>' operator is incompatible with C++ standards before C++20}}109#endif110 bool operator<(const DefaultedComparisons&) const = default;111 bool operator<=(const DefaultedComparisons&) const = default;112 bool operator>(const DefaultedComparisons&) const = default;113 bool operator>=(const DefaultedComparisons&) const = default;114#if __cplusplus <= 201703L115 // expected-error@-5 {{only special member functions}}116 // expected-error@-5 {{only special member functions}}117 // expected-error@-5 {{only special member functions}}118 // expected-error@-5 {{only special member functions}}119#else120 // expected-warning@-10 {{defaulted comparison operators are incompatible with C++ standards before C++20}}121 // expected-warning@-10 {{defaulted comparison operators are incompatible with C++ standards before C++20}}122 // expected-warning@-10 {{defaulted comparison operators are incompatible with C++ standards before C++20}}123 // expected-warning@-10 {{defaulted comparison operators are incompatible with C++ standards before C++20}}124#endif125};126 127namespace NTTP {128 struct A {};129 template<A> struct Class {};130#if __cplusplus <= 201703L131 // expected-error@-2 {{non-type template parameter cannot have type 'A' before C++20}}132#else133 // expected-warning@-4 {{non-type template parameter of type 'A' is incompatible with C++ standards before C++20}}134#endif135}136 137namespace CTADForAliasTemplate {138template<typename T> struct A { A(T); };139template<typename T> using B = A<T>;140B b = {1};141#if __cplusplus <= 201703L142 // expected-warning@-2 {{class template argument deduction for alias templates is a C++20 extension}}143#else144 // expected-warning@-4 {{class template argument deduction for alias templates is incompatible with C++ standards before C++20}}145#endif146}147