blob: 731e0c312fa13f1a284ca9c727f05101ad3e01a9 [file] [log] [blame]
Richard Smithf8379a02012-01-18 23:55:52 +00001// RUN: %clang_cc1 -fsyntax-only -std=c++11 -verify %s
Richard Smith3c4f8d22016-10-16 17:54:23 +00002// RUN: %clang_cc1 -fsyntax-only -std=c++1z -verify %s
Richard Smithf8379a02012-01-18 23:55:52 +00003
4// A converted constant expression of type T is a core constant expression,
5int nonconst = 8; // expected-note 3 {{here}}
6enum NonConstE : unsigned char { NCE = nonconst }; // expected-error {{enumerator value is not a constant expression}} expected-note {{read of non-const}}
7template<int = nonconst> struct NonConstT {}; // expected-error {{non-type template argument is not a constant expression}} expected-note {{read of non-const}}
8void 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 return;
14}
15
16// implicitly converted to a prvalue of type T, where the converted expression
17// is a literal constant expression
18
19bool a(int n) {
20 constexpr char vowels[] = "aeiou";
21 switch (n) {
22 case vowels[0]:
23 case vowels[1]:
24 case vowels[2]:
25 case vowels[3]:
26 case vowels[4]:
27 static_assert(!vowels[5], "unexpected number of vowels");
28 return true;
29 }
30 return false;
31}
32
33// and the implicit conversion sequence contains only
34//
35// user-defined conversions,
36struct S { constexpr operator int() const { return 5; } };
37enum E : unsigned char { E5 = S(), E6, E10 = S() * 2, E1 = E5 / 5 };
38
39// lvalue-to-rvalue conversions,
40const E e10 = E10;
41template<E> struct T {};
42T<e10> s10;
43
Richard Smith3c4f8d22016-10-16 17:54:23 +000044// integral promotions,
Richard Smithf8379a02012-01-18 23:55:52 +000045enum class EE { EE32 = ' ', EE65 = 'A', EE1 = (short)1, EE5 = E5 };
46
Richard Smith3c4f8d22016-10-16 17:54:23 +000047// integral conversions other than narrowing conversions,
Richard Smithf8379a02012-01-18 23:55:52 +000048int b(unsigned n) {
49 switch (n) {
50 case E6:
51 case EE::EE32: // expected-error {{not implicitly convertible}}
52 case (int)EE::EE32:
53 case 1000:
54 case (long long)1e10: // expected-error {{case value evaluates to 10000000000, which cannot be narrowed to type 'unsigned int'}}
55 case -3: // expected-error {{case value evaluates to -3, which cannot be narrowed to type 'unsigned int'}}
56 return n;
57 }
58 return 0;
59}
60enum class EEE : unsigned short {
61 a = E6,
62 b = EE::EE32, // expected-error {{not implicitly convertible}}
63 c = (int)EE::EE32,
64 d = 1000,
65 e = 123456, // expected-error {{enumerator value evaluates to 123456, which cannot be narrowed to type 'unsigned short'}}
66 f = -3 // expected-error {{enumerator value evaluates to -3, which cannot be narrowed to type 'unsigned short'}}
67};
68template<unsigned char> using A = int;
69using Int = A<E6>;
70using Int = A<EE::EE32>; // expected-error {{not implicitly convertible}}
71using Int = A<(int)EE::EE32>;
72using Int = A<200>;
73using Int = A<1000>; // expected-error {{template argument evaluates to 1000, which cannot be narrowed to type 'unsigned char'}}
74using Int = A<-3>; // expected-error {{template argument evaluates to -3, which cannot be narrowed to type 'unsigned char'}}
75
76// Note, conversions from integral or unscoped enumeration types to bool are
Richard Smithca24ed42012-09-13 22:00:12 +000077// integral conversions as well as boolean conversions.
Richard Smith3c4f8d22016-10-16 17:54:23 +000078// FIXME: Per core issue 1407, this is not correct.
Richard Smithf8379a02012-01-18 23:55:52 +000079template<typename T, T v> struct Val { static constexpr T value = v; };
Richard Smithca24ed42012-09-13 22:00:12 +000080static_assert(Val<bool, E1>::value == 1, ""); // ok
81static_assert(Val<bool, '\0'>::value == 0, ""); // ok
82static_assert(Val<bool, U'\1'>::value == 1, ""); // ok
83static_assert(Val<bool, E5>::value == 1, ""); // expected-error {{5, which cannot be narrowed to type 'bool'}}
Richard Smithf8379a02012-01-18 23:55:52 +000084
Richard Smith3c4f8d22016-10-16 17:54:23 +000085// function pointer conversions [C++17]
86void noexcept_false() noexcept(false);
87void noexcept_true() noexcept(true);
88Val<decltype(&noexcept_false), &noexcept_true> remove_noexcept;
89Val<decltype(&noexcept_true), &noexcept_false> add_noexcept;
90#if __cplusplus > 201402L
91// expected-error@-2 {{value of type 'void (*)() noexcept(false)' is not implicitly convertible to 'void (*)() noexcept'}}
92#endif
93
Richard Smithf8379a02012-01-18 23:55:52 +000094// (no other conversions are permitted)
95using Int = A<1.0>; // expected-error {{conversion from 'double' to 'unsigned char' is not allowed in a converted constant expression}}
96enum B : bool {
97 True = &a, // expected-error {{conversion from 'bool (*)(int)' to 'bool' is not allowed in a converted constant expression}}
98 False = nullptr // expected-error {{conversion from 'nullptr_t' to 'bool' is not allowed in a converted constant expression}}
99};
100void c() {
101 // Note, promoted type of switch is 'int'.
102 switch (bool b = a(5)) { // expected-warning {{boolean value}}
103 case 0.0f: // expected-error {{conversion from 'float' to 'int' is not allowed in a converted constant expression}}
104 break;
105 }
106}
Larisse Voufo98b20f12013-07-19 23:00:19 +0000107template <bool B> int f() { return B; } // expected-note {{candidate template ignored: invalid explicitly-specified argument for template parameter 'B'}}
Richard Smithf8379a02012-01-18 23:55:52 +0000108template int f<&S::operator int>(); // expected-error {{does not refer to a function template}}
109template int f<(bool)&S::operator int>();
110
Alp Toker6ed72512013-12-14 01:07:05 +0000111int 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}}
Richard Smithf8379a02012-01-18 23:55:52 +0000112
113namespace NonConstLValue {
114 struct S {
Richard Smith034185c2013-04-21 01:08:50 +0000115 constexpr operator int() const { return 10; }
Richard Smithf8379a02012-01-18 23:55:52 +0000116 };
117 S s; // not constexpr
118 // Under the FDIS, this is not a converted constant expression.
119 // Under the new proposed wording, it is.
120 enum E : char { e = s };
121}