head	1.1;
branch	1.1.1;
access;
symbols
	netbsd-11-0-RC5:1.1.1.4
	netbsd-11-0-RC4:1.1.1.4
	netbsd-11-0-RC3:1.1.1.4
	netbsd-11-0-RC2:1.1.1.4
	netbsd-11-0-RC1:1.1.1.4
	perseant-exfatfs-base-20250801:1.1.1.4
	netbsd-11:1.1.1.4.0.10
	netbsd-11-base:1.1.1.4
	netbsd-10-1-RELEASE:1.1.1.4
	perseant-exfatfs-base-20240630:1.1.1.4
	perseant-exfatfs:1.1.1.4.0.8
	perseant-exfatfs-base:1.1.1.4
	netbsd-8-3-RELEASE:1.1.1.1
	netbsd-9-4-RELEASE:1.1.1.3
	netbsd-10-0-RELEASE:1.1.1.4
	netbsd-10-0-RC6:1.1.1.4
	netbsd-10-0-RC5:1.1.1.4
	netbsd-10-0-RC4:1.1.1.4
	netbsd-10-0-RC3:1.1.1.4
	netbsd-10-0-RC2:1.1.1.4
	netbsd-10-0-RC1:1.1.1.4
	netbsd-10:1.1.1.4.0.6
	netbsd-10-base:1.1.1.4
	netbsd-9-3-RELEASE:1.1.1.3
	cjep_sun2x:1.1.1.4.0.4
	cjep_sun2x-base:1.1.1.4
	cjep_staticlib_x-base1:1.1.1.4
	netbsd-9-2-RELEASE:1.1.1.3
	cjep_staticlib_x:1.1.1.4.0.2
	cjep_staticlib_x-base:1.1.1.4
	netbsd-9-1-RELEASE:1.1.1.3
	phil-wifi-20200421:1.1.1.4
	phil-wifi-20200411:1.1.1.4
	phil-wifi-20200406:1.1.1.4
	netbsd-8-2-RELEASE:1.1.1.1
	netbsd-9-0-RELEASE:1.1.1.3
	netbsd-9-0-RC2:1.1.1.3
	netbsd-9-0-RC1:1.1.1.3
	netbsd-9:1.1.1.3.0.2
	netbsd-9-base:1.1.1.3
	phil-wifi-20190609:1.1.1.3
	netbsd-8-1-RELEASE:1.1.1.1
	netbsd-8-1-RC1:1.1.1.1
	pgoyette-compat-merge-20190127:1.1.1.2.2.1
	pgoyette-compat-20190127:1.1.1.3
	pgoyette-compat-20190118:1.1.1.3
	pgoyette-compat-1226:1.1.1.3
	pgoyette-compat-1126:1.1.1.3
	pgoyette-compat-1020:1.1.1.3
	pgoyette-compat-0930:1.1.1.3
	pgoyette-compat-0906:1.1.1.3
	pgoyette-compat-0728:1.1.1.3
	clang-337282:1.1.1.3
	netbsd-8-0-RELEASE:1.1.1.1
	phil-wifi:1.1.1.2.0.4
	phil-wifi-base:1.1.1.2
	pgoyette-compat-0625:1.1.1.2
	netbsd-8-0-RC2:1.1.1.1
	pgoyette-compat-0521:1.1.1.2
	pgoyette-compat-0502:1.1.1.2
	pgoyette-compat-0422:1.1.1.2
	netbsd-8-0-RC1:1.1.1.1
	pgoyette-compat-0415:1.1.1.2
	pgoyette-compat-0407:1.1.1.2
	pgoyette-compat-0330:1.1.1.2
	pgoyette-compat-0322:1.1.1.2
	pgoyette-compat-0315:1.1.1.2
	pgoyette-compat:1.1.1.2.0.2
	pgoyette-compat-base:1.1.1.2
	clang-319952:1.1.1.2
	matt-nb8-mediatek:1.1.1.1.0.12
	matt-nb8-mediatek-base:1.1.1.1
	clang-309604:1.1.1.2
	perseant-stdc-iso10646:1.1.1.1.0.10
	perseant-stdc-iso10646-base:1.1.1.1
	netbsd-8:1.1.1.1.0.8
	netbsd-8-base:1.1.1.1
	prg-localcount2-base3:1.1.1.1
	prg-localcount2-base2:1.1.1.1
	prg-localcount2-base1:1.1.1.1
	prg-localcount2:1.1.1.1.0.6
	prg-localcount2-base:1.1.1.1
	pgoyette-localcount-20170426:1.1.1.1
	bouyer-socketcan-base1:1.1.1.1
	pgoyette-localcount:1.1.1.1.0.4
	pgoyette-localcount-20170320:1.1.1.1
	clang-294123:1.1.1.1
	bouyer-socketcan:1.1.1.1.0.2
	bouyer-socketcan-base:1.1.1.1
	clang-291444:1.1.1.1
	LLVM:1.1.1;
locks; strict;
comment	@// @;


