diff options
Diffstat (limited to 'test/CXX/dcl.decl/dcl.init/dcl.init.list/p7-0x.cpp')
-rw-r--r-- | test/CXX/dcl.decl/dcl.init/dcl.init.list/p7-0x.cpp | 40 |
1 files changed, 37 insertions, 3 deletions
diff --git a/test/CXX/dcl.decl/dcl.init/dcl.init.list/p7-0x.cpp b/test/CXX/dcl.decl/dcl.init/dcl.init.list/p7-0x.cpp index 2294a4eb08940..db20ea6426e00 100644 --- a/test/CXX/dcl.decl/dcl.init/dcl.init.list/p7-0x.cpp +++ b/test/CXX/dcl.decl/dcl.init/dcl.init.list/p7-0x.cpp @@ -31,12 +31,20 @@ struct Agg { T t; }; +template<typename T> +struct Convert { + constexpr Convert(T v) : v(v) {} + constexpr operator T() const { return v; } + T v; +}; +template<typename T> Convert<T> ConvertVar(); + // C++0x [dcl.init.list]p7: A narrowing conversion is an implicit conversion // // * from a floating-point type to an integer type, or void float_to_int() { - Agg<char> a1 = {1.0F}; // expected-error {{ cannot be narrowed }} expected-note {{override}} + Agg<char> a1 = {1.0F}; // expected-error {{type 'float' cannot be narrowed to 'char'}} expected-note {{override}} Agg<char> a2 = {1.0}; // expected-error {{ cannot be narrowed }} expected-note {{override}} Agg<char> a3 = {1.0L}; // expected-error {{ cannot be narrowed }} expected-note {{override}} @@ -46,6 +54,9 @@ void float_to_int() { Agg<char> a4 = {f}; // expected-error {{ cannot be narrowed }} expected-note {{override}} Agg<char> a5 = {d}; // expected-error {{ cannot be narrowed }} expected-note {{override}} Agg<char> a6 = {ld}; // expected-error {{ cannot be narrowed }} expected-note {{override}} + + Agg<char> ce1 = { Convert<float>(1.0) }; // expected-error {{type 'float' cannot be narrowed to 'char'}} expected-note {{override}} + Agg<char> ce2 = { ConvertVar<double>() }; // expected-error {{type 'double' cannot be narrowed to 'char'}} expected-note {{override}} } // * from long double to double or float, or from double to float, except where @@ -61,7 +72,7 @@ void shrink_float() { // Variables. Agg<float> f1 = {f}; // OK (no-op) - Agg<float> f2 = {d}; // expected-error {{ cannot be narrowed }} expected-note {{override}} + Agg<float> f2 = {d}; // expected-error {{non-constant-expression cannot be narrowed from type 'double' to 'float'}} expected-note {{override}} Agg<float> f3 = {ld}; // expected-error {{ cannot be narrowed }} expected-note {{override}} // Exact constants. Agg<float> f4 = {1.0}; // OK (double constant represented exactly) @@ -70,7 +81,7 @@ void shrink_float() { Agg<float> f6 = {0.1}; // OK (double constant in range but rounded) Agg<float> f7 = {0.1L}; // OK (long double constant in range but rounded) // Out of range constants. - Agg<float> f8 = {1E50}; // expected-error {{ cannot be narrowed }} expected-note {{override}} + Agg<float> f8 = {1E50}; // expected-error {{constant expression evaluates to 1.000000e+50 which cannot be narrowed to type 'float'}} expected-note {{override}} Agg<float> f9 = {1E50L}; // expected-error {{ cannot be narrowed }} expected-note {{override}} // More complex constant expression. constexpr long double e40 = 1E40L, e30 = 1E30L, e39 = 1E39L; @@ -89,6 +100,9 @@ void shrink_float() { // More complex constant expression. constexpr long double e315 = 1E315L, e305 = 1E305L, e314 = 1E314L; Agg<double> d7 = {e315 - 5 * e314 + e305 - 5 * e314}; // OK + + Agg<float> ce1 = { Convert<double>(1e300) }; // expected-error {{constant expression evaluates to 1.000000e+300 which cannot be narrowed to type 'float'}} expected-note {{override}} + Agg<double> ce2 = { ConvertVar<long double>() }; // expected-error {{non-constant-expression cannot be narrowed from type 'long double' to 'double'}} expected-note {{override}} } // * from an integer type or unscoped enumeration type to a floating-point type, @@ -107,6 +121,9 @@ void int_to_float() { // Constants. Agg<float> f4 = {12345678}; // OK (exactly fits in a float) Agg<float> f5 = {123456789}; // expected-error {{ cannot be narrowed }} expected-note {{override}} + + Agg<float> ce1 = { Convert<int>(123456789) }; // expected-error {{constant expression evaluates to 123456789 which cannot be narrowed to type 'float'}} expected-note {{override}} + Agg<double> ce2 = { ConvertVar<long long>() }; // expected-error {{non-constant-expression cannot be narrowed from type 'long long' to 'double'}} expected-note {{override}} } // * from an integer type or unscoped enumeration type to an integer type that @@ -147,6 +164,9 @@ void shrink_int() { // Conversions from pointers to booleans aren't narrowing conversions. Agg<bool> b = {&b1}; // OK + + Agg<short> ce1 = { Convert<int>(100000) }; // expected-error {{constant expression evaluates to 100000 which cannot be narrowed to type 'short'}} expected-note {{override}} expected-warning {{changes value from 100000 to -31072}} + Agg<char> ce2 = { ConvertVar<short>() }; // expected-error {{non-constant-expression cannot be narrowed from type 'short' to 'char'}} expected-note {{override}} } // Be sure that type- and value-dependent expressions in templates get the error @@ -173,3 +193,17 @@ void test_qualifiers(int i) { // Template arguments make it harder to avoid printing qualifiers: Agg<const unsigned char> c2 = {j}; // expected-error {{from type 'int' to 'const unsigned char' in}} expected-note {{override}} } + +// Test SFINAE checks. +template<unsigned> struct Value { }; + +template<typename T> +int &check_narrowed(Value<sizeof((T){1.1})>); + +template<typename T> +float &check_narrowed(...); + +void test_narrowed(Value<sizeof(int)> vi, Value<sizeof(double)> vd) { + int &ir = check_narrowed<double>(vd); + float &fr = check_narrowed<int>(vi); +} |