@@ -776,20 +776,11 @@ ExprResult Sema::CallExprUnaryConversions(Expr *E) {
776
776
return Res.get();
777
777
}
778
778
779
- /// UsualUnaryConversions - Performs various conversions that are common to most
780
- /// operators (C99 6.3). The conversions of array and function types are
781
- /// sometimes suppressed. For example, the array->pointer conversion doesn't
782
- /// apply if the array is an argument to the sizeof or address (&) operators.
783
- /// In these instances, this routine should *not* be called.
784
- ExprResult Sema::UsualUnaryConversions(Expr *E) {
785
- // First, convert to an r-value.
786
- ExprResult Res = DefaultFunctionArrayLvalueConversion(E);
787
- if (Res.isInvalid())
788
- return ExprError();
789
- E = Res.get();
790
-
779
+ /// UsualUnaryFPConversions - Promotes floating-point types according to the
780
+ /// current language semantics.
781
+ ExprResult Sema::UsualUnaryFPConversions(Expr *E) {
791
782
QualType Ty = E->getType();
792
- assert(!Ty.isNull() && "UsualUnaryConversions - missing type");
783
+ assert(!Ty.isNull() && "UsualUnaryFPConversions - missing type");
793
784
794
785
LangOptions::FPEvalMethodKind EvalMethod = CurFPFeatures.getFPEvalMethod();
795
786
if (EvalMethod != LangOptions::FEM_Source && Ty->isFloatingType() &&
@@ -827,7 +818,30 @@ ExprResult Sema::UsualUnaryConversions(Expr *E) {
827
818
828
819
// Half FP have to be promoted to float unless it is natively supported
829
820
if (Ty->isHalfType() && !getLangOpts().NativeHalfType)
830
- return ImpCastExprToType(Res.get(), Context.FloatTy, CK_FloatingCast);
821
+ return ImpCastExprToType(E, Context.FloatTy, CK_FloatingCast);
822
+
823
+ return E;
824
+ }
825
+
826
+ /// UsualUnaryConversions - Performs various conversions that are common to most
827
+ /// operators (C99 6.3). The conversions of array and function types are
828
+ /// sometimes suppressed. For example, the array->pointer conversion doesn't
829
+ /// apply if the array is an argument to the sizeof or address (&) operators.
830
+ /// In these instances, this routine should *not* be called.
831
+ ExprResult Sema::UsualUnaryConversions(Expr *E) {
832
+ // First, convert to an r-value.
833
+ ExprResult Res = DefaultFunctionArrayLvalueConversion(E);
834
+ if (Res.isInvalid())
835
+ return ExprError();
836
+
837
+ // Promote floating-point types.
838
+ Res = UsualUnaryFPConversions(Res.get());
839
+ if (Res.isInvalid())
840
+ return ExprError();
841
+ E = Res.get();
842
+
843
+ QualType Ty = E->getType();
844
+ assert(!Ty.isNull() && "UsualUnaryConversions - missing type");
831
845
832
846
// Try to perform integral promotions if the object has a theoretically
833
847
// promotable type.
@@ -1489,64 +1503,63 @@ static QualType handleFixedPointConversion(Sema &S, QualType LHSTy,
1489
1503
1490
1504
/// Check that the usual arithmetic conversions can be performed on this pair of
1491
1505
/// expressions that might be of enumeration type.
1492
- static void checkEnumArithmeticConversions(Sema &S, Expr *LHS, Expr *RHS,
1493
- SourceLocation Loc,
1494
- Sema::ArithConvKind ACK) {
1506
+ void Sema:: checkEnumArithmeticConversions(Expr *LHS, Expr *RHS,
1507
+ SourceLocation Loc,
1508
+ Sema::ArithConvKind ACK) {
1495
1509
// C++2a [expr.arith.conv]p1:
1496
1510
// If one operand is of enumeration type and the other operand is of a
1497
1511
// different enumeration type or a floating-point type, this behavior is
1498
1512
// deprecated ([depr.arith.conv.enum]).
1499
1513
//
1500
1514
// Warn on this in all language modes. Produce a deprecation warning in C++20.
1501
1515
// Eventually we will presumably reject these cases (in C++23 onwards?).
1502
- QualType L = LHS->getEnumCoercedType(S. Context),
1503
- R = RHS->getEnumCoercedType(S. Context);
1516
+ QualType L = LHS->getEnumCoercedType(Context),
1517
+ R = RHS->getEnumCoercedType(Context);
1504
1518
bool LEnum = L->isUnscopedEnumerationType(),
1505
1519
REnum = R->isUnscopedEnumerationType();
1506
1520
bool IsCompAssign = ACK == Sema::ACK_CompAssign;
1507
1521
if ((!IsCompAssign && LEnum && R->isFloatingType()) ||
1508
1522
(REnum && L->isFloatingType())) {
1509
- S.Diag(Loc, S.getLangOpts().CPlusPlus26
1510
- ? diag::err_arith_conv_enum_float_cxx26
1511
- : S.getLangOpts().CPlusPlus20
1512
- ? diag::warn_arith_conv_enum_float_cxx20
1513
- : diag::warn_arith_conv_enum_float)
1523
+ Diag(Loc, getLangOpts().CPlusPlus26 ? diag::err_arith_conv_enum_float_cxx26
1524
+ : getLangOpts().CPlusPlus20
1525
+ ? diag::warn_arith_conv_enum_float_cxx20
1526
+ : diag::warn_arith_conv_enum_float)
1514
1527
<< LHS->getSourceRange() << RHS->getSourceRange() << (int)ACK << LEnum
1515
1528
<< L << R;
1516
1529
} else if (!IsCompAssign && LEnum && REnum &&
1517
- !S. Context.hasSameUnqualifiedType(L, R)) {
1530
+ !Context.hasSameUnqualifiedType(L, R)) {
1518
1531
unsigned DiagID;
1519
1532
// In C++ 26, usual arithmetic conversions between 2 different enum types
1520
1533
// are ill-formed.
1521
- if (S. getLangOpts().CPlusPlus26)
1534
+ if (getLangOpts().CPlusPlus26)
1522
1535
DiagID = diag::err_conv_mixed_enum_types_cxx26;
1523
1536
else if (!L->castAs<EnumType>()->getDecl()->hasNameForLinkage() ||
1524
1537
!R->castAs<EnumType>()->getDecl()->hasNameForLinkage()) {
1525
1538
// If either enumeration type is unnamed, it's less likely that the
1526
1539
// user cares about this, but this situation is still deprecated in
1527
1540
// C++2a. Use a different warning group.
1528
- DiagID = S. getLangOpts().CPlusPlus20
1529
- ? diag::warn_arith_conv_mixed_anon_enum_types_cxx20
1530
- : diag::warn_arith_conv_mixed_anon_enum_types;
1541
+ DiagID = getLangOpts().CPlusPlus20
1542
+ ? diag::warn_arith_conv_mixed_anon_enum_types_cxx20
1543
+ : diag::warn_arith_conv_mixed_anon_enum_types;
1531
1544
} else if (ACK == Sema::ACK_Conditional) {
1532
1545
// Conditional expressions are separated out because they have
1533
1546
// historically had a different warning flag.
1534
- DiagID = S. getLangOpts().CPlusPlus20
1547
+ DiagID = getLangOpts().CPlusPlus20
1535
1548
? diag::warn_conditional_mixed_enum_types_cxx20
1536
1549
: diag::warn_conditional_mixed_enum_types;
1537
1550
} else if (ACK == Sema::ACK_Comparison) {
1538
1551
// Comparison expressions are separated out because they have
1539
1552
// historically had a different warning flag.
1540
- DiagID = S. getLangOpts().CPlusPlus20
1553
+ DiagID = getLangOpts().CPlusPlus20
1541
1554
? diag::warn_comparison_mixed_enum_types_cxx20
1542
1555
: diag::warn_comparison_mixed_enum_types;
1543
1556
} else {
1544
- DiagID = S. getLangOpts().CPlusPlus20
1557
+ DiagID = getLangOpts().CPlusPlus20
1545
1558
? diag::warn_arith_conv_mixed_enum_types_cxx20
1546
1559
: diag::warn_arith_conv_mixed_enum_types;
1547
1560
}
1548
- S. Diag(Loc, DiagID) << LHS->getSourceRange() << RHS->getSourceRange()
1549
- << (int)ACK << L << R;
1561
+ Diag(Loc, DiagID) << LHS->getSourceRange() << RHS->getSourceRange()
1562
+ << (int)ACK << L << R;
1550
1563
}
1551
1564
}
1552
1565
@@ -1557,7 +1570,7 @@ static void checkEnumArithmeticConversions(Sema &S, Expr *LHS, Expr *RHS,
1557
1570
QualType Sema::UsualArithmeticConversions(ExprResult &LHS, ExprResult &RHS,
1558
1571
SourceLocation Loc,
1559
1572
ArithConvKind ACK) {
1560
- checkEnumArithmeticConversions(*this, LHS.get(), RHS.get(), Loc, ACK);
1573
+ checkEnumArithmeticConversions(LHS.get(), RHS.get(), Loc, ACK);
1561
1574
1562
1575
if (ACK != ACK_CompAssign) {
1563
1576
LHS = UsualUnaryConversions(LHS.get());
0 commit comments