// 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
int ; // expected-note 0+ {{declared here}}
;
;
;
;
// __cplusplus
// Test diagnostics when attribute is applied to non-static declarations.
void
;
// [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 = ;
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
ATTR const int &temp_ref = 42;
ATTR const int &temp_ref2 = ; // expected-error {{variable does not have a constant initializer}}
// expected-note@-1 {{required by 'require_constant_initialization' attribute here}}
// expected-note@-3 {{non-constexpr function 'ReturnInt' cannot be used in a constant expression}}
// expected-note@-5 {{subexpression not valid in a constant expression}}
ATTR const NonLit &nl_temp_ref = 42; // expected-error {{variable does not have a constant initializer}}
// expected-note@-1 {{required by 'require_constant_initialization' attribute here}}
// expected-note@-3 {{non-literal type 'const NonLit' cannot be used in a constant expression}}
// expected-note@-5 {{subexpression not valid in a constant expression}}
ATTR const LitType &lit_temp_ref = 42;
ATTR const int &subobj_ref = LitType.value;
ATTR const int &nl_subobj_ref = .value; // expected-error {{variable does not have a constant initializer}}
// expected-note@-1 {{required by 'require_constant_initialization' attribute here}}
// expected-note-re@-3 {{non-literal type '{{.*}}' cannot be used in a constant expression}}
// expected-note@-5 {{subexpression not valid in a constant expression}}
;
const int &TT1::glvalue_init = glvalue_int;
const int &TT1::temp_init = 42;
const int &TT1::subobj_init = .value;
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}}
// expected-note@-1 {{reference to temporary is not a constant expression}}
// expected-note@-2 {{temporary created here}}
// [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
;
PODType TT2::pod_noinit; // expected-note 0+ {{declared here}}
// expected-error@-2 {{variable does not have a constant initializer}}
// expected-note-re@-3 {{{{non-constexpr constructor|subobject of type 'int' is not initialized}}}}
PODType ; // expected-error {{variable does not have a constant initializer}}
// 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)'}}
// expected-note@-5 {{subexpression not valid in a constant expression}}
const NonLit ;
const NonLit TT2::non_lit_list_init = ;
// FIXME: This is invalid, but we incorrectly elide the copy. It's OK if we
// start diagnosing this.
const NonLit TT2::non_lit_copy_init = 42;
ATTR LitType lit_ctor;
ATTR LitType lit_ctor2;
ATTR LitType lit_ctor3 = ;
ATTR __thread LitType lit_ctor_tl = ;
ATTR NonLit nl_ctor;
ATTR NonLit nl_ctor2;
ATTR NonLit nl_ctor3 = ;
ATTR thread_local NonLit nl_ctor_tl = ;
ATTR StoresNonLit snl;
ATTR NonLit nl_ctor; // expected-error {{variable does not have a constant initializer}}
// expected-note@-1 {{required by 'require_constant_initialization' attribute here}}
// expected-note@-2 {{non-constexpr constructor 'NonLit' cannot be used in a constant expression}}
ATTR NonLit nl_ctor2; // expected-error {{variable does not have a constant initializer}}
// expected-note@-1 {{required by 'require_constant_initialization' attribute here}}
// expected-note@-2 {{non-constexpr constructor 'NonLit' cannot be used in a constant expression}}
ATTR NonLit nl_ctor3 = ; // expected-error {{variable does not have a constant initializer}}
// expected-note@-1 {{required by 'require_constant_initialization' attribute here}}
// expected-note@-2 {{non-constexpr constructor 'NonLit' cannot be used in a constant expression}}
ATTR thread_local NonLit nl_ctor_tl = ; // expected-error {{variable does not have a constant initializer}}
// expected-note@-1 {{required by 'require_constant_initialization' attribute here}}
// expected-note@-2 {{non-constexpr constructor 'NonLit' cannot be used in a constant expression}}
ATTR StoresNonLit snl; // expected-error {{variable does not have a constant initializer}}
// expected-note@-1 {{required by 'require_constant_initialization' attribute here}}
// expected-note@-2 {{non-constexpr constructor 'StoresNonLit' cannot be used in a constant expression}}
// Non-literal types cannot appear in the initializer of a non-literal type.
ATTR int nl_in_init = NonLit.value; // expected-error {{variable does not have a constant initializer}}
// expected-note@-1 {{required by 'require_constant_initialization' attribute here}}
// expected-note@-2 {{non-literal type 'NonLit' cannot be used in a constant expression}}
ATTR int lit_in_init = LitType.value;
// [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
ATTR int no_init; // zero initialization takes place
ATTR int arg_init = 42;
ATTR PODType pod_init = ;
ATTR PODType pod_missing_init = ;
ATTR PODType pod_full_init = ;
ATTR PODType pod_non_constexpr_init = ; // expected-error {{variable does not have a constant initializer}}
// expected-note@-1 {{required by 'require_constant_initialization' attribute here}}
// expected-note@-3 {{non-constexpr function 'ReturnInt' cannot be used in a constant expression}}
// expected-note@-5 {{subexpression not valid in a constant expression}}
ATTR int val_init;
ATTR int brace_init = ;
ATTR __thread int tl_init = 0;
typedef const char *StrType;
// Test that the validity of the selected constructor is checked, not just the
// initializer
;
;
ATTR TestCtor<NotC> ; // expected-error {{variable does not have a constant initializer}}
// expected-note@-1 {{required by 'require_constant_initialization' attribute here}}
// expected-note@-2 {{in call to 'TestCtor(42)'}}
// Test various array types
ATTR const char *foo = ;
ATTR PODType bar = ;
;
;
ATTR LitType ; // expected-error {{variable does not have a constant initializer}}
// expected-note@-1 {{required by 'require_constant_initialization' attribute here}}
// expected-note@-2 {{non-constexpr constructor 'LitType' cannot be used in a constant expression}}
ATTR NonLit ; // expected-error {{variable does not have a constant initializer}}
// expected-warning@-1 {{declaration requires a global destructor}}
// expected-note@-2 {{required by 'require_constant_initialization' attribute here}}
// expected-note@-3 {{non-constexpr constructor 'NonLit' cannot be used in a constant expression}}
LitType ; // expected-warning {{declaration requires a global constructor}}
NonLit const_init; // expected-warning {{declaration requires a global destructor}}
constexpr TestCtor<NotC> ; // expected-error {{must be initialized by a constant expression}}
// expected-note@-1 {{in call to 'TestCtor(42)'}}
ATTR constexpr TestCtor<NotC> ; // expected-error {{must be initialized by a constant expression}}
// expected-note@-1 {{in call to 'TestCtor(42)'}}
// Test that using the attribute in C results in a diagnostic
ATTR int x = 0; // expected-warning {{attribute ignored}}
// defined(TEST_N)