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

Reply via email to