// RUN: %clang_cc1 -std=c++17 -verify %s template int not_constexpr() { return T::error; } template constexpr int is_constexpr() { return T::error; } // expected-error {{'::'}} template int not_constexpr_var = T::error; template constexpr int is_constexpr_var = T::error; // expected-error {{'::'}} template const int is_const_var = T::error; // expected-error {{'::'}} template const volatile int is_const_volatile_var = T::error; template T is_dependent_var = T::error; // expected-error {{'::'}} template int &is_reference_var = T::error; // expected-error {{'::'}} template float is_float_var = T::error; void test() { // Do not instantiate functions referenced in unevaluated operands... (void)sizeof(not_constexpr()); (void)sizeof(is_constexpr()); (void)sizeof(not_constexpr_var); (void)sizeof(is_constexpr_var); (void)sizeof(is_const_var); (void)sizeof(is_const_volatile_var); (void)sizeof(is_dependent_var); (void)sizeof(is_dependent_var); (void)sizeof(is_reference_var); (void)sizeof(is_float_var); // ... but do if they are potentially constant evaluated, and refer to // constexpr functions or to variables usable in constant expressions. (void)sizeof(int{not_constexpr()}); (void)sizeof(int{is_constexpr()}); // expected-note {{instantiation of}} (void)sizeof(int{not_constexpr_var}); (void)sizeof(int{is_constexpr_var}); // expected-note {{instantiation of}} (void)sizeof(int{is_const_var}); // expected-note {{instantiation of}} (void)sizeof(int{is_const_volatile_var}); (void)sizeof(int{is_dependent_var}); (void)sizeof(int{is_dependent_var}); // expected-note {{instantiation of}} (void)sizeof(int{is_reference_var}); // expected-note {{instantiation of}} (void)sizeof(int{is_float_var}); // expected-error {{cannot be narrowed}} expected-note {{cast}} }