1.1
date	2017.01.11.10.37.45;	author joerg;	state Exp;
branches
	1.1.1.1;
next	;
commitid	CNnUNfII1jgNmxBz;

1.1.1.1
date	2017.01.11.10.37.45;	author joerg;	state Exp;
branches
	1.1.1.1.4.1;
next	1.1.1.2;
commitid	CNnUNfII1jgNmxBz;

1.1.1.2
date	2017.08.01.19.34.19;	author joerg;	state Exp;
branches
	1.1.1.2.2.1
	1.1.1.2.4.1;
next	1.1.1.3;
commitid	pMuDy65V0VicSx1A;

1.1.1.3
date	2018.07.17.18.31.35;	author joerg;	state Exp;
branches;
next	1.1.1.4;
commitid	wDzL46ALjrCZgwKA;

1.1.1.4
date	2019.11.13.22.22.54;	author joerg;	state dead;
branches;
next	;
commitid	QD8YATxuNG34YJKB;

1.1.1.1.4.1
date	2017.01.11.10.37.45;	author pgoyette;	state dead;
branches;
next	1.1.1.1.4.2;
commitid	jjw7cAwgyKq7RfKz;

1.1.1.1.4.2
date	2017.03.20.06.53.33;	author pgoyette;	state Exp;
branches;
next	;
commitid	jjw7cAwgyKq7RfKz;

1.1.1.2.2.1
date	2018.07.28.04.34.11;	author pgoyette;	state Exp;
branches;
next	;
commitid	1UP1xAIUxv1ZgRLA;

1.1.1.2.4.1
date	2019.06.10.21.46.35;	author christos;	state Exp;
branches;
next	1.1.1.2.4.2;
commitid	jtc8rnCzWiEEHGqB;

1.1.1.2.4.2
date	2020.04.13.07.50.22;	author martin;	state dead;
branches;
next	;
commitid	X01YhRUPVUDaec4C;


desc
@@


1.1
log
@Initial revision
@
text
@// RUN: %clang_cc1 -fsyntax-only -verify -DTEST_ONE -std=c++03 %s
// RUN: %clang_cc1 -fsyntax-only -verify -DTEST_ONE -std=c++11 %s
// RUN: %clang_cc1 -fsyntax-only -verify -DTEST_ONE -std=c++14 %s
// RUN: %clang_cc1 -fsyntax-only -verify -DTEST_TWO \
// RUN: -Wglobal-constructors -std=c++14 %s
// RUN: %clang_cc1 -fsyntax-only -verify -DTEST_THREE -xc %s

#define ATTR __attribute__((require_constant_initialization)) // expected-note 0+ {{expanded from macro}}

int ReturnInt();

struct PODType {
  int value;
  int value2;
};

#if defined(__cplusplus)

#if __cplusplus >= 201103L
struct LitType {
  constexpr LitType() : value(0) {}
  constexpr LitType(int x) : value(x) {}
  LitType(void *) : value(-1) {}
  int value;
};
#endif

struct NonLit {
#if __cplusplus >= 201402L
  constexpr NonLit() : value(0) {}
  constexpr NonLit(int x) : value(x) {}
#else
  NonLit() : value(0) {}
  NonLit(int x) : value(x) {}
#endif
  NonLit(void *) : value(-1) {}
  ~NonLit() {}
  int value;
};

struct StoresNonLit {
#if __cplusplus >= 201402L
  constexpr StoresNonLit() : obj() {}
  constexpr StoresNonLit(int x) : obj(x) {}
#else
  StoresNonLit() : obj() {}
  StoresNonLit(int x) : obj(x) {}
#endif
  StoresNonLit(void *p) : obj(p) {}
  NonLit obj;
};

#endif // __cplusplus


#if defined(TEST_ONE) // Test semantics of attribute

// Test diagnostics when attribute is applied to non-static declarations.
void test_func_local(ATTR int param) { // expected-error {{only applies to variables with static or thread}}
  ATTR int x = 42;                     // expected-error {{only applies to variables with static or thread}}
  ATTR extern int y;
}
struct ATTR class_mem { // expected-error {{only applies to variables with static or thread}}
  ATTR int x;           // expected-error {{only applies to variables with static or thread}}
};

// [basic.start.static]p2.1
// if each full-expression (including implicit conversions) that appears in
// the initializer of a reference with static or thread storage duration is
// a constant expression (5.20) and the reference is bound to a glvalue
// designating an object with static storage duration, to a temporary object
// (see 12.2) or subobject thereof, or to a function;

// Test binding to a static glvalue
const int glvalue_int = 42;
const int glvalue_int2 = ReturnInt();
ATTR const int &glvalue_ref ATTR = glvalue_int;
ATTR const int &glvalue_ref2 ATTR = glvalue_int2;
ATTR __thread const int &glvalue_ref_tl = glvalue_int;

