brintos

brintos / llvm-project-archived public Read only

0
0
Text · 16.7 KiB · bd233bb Raw
463 lines · cpp
1// RUN: %clang_cc1 -std=c++98 -triple x86_64-unknown-unknown %s -verify=expected,cxx98 -fexceptions -fcxx-exceptions -pedantic-errors2// RUN: %clang_cc1 -std=c++11 -triple x86_64-unknown-unknown %s -verify=expected,since-cxx11,cxx11 -fexceptions -fcxx-exceptions -pedantic-errors3// RUN: %clang_cc1 -std=c++14 -triple x86_64-unknown-unknown %s -verify=expected,since-cxx11,since-cxx14 -fexceptions -fcxx-exceptions -pedantic-errors4// RUN: %clang_cc1 -std=c++17 -triple x86_64-unknown-unknown %s -verify=expected,since-cxx11,since-cxx14 -fexceptions -fcxx-exceptions -pedantic-errors5// RUN: %clang_cc1 -std=c++20 -triple x86_64-unknown-unknown %s -verify=expected,since-cxx11,since-cxx14,since-cxx20 -fexceptions -fcxx-exceptions -pedantic-errors6// RUN: %clang_cc1 -std=c++23 -triple x86_64-unknown-unknown %s -verify=expected,since-cxx11,since-cxx14,since-cxx20 -fexceptions -fcxx-exceptions -pedantic-errors7// RUN: %clang_cc1 -std=c++2c -triple x86_64-unknown-unknown %s -verify=expected,since-cxx11,since-cxx14,since-cxx20 -fexceptions -fcxx-exceptions -pedantic-errors8 9#if __cplusplus == 199711L10#define static_assert(...) __extension__ _Static_assert(__VA_ARGS__)11// cxx98-error@-1 {{variadic macros are a C99 feature}}12#endif13 14namespace cwg2007 { // cwg2007: 3.415template<typename T> struct A { typename T::error e; };16template<typename T> struct B { };17B<A<void> > b1;18B<A<void> > b2 = b1;19int a = b2[0];20// cxx98-error@-1 {{type 'B<A<void> >' does not provide a subscript operator}}21// since-cxx11-error@-2 {{type 'B<A<void>>' does not provide a subscript operator}}22int b = __builtin_addressof(b2)->foo;23// cxx98-error@-1 {{no member named 'foo' in 'cwg2007::B<cwg2007::A<void> >'}}24// since-cxx11-error@-2 {{no member named 'foo' in 'cwg2007::B<cwg2007::A<void>>'}}25} // namespace cwg200726 27// cwg2009: na28 29namespace cwg2026 { // cwg2026: 1130  template<int> struct X {};31 32  const int a = a + 1; // #cwg2026-a33  // expected-warning@-1 {{variable 'a' is uninitialized when used within its own initialization}}34  X<a> xa; // #cwg2026-xa35  // cxx98-error@-1 {{non-type template argument of type 'int' is not an integral constant expression}}36  //   cxx98-note@-2 {{initializer of 'a' is not a constant expression}}37  //   cxx98-note@#cwg2026-a {{declared here}}38  // since-cxx11-error@#cwg2026-xa {{non-type template argument is not a constant expression}}39  //   since-cxx11-note@#cwg2026-xa {{initializer of 'a' is not a constant expression}}40  //   since-cxx11-note@#cwg2026-a {{declared here}}41 42#if __cplusplus >= 201103L43  constexpr int b = b;44  // since-cxx11-error@-1 {{constexpr variable 'b' must be initialized by a constant expression}}45  //   since-cxx11-note@-2 {{read of object outside its lifetime is not allowed in a constant expression}}46  [[clang::require_constant_initialization]] int c = c;47  // since-cxx11-error@-1 {{variable does not have a constant initializer}}48  //   since-cxx11-note@-2 {{required by 'require_constant_initialization' attribute here}}49  //   cxx11-note@-3 {{read of non-const variable 'c' is not allowed in a constant expression}}50  //   cxx11-note@-4 {{declared here}}51  //   since-cxx14-note@-5 {{read of object outside its lifetime is not allowed in a constant expression}}52#endif53 54#if __cplusplus >= 202002L55  constinit int d = d;56  // since-cxx20-error@-1 {{variable does not have a constant initializer}}57  //   since-cxx20-note@-2 {{required by 'constinit' specifier here}}58  //   since-cxx20-note@-3 {{read of object outside its lifetime is not allowed in a constant expression}}59#endif60 61  void f() {62    static const int e = e + 1; // #cwg2026-e63    // expected-warning@-1 {{static variable 'e' is suspiciously used within its own initialization}}64    X<e> xe; // #cwg2026-xe65    // cxx98-error@-1 {{non-type template argument of type 'int' is not an integral constant expression}}66    //   cxx98-note@-2 {{initializer of 'e' is not a constant expression}}67    //   cxx98-note@#cwg2026-e {{declared here}}68    // since-cxx11-error@#cwg2026-xe {{non-type template argument is not a constant expression}}69    //   since-cxx11-note@#cwg2026-xe {{initializer of 'e' is not a constant expression}}70    //   since-cxx11-note@#cwg2026-e {{declared here}}71 72#if __cplusplus >= 201103L73    static constexpr int f = f;74    // since-cxx11-error@-1 {{constexpr variable 'f' must be initialized by a constant expression}}75    //   since-cxx11-note@-2 {{read of object outside its lifetime is not allowed in a constant expression}}76    [[clang::require_constant_initialization]] static int g = g;77    // since-cxx11-error@-1 {{variable does not have a constant initializer}}78    //   since-cxx11-note@-2 {{required by 'require_constant_initialization' attribute here}}79    //   cxx11-note@-3 {{read of non-const variable 'g' is not allowed in a constant expression}}80    //   cxx11-note@-4 {{declared here}}81    //   since-cxx14-note@-5 {{read of object outside its lifetime is not allowed in a constant expression}}82#endif83 84#if __cplusplus >= 202002L85    static constinit int h = h;86    // since-cxx20-error@-1 {{variable does not have a constant initializer}}87    //   since-cxx20-note@-2 {{required by 'constinit' specifier here}}88    //   since-cxx20-note@-3 {{read of object outside its lifetime is not allowed in a constant expression}}89#endif90  }91} // namespace cwg202692 93namespace cwg2049 { // cwg2049: 1894#if __cplusplus >= 202302L95template <int* x = {}> struct X {};96X<> a;97X<nullptr> b;98static_assert(__is_same(decltype(a), decltype(b)));99#endif100} // namespace cwg2049101 102namespace cwg2061 { // cwg2061: 2.7103#if __cplusplus >= 201103L104  namespace A {105    inline namespace b {106      namespace C {107        // 'f' is the example from the DR.  'S' is an example where if we didn't108        // properly handle the two being the same, we would get an incomplete109        // type error during attempted instantiation.110        template<typename T> void f();111        template<typename T> struct S;112      }113    }114  }115 116  namespace A {117    namespace C {118      template<> void f<int>() { }119      template<> struct S<int> { };120    }121  }122 123  void use() {124    A::C::f<int>();125    A::C::S<int> s;126  }127#endif // C++11128} // namespace cwg2061129 130namespace cwg2076 { // cwg2076: 13131#if __cplusplus >= 201103L132  namespace std_example {133    struct A { A(int); };134    struct B { B(A); };135    B b{{0}};136 137    struct Params { int a; int b; };138    struct Foo {139      Foo(Params);140    };141    Foo foo{{1, 2}};142  }143 144  struct string_view {145    string_view(int); // not an aggregate146  };147  struct string {148    string(int); // not an aggregate149    operator string_view() const;150  };151 152  void foo(const string &); // #cwg2076-foo 153  void bar(string_view); // #cwg2076-bar154 155  void func(const string &arg) {156    // An argument in one set of braces is subject to user-defined conversions;157    // an argument in two sets of braces is not, but an identity conversion is158    // still OK.159    foo(arg);160    foo({arg});161    foo({{arg}});162    foo({{{arg}}});163    // since-cxx11-error@-1 {{no matching function}}164    //   since-cxx11-note@#cwg2076-foo  {{cannot convert initializer list}}165    bar(arg);166    bar({arg});167    bar({{arg}});168    // since-cxx11-error@-1 {{no matching function}}169    //   since-cxx11-note@#cwg2076-bar {{cannot convert initializer list}}170    bar({{{arg}}});171    // since-cxx11-error@-1 {{no matching function}}172    //   since-cxx11-note@#cwg2076-bar {{cannot convert initializer list}}173  }174#endif175} // namespace cwg2076176 177namespace cwg2082 { // cwg2082: 11178  void test1(int x, int = sizeof(x)); // ok179#if __cplusplus >= 201103L180  void test2(int x, int = decltype(x){}); // ok181#endif182} // namespace cwg2082183 184namespace cwg2083 { // cwg2083: partial185#if __cplusplus >= 201103L186  void non_const_mem_ptr() {187    struct A {188      int x;189      int y;190    };191    constexpr A a = {1, 2};192    struct B {193      int A::*p;194      constexpr int g() const {195        // OK, not an odr-use of 'a'.196        return a.*p;197      };198    };199    static_assert(B{&A::x}.g() == 1, "");200    static_assert(B{&A::y}.g() == 2, "");201  }202#endif203 204  const int a = 1;205  int b;206  // Note, references only get special odr-use / constant initializxer207  // treatment in C++11 onwards. We continue to apply that even after CWG2083.208  void ref_to_non_const() {209    int c;210    const int &ra = a; // #cwg2083-ra211    int &rb = b; // #cwg2083-rb212    int &rc = c; // #cwg2083-rc213    struct A {214      int f() {215        int a = ra;216        // cxx98-error@-1 {{reference to local variable 'ra' declared in enclosing function 'cwg2083::ref_to_non_const'}}217        //   cxx98-note@#cwg2083-ra {{'ra' declared here}}218        int b = rb;219        // cxx98-error@-1 {{reference to local variable 'rb' declared in enclosing function 'cwg2083::ref_to_non_const'}}220        //   cxx98-note@#cwg2083-rb {{'rb' declared here}}221        int c = rc;222        // expected-error@-1 {{reference to local variable 'rc' declared in enclosing function 'cwg2083::ref_to_non_const'}}223        //   expected-note@#cwg2083-rc {{'rc' declared here}}224        return a + b + c;225      }226    };227  }228 229#if __cplusplus >= 201103L230  struct NoMut1 { int a, b; };231  struct NoMut2 { NoMut1 m; };232  struct NoMut3 : NoMut1 {233    constexpr NoMut3(int a, int b) : NoMut1{a, b} {}234  };235  struct Mut1 {236    int a;237    mutable int b;238  };239  struct Mut2 { Mut1 m; };240  struct Mut3 : Mut1 {241    constexpr Mut3(int a, int b) : Mut1{a, b} {}242  };243  void mutable_subobjects() {244    constexpr NoMut1 nm1 = {1, 2};245    constexpr NoMut2 nm2 = {1, 2};246    constexpr NoMut3 nm3 = {1, 2};247    constexpr Mut1 m1 = {1, 2}; // #cwg2083-m1248    constexpr Mut2 m2 = {1, 2}; // #cwg2083-m2249    constexpr Mut3 m3 = {1, 2}; // #cwg2083-m3250    struct A {251      void f() {252        static_assert(nm1.a == 1, "");253        static_assert(nm2.m.a == 1, "");254        static_assert(nm3.a == 1, "");255        // Can't even access a non-mutable member of a variable containing mutable fields.256        static_assert(m1.a == 1, "");257        // since-cxx11-error@-1 {{reference to local variable 'm1' declared in enclosing function 'cwg2083::mutable_subobjects'}}258        //   since-cxx11-note@#cwg2083-m1 {{'m1' declared here}}259        static_assert(m2.m.a == 1, "");260        // since-cxx11-error@-1 {{reference to local variable 'm2' declared in enclosing function 'cwg2083::mutable_subobjects'}}261        //   since-cxx11-note@#cwg2083-m2 {{'m2' declared here}}262        static_assert(m3.a == 1, "");263        // since-cxx11-error@-1 {{reference to local variable 'm3' declared in enclosing function 'cwg2083::mutable_subobjects'}}264        //   since-cxx11-note@#cwg2083-m3 {{'m3' declared here}}265      }266    };267  }268#endif269 270  void ellipsis() {271    void ellipsis(...);272    struct A {};273    const int n = 0;274#if __cplusplus >= 201103L275    constexpr276#endif277      A a = {}; // #cwg2083-a278    struct B {279      void f() {280        ellipsis(n);281        // Even though this is technically modelled as an lvalue-to-rvalue282        // conversion, it calls a constructor and binds 'a' to a reference, so283        // it results in an odr-use.284        ellipsis(a);285        // expected-error@-1 {{reference to local variable 'a' declared in enclosing function 'cwg2083::ellipsis'}}286        //   expected-note@#cwg2083-a {{'a' declared here}}287      }288    };289  }290 291#if __cplusplus >= 201103L292  void volatile_lval() {293    struct A { int n; };294    constexpr A a = {0}; // #cwg2083-a2295    struct B {296      void f() {297        // An lvalue-to-rvalue conversion of a volatile lvalue always results298        // in odr-use.299        int A::*p = &A::n;300        int x = a.*p;301        volatile int A::*q = p;302        int y = a.*q;303        // since-cxx11-error@-1 {{reference to local variable 'a' declared in enclosing function 'cwg2083::volatile_lval'}}304        //   since-cxx11-note@#cwg2083-a2 {{'a' declared here}}305      }306    };307  }308#endif309 310  void discarded_lval() {311    struct A { int x; mutable int y; volatile int z; };312    A a; // #cwg2083-a-3313    int &r = a.x; // #cwg2083-r314    struct B {315      void f() {316        // FIXME: We emit more errors than we should be. They are explicitly317        // marked below.318        a.x;319        // expected-warning@-1 {{expression result unused}}320        // expected-error@-2 {{reference to local variable 'a' declared in enclosing function 'cwg2083::discarded_lval'}} FIXME321        //   expected-note@#cwg2083-a-3 {{'a' declared here}}322        a.*&A::x;323        // expected-warning@-1 {{expression result unused}}324        // expected-error@-2 {{reference to local variable 'a' declared in enclosing function 'cwg2083::discarded_lval'}} FIXME325        //   expected-note@#cwg2083-a-3 {{'a' declared here}}326        true ? a.x : a.y; // #cwg2083-ternary327        // expected-warning@-1 {{expression result unused}}328        // expected-error@#cwg2083-ternary {{reference to local variable 'a' declared in enclosing function 'cwg2083::discarded_lval'}} FIXME329        //   expected-note@#cwg2083-a-3 {{'a' declared here}}330        // expected-error@#cwg2083-ternary {{reference to local variable 'a' declared in enclosing function 'cwg2083::discarded_lval'}} FIXME331        //   expected-note@#cwg2083-a-3 {{'a' declared here}}332        (void)a.x;333        // expected-error@-1 {{reference to local variable 'a' declared in enclosing function 'cwg2083::discarded_lval'}} FIXME334        //   expected-note@#cwg2083-a-3 {{'a' declared here}}335        a.x, discarded_lval();336        // expected-warning@-1 {{left operand of comma operator has no effect}}337        // expected-error@-2 {{reference to local variable 'a' declared in enclosing function 'cwg2083::discarded_lval'}} FIXME338        //   expected-note@#cwg2083-a-3 {{'a' declared here}}339 340        // 'volatile' qualifier triggers an lvalue-to-rvalue conversion.341        a.z;342        // cxx98-warning@-1 {{expression result unused; assign into a variable to force a volatile load}}343        // expected-error@-2 {{reference to local variable 'a' declared in enclosing function 'cwg2083::discarded_lval'}}344        //   expected-note@#cwg2083-a-3 {{'a' declared here}}345 346        // References always get "loaded" to determine what they reference,347        // even if the result is discarded.348        r;349        // expected-warning@-1 {{expression result unused}}350        // expected-error@-2 {{reference to local variable 'r' declared in enclosing function 'cwg2083::discarded_lval'}}351        //   expected-note@#cwg2083-r {{'r' declared here}}352      }353    };354  }355 356  namespace dr_example_1 {357    extern int globx;358    int main() {359      const int &x = globx; // #cwg2083-x360      struct A {361        const int *foo() { return &x; }362        // cxx98-error@-1 {{reference to local variable 'x' declared in enclosing function 'cwg2083::dr_example_1::main'}}363        //   cxx98-note@#cwg2083-x {{'x' declared here}}364      } a;365      return *a.foo();366    }367  }368 369#if __cplusplus >= 201103L370  namespace dr_example_2 {371    struct A {372      int q;373      constexpr A(int q) : q(q) {}374      constexpr A(const A &a) : q(a.q * 2) {} // (note, not called)375    };376 377    int main(void) {378      constexpr A a(42);379      constexpr int aq = a.q;380      struct Q {381        int foo() { return a.q; }382      } q;383      return q.foo();384    }385 386    // Checking odr-use does not invent an lvalue-to-rvalue conversion (and387    // hence copy construction) on the potential result variable.388    struct B {389      int b = 42;390      constexpr B() {}391      constexpr B(const B&) = delete;392    };393    void f() {394      constexpr B b;395      struct Q {396        constexpr int foo() const { return b.b; }397      };398      static_assert(Q().foo() == 42, "");399    }400  }401#endif402} // namespace cwg2083403 404namespace cwg2084 { // cwg2084: 3.1405struct S {406  S();407};408union U {409  S s{}; // cxx98-error {{function definition does not declare parameters}}410} u;411} // namespace cwg2084412 413namespace cwg2091 { // cwg2091: 10414template<int &> struct X;415template<int &N> void f(X<N>&);416int n;417void g(X<n> &x) { f(x); }418 419namespace GH42233 {420enum E { I };421 422class AA { };423E EV[1] = {I};424 425template<class ENUM, const ENUM* const VALUES>426struct S427{428  template< class E, const E* const V>429    friend AA& operator<<( AA& os, const S<E,V>& e );430};431 432int f()433{434  S< E, EV > x;435 436  AA a;437  a << x;438  return 0;439}440} // namespace GH42233441} // namespace cwg2091 442 443namespace cwg2094 { // cwg2094: 5444  struct A { int n; };445  struct B { volatile int n; };446  static_assert(__is_trivially_copyable(volatile int), "");447  static_assert(__is_trivially_copyable(const volatile int), "");448  static_assert(__is_trivially_copyable(const volatile int[]), "");449  static_assert(__is_trivially_copyable(A), "");450  static_assert(__is_trivially_copyable(volatile A), "");451  static_assert(__is_trivially_copyable(const volatile A), "");452  static_assert(__is_trivially_copyable(const volatile A[]), "");453  static_assert(__is_trivially_copyable(B), "");454 455  static_assert(__is_trivially_constructible(A, A const&), "");456  static_assert(__is_trivially_constructible(B, B const&), "");457 458  static_assert(__is_trivially_assignable(A, const A&), "");459  static_assert(__is_trivially_assignable(B, const B&), "");460} // namespace cwg2094461 462// cwg2096: dup 2598463