qiucf added a comment. In D109751#3168982 <https://reviews.llvm.org/D109751#3168982>, @hubert.reinterpretcast wrote:
> In D109751#3136543 <https://reviews.llvm.org/D109751#3136543>, @qiucf wrote: > >> Because the piece of code will be expanded to: >> >> long double _Complex x; >> >> if ((__builtin_types_compatible_p(__typeof(creall(x)), _Float128) >> ? __isinff128(creall(x)) >> : __builtin_isinf_sign(creall(x))) || >> (__builtin_types_compatible_p(__typeof(cimagl(x)), _Float128) >> ? __isinff128(cimagl(x)) >> : __builtin_isinf_sign(cimagl(x)))) >> return inf; >> >> which requires 'long double' (the same semantics to `__ibm128` by default) >> and '_Float128' are compatible. > > Noting that the way the types are implemented in Clang, the conversion isn't > the first problem with the above code. The types with the same representation > are not considered "compatible" by Clang: > > extern char x[__builtin_types_compatible_p(long double, __ibm128) ? 1 : > -1]; // errors > extern char x[__builtin_types_compatible_p(long double, __ieee128) ? 1 : > -1]; // errors too > > Compiler Explorer link: https://godbolt.org/z/fP3MfdexM Thanks for the reminder. Here GCC and Clang diverges in the handling of `__ibm128`/`__float128` and `long double`. Not sure whether GCC will 'fix' the behavior, but here (and in most of the use case in glibc headers) it's `__builtin_types_compatible_p(..., _Float128)` where GCC/Clang behaves the same. ================ Comment at: clang/test/Sema/float128-ld-incompatibility.cpp:13 +long double ld{qf()}; // expected-error {{non-constant-expression cannot be narrowed from type '__float128' to 'long double' in initializer list}} expected-note {{insert an explicit cast to silence this issue}} +__float128 q{ldf()}; // expected-no-error ---------------- hubert.reinterpretcast wrote: > hubert.reinterpretcast wrote: > > hubert.reinterpretcast wrote: > > > Should also test `__ibm128` cases. > > The C++ committee has advised that this implicit conversion should be > > considered ill-formed (see other comment). > > > > Note that the //allowed// implicit conversion from `__ibm128` to `long > > double` (and vice versa) is still a conversion, which means that overload > > resolution is still a problem: > > ``` > > void f(__ibm128); > > void f(int); > > void g(long double d) { return f(d); } // okay with GCC but not Clang; > > https://godbolt.org/z/fonsEbbY1 > > ``` > Even if the implicit conversion is to be allowed, there is not much reason > why this is not considered narrowing (given the revised definition of > narrowing conversions). > > GCC's behaviour around the narrowing check has limited value as a reference > point: Which of `__float128` or `__ibm128` is considered by GCC on Power to > be the "wider type" depends on the `-mabi` option. That is, the behaviour is > not consistent with there being a principled decision made by the GCC > developers as to which representation format is "wider". Thanks for the information. The behavior of GCC looks somewhat reasonable but I notice the naming convention of support functions is interesting: `__ibm128` to `__float128` is 'extend', `__float128` to `__ibm128` 'truncate'. Repository: rG LLVM Github Monorepo CHANGES SINCE LAST ACTION https://reviews.llvm.org/D109751/new/ https://reviews.llvm.org/D109751 _______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits