1 // P1467R9 - Extended floating-point types and standard names.
2 // Variant of ext-floating2.C test with x86 specific assumptions
3 // about float, double, long double and existence of __float128.
4 // And some further tests.
5 // { dg-do compile { target { c++23 && { i?86-*-linux* x86_64-*-linux* } } } }
7 // { dg-add-options float16 }
9 #include "ext-floating.h"
11 #if !defined(__STDCPP_FLOAT32_T__) \
12 || !defined(__STDCPP_FLOAT64_T__) || !defined(__STDCPP_FLOAT128_T__) \
13 || __FLT_MAX_EXP__ != __FLT32_MAX_EXP__ || __FLT_MANT_DIG__ != __FLT32_MANT_DIG__ \
14 || __DBL_MAX_EXP__ != __FLT64_MAX_EXP__ || __DBL_MANT_DIG__ != __FLT64_MANT_DIG__ \
15 || __LDBL_MAX_EXP__ != __FLT128_MAX_EXP__ || __LDBL_MANT_DIG__ >= __FLT128_MANT_DIG__ \
16 || !defined(__SIZEOF_FLOAT128__)
17 #error Unexpected set of floating point types
22 #ifdef __STDCPP_FLOAT16_T__
23 float16_t f16i = 1.0f; // { dg-warning "converting to 'std::float16_t' \\\{aka '_Float16'\\\} from 'float' with greater conversion rank" "" { target float16 } }
24 float16_t f16k = 1.0; // { dg-warning "converting to 'std::float16_t' \\\{aka '_Float16'\\\} from 'double' with greater conversion rank" "" { target float16 } }
25 float16_t f16m = 1.0L; // { dg-warning "converting to 'std::float16_t' \\\{aka '_Float16'\\\} from 'long double' with greater conversion rank" "" { target float16 } }
26 float16_t f16o = 1.0Q; // { dg-warning "converting to 'std::float16_t' \\\{aka '_Float16'\\\} from '__float128' with greater conversion rank" "" { target float16 } }
28 float32_t f32i = 1.0f;
29 float32_t f32k = 1.0; // { dg-warning "converting to 'std::float32_t' \\\{aka '_Float32'\\\} from 'double' with greater conversion rank" }
30 float32_t f32m = 1.0L; // { dg-warning "converting to 'std::float32_t' \\\{aka '_Float32'\\\} from 'long double' with greater conversion rank" }
31 float32_t f32o = 1.0Q; // { dg-warning "converting to 'std::float32_t' \\\{aka '_Float32'\\\} from '__float128' with greater conversion rank" }
32 float64_t f64i = 1.0f;
34 float64_t f64m = 1.0L; // { dg-warning "converting to 'std::float64_t' \\\{aka '_Float64'\\\} from 'long double' with greater conversion rank" }
35 float64_t f64o = 1.0Q; // { dg-warning "converting to 'std::float64_t' \\\{aka '_Float64'\\\} from '__float128' with greater conversion rank" }
36 float128_t f128i = 1.0f;
37 float128_t f128k = 1.0;
38 float128_t f128m = 1.0L;
39 float128_t f128o = 1.0Q;
41 #ifdef __STDCPP_FLOAT16_T__
42 constexpr float16_t f16x = 1.0F16;
44 constexpr float32_t f32x = 2.0F32;
45 constexpr float64_t f64x = 3.0F64;
46 constexpr float128_t f128x = 4.0F128;
47 constexpr float fx = 5.0f;
48 constexpr double dx = 6.0;
49 constexpr long double ldx = 7.0L;
51 constexpr int foo (float32_t) { return 1; }
52 constexpr int foo (float64_t) { return 2; }
53 constexpr int bar (float) { return 3; }
54 constexpr int bar (double) { return 4; }
55 constexpr int bar (long double) { return 5; }
56 constexpr int baz (float32_t) { return 6; }
57 constexpr int baz (float64_t) { return 7; }
58 constexpr int baz (float128_t) { return 8; }
59 constexpr int qux (float64_t) { return 9; }
60 constexpr int qux (float32_t) { return 10; }
61 constexpr int fred (long double) { return 11; }
62 constexpr int fred (double) { return 12; }
63 constexpr int fred (float) { return 13; }
64 constexpr int thud (float128_t) { return 14; }
65 constexpr int thud (float64_t) { return 15; }
66 constexpr int thud (float32_t) { return 16; }
68 constexpr operator float32_t () const { return 1.0f32; }
69 constexpr operator float64_t () const { return 2.0f64; }
72 constexpr operator float64_t () const { return 3.0f64; }
73 constexpr operator float32_t () const { return 4.0f32; }
79 #ifdef __STDCPP_FLOAT16_T__
80 foo (float16_t (1.0)); // { dg-error "call of overloaded 'foo\\\(std::float16_t\\\)' is ambiguous" "" { target float16 } }
82 static_assert (foo (float (2.0)) == 1);
83 static_assert (foo (double (3.0)) == 2);
84 constexpr double x (s);
85 static_assert (x == 2.0);
86 #ifdef __STDCPP_FLOAT16_T__
87 bar (f16x); // { dg-error "call of overloaded 'bar\\\(const std::float16_t\\\&\\\)' is ambiguous" "" { target float16 } }
89 static_assert (bar (f32x) == 3);
90 static_assert (bar (f64x) == 4);
91 bar (f128x); // { dg-error "no matching function for call to 'bar\\\(const std::float128_t\\\&\\\)'" }
92 // { dg-warning "converting to 'float' from 'const std::float128_t' \\\{aka 'const _Float128'\\\} with greater conversion rank" "" { target *-*-* } .-1 }
93 // { dg-warning "converting to 'double' from 'const std::float128_t' \\\{aka 'const _Float128'\\\} with greater conversion rank" "" { target *-*-* } .-2 }
94 // { dg-warning "converting to 'long double' from 'const std::float128_t' \\\{aka 'const _Float128'\\\} with greater conversion rank" "" { target *-*-* } .-3 }
95 static_assert (bar (fx) == 3);
96 static_assert (bar (dx) == 4);
97 static_assert (bar (ldx) == 5);
98 #ifdef __STDCPP_FLOAT16_T__
99 baz (f16x); // { dg-error "call of overloaded 'baz\\\(const std::float16_t\\\&\\\)' is ambiguous" "" { target float16 } }
101 static_assert (baz (f32x) == 6);
102 static_assert (baz (f64x) == 7);
103 static_assert (baz (f128x) == 8);
104 static_assert (baz (fx) == 6);
105 static_assert (baz (dx) == 7);
106 static_assert (baz (ldx) == 8);
107 #ifdef __STDCPP_FLOAT16_T__
108 qux (float16_t (1.0)); // { dg-error "call of overloaded 'qux\\\(std::float16_t\\\)' is ambiguous" "" { target float16 } }
110 static_assert (qux (float (2.0)) == 10);
111 static_assert (qux (double (3.0)) == 9);
112 constexpr double y (t);
113 static_assert (y == 3.0);
114 #ifdef __STDCPP_FLOAT16_T__
115 fred (f16x); // { dg-error "call of overloaded 'fred\\\(const std::float16_t\\\&\\\)' is ambiguous" "" { target float16 } }
117 static_assert (fred (f32x) == 13);
118 static_assert (fred (f64x) == 12);
119 fred (f128x); // { dg-error "no matching function for call to 'fred\\\(const std::float128_t\\\&\\\)'" }
120 // { dg-warning "converting to 'float' from 'const std::float128_t' \\\{aka 'const _Float128'\\\} with greater conversion rank" "" { target *-*-* } .-1 }
121 // { dg-warning "converting to 'double' from 'const std::float128_t' \\\{aka 'const _Float128'\\\} with greater conversion rank" "" { target *-*-* } .-2 }
122 // { dg-warning "converting to 'long double' from 'const std::float128_t' \\\{aka 'const _Float128'\\\} with greater conversion rank" "" { target *-*-* } .-3 }
123 static_assert (fred (fx) == 13);
124 static_assert (fred (dx) == 12);
125 static_assert (fred (ldx) == 11);
126 #ifdef __STDCPP_FLOAT16_T__
127 thud (f16x); // { dg-error "call of overloaded 'thud\\\(const std::float16_t\\\&\\\)' is ambiguous" "" { target float16 } }
129 static_assert (thud (f32x) == 16);
130 static_assert (thud (f64x) == 15);
131 static_assert (thud (f128x) == 14);
132 static_assert (thud (fx) == 16);
133 static_assert (thud (dx) == 15);
134 static_assert (thud (ldx) == 14);