|
3 | 3 | // RUN: %clang_cc1 -std=c++14 -verify=expected %s
|
4 | 4 | // RUN: %clang_cc1 -std=c++17 -verify=expected %s
|
5 | 5 | // RUN: %clang_cc1 -std=c++20 -verify=expected,since-cxx20 %s
|
| 6 | +// RUN: %clang_cc1 -std=c++20 -mlong-double-64 -verify=expected,since-cxx20 %s |
6 | 7 | // RUN: %clang_cc1 -std=c++23 -verify=expected,since-cxx20,since-cxx23 %s
|
7 | 8 | // RUN: %clang_cc1 -std=c++2c -verify=expected,since-cxx20,since-cxx23,since-cxx26 %s
|
8 | 9 |
|
@@ -67,6 +68,69 @@ void B<int>::g() requires true;
|
67 | 68 |
|
68 | 69 | } // namespace cwg2847
|
69 | 70 |
|
| 71 | +namespace cwg2851 { // cwg2851: 19 |
| 72 | + |
| 73 | +#if __cplusplus >= 202002L |
| 74 | +template<typename T, T v> struct Val { static constexpr T value = v; }; |
| 75 | + |
| 76 | + |
| 77 | +// Floating-point promotions |
| 78 | + |
| 79 | +static_assert(Val<long double, 0.0>::value == 0.0L); |
| 80 | +static_assert(Val<long double, 0.0f>::value == 0.0L); |
| 81 | +static_assert(Val<double, 0.0f>::value == 0.0); |
| 82 | +static_assert(Val<long double, -0.0>::value == -0.0L); |
| 83 | + |
| 84 | +static_assert(!__is_same(Val<long double, -0.0>, Val<long double, 0.0L>)); |
| 85 | +static_assert(__is_same(Val<long double, 0.5>, Val<long double, 0.5L>)); |
| 86 | + |
| 87 | +static_assert(__is_same(Val<long double, __builtin_inff()>, Val<long double, __builtin_infl()>)); |
| 88 | + |
| 89 | +static_assert(__is_same(Val<long double, __builtin_nanf("")>, Val<long double, static_cast<long double>(__builtin_nanf(""))>)); |
| 90 | +static_assert(__is_same(Val<long double, __builtin_nansf("")>, Val<long double, static_cast<long double>(__builtin_nansf(""))>)); |
| 91 | +static_assert(__is_same(Val<long double, __builtin_nanf("0x1")>, Val<long double, static_cast<long double>(__builtin_nanf("0x1"))>)); |
| 92 | +static_assert(__is_same(Val<long double, __builtin_nansf("0x1")>, Val<long double, static_cast<long double>(__builtin_nansf("0x1"))>)); |
| 93 | + |
| 94 | + |
| 95 | +// Floating-point conversions where the source value can be represented exactly in the destination type |
| 96 | + |
| 97 | +static_assert(Val<float, 0.0L>::value == 0.0L); |
| 98 | +static_assert(__is_same(Val<float, 0.0>, Val<float, 0.0L>)); |
| 99 | +static_assert(__is_same(Val<float, 0.0>, Val<float, 0.0f>)); |
| 100 | +static_assert(!__is_same(Val<float, -0.0L>, Val<float, 0.0f>)); |
| 101 | +static_assert(__is_same(Val<float, 0.5L>, Val<float, 0.5f>)); |
| 102 | +static_assert(__is_same(Val<float, 0.5L>, Val<float, 0.5f>)); |
| 103 | + |
| 104 | +static_assert(__is_same(Val<float, double{__FLT_DENORM_MIN__}>, Val<float, __FLT_DENORM_MIN__>)); |
| 105 | +Val<float, double{__FLT_DENORM_MIN__} / 2.0> _1; |
| 106 | +// since-cxx20-error-re@-1 {{non-type template argument evaluates to {{.+}} which cannot be exactly represented in type 'float'}} |
| 107 | +Val<float, static_cast<long double>(__FLT_DENORM_MIN__) / 2.0L> _2; |
| 108 | +// since-cxx20-error-re@-1 {{non-type template argument evaluates to {{.+}} which cannot be exactly represented in type 'float'}} |
| 109 | +Val<float, __DBL_MAX__> _3; |
| 110 | +// since-cxx20-error-re@-1 {{non-type template argument evaluates to {{.+}} which cannot be exactly represented in type 'float'}} |
| 111 | + |
| 112 | +static_assert(__is_same(Val<float, __builtin_infl()>, Val<float, __builtin_inff()>)); |
| 113 | + |
| 114 | +static_assert(__is_same(Val<float, __builtin_nanl("")>, Val<float, static_cast<float>(__builtin_nanl(""))>)); |
| 115 | +static_assert(__is_same(Val<float, __builtin_nansl("")>, Val<float, static_cast<float>(__builtin_nansl(""))>)); |
| 116 | +#if __SIZEOF_LONG_DOUBLE__ > 8 |
| 117 | +// since-cxx20-error@-2 {{non-type template argument evaluates to nan which cannot be exactly represented in type 'float'}} |
| 118 | +#endif |
| 119 | +// Payload is shifted right so these payloads will be preserved |
| 120 | +static_assert(__is_same(Val<float, __builtin_nan("0xFF00000000")>, Val<float, static_cast<float>(__builtin_nan("0xFF00000000"))>)); |
| 121 | +static_assert(__is_same(Val<float, __builtin_nans("0xFF00000000")>, Val<float, static_cast<float>(__builtin_nans("0xFF00000000"))>)); |
| 122 | +static_assert(__is_same(Val<float, __builtin_nanl("0x1")>, Val<float, static_cast<float>(__builtin_nanl("0x1"))>)); |
| 123 | +// since-cxx20-error@-1 {{non-type template argument evaluates to nan which cannot be exactly represented in type 'float'}} |
| 124 | +static_assert(__is_same(Val<float, __builtin_nansl("0x1")>, Val<float, static_cast<float>(__builtin_nansl("0x1"))>)); |
| 125 | +// since-cxx20-error@-1 {{non-type template argument evaluates to nan which cannot be exactly represented in type 'float'}} |
| 126 | +static_assert(__is_same(Val<float, __builtin_nanl("0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF")>, Val<float, static_cast<float>(__builtin_nanl("0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF"))>)); |
| 127 | +// since-cxx20-error@-1 {{non-type template argument evaluates to nan which cannot be exactly represented in type 'float'}} |
| 128 | +static_assert(__is_same(Val<float, __builtin_nansl("0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF")>, Val<float, static_cast<float>(__builtin_nansl("0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF"))>)); |
| 129 | +// since-cxx20-error@-1 {{non-type template argument evaluates to nan which cannot be exactly represented in type 'float'}} |
| 130 | +#endif |
| 131 | + |
| 132 | +} |
| 133 | + |
70 | 134 | namespace cwg2858 { // cwg2858: 19 tentatively ready 2024-04-05
|
71 | 135 |
|
72 | 136 | #if __cplusplus > 202302L
|
|
0 commit comments