void test_basic_start_static_2_1() {
  const int non_global = 42;
  ATTR static const int &local_init = non_global; // expected-error {{variable does not have a constant initializer}}
  // expected-note@@-1 {{required by 'require_constant_initializer' attribute here}}
  ATTR static const int &global_init = glvalue_int;
  ATTR static const int &temp_init = 42;
}

ATTR const int &temp_ref = 42;
ATTR const int &temp_ref2 = ReturnInt(); // expected-error {{variable does not have a constant initializer}}
// expected-note@@-1 {{required by 'require_constant_initializer' attribute here}}
ATTR const NonLit &nl_temp_ref = 42; // expected-error {{variable does not have a constant initializer}}
// expected-note@@-1 {{required by 'require_constant_initializer' attribute here}}

#if __cplusplus >= 201103L
ATTR const LitType &lit_temp_ref = 42;
ATTR const int &subobj_ref = LitType{}.value;
#endif

ATTR const int &nl_subobj_ref = NonLit().value; // expected-error {{variable does not have a constant initializer}}
// expected-note@@-1 {{required by 'require_constant_initializer' attribute here}}

struct TT1 {
  ATTR static const int &no_init;
  ATTR static const int &glvalue_init;
  ATTR static const int &temp_init;
  ATTR static const int &subobj_init;
#if __cplusplus >= 201103L
  ATTR static thread_local const int &tl_glvalue_init;
  ATTR static thread_local const int &tl_temp_init; // expected-note {{required by 'require_constant_initializer' attribute here}}
#endif
};
const int &TT1::glvalue_init = glvalue_int;
const int &TT1::temp_init = 42;
const int &TT1::subobj_init = PODType().value;
#if __cplusplus >= 201103L
thread_local const int &TT1::tl_glvalue_init = glvalue_int;
thread_local const int &TT1::tl_temp_init = 42; // expected-error {{variable does not have a constant initializer}}
#endif

// [basic.start.static]p2.2
// if an object with static or thread storage duration is initialized by a
// constructor call, and if the initialization full-expression is a constant
// initializer for the object;

void test_basic_start_static_2_2() {
#if __cplusplus < 201103L
  ATTR static PODType pod;
#else
  ATTR static PODType pod; // expected-error {{variable does not have a constant initializer}}
// expected-note@@-1 {{required by 'require_constant_initializer' attribute here}}
#endif
  ATTR static PODType pot2 = {ReturnInt()}; // expected-error {{variable does not have a constant initializer}}
                                            // expected-note@@-1 {{required by 'require_constant_initializer' attribute here}}

#if __cplusplus >= 201103L
  constexpr LitType l;
  ATTR static LitType static_lit = l;
  ATTR static LitType static_lit2 = (void *)0; // expected-error {{variable does not have a constant initializer}}
  // expected-note@@-1 {{required by 'require_constant_initializer' attribute here}}
  ATTR static LitType static_lit3 = ReturnInt(); // expected-error {{variable does not have a constant initializer}}
  // expected-note@@-1 {{required by 'require_constant_initializer' attribute here}}
  ATTR thread_local LitType tls = 42;
#endif
}

struct TT2 {
  ATTR static PODType pod_noinit;
#if __cplusplus >= 201103L
// expected-note@@-2 {{required by 'require_constant_initializer' attribute here}}
#endif
  ATTR static PODType pod_copy_init; // expected-note {{required by 'require_constant_initializer' attribute here}}
#if __cplusplus >= 201402L
  ATTR static constexpr LitType lit = {};
  ATTR static const NonLit non_lit;
  ATTR static const NonLit non_lit_list_init;
  ATTR static const NonLit non_lit_copy_init; // expected-note {{required by 'require_constant_initializer' attribute here}}
#endif
};
PODType TT2::pod_noinit;
#if __cplusplus >= 201103L
// expected-error@@-2 {{variable does not have a constant initializer}}
#endif
PODType TT2::pod_copy_init(TT2::pod_noinit); // expected-error {{variable does not have a constant initializer}}
#if __cplusplus >= 201402L
const NonLit TT2::non_lit(42);
const NonLit TT2::non_lit_list_init = {42};
const NonLit TT2::non_lit_copy_init = 42; // expected-error {{variable does not have a constant initializer}}
#endif

#if __cplusplus >= 201103L
ATTR LitType lit_ctor;
ATTR LitType lit_ctor2{};
ATTR LitType lit_ctor3 = {};
ATTR __thread LitType lit_ctor_tl = {};

#if __cplusplus >= 201402L
ATTR NonLit nl_ctor;
ATTR NonLit nl_ctor2{};
ATTR NonLit nl_ctor3 = {};
ATTR thread_local NonLit nl_ctor_tl = {};
ATTR StoresNonLit snl;
#else
ATTR NonLit nl_ctor; // expected-error {{variable does not have a constant initializer}}
// expected-note@@-1 {{required by 'require_constant_initializer' attribute here}}
ATTR NonLit nl_ctor2{}; // expected-error {{variable does not have a constant initializer}}
// expected-note@@-1 {{required by 'require_constant_initializer' attribute here}}
ATTR NonLit nl_ctor3 = {}; // expected-error {{variable does not have a constant initializer}}
// expected-note@@-1 {{required by 'require_constant_initializer' attribute here}}
ATTR thread_local NonLit nl_ctor_tl = {}; // expected-error {{variable does not have a constant initializer}}
// expected-note@@-1 {{required by 'require_constant_initializer' attribute here}}
ATTR StoresNonLit snl; // expected-error {{variable does not have a constant initializer}}
// expected-note@@-1 {{required by 'require_constant_initializer' attribute here}}
#endif

