@@ -432,6 +432,14 @@ NarrowingKind StandardConversionSequence::getNarrowingKind(
432
432
Converted.convert(Ctx.getFloatTypeSemantics(FromType),
433
433
llvm::APFloat::rmNearestTiesToEven, &ignored);
434
434
if (Ctx.getLangOpts().C23) {
435
+ if (FloatVal.isNaN() && Converted.isNaN()) {
436
+ if (!FloatVal.isSignaling() && !Converted.isSignaling()) {
437
+ // Quiet NaNs are considered the same value, regardless of
438
+ // payloads.
439
+ return NK_Not_Narrowing;
440
+ }
441
+ }
442
+ // For normal values, check exact equality.
435
443
if (!Converted.bitwiseIsEqual(FloatVal)) {
436
444
ConstantType = Initializer->getType();
437
445
return NK_Constant_Narrowing;
@@ -514,6 +522,25 @@ NarrowingKind StandardConversionSequence::getNarrowingKind(
514
522
return NK_Type_Narrowing;
515
523
return NK_Not_Narrowing;
516
524
525
+ case ICK_Floating_Promotion:
526
+ if (Ctx.getLangOpts().C23) {
527
+ const Expr *Initializer = IgnoreNarrowingConversion(Ctx, Converted);
528
+ Expr::EvalResult R;
529
+ if (Initializer->EvaluateAsRValue(R, Ctx)) {
530
+ ConstantValue = R.Val;
531
+ assert(ConstantValue.isFloat());
532
+ llvm::APFloat FloatVal = ConstantValue.getFloat();
533
+ // C23 6.7.3p6 If the initializer has real type and a signaling NaN
534
+ // value, the unqualified versions of the type of the initializer and
535
+ // the corresponding real type of the object declared shall be
536
+ // compatible.
537
+ if (FloatVal.isNaN() && FloatVal.isSignaling()) {
538
+ ConstantType = Initializer->getType();
539
+ return NK_Constant_Narrowing;
540
+ }
541
+ }
542
+ }
543
+ return NK_Not_Narrowing;
517
544
default:
518
545
// Other kinds of conversions are not narrowings.
519
546
return NK_Not_Narrowing;
0 commit comments