brintos

brintos / llvm-project-archived public Read only

0
0
Text · 14.7 KiB · b1736ea Raw
354 lines · cpp
1// RUN: %clang_cc1 -fsyntax-only -verify -DTEST_ONE -std=c++03 %s2// RUN: %clang_cc1 -fsyntax-only -verify -DTEST_ONE -std=c++11 %s3// RUN: %clang_cc1 -fsyntax-only -verify -DTEST_ONE -std=c++14 %s4// RUN: %clang_cc1 -fsyntax-only -verify -DTEST_TWO \5// RUN: -Wglobal-constructors -std=c++14 %s6// RUN: %clang_cc1 -fsyntax-only -verify -DTEST_THREE -xc %s7 8#define ATTR __attribute__((require_constant_initialization)) // expected-note 0+ {{expanded from macro}}9 10int ReturnInt(void); // expected-note 0+ {{declared here}}11 12struct PODType { // expected-note 0+ {{declared here}}13  int value; // expected-note 0-2 {{declared here}}14  int value2;15};16 17#if defined(__cplusplus)18 19#if __cplusplus >= 201103L20struct LitType {21  constexpr LitType() : value(0) {}22  constexpr LitType(int x) : value(x) {}23  LitType(void *) : value(-1) {} // expected-note 0+ {{declared here}}24  int value;25};26#endif27 28struct NonLit { // expected-note 0+ {{declared here}}29#if __cplusplus >= 201402L30  constexpr NonLit() : value(0) {}31  constexpr NonLit(int x) : value(x) {}32#else33  NonLit() : value(0) {} // expected-note 0+ {{declared here}}34  NonLit(int x) : value(x) {}35#endif36  NonLit(void *) : value(-1) {} // expected-note 0+ {{declared here}}37  ~NonLit() {}38  int value;39};40 41struct StoresNonLit {42#if __cplusplus >= 201402L43  constexpr StoresNonLit() : obj() {}44  constexpr StoresNonLit(int x) : obj(x) {}45#else46  StoresNonLit() : obj() {} // expected-note 0+ {{declared here}}47  StoresNonLit(int x) : obj(x) {}48#endif49  StoresNonLit(void *p) : obj(p) {}50  NonLit obj;51};52 53#endif // __cplusplus54 55 56#if defined(TEST_ONE) // Test semantics of attribute57 58// Test diagnostics when attribute is applied to non-static declarations.59void test_func_local(ATTR int param) { // expected-error {{only applies to global variables}}60  ATTR int x = 42;                     // expected-error {{only applies to}}61  ATTR extern int y;62}63struct ATTR class_mem { // expected-error {{only applies to}}64  ATTR int x;           // expected-error {{only applies to}}65};66 67// [basic.start.static]p2.168// if each full-expression (including implicit conversions) that appears in69// the initializer of a reference with static or thread storage duration is70// a constant expression (5.20) and the reference is bound to a glvalue71// designating an object with static storage duration, to a temporary object72// (see 12.2) or subobject thereof, or to a function;73 74// Test binding to a static glvalue75const int glvalue_int = 42;76const int glvalue_int2 = ReturnInt();77ATTR const int &glvalue_ref ATTR = glvalue_int;78ATTR const int &glvalue_ref2 ATTR = glvalue_int2;79ATTR __thread const int &glvalue_ref_tl = glvalue_int;80 81void test_basic_start_static_2_1(void) {82  const int non_global = 42;83  ATTR static const int &local_init = non_global; // expected-error {{variable does not have a constant initializer}}84  // expected-note@-1 {{required by 'require_constant_initialization' attribute here}}85#if __cplusplus >= 201103L86  // expected-note@-3 {{reference to 'non_global' is not a constant expression}}87  // expected-note@-5 {{declared here}}88#else89  // expected-note@-6 {{subexpression not valid in a constant expression}}90#endif91  ATTR static const int &global_init = glvalue_int;92  ATTR static const int &temp_init = 42;93}94 95ATTR const int &temp_ref = 42;96ATTR const int &temp_ref2 = ReturnInt(); // expected-error {{variable does not have a constant initializer}}97// expected-note@-1 {{required by 'require_constant_initialization' attribute here}}98#if __cplusplus >= 201103L99// expected-note@-3 {{non-constexpr function 'ReturnInt' cannot be used in a constant expression}}100#else101// expected-note@-5 {{subexpression not valid in a constant expression}}102#endif103ATTR const NonLit &nl_temp_ref = 42; // expected-error {{variable does not have a constant initializer}}104// expected-note@-1 {{required by 'require_constant_initialization' attribute here}}105#if __cplusplus >= 201103L106// expected-note@-3 {{non-literal type 'const NonLit' cannot be used in a constant expression}}107#else108// expected-note@-5 {{subexpression not valid in a constant expression}}109#endif110 111#if __cplusplus >= 201103L112ATTR const LitType &lit_temp_ref = 42;113ATTR const int &subobj_ref = LitType{}.value;114#endif115 116ATTR const int &nl_subobj_ref = NonLit().value; // expected-error {{variable does not have a constant initializer}}117// expected-note@-1 {{required by 'require_constant_initialization' attribute here}}118#if __cplusplus >= 201103L119// expected-note-re@-3 {{non-literal type '{{.*}}' cannot be used in a constant expression}}120#else121// expected-note@-5 {{subexpression not valid in a constant expression}}122#endif123 124struct TT1 {125  ATTR static const int &no_init;126  ATTR static const int &glvalue_init;127  ATTR static const int &temp_init;128  ATTR static const int &subobj_init;129#if __cplusplus >= 201103L130  ATTR static thread_local const int &tl_glvalue_init;131  ATTR static thread_local const int &tl_temp_init; // expected-note {{required by 'require_constant_initialization' attribute here}}132#endif133};134const int &TT1::glvalue_init = glvalue_int;135const int &TT1::temp_init = 42;136const int &TT1::subobj_init = PODType().value;137#if __cplusplus >= 201103L138thread_local const int &TT1::tl_glvalue_init = glvalue_int;139thread_local const int &TT1::tl_temp_init = 42; // expected-error {{variable does not have a constant initializer}}140// expected-note@-1 {{reference to temporary is not a constant expression}}141// expected-note@-2 {{temporary created here}}142#endif143 144// [basic.start.static]p2.2145// if an object with static or thread storage duration is initialized by a146// constructor call, and if the initialization full-expression is a constant147// initializer for the object;148 149void test_basic_start_static_2_2(void) {150#if __cplusplus < 201103L151  ATTR static PODType pod;152#else153  ATTR static PODType pod; // expected-error {{variable does not have a constant initializer}}154// expected-note@-1 {{required by 'require_constant_initialization' attribute here}}155// expected-note-re@-2 {{{{non-constexpr constructor|subobject of type 'int' is not initialized}}}}156#endif157  ATTR static PODType pot2 = {ReturnInt()}; // expected-error {{variable does not have a constant initializer}}158                                            // expected-note@-1 {{required by 'require_constant_initialization' attribute here}}159#if __cplusplus >= 201103L160// expected-note@-3 {{non-constexpr function 'ReturnInt' cannot be used in a constant expression}}161#else162// expected-note@-5 {{subexpression not valid in a constant expression}}163#endif164 165#if __cplusplus >= 201103L166  constexpr LitType l;167  ATTR static LitType static_lit = l;168  ATTR static LitType static_lit2 = (void *)0; // expected-error {{variable does not have a constant initializer}}169  // expected-note@-1 {{required by 'require_constant_initialization' attribute here}}170  // expected-note@-2 {{non-constexpr constructor 'LitType' cannot be used in a constant expression}}171  ATTR static LitType static_lit3 = ReturnInt(); // expected-error {{variable does not have a constant initializer}}172  // expected-note@-1 {{required by 'require_constant_initialization' attribute here}}173  // expected-note@-2 {{non-constexpr function 'ReturnInt' cannot be used in a constant expression}}174  ATTR thread_local LitType tls = 42;175#endif176}177 178struct TT2 {179  ATTR static PODType pod_noinit;180#if __cplusplus >= 201103L181// expected-note@-2 {{required by 'require_constant_initialization' attribute here}}182#endif183  ATTR static PODType pod_copy_init; // expected-note {{required by 'require_constant_initialization' attribute here}}184#if __cplusplus >= 201402L185  ATTR static constexpr LitType lit = {};186  ATTR static const NonLit non_lit;187  ATTR static const NonLit non_lit_list_init;188  ATTR static const NonLit non_lit_copy_init;189#endif190};191PODType TT2::pod_noinit; // expected-note 0+ {{declared here}}192#if __cplusplus >= 201103L193// expected-error@-2 {{variable does not have a constant initializer}}194// expected-note-re@-3 {{{{non-constexpr constructor|subobject of type 'int' is not initialized}}}}195#endif196PODType TT2::pod_copy_init(TT2::pod_noinit); // expected-error {{variable does not have a constant initializer}}197#if __cplusplus >= 201103L198// expected-note@-2 {{read of non-constexpr variable 'pod_noinit' is not allowed in a constant expression}}199// expected-note@-3 {{in call to 'PODType(pod_noinit)'}}200#else201// expected-note@-5 {{subexpression not valid in a constant expression}}202#endif203#if __cplusplus >= 201402L204const NonLit TT2::non_lit(42);205const NonLit TT2::non_lit_list_init = {42};206// FIXME: This is invalid, but we incorrectly elide the copy. It's OK if we207// start diagnosing this.208const NonLit TT2::non_lit_copy_init = 42;209#endif210 211#if __cplusplus >= 201103L212ATTR LitType lit_ctor;213ATTR LitType lit_ctor2{};214ATTR LitType lit_ctor3 = {};215ATTR __thread LitType lit_ctor_tl = {};216 217#if __cplusplus >= 201402L218ATTR NonLit nl_ctor;219ATTR NonLit nl_ctor2{};220ATTR NonLit nl_ctor3 = {};221ATTR thread_local NonLit nl_ctor_tl = {};222ATTR StoresNonLit snl;223#else224ATTR NonLit nl_ctor; // expected-error {{variable does not have a constant initializer}}225// expected-note@-1 {{required by 'require_constant_initialization' attribute here}}226// expected-note@-2 {{non-constexpr constructor 'NonLit' cannot be used in a constant expression}}227ATTR NonLit nl_ctor2{}; // expected-error {{variable does not have a constant initializer}}228// expected-note@-1 {{required by 'require_constant_initialization' attribute here}}229// expected-note@-2 {{non-constexpr constructor 'NonLit' cannot be used in a constant expression}}230ATTR NonLit nl_ctor3 = {}; // expected-error {{variable does not have a constant initializer}}231// expected-note@-1 {{required by 'require_constant_initialization' attribute here}}232// expected-note@-2 {{non-constexpr constructor 'NonLit' cannot be used in a constant expression}}233ATTR thread_local NonLit nl_ctor_tl = {}; // expected-error {{variable does not have a constant initializer}}234// expected-note@-1 {{required by 'require_constant_initialization' attribute here}}235// expected-note@-2 {{non-constexpr constructor 'NonLit' cannot be used in a constant expression}}236ATTR StoresNonLit snl; // expected-error {{variable does not have a constant initializer}}237// expected-note@-1 {{required by 'require_constant_initialization' attribute here}}238// expected-note@-2 {{non-constexpr constructor 'StoresNonLit' cannot be used in a constant expression}}239#endif240 241// Non-literal types cannot appear in the initializer of a non-literal type.242ATTR int nl_in_init = NonLit{42}.value; // expected-error {{variable does not have a constant initializer}}243// expected-note@-1 {{required by 'require_constant_initialization' attribute here}}244// expected-note@-2 {{non-literal type 'NonLit' cannot be used in a constant expression}}245ATTR int lit_in_init = LitType{42}.value;246#endif247 248// [basic.start.static]p2.3249// if an object with static or thread storage duration is not initialized by a250// constructor call and if either the object is value-initialized or every251// full-expression that appears in its initializer is a constant expression.252void test_basic_start_static_2_3(void) {253  ATTR static int static_local = 42;254  ATTR static int static_local2; // zero-initialization takes place255#if __cplusplus >= 201103L256  ATTR thread_local int tl_local = 42;257#endif258}259 260ATTR int no_init; // zero initialization takes place261ATTR int arg_init = 42;262ATTR PODType pod_init = {};263ATTR PODType pod_missing_init = {42 /* should have second arg */};264ATTR PODType pod_full_init = {1, 2};265ATTR PODType pod_non_constexpr_init = {1, ReturnInt()}; // expected-error {{variable does not have a constant initializer}}266// expected-note@-1 {{required by 'require_constant_initialization' attribute here}}267#if __cplusplus >= 201103L268// expected-note@-3 {{non-constexpr function 'ReturnInt' cannot be used in a constant expression}}269#else270// expected-note@-5 {{subexpression not valid in a constant expression}}271#endif272 273#if __cplusplus >= 201103L274ATTR int val_init{};275ATTR int brace_init = {};276#endif277 278ATTR __thread int tl_init = 0;279typedef const char *StrType;280 281#if __cplusplus >= 201103L282 283// Test that the validity of the selected constructor is checked, not just the284// initializer285struct NotC {286  constexpr NotC(void *) {}287  NotC(int) {} // expected-note 0+ {{declared here}}288};289template <class T>290struct TestCtor {291  constexpr TestCtor(int x) : value(x) {}292  // expected-note@-1  {{non-constexpr constructor 'NotC' cannot be used in a constant expression}}293  T value;294};295ATTR TestCtor<NotC> t(42); // expected-error {{variable does not have a constant initializer}}296// expected-note@-1 {{required by 'require_constant_initialization' attribute here}}297// expected-note@-2 {{in call to 'TestCtor(42)'}}298#endif299 300// Test various array types301ATTR const char *foo[] = {"abc", "def"};302ATTR PODType bar[] = {{}, {123, 456}};303 304 305namespace AttrAddedTooLate {306  struct A {307    static const int n = 0; // expected-note {{here}}308  };309  ATTR const int A::n; // expected-warning {{added after initialization}}310 311  int m = 0; // expected-note {{here}}312  extern ATTR int m; // expected-warning {{added after initialization}}313}314 315#elif defined(TEST_TWO) // Test for duplicate warnings316struct NotC {317  constexpr NotC(void *) {}318  NotC(int) {} // expected-note 2 {{declared here}}319};320template <class T>321struct TestCtor {322  constexpr TestCtor(int x) : value(x) {} // expected-note 2 {{non-constexpr constructor}}323  T value;324};325 326ATTR LitType non_const_lit(nullptr); // expected-error {{variable does not have a constant initializer}}327// expected-note@-1 {{required by 'require_constant_initialization' attribute here}}328// expected-note@-2 {{non-constexpr constructor 'LitType' cannot be used in a constant expression}}329ATTR NonLit non_const(nullptr); // expected-error {{variable does not have a constant initializer}}330// expected-warning@-1 {{declaration requires a global destructor}}331// expected-note@-2 {{required by 'require_constant_initialization' attribute here}}332// expected-note@-3 {{non-constexpr constructor 'NonLit' cannot be used in a constant expression}}333LitType const_init_lit(nullptr);              // expected-warning {{declaration requires a global constructor}}334NonLit const_init{42};                        // expected-warning {{declaration requires a global destructor}}335constexpr TestCtor<NotC> inval_constexpr(42); // expected-error {{must be initialized by a constant expression}}336// expected-note@-1 {{in call to 'TestCtor(42)'}}337ATTR constexpr TestCtor<NotC> inval_constexpr2(42); // expected-error {{must be initialized by a constant expression}}338// expected-note@-1 {{in call to 'TestCtor(42)'}}339 340[[gnu::constructor]] void ctor() {}341// expected-warning@-1 {{declaration requires a global constructor}}342[[gnu::destructor]] void dtor() {}343// expected-warning@-1 {{declaration requires a global destructor}}344 345#elif defined(TEST_THREE)346#if defined(__cplusplus)347#error This test requires C348#endif349// Test that using the attribute in C results in a diagnostic350ATTR int x = 0; // expected-warning {{attribute ignored}}351#else352#error No test case specified353#endif // defined(TEST_N)354