1 // RUN: %clang_cc1 -fsyntax-only -std=c++11 -verify=expected,cxx11 %s 2 // RUN: %clang_cc1 -fsyntax-only -std=c++17 -verify=expected,cxx17 %s 3 4 // A converted constant expression of type T is a core constant expression, 5 int nonconst = 8; // expected-note 3 {{here}} 6 enum NonConstE : unsigned char { NCE = nonconst }; // expected-error {{enumerator value is not a constant expression}} expected-note {{read of non-const}} 7 template<int = nonconst> struct NonConstT {}; // expected-error {{non-type template argument is not a constant expression}} expected-note {{read of non-const}} 8 void NonConstF() { 9 switch (nonconst) { 10 case nonconst: // expected-error {{case value is not a constant expression}} expected-note {{read of non-const}} 11 break; 12 } 13 NonConstT<> V; // expected-note {{while checking a default template argument used here}} 14 return; 15 } 16 17 // implicitly converted to a prvalue of type T, where the converted expression 18 // is a literal constant expression 19 20 bool a(int n) { 21 constexpr char vowels[] = "aeiou"; 22 switch (n) { 23 case vowels[0]: 24 case vowels[1]: 25 case vowels[2]: 26 case vowels[3]: 27 case vowels[4]: 28 static_assert(!vowels[5], "unexpected number of vowels"); 29 return true; 30 } 31 return false; 32 } 33 34 // and the implicit conversion sequence contains only 35 // 36 // user-defined conversions, 37 struct S { constexpr operator int() const { return 5; } }; 38 enum E : unsigned char { E5 = S(), E6, E10 = S() * 2, E1 = E5 / 5 }; 39 40 // lvalue-to-rvalue conversions, 41 const E e10 = E10; 42 template<E> struct T {}; 43 T<e10> s10; 44 45 // integral promotions, 46 enum class EE { EE32 = ' ', EE65 = 'A', EE1 = (short)1, EE5 = E5 }; 47 48 // integral conversions other than narrowing conversions, 49 int b(unsigned n) { 50 switch (n) { 51 case E6: 52 case EE::EE32: // expected-error {{not implicitly convertible}} 53 case (int)EE::EE32: 54 case 1000: 55 case (long long)1e10: // expected-error {{case value evaluates to 10000000000, which cannot be narrowed to type 'unsigned int'}} 56 case -3: // expected-error {{case value evaluates to -3, which cannot be narrowed to type 'unsigned int'}} 57 return n; 58 } 59 return 0; 60 } 61 enum class EEE : unsigned short { 62 a = E6, 63 b = EE::EE32, // expected-error {{not implicitly convertible}} 64 c = (int)EE::EE32, 65 d = 1000, 66 e = 123456, // expected-error {{enumerator value evaluates to 123456, which cannot be narrowed to type 'unsigned short'}} 67 f = -3 // expected-error {{enumerator value evaluates to -3, which cannot be narrowed to type 'unsigned short'}} 68 }; 69 template<unsigned char> using A = int; // cxx17-note 2{{template parameter is declared here}} 70 71 using Int = A<E6>; 72 using Int = A<EE::EE32>; // expected-error {{not implicitly convertible}} 73 using Int = A<(int)EE::EE32>; 74 using Int = A<200>; 75 using Int = A<1000>; // expected-error {{template argument evaluates to 1000, which cannot be narrowed to type 'unsigned char'}} 76 using Int = A<-3>; // expected-error {{template argument evaluates to -3, which cannot be narrowed to type 'unsigned char'}} 77 78 // Note, conversions from integral or unscoped enumeration types to bool are 79 // integral conversions as well as boolean conversions. 80 // FIXME: Per core issue 1407, this is not correct. 81 template<typename T, T v> struct Val { static constexpr T value = v; }; 82 // cxx17-note@-1 2{{template parameter is declared here}} 83 static_assert(Val<bool, E1>::value == 1, ""); // ok 84 static_assert(Val<bool, '\0'>::value == 0, ""); // ok 85 static_assert(Val<bool, U'\1'>::value == 1, ""); // ok 86 static_assert(Val<bool, E5>::value == 1, ""); // expected-error {{5, which cannot be narrowed to type 'bool'}} 87 88 // function pointer conversions [C++17] 89 void noexcept_false() noexcept(false); 90 void noexcept_true() noexcept(true); 91 Val<decltype(&noexcept_false), &noexcept_true> remove_noexcept; 92 Val<decltype(&noexcept_true), &noexcept_false> add_noexcept; 93 #if __cplusplus > 201402L 94 // expected-error@-2 {{value of type 'void (*)() noexcept(false)' is not implicitly convertible to 'decltype(&noexcept_true)' (aka 'void (*)() noexcept(true)')}} 95 #endif 96 97 // (no other conversions are permitted) 98 using Int = A<1.0>; // expected-error {{conversion from 'double' to 'unsigned char' is not allowed in a converted constant expression}} 99 enum B : bool { 100 True = &a, // expected-error {{conversion from 'bool (*)(int)' to 'bool' is not allowed in a converted constant expression}} 101 False = 0.0, // expected-error {{conversion from 'double' to 'bool' is not allowed in a converted constant expression}} 102 }; 103 void c() { 104 // Note, promoted type of switch is 'int'. 105 switch (bool b = a(5)) { // expected-warning {{boolean value}} 106 case 0.0f: // expected-error {{conversion from 'float' to 'int' is not allowed in a converted constant expression}} 107 break; 108 } 109 } 110 template <bool B> int f() { return B; } // expected-note {{candidate template ignored: invalid explicitly-specified argument for template parameter 'B'}} 111 template int f<&S::operator int>(); // expected-error {{does not refer to a function template}} 112 template int f<(bool)&S::operator int>(); 113 114 int n = Val<bool, &S::operator int>::value; // expected-error-re {{conversion from 'int (S::*)(){{( __attribute__\(\(thiscall\)\))?}} const' to 'bool' is not allowed in a converted constant expression}} 115 116 namespace NonConstLValue { 117 struct S { 118 constexpr operator int() const { return 10; } 119 }; 120 S s; // not constexpr 121 // Under the FDIS, this is not a converted constant expression. 122 // Under the new proposed wording, it is. 123 enum E : char { e = s }; 124 } 125