// P1467R9 - Extended floating-point types and standard names. // Variant of ext-floating3.C test with different specific assumptions // about float, double, long double. // float, double and long double are assumed to be IEEE 754 single, double // and quad. // { dg-do compile { target { c++23 && { aarch64*-*-* powerpc64le*-*-linux* riscv*-*-* s390*-*-* sparc*-*-linux* } } } } // { dg-options "" } // { dg-additional-options "-mlong-double-128" { target s390*-*-* sparc*-*-linux* } } // { dg-additional-options "-mvsx -mfloat128 -mlong-double-128 -mabi=ieeelongdouble -Wno-psabi" { target powerpc64le*-*-linux* } } #include "ext-floating.h" #if !defined(__STDCPP_FLOAT32_T__) \ || !defined(__STDCPP_FLOAT64_T__) || !defined(__STDCPP_FLOAT128_T__) \ || __FLT_MAX_EXP__ != __FLT32_MAX_EXP__ || __FLT_MANT_DIG__ != __FLT32_MANT_DIG__ \ || __DBL_MAX_EXP__ != __FLT64_MAX_EXP__ || __DBL_MANT_DIG__ != __FLT64_MANT_DIG__ \ || __LDBL_MAX_EXP__ != __FLT128_MAX_EXP__ || __LDBL_MANT_DIG__ != __FLT128_MANT_DIG__ #error Unexpected set of floating point types #endif using namespace std; #ifdef __STDCPP_FLOAT16_T__ float16_t f16i = 1.0f; // { dg-warning "converting to 'std::float16_t' \\\{aka '_Float16'\\\} from 'float' with greater conversion rank" "" { target float16 } } float16_t f16k = 1.0; // { dg-warning "converting to 'std::float16_t' \\\{aka '_Float16'\\\} from 'double' with greater conversion rank" "" { target float16 } } float16_t f16m = 1.0L; // { dg-warning "converting to 'std::float16_t' \\\{aka '_Float16'\\\} from 'long double' with greater conversion rank" "" { target float16 } } #endif float32_t f32i = 1.0f; float32_t f32k = 1.0; // { dg-warning "converting to 'std::float32_t' \\\{aka '_Float32'\\\} from 'double' with greater conversion rank" } float32_t f32m = 1.0L; // { dg-warning "converting to 'std::float32_t' \\\{aka '_Float32'\\\} from 'long double' with greater conversion rank" } float64_t f64i = 1.0f; float64_t f64k = 1.0; float64_t f64m = 1.0L; // { dg-warning "converting to 'std::float64_t' \\\{aka '_Float64'\\\} from 'long double' with greater conversion rank" } float128_t f128i = 1.0f; float128_t f128k = 1.0; float128_t f128m = 1.0L; #ifdef __STDCPP_FLOAT16_T__ constexpr float16_t f16x = 1.0F16; #endif constexpr float32_t f32x = 2.0F32; constexpr float64_t f64x = 3.0F64; constexpr float128_t f128x = 4.0F128; constexpr float fx = 5.0f; constexpr double dx = 6.0; constexpr long double ldx = 7.0L; constexpr int foo (float32_t) { return 1; } constexpr int foo (float64_t) { return 2; } constexpr int bar (float) { return 3; } constexpr int bar (double) { return 4; } constexpr int bar (long double) { return 5; } constexpr int baz (float32_t) { return 6; } constexpr int baz (float64_t) { return 7; } constexpr int baz (float128_t) { return 8; } constexpr int qux (float64_t) { return 9; } constexpr int qux (float32_t) { return 10; } constexpr int fred (long double) { return 11; } constexpr int fred (double) { return 12; } constexpr int fred (float) { return 13; } constexpr int thud (float128_t) { return 14; } constexpr int thud (float64_t) { return 15; } constexpr int thud (float32_t) { return 16; } struct S { constexpr operator float32_t () const { return 1.0f32; } constexpr operator float64_t () const { return 2.0f64; } }; struct T { constexpr operator float64_t () const { return 3.0f64; } constexpr operator float32_t () const { return 4.0f32; } }; void test (S s, T t) { #ifdef __STDCPP_FLOAT16_T__ foo (float16_t (1.0)); // { dg-error "call of overloaded 'foo\\\(std::float16_t\\\)' is ambiguous" "" { target float16 } } #endif static_assert (foo (float (2.0)) == 1); static_assert (foo (double (3.0)) == 2); constexpr double x (s); static_assert (x == 2.0); #ifdef __STDCPP_FLOAT16_T__ bar (f16x); // { dg-error "call of overloaded 'bar\\\(const std::float16_t\\\&\\\)' is ambiguous" "" { target float16 } } #endif static_assert (bar (f32x) == 3); static_assert (bar (f64x) == 4); static_assert (bar (f128x) == 5); static_assert (bar (fx) == 3); static_assert (bar (dx) == 4); static_assert (bar (ldx) == 5); #ifdef __STDCPP_FLOAT16_T__ baz (f16x); // { dg-error "call of overloaded 'baz\\\(const std::float16_t\\\&\\\)' is ambiguous" "" { target float16 } } #endif static_assert (baz (f32x) == 6); static_assert (baz (f64x) == 7); static_assert (baz (f128x) == 8); static_assert (baz (fx) == 6); static_assert (baz (dx) == 7); static_assert (baz (ldx) == 8); #ifdef __STDCPP_FLOAT16_T__ qux (float16_t (1.0)); // { dg-error "call of overloaded 'qux\\\(std::float16_t\\\)' is ambiguous" "" { target float16 } } #endif static_assert (qux (float (2.0)) == 10); static_assert (qux (double (3.0)) == 9); constexpr double y (t); static_assert (y == 3.0); #ifdef __STDCPP_FLOAT16_T__ fred (f16x); // { dg-error "call of overloaded 'fred\\\(const std::float16_t\\\&\\\)' is ambiguous" "" { target float16 } } #endif static_assert (fred (f32x) == 13); static_assert (fred (f64x) == 12); static_assert (fred (f128x) == 11); static_assert (fred (fx) == 13); static_assert (fred (dx) == 12); static_assert (fred (ldx) == 11); #ifdef __STDCPP_FLOAT16_T__ thud (f16x); // { dg-error "call of overloaded 'thud\\\(const std::float16_t\\\&\\\)' is ambiguous" "" { target float16 } } #endif static_assert (thud (f32x) == 16); static_assert (thud (f64x) == 15); static_assert (thud (f128x) == 14); static_assert (thud (fx) == 16); static_assert (thud (dx) == 15); static_assert (thud (ldx) == 14); }