1 // RUN: %clang_cc1 -fsyntax-only -std=c++11 -verify %s
2 // RUN: %clang_cc1 -fsyntax-only -std=c++1z -verify %s
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}}
10 case nonconst
: // expected-error {{case value is not a constant expression}} expected-note {{read of non-const}}
13 NonConstT
<> V
; // expected-note {{while checking a default template argument used here}}
17 // implicitly converted to a prvalue of type T, where the converted expression
18 // is a literal constant expression
21 constexpr char vowels
[] = "aeiou";
28 static_assert(!vowels
[5], "unexpected number of vowels");
34 // and the implicit conversion sequence contains only
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 };
40 // lvalue-to-rvalue conversions,
42 template<E
> struct T
{};
45 // integral promotions,
46 enum class EE
{ EE32
= ' ', EE65
= 'A', EE1
= (short)1, EE5
= E5
};
48 // integral conversions other than narrowing conversions,
52 case EE::EE32
: // expected-error {{not implicitly convertible}}
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'}}
61 enum class EEE
: unsigned short {
63 b
= EE::EE32
, // expected-error {{not implicitly convertible}}
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'}}
69 template<unsigned char> using A
= int;
71 using Int
= A
<EE::EE32
>; // expected-error {{not implicitly convertible}}
72 using Int
= A
<(int)EE::EE32
>;
74 using Int
= A
<1000>; // expected-error {{template argument evaluates to 1000, which cannot be narrowed to type 'unsigned char'}}
75 using Int
= A
<-3>; // expected-error {{template argument evaluates to -3, which cannot be narrowed to type 'unsigned char'}}
77 // Note, conversions from integral or unscoped enumeration types to bool are
78 // integral conversions as well as boolean conversions.
79 // FIXME: Per core issue 1407, this is not correct.
80 template<typename T
, T v
> struct Val
{ static constexpr T value
= v
; };
81 static_assert(Val
<bool, E1
>::value
== 1, ""); // ok
82 static_assert(Val
<bool, '\0'>::value
== 0, ""); // ok
83 static_assert(Val
<bool, U
'\1'>::value
== 1, ""); // ok
84 static_assert(Val
<bool, E5
>::value
== 1, ""); // expected-error {{5, which cannot be narrowed to type 'bool'}}
86 // function pointer conversions [C++17]
87 void noexcept_false() noexcept(false);
88 void noexcept_true() noexcept(true);
89 Val
<decltype(&noexcept_false
), &noexcept_true
> remove_noexcept
;
90 Val
<decltype(&noexcept_true
), &noexcept_false
> add_noexcept
;
91 #if __cplusplus > 201402L
92 // expected-error@-2 {{value of type 'void (*)() noexcept(false)' is not implicitly convertible to 'decltype(&noexcept_true)' (aka 'void (*)() noexcept(true)')}}
95 // (no other conversions are permitted)
96 using Int
= A
<1.0>; // expected-error {{conversion from 'double' to 'unsigned char' is not allowed in a converted constant expression}}
98 True
= &a
, // expected-error {{conversion from 'bool (*)(int)' to 'bool' is not allowed in a converted constant expression}}
99 False
= 0.0, // expected-error {{conversion from 'double' to 'bool' is not allowed in a converted constant expression}}
102 // Note, promoted type of switch is 'int'.
103 switch (bool b
= a(5)) { // expected-warning {{boolean value}}
104 case 0.0f
: // expected-error {{conversion from 'float' to 'int' is not allowed in a converted constant expression}}
108 template <bool B
> int f() { return B
; } // expected-note {{candidate template ignored: invalid explicitly-specified argument for template parameter 'B'}}
109 template int f
<&S::operator int>(); // expected-error {{does not refer to a function template}}
110 template int f
<(bool)&S::operator int>();
112 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}}
114 namespace NonConstLValue
{
116 constexpr operator int() const { return 10; }
118 S s
; // not constexpr
119 // Under the FDIS, this is not a converted constant expression.
120 // Under the new proposed wording, it is.
121 enum E
: char { e
= s
};