// Non-literal types cannot appear in the initializer of a non-literal type.
ATTR int nl_in_init = NonLit{42}.value; // expected-error {{variable does not have a constant initializer}}
// expected-note@@-1 {{required by 'require_constant_initializer' attribute here}}
ATTR int lit_in_init = LitType{42}.value;
#endif

// [basic.start.static]p2.3
// if an object with static or thread storage duration is not initialized by a
// constructor call and if either the object is value-initialized or every
// full-expression that appears in its initializer is a constant expression.
void test_basic_start_static_2_3() {
  ATTR static int static_local = 42;
  ATTR static int static_local2; // zero-initialization takes place
#if __cplusplus >= 201103L
  ATTR thread_local int tl_local = 42;
#endif
}

ATTR int no_init; // zero initialization takes place
ATTR int arg_init = 42;
ATTR PODType pod_init = {};
ATTR PODType pod_missing_init = {42 /* should have second arg */};
ATTR PODType pod_full_init = {1, 2};
ATTR PODType pod_non_constexpr_init = {1, ReturnInt()}; // expected-error {{variable does not have a constant initializer}}
// expected-note@@-1 {{required by 'require_constant_initializer' attribute here}}

#if __cplusplus >= 201103L
ATTR int val_init{};
ATTR int brace_init = {};
#endif

ATTR __thread int tl_init = 0;
typedef const char *StrType;

#if __cplusplus >= 201103L

// Test that the validity of the selected constructor is checked, not just the
// initializer
struct NotC {
  constexpr NotC(void *) {}
  NotC(int) {}
};
template <class T>
struct TestCtor {
  constexpr TestCtor(int x) : value(x) {}
  T value;
};
ATTR TestCtor<NotC> t(42); // expected-error {{variable does not have a constant initializer}}
// expected-note@@-1 {{required by 'require_constant_initializer' attribute here}}
#endif

// Test various array types
ATTR const char *foo[] = {"abc", "def"};
ATTR PODType bar[] = {{}, {123, 456}};

#elif defined(TEST_TWO) // Test for duplicate warnings
struct NotC {
  constexpr NotC(void *) {}
  NotC(int) {} // expected-note 2 {{declared here}}
};
template <class T>
struct TestCtor {
  constexpr TestCtor(int x) : value(x) {} // expected-note 2 {{non-constexpr constructor}}
  T value;
};

ATTR LitType non_const_lit(nullptr); // expected-error {{variable does not have a constant initializer}}
// expected-note@@-1 {{required by 'require_constant_initializer' attribute here}}
ATTR NonLit non_const(nullptr); // expected-error {{variable does not have a constant initializer}}
// expected-warning@@-1 {{declaration requires a global destructor}}
// expected-note@@-2 {{required by 'require_constant_initializer' attribute here}}
LitType const_init_lit(nullptr);              // expected-warning {{declaration requires a global constructor}}
NonLit const_init{42};                        // expected-warning {{declaration requires a global destructor}}
constexpr TestCtor<NotC> inval_constexpr(42); // expected-error {{must be initialized by a constant expression}}
// expected-note@@-1 {{in call to 'TestCtor(42)'}}
ATTR constexpr TestCtor<NotC> inval_constexpr2(42); // expected-error {{must be initialized by a constant expression}}
// expected-note@@-1 {{in call to 'TestCtor(42)'}}

#elif defined(TEST_THREE)
#if defined(__cplusplus)
#error This test requires C
#endif
// Test that using the attribute in C results in a diagnostic
ATTR int x = 0; // expected-warning {{attribute ignored}}
#else
#error No test case specified
#endif // defined(TEST_N)
@


1.1.1.1
log
@Import Clang pre-4.0.0 r291444.
@
text
@@


1.1.1.2
log
@Import clang r309604 from branches/release_50
@
text
@d10 1
a10 1
int ReturnInt(); // expected-note 0+ {{declared here}}
d12 1
a12 1
struct PODType { // expected-note 0+ {{declared here}}
d23 1
a23 1
  LitType(void *) : value(-1) {} // expected-note 0+ {{declared here}}
d28 1
a28 1
struct NonLit { // expected-note 0+ {{declared here}}
d33 1
a33 1
  NonLit() : value(0) {} // expected-note 0+ {{declared here}}
d36 1
a36 1
  NonLit(void *) : value(-1) {} // expected-note 0+ {{declared here}}
d46 1
a46 1
  StoresNonLit() : obj() {} // expected-note 0+ {{declared here}}
d84 1
a84 7
  // expected-note@@-1 {{required by 'require_constant_initialization' attribute here}}
#if __cplusplus >= 201103L
  // expected-note@@-3 {{reference to 'non_global' is not a constant expression}}
  // expected-note@@-5 {{declared here}}
#else
  // expected-note@@-6 {{subexpression not valid in a constant expression}}
#endif
d91 1
a91 6
// expected-note@@-1 {{required by 'require_constant_initialization' attribute here}}
#if __cplusplus >= 201103L
// expected-note@@-3 {{non-constexpr function 'ReturnInt' cannot be used in a constant expression}}
#else
// expected-note@@-5 {{subexpression not valid in a constant expression}}
#endif
d93 1
a93 6
// expected-note@@-1 {{required by 'require_constant_initialization' attribute here}}
#if __cplusplus >= 201103L
// expected-note@@-3 {{non-literal type 'const NonLit' cannot be used in a constant expression}}
#else
// expected-note@@-5 {{subexpression not valid in a constant expression}}
#endif
d101 1
a101 6
// expected-note@@-1 {{required by 'require_constant_initialization' attribute here}}
#if __cplusplus >= 201103L
// expected-note-re@@-3 {{non-literal type '{{.*}}' cannot be used in a constant expression}}
#else
// expected-note@@-5 {{subexpression not valid in a constant expression}}
#endif
d110 1
a110 1
  ATTR static thread_local const int &tl_temp_init; // expected-note {{required by 'require_constant_initialization' attribute here}}
a118 2
// expected-note@@-1 {{reference to temporary is not a constant expression}}
// expected-note@@-2 {{temporary created here}}
d131 1
a131 2
// expected-note@@-1 {{required by 'require_constant_initialization' attribute here}}
// expected-note@@-2 {{non-constexpr constructor 'PODType' cannot be used in a constant expression}}
d134 1
a134 6
                                            // expected-note@@-1 {{required by 'require_constant_initialization' attribute here}}
#if __cplusplus >= 201103L
// expected-note@@-3 {{non-constexpr function 'ReturnInt' cannot be used in a constant expression}}
#else
// expected-note@@-5 {{subexpression not valid in a constant expression}}
#endif
d140 1
a140 2
  // expected-note@@-1 {{required by 'require_constant_initialization' attribute here}}
  // expected-note@@-2 {{non-constexpr constructor 'LitType' cannot be used in a constant expression}}
d142 1
a142 2
  // expected-note@@-1 {{required by 'require_constant_initialization' attribute here}}
  // expected-note@@-2 {{non-constexpr function 'ReturnInt' cannot be used in a constant expression}}
d150 1
a150 1
// expected-note@@-2 {{required by 'require_constant_initialization' attribute here}}
d152 1
a152 1
  ATTR static PODType pod_copy_init; // expected-note {{required by 'require_constant_initialization' attribute here}}
d157 1
a157 1
  ATTR static const NonLit non_lit_copy_init; // expected-note {{required by 'require_constant_initialization' attribute here}}
d160 1
a160 1
PODType TT2::pod_noinit; // expected-note 0+ {{declared here}}
a162 1
// expected-note@@-3 {{non-constexpr constructor 'PODType' cannot be used in a constant expression}}
a164 6
#if __cplusplus >= 201103L
// expected-note@@-2 {{read of non-constexpr variable 'pod_noinit' is not allowed in a constant expression}}
// expected-note@@-3 {{in call to 'PODType(pod_noinit)'}}
#else
// expected-note@@-5 {{subexpression not valid in a constant expression}}
#endif
a168 1
// expected-note@@-1 {{subexpression not valid in a constant expression}}
d185 1
a185 2
// expected-note@@-1 {{required by 'require_constant_initialization' attribute here}}
// expected-note@@-2 {{non-constexpr constructor 'NonLit' cannot be used in a constant expression}}
d187 1
a187 2
// expected-note@@-1 {{required by 'require_constant_initialization' attribute here}}
// expected-note@@-2 {{non-constexpr constructor 'NonLit' cannot be used in a constant expression}}
d189 1
a189 2
// expected-note@@-1 {{required by 'require_constant_initialization' attribute here}}
// expected-note@@-2 {{non-constexpr constructor 'NonLit' cannot be used in a constant expression}}
d191 1
a191 2
// expected-note@@-1 {{required by 'require_constant_initialization' attribute here}}
// expected-note@@-2 {{non-constexpr constructor 'NonLit' cannot be used in a constant expression}}
d193 1
a193 2
// expected-note@@-1 {{required by 'require_constant_initialization' attribute here}}
// expected-note@@-2 {{non-constexpr constructor 'StoresNonLit' cannot be used in a constant expression}}
d198 1
a198 2
// expected-note@@-1 {{required by 'require_constant_initialization' attribute here}}
// expected-note@@-2 {{non-literal type 'NonLit' cannot be used in a constant expression}}
d220 1
a220 6
// expected-note@@-1 {{required by 'require_constant_initialization' attribute here}}
#if __cplusplus >= 201103L
// expected-note@@-3 {{non-constexpr function 'ReturnInt' cannot be used in a constant expression}}
#else
// expected-note@@-5 {{subexpression not valid in a constant expression}}
#endif
d236 1
a236 1
  NotC(int) {} // expected-note 0+ {{declared here}}
a240 1
  // expected-note@@-1  {{non-constexpr constructor 'NotC' cannot be used in a constant expression}}
d244 1
a244 2
// expected-note@@-1 {{required by 'require_constant_initialization' attribute here}}
// expected-note@@-2 {{in call to 'TestCtor(42)'}}
d263 1
a263 2
// expected-note@@-1 {{required by 'require_constant_initialization' attribute here}}
// expected-note@@-2 {{non-constexpr constructor 'LitType' cannot be used in a constant expression}}
d266 1
a266 2
// expected-note@@-2 {{required by 'require_constant_initialization' attribute here}}
// expected-note@@-3 {{non-constexpr constructor 'NonLit' cannot be used in a constant expression}}
@


1.1.1.2.4.1
log
@Sync with HEAD
@
text
@d59 2
a60 2
void test_func_local(ATTR int param) { // expected-error {{only applies to global variables}}
  ATTR int x = 42;                     // expected-error {{only applies to}}
d63 2
a64 2
struct ATTR class_mem { // expected-error {{only applies to}}
  ATTR int x;           // expected-error {{only applies to}}
@


1.1.1.2.4.2
log
@Mostly merge changes from HEAD upto 20200411
@
text
@@


1.1.1.2.2.1
log
@Sync with HEAD
@
text
@d59 2
a60 2
void test_func_local(ATTR int param) { // expected-error {{only applies to global variables}}
  ATTR int x = 42;                     // expected-error {{only applies to}}
d63 2
a64 2
struct ATTR class_mem { // expected-error {{only applies to}}
  ATTR int x;           // expected-error {{only applies to}}
@


1.1.1.3
log
@Import clang r337282 from trunk
@
text
@d59 2
a60 2
void test_func_local(ATTR int param) { // expected-error {{only applies to global variables}}
  ATTR int x = 42;                     // expected-error {{only applies to}}
d63 2
a64 2
struct ATTR class_mem { // expected-error {{only applies to}}
  ATTR int x;           // expected-error {{only applies to}}
@


1.1.1.4
log
@Mark old LLVM instance as dead.
@
text
@@


1.1.1.1.4.1
log
@file attr-require-constant-initialization.cpp was added on branch pgoyette-localcount on 2017-03-20 06:53:33 +0000
@
text
@d1 282
@


1.1.1.1.4.2
log
@Sync with HEAD
@
text
@a0 282
// RUN: %clang_cc1 -fsyntax-only -verify -DTEST_ONE -std=c++03 %s
// RUN: %clang_cc1 -fsyntax-only -verify -DTEST_ONE -std=c++11 %s
// RUN: %clang_cc1 -fsyntax-only -verify -DTEST_ONE -std=c++14 %s
// RUN: %clang_cc1 -fsyntax-only -verify -DTEST_TWO \
// RUN: -Wglobal-constructors -std=c++14 %s
// RUN: %clang_cc1 -fsyntax-only -verify -DTEST_THREE -xc %s

#define ATTR __attribute__((require_constant_initialization)) // expected-note 0+ {{expanded from macro}}

int ReturnInt();

struct PODType {
  int value;
  int value2;
};

#if defined(__cplusplus)

#if __cplusplus >= 201103L
struct LitType {
  constexpr LitType() : value(0) {}
  constexpr LitType(int x) : value(x) {}
  LitType(void *) : value(-1) {}
  int value;
};
#endif

struct NonLit {
#if __cplusplus >= 201402L
  constexpr NonLit() : value(0) {}
  constexpr NonLit(int x) : value(x) {}
#else
  NonLit() : value(0) {}
  NonLit(int x) : value(x) {}
#endif
  NonLit(void *) : value(-1) {}
  ~NonLit() {}
  int value;
};

struct StoresNonLit {
#if __cplusplus >= 201402L
  constexpr StoresNonLit() : obj() {}
  constexpr StoresNonLit(int x) : obj(x) {}
#else
  StoresNonLit() : obj() {}
  StoresNonLit(int x) : obj(x) {}
#endif
  StoresNonLit(void *p) : obj(p) {}
  NonLit obj;
};

#endif // __cplusplus


#if defined(TEST_ONE) // Test semantics of attribute

// Test diagnostics when attribute is applied to non-static declarations.
void test_func_local(ATTR int param) { // expected-error {{only applies to variables with static or thread}}
  ATTR int x = 42;                     // expected-error {{only applies to variables with static or thread}}
  ATTR extern int y;
}
struct ATTR class_mem { // expected-error {{only applies to variables with static or thread}}
  ATTR int x;           // expected-error {{only applies to variables with static or thread}}
};

// [basic.start.static]p2.1
// if each full-expression (including implicit conversions) that appears in
// the initializer of a reference with static or thread storage duration is
// a constant expression (5.20) and the reference is bound to a glvalue
// designating an object with static storage duration, to a temporary object
// (see 12.2) or subobject thereof, or to a function;

// Test binding to a static glvalue
const int glvalue_int = 42;
const int glvalue_int2 = ReturnInt();
ATTR const int &glvalue_ref ATTR = glvalue_int;
ATTR const int &glvalue_ref2 ATTR = glvalue_int2;
ATTR __thread const int &glvalue_ref_tl = glvalue_int;

void test_basic_start_static_2_1() {
  const int non_global = 42;
  ATTR static const int &local_init = non_global; // expected-error {{variable does not have a constant initializer}}
  // expected-note@@-1 {{required by 'require_constant_initializer' attribute here}}
  ATTR static const int &global_init = glvalue_int;
  ATTR static const int &temp_init = 42;
}

ATTR const int &temp_ref = 42;
ATTR const int &temp_ref2 = ReturnInt(); // expected-error {{variable does not have a constant initializer}}
// expected-note@@-1 {{required by 'require_constant_initializer' attribute here}}
ATTR const NonLit &nl_temp_ref = 42; // expected-error {{variable does not have a constant initializer}}
// expected-note@@-1 {{required by 'require_constant_initializer' attribute here}}

#if __cplusplus >= 201103L
ATTR const LitType &lit_temp_ref = 42;
ATTR const int &subobj_ref = LitType{}.value;
#endif

ATTR const int &nl_subobj_ref = NonLit().value; // expected-error {{variable does not have a constant initializer}}
// expected-note@@-1 {{required by 'require_constant_initializer' attribute here}}

struct TT1 {
  ATTR static const int &no_init;
  ATTR static const int &glvalue_init;
  ATTR static const int &temp_init;
  ATTR static const int &subobj_init;
#if __cplusplus >= 201103L
  ATTR static thread_local const int &tl_glvalue_init;
  ATTR static thread_local const int &tl_temp_init; // expected-note {{required by 'require_constant_initializer' attribute here}}
#endif
};
const int &TT1::glvalue_init = glvalue_int;
const int &TT1::temp_init = 42;
const int &TT1::subobj_init = PODType().value;
#if __cplusplus >= 201103L
thread_local const int &TT1::tl_glvalue_init = glvalue_int;
thread_local const int &TT1::tl_temp_init = 42; // expected-error {{variable does not have a constant initializer}}
#endif

// [basic.start.static]p2.2
// if an object with static or thread storage duration is initialized by a
// constructor call, and if the initialization full-expression is a constant
// initializer for the object;

void test_basic_start_static_2_2() {
#if __cplusplus < 201103L
  ATTR static PODType pod;
#else
  ATTR static PODType pod; // expected-error {{variable does not have a constant initializer}}
// expected-note@@-1 {{required by 'require_constant_initializer' attribute here}}
#endif
  ATTR static PODType pot2 = {ReturnInt()}; // expected-error {{variable does not have a constant initializer}}
                                            // expected-note@@-1 {{required by 'require_constant_initializer' attribute here}}

#if __cplusplus >= 201103L
  constexpr LitType l;
  ATTR static LitType static_lit = l;
  ATTR static LitType static_lit2 = (void *)0; // expected-error {{variable does not have a constant initializer}}
  // expected-note@@-1 {{required by 'require_constant_initializer' attribute here}}
  ATTR static LitType static_lit3 = ReturnInt(); // expected-error {{variable does not have a constant initializer}}
  // expected-note@@-1 {{required by 'require_constant_initializer' attribute here}}
  ATTR thread_local LitType tls = 42;
#endif
}

struct TT2 {
  ATTR static PODType pod_noinit;
#if __cplusplus >= 201103L
// expected-note@@-2 {{required by 'require_constant_initializer' attribute here}}
#endif
  ATTR static PODType pod_copy_init; // expected-note {{required by 'require_constant_initializer' attribute here}}
#if __cplusplus >= 201402L
  ATTR static constexpr LitType lit = {};
  ATTR static const NonLit non_lit;
  ATTR static const NonLit non_lit_list_init;
  ATTR static const NonLit non_lit_copy_init; // expected-note {{required by 'require_constant_initializer' attribute here}}
#endif
};
PODType TT2::pod_noinit;
#if __cplusplus >= 201103L
// expected-error@@-2 {{variable does not have a constant initializer}}
#endif
PODType TT2::pod_copy_init(TT2::pod_noinit); // expected-error {{variable does not have a constant initializer}}
#if __cplusplus >= 201402L
const NonLit TT2::non_lit(42);
const NonLit TT2::non_lit_list_init = {42};
const NonLit TT2::non_lit_copy_init = 42; // expected-error {{variable does not have a constant initializer}}
#endif

#if __cplusplus >= 201103L
ATTR LitType lit_ctor;
ATTR LitType lit_ctor2{};
ATTR LitType lit_ctor3 = {};
ATTR __thread LitType lit_ctor_tl = {};

#if __cplusplus >= 201402L
ATTR NonLit nl_ctor;
ATTR NonLit nl_ctor2{};
ATTR NonLit nl_ctor3 = {};
ATTR thread_local NonLit nl_ctor_tl = {};
ATTR StoresNonLit snl;
#else
ATTR NonLit nl_ctor; // expected-error {{variable does not have a constant initializer}}
// expected-note@@-1 {{required by 'require_constant_initializer' attribute here}}
ATTR NonLit nl_ctor2{}; // expected-error {{variable does not have a constant initializer}}
// expected-note@@-1 {{required by 'require_constant_initializer' attribute here}}
ATTR NonLit nl_ctor3 = {}; // expected-error {{variable does not have a constant initializer}}
// expected-note@@-1 {{required by 'require_constant_initializer' attribute here}}
ATTR thread_local NonLit nl_ctor_tl = {}; // expected-error {{variable does not have a constant initializer}}
// expected-note@@-1 {{required by 'require_constant_initializer' attribute here}}
ATTR StoresNonLit snl; // expected-error {{variable does not have a constant initializer}}
// expected-note@@-1 {{required by 'require_constant_initializer' attribute here}}
#endif

// Non-literal types cannot appear in the initializer of a non-literal type.
ATTR int nl_in_init = NonLit{42}.value; // expected-error {{variable does not have a constant initializer}}
// expected-note@@-1 {{required by 'require_constant_initializer' attribute here}}
ATTR int lit_in_init = LitType{42}.value;
#endif

// [basic.start.static]p2.3
// if an object with static or thread storage duration is not initialized by a
// constructor call and if either the object is value-initialized or every
// full-expression that appears in its initializer is a constant expression.
void test_basic_start_static_2_3() {
  ATTR static int static_local = 42;
  ATTR static int static_local2; // zero-initialization takes place
#if __cplusplus >= 201103L
  ATTR thread_local int tl_local = 42;
#endif
}

ATTR int no_init; // zero initialization takes place
ATTR int arg_init = 42;
ATTR PODType pod_init = {};
ATTR PODType pod_missing_init = {42 /* should have second arg */};
ATTR PODType pod_full_init = {1, 2};
ATTR PODType pod_non_constexpr_init = {1, ReturnInt()}; // expected-error {{variable does not have a constant initializer}}
// expected-note@@-1 {{required by 'require_constant_initializer' attribute here}}

#if __cplusplus >= 201103L
ATTR int val_init{};
ATTR int brace_init = {};
#endif

ATTR __thread int tl_init = 0;
typedef const char *StrType;

#if __cplusplus >= 201103L

// Test that the validity of the selected constructor is checked, not just the
// initializer
struct NotC {
  constexpr NotC(void *) {}
  NotC(int) {}
};
template <class T>
struct TestCtor {
  constexpr TestCtor(int x) : value(x) {}
  T value;
};
ATTR TestCtor<NotC> t(42); // expected-error {{variable does not have a constant initializer}}
// expected-note@@-1 {{required by 'require_constant_initializer' attribute here}}
#endif

// Test various array types
ATTR const char *foo[] = {"abc", "def"};
ATTR PODType bar[] = {{}, {123, 456}};

#elif defined(TEST_TWO) // Test for duplicate warnings
struct NotC {
  constexpr NotC(void *) {}
  NotC(int) {} // expected-note 2 {{declared here}}
};
template <class T>
struct TestCtor {
  constexpr TestCtor(int x) : value(x) {} // expected-note 2 {{non-constexpr constructor}}
  T value;
};

ATTR LitType non_const_lit(nullptr); // expected-error {{variable does not have a constant initializer}}
// expected-note@@-1 {{required by 'require_constant_initializer' attribute here}}
ATTR NonLit non_const(nullptr); // expected-error {{variable does not have a constant initializer}}
// expected-warning@@-1 {{declaration requires a global destructor}}
// expected-note@@-2 {{required by 'require_constant_initializer' attribute here}}
LitType const_init_lit(nullptr);              // expected-warning {{declaration requires a global constructor}}
NonLit const_init{42};                        // expected-warning {{declaration requires a global destructor}}
constexpr TestCtor<NotC> inval_constexpr(42); // expected-error {{must be initialized by a constant expression}}
// expected-note@@-1 {{in call to 'TestCtor(42)'}}
ATTR constexpr TestCtor<NotC> inval_constexpr2(42); // expected-error {{must be initialized by a constant expression}}
// expected-note@@-1 {{in call to 'TestCtor(42)'}}

#elif defined(TEST_THREE)
#if defined(__cplusplus)
#error This test requires C
#endif
// Test that using the attribute in C results in a diagnostic
ATTR int x = 0; // expected-warning {{attribute ignored}}
#else
#error No test case specified
#endif // defined(TEST_N)
@


