@@ -1088,7 +1088,7 @@ static bool handleIntegerToComplexFloatConversion(Sema &S, ExprResult &IntExpr,
1088
1088
if (IntTy->isComplexType() || IntTy->isRealFloatingType()) return true;
1089
1089
if (SkipCast) return false;
1090
1090
if (IntTy->isIntegerType()) {
1091
- QualType fpTy = ComplexTy->castAs <ComplexType>()->getElementType();
1091
+ QualType fpTy = cast <ComplexType>(ComplexTy )->getElementType();
1092
1092
IntExpr = S.ImpCastExprToType(IntExpr.get(), fpTy, CK_IntegralToFloating);
1093
1093
IntExpr = S.ImpCastExprToType(IntExpr.get(), ComplexTy,
1094
1094
CK_FloatingRealToComplex);
@@ -1100,59 +1100,60 @@ static bool handleIntegerToComplexFloatConversion(Sema &S, ExprResult &IntExpr,
1100
1100
return false;
1101
1101
}
1102
1102
1103
- // This handles complex/complex, complex/float, or float/complex.
1104
- // When both operands are complex, the shorter operand is converted to the
1105
- // type of the longer, and that is the type of the result. This corresponds
1106
- // to what is done when combining two real floating-point operands.
1107
- // The fun begins when size promotion occur across type domains.
1108
- // From H&S 6.3.4: When one operand is complex and the other is a real
1109
- // floating-point type, the less precise type is converted, within it's
1110
- // real or complex domain, to the precision of the other type. For example,
1111
- // when combining a "long double" with a "double _Complex", the
1112
- // "double _Complex" is promoted to "long double _Complex".
1113
- static QualType handleComplexFloatConversion(Sema &S, ExprResult &Shorter,
1114
- QualType ShorterType,
1115
- QualType LongerType,
1116
- bool PromotePrecision) {
1117
- bool LongerIsComplex = isa<ComplexType>(LongerType.getCanonicalType());
1118
- QualType Result =
1119
- LongerIsComplex ? LongerType : S.Context.getComplexType(LongerType);
1120
-
1121
- if (PromotePrecision) {
1122
- if (isa<ComplexType>(ShorterType.getCanonicalType())) {
1123
- Shorter =
1124
- S.ImpCastExprToType(Shorter.get(), Result, CK_FloatingComplexCast);
1125
- } else {
1126
- if (LongerIsComplex)
1127
- LongerType = LongerType->castAs<ComplexType>()->getElementType();
1128
- Shorter = S.ImpCastExprToType(Shorter.get(), LongerType, CK_FloatingCast);
1129
- }
1130
- }
1131
- return Result;
1132
- }
1133
-
1134
1103
/// Handle arithmetic conversion with complex types. Helper function of
1135
1104
/// UsualArithmeticConversions()
1136
- static QualType handleComplexConversion(Sema &S, ExprResult &LHS,
1137
- ExprResult &RHS, QualType LHSType,
1138
- QualType RHSType, bool IsCompAssign) {
1105
+ static QualType handleComplexFloatConversion(Sema &S, ExprResult &LHS,
1106
+ ExprResult &RHS, QualType LHSType,
1107
+ QualType RHSType,
1108
+ bool IsCompAssign) {
1139
1109
// if we have an integer operand, the result is the complex type.
1140
1110
if (!handleIntegerToComplexFloatConversion(S, RHS, LHS, RHSType, LHSType,
1141
- /*SkipCast= */false))
1111
+ /*skipCast */false))
1142
1112
return LHSType;
1143
1113
if (!handleIntegerToComplexFloatConversion(S, LHS, RHS, LHSType, RHSType,
1144
- /*SkipCast= */IsCompAssign))
1114
+ /*skipCast */IsCompAssign))
1145
1115
return RHSType;
1146
1116
1117
+ // This handles complex/complex, complex/float, or float/complex.
1118
+ // When both operands are complex, the shorter operand is converted to the
1119
+ // type of the longer, and that is the type of the result. This corresponds
1120
+ // to what is done when combining two real floating-point operands.
1121
+ // The fun begins when size promotion occur across type domains.
1122
+ // From H&S 6.3.4: When one operand is complex and the other is a real
1123
+ // floating-point type, the less precise type is converted, within it's
1124
+ // real or complex domain, to the precision of the other type. For example,
1125
+ // when combining a "long double" with a "double _Complex", the
1126
+ // "double _Complex" is promoted to "long double _Complex".
1127
+
1147
1128
// Compute the rank of the two types, regardless of whether they are complex.
1148
1129
int Order = S.Context.getFloatingTypeOrder(LHSType, RHSType);
1149
- if (Order < 0)
1130
+
1131
+ auto *LHSComplexType = dyn_cast<ComplexType>(LHSType);
1132
+ auto *RHSComplexType = dyn_cast<ComplexType>(RHSType);
1133
+ QualType LHSElementType =
1134
+ LHSComplexType ? LHSComplexType->getElementType() : LHSType;
1135
+ QualType RHSElementType =
1136
+ RHSComplexType ? RHSComplexType->getElementType() : RHSType;
1137
+
1138
+ QualType ResultType = S.Context.getComplexType(LHSElementType);
1139
+ if (Order < 0) {
1150
1140
// Promote the precision of the LHS if not an assignment.
1151
- return handleComplexFloatConversion(S, LHS, LHSType, RHSType,
1152
- /*PromotePrecision=*/!IsCompAssign);
1153
- // Promote the precision of the RHS unless it is already the same as the LHS.
1154
- return handleComplexFloatConversion(S, RHS, RHSType, LHSType,
1155
- /*PromotePrecision=*/Order > 0);
1141
+ ResultType = S.Context.getComplexType(RHSElementType);
1142
+ if (!IsCompAssign) {
1143
+ if (LHSComplexType)
1144
+ LHS =
1145
+ S.ImpCastExprToType(LHS.get(), ResultType, CK_FloatingComplexCast);
1146
+ else
1147
+ LHS = S.ImpCastExprToType(LHS.get(), RHSElementType, CK_FloatingCast);
1148
+ }
1149
+ } else if (Order > 0) {
1150
+ // Promote the precision of the RHS.
1151
+ if (RHSComplexType)
1152
+ RHS = S.ImpCastExprToType(RHS.get(), ResultType, CK_FloatingComplexCast);
1153
+ else
1154
+ RHS = S.ImpCastExprToType(RHS.get(), LHSElementType, CK_FloatingCast);
1155
+ }
1156
+ return ResultType;
1156
1157
}
1157
1158
1158
1159
/// Handle arithmetic conversion from integer to float. Helper function
@@ -1538,16 +1539,18 @@ QualType Sema::UsualArithmeticConversions(ExprResult &LHS, ExprResult &RHS,
1538
1539
1539
1540
// For conversion purposes, we ignore any qualifiers.
1540
1541
// For example, "const float" and "float" are equivalent.
1541
- QualType LHSType = LHS.get()->getType().getUnqualifiedType();
1542
- QualType RHSType = RHS.get()->getType().getUnqualifiedType();
1542
+ QualType LHSType =
1543
+ Context.getCanonicalType(LHS.get()->getType()).getUnqualifiedType();
1544
+ QualType RHSType =
1545
+ Context.getCanonicalType(RHS.get()->getType()).getUnqualifiedType();
1543
1546
1544
1547
// For conversion purposes, we ignore any atomic qualifier on the LHS.
1545
1548
if (const AtomicType *AtomicLHS = LHSType->getAs<AtomicType>())
1546
1549
LHSType = AtomicLHS->getValueType();
1547
1550
1548
1551
// If both types are identical, no conversion is needed.
1549
- if (Context.hasSameType( LHSType, RHSType) )
1550
- return Context.getCommonSugaredType( LHSType, RHSType) ;
1552
+ if (LHSType == RHSType)
1553
+ return LHSType;
1551
1554
1552
1555
// If either side is a non-arithmetic type (e.g. a pointer), we are done.
1553
1556
// The caller can deal with this (e.g. pointer + int).
@@ -1565,8 +1568,8 @@ QualType Sema::UsualArithmeticConversions(ExprResult &LHS, ExprResult &RHS,
1565
1568
LHS = ImpCastExprToType(LHS.get(), LHSType, CK_IntegralCast);
1566
1569
1567
1570
// If both types are identical, no conversion is needed.
1568
- if (Context.hasSameType( LHSType, RHSType) )
1569
- return Context.getCommonSugaredType( LHSType, RHSType) ;
1571
+ if (LHSType == RHSType)
1572
+ return LHSType;
1570
1573
1571
1574
// At this point, we have two different arithmetic types.
1572
1575
@@ -1577,8 +1580,8 @@ QualType Sema::UsualArithmeticConversions(ExprResult &LHS, ExprResult &RHS,
1577
1580
1578
1581
// Handle complex types first (C99 6.3.1.8p1).
1579
1582
if (LHSType->isComplexType() || RHSType->isComplexType())
1580
- return handleComplexConversion (*this, LHS, RHS, LHSType, RHSType,
1581
- ACK == ACK_CompAssign);
1583
+ return handleComplexFloatConversion (*this, LHS, RHS, LHSType, RHSType,
1584
+ ACK == ACK_CompAssign);
1582
1585
1583
1586
// Now handle "real" floating types (i.e. float, double, long double).
1584
1587
if (LHSType->isRealFloatingType() || RHSType->isRealFloatingType())
@@ -8155,6 +8158,23 @@ static bool checkCondition(Sema &S, Expr *Cond, SourceLocation QuestionLoc) {
8155
8158
return true;
8156
8159
}
8157
8160
8161
+ /// Handle when one or both operands are void type.
8162
+ static QualType checkConditionalVoidType(Sema &S, ExprResult &LHS,
8163
+ ExprResult &RHS) {
8164
+ Expr *LHSExpr = LHS.get();
8165
+ Expr *RHSExpr = RHS.get();
8166
+
8167
+ if (!LHSExpr->getType()->isVoidType())
8168
+ S.Diag(RHSExpr->getBeginLoc(), diag::ext_typecheck_cond_one_void)
8169
+ << RHSExpr->getSourceRange();
8170
+ if (!RHSExpr->getType()->isVoidType())
8171
+ S.Diag(LHSExpr->getBeginLoc(), diag::ext_typecheck_cond_one_void)
8172
+ << LHSExpr->getSourceRange();
8173
+ LHS = S.ImpCastExprToType(LHS.get(), S.Context.VoidTy, CK_ToVoid);
8174
+ RHS = S.ImpCastExprToType(RHS.get(), S.Context.VoidTy, CK_ToVoid);
8175
+ return S.Context.VoidTy;
8176
+ }
8177
+
8158
8178
/// Return false if the NullExpr can be promoted to PointerTy,
8159
8179
/// true otherwise.
8160
8180
static bool checkConditionalNullPointer(Sema &S, ExprResult &NullExpr,
@@ -8178,7 +8198,7 @@ static QualType checkConditionalPointerCompatibility(Sema &S, ExprResult &LHS,
8178
8198
8179
8199
if (S.Context.hasSameType(LHSTy, RHSTy)) {
8180
8200
// Two identical pointers types are always compatible.
8181
- return S.Context.getCommonSugaredType( LHSTy, RHSTy) ;
8201
+ return LHSTy;
8182
8202
}
8183
8203
8184
8204
QualType lhptee, rhptee;
@@ -8680,7 +8700,7 @@ QualType Sema::CheckConditionalOperands(ExprResult &Cond, ExprResult &LHS,
8680
8700
8681
8701
// And if they're both bfloat (which isn't arithmetic), that's fine too.
8682
8702
if (LHSTy->isBFloat16Type() && RHSTy->isBFloat16Type()) {
8683
- return Context.getCommonSugaredType( LHSTy, RHSTy) ;
8703
+ return LHSTy;
8684
8704
}
8685
8705
8686
8706
// If both operands are the same structure or union type, the result is that
@@ -8690,29 +8710,14 @@ QualType Sema::CheckConditionalOperands(ExprResult &Cond, ExprResult &LHS,
8690
8710
if (LHSRT->getDecl() == RHSRT->getDecl())
8691
8711
// "If both the operands have structure or union type, the result has
8692
8712
// that type." This implies that CV qualifiers are dropped.
8693
- return Context.getCommonSugaredType(LHSTy.getUnqualifiedType(),
8694
- RHSTy.getUnqualifiedType());
8713
+ return LHSTy.getUnqualifiedType();
8695
8714
// FIXME: Type of conditional expression must be complete in C mode.
8696
8715
}
8697
8716
8698
8717
// C99 6.5.15p5: "If both operands have void type, the result has void type."
8699
8718
// The following || allows only one side to be void (a GCC-ism).
8700
8719
if (LHSTy->isVoidType() || RHSTy->isVoidType()) {
8701
- QualType ResTy;
8702
- if (LHSTy->isVoidType() && RHSTy->isVoidType()) {
8703
- ResTy = Context.getCommonSugaredType(LHSTy, RHSTy);
8704
- } else if (RHSTy->isVoidType()) {
8705
- ResTy = RHSTy;
8706
- Diag(RHS.get()->getBeginLoc(), diag::ext_typecheck_cond_one_void)
8707
- << RHS.get()->getSourceRange();
8708
- } else {
8709
- ResTy = LHSTy;
8710
- Diag(LHS.get()->getBeginLoc(), diag::ext_typecheck_cond_one_void)
8711
- << LHS.get()->getSourceRange();
8712
- }
8713
- LHS = ImpCastExprToType(LHS.get(), ResTy, CK_ToVoid);
8714
- RHS = ImpCastExprToType(RHS.get(), ResTy, CK_ToVoid);
8715
- return ResTy;
8720
+ return checkConditionalVoidType(*this, LHS, RHS);
8716
8721
}
8717
8722
8718
8723
// C99 6.5.15p6 - "if one operand is a null pointer constant, the result has
@@ -8751,7 +8756,7 @@ QualType Sema::CheckConditionalOperands(ExprResult &Cond, ExprResult &LHS,
8751
8756
// Allow ?: operations in which both operands have the same
8752
8757
// built-in sizeless type.
8753
8758
if (LHSTy->isSizelessBuiltinType() && Context.hasSameType(LHSTy, RHSTy))
8754
- return Context.getCommonSugaredType( LHSTy, RHSTy) ;
8759
+ return LHSTy;
8755
8760
8756
8761
// Emit a better diagnostic if one of the expressions is a null pointer
8757
8762
// constant and the other is not a pointer type. In this case, the user most
@@ -10422,7 +10427,7 @@ QualType Sema::CheckVectorOperands(ExprResult &LHS, ExprResult &RHS,
10422
10427
10423
10428
// If the vector types are identical, return.
10424
10429
if (Context.hasSameType(LHSType, RHSType))
10425
- return Context.getCommonSugaredType( LHSType, RHSType) ;
10430
+ return LHSType;
10426
10431
10427
10432
// If we have compatible AltiVec and GCC vector types, use the AltiVec type.
10428
10433
if (LHSVecType && RHSVecType &&
@@ -13140,7 +13145,7 @@ QualType Sema::CheckMatrixElementwiseOperands(ExprResult &LHS, ExprResult &RHS,
13140
13145
assert((LHSMatType || RHSMatType) && "At least one operand must be a matrix");
13141
13146
13142
13147
if (Context.hasSameType(LHSType, RHSType))
13143
- return Context.getCommonSugaredType( LHSType, RHSType) ;
13148
+ return LHSType;
13144
13149
13145
13150
// Type conversion may change LHS/RHS. Keep copies to the original results, in
13146
13151
// case we have to return InvalidOperands.
@@ -13184,19 +13189,13 @@ QualType Sema::CheckMatrixMultiplyOperands(ExprResult &LHS, ExprResult &RHS,
13184
13189
if (LHSMatType->getNumColumns() != RHSMatType->getNumRows())
13185
13190
return InvalidOperands(Loc, LHS, RHS);
13186
13191
13187
- if (Context.hasSameType(LHSMatType, RHSMatType))
13188
- return Context.getCommonSugaredType(
13189
- LHS.get()->getType().getUnqualifiedType(),
13190
- RHS.get()->getType().getUnqualifiedType());
13191
-
13192
- QualType LHSELTy = LHSMatType->getElementType(),
13193
- RHSELTy = RHSMatType->getElementType();
13194
- if (!Context.hasSameType(LHSELTy, RHSELTy))
13192
+ if (!Context.hasSameType(LHSMatType->getElementType(),
13193
+ RHSMatType->getElementType()))
13195
13194
return InvalidOperands(Loc, LHS, RHS);
13196
13195
13197
- return Context.getConstantMatrixType(
13198
- Context.getCommonSugaredType(LHSELTy, RHSELTy ),
13199
- LHSMatType->getNumRows(), RHSMatType->getNumColumns());
13196
+ return Context.getConstantMatrixType(LHSMatType->getElementType(),
13197
+ LHSMatType->getNumRows( ),
13198
+ RHSMatType->getNumColumns());
13200
13199
}
13201
13200
return CheckMatrixElementwiseOperands(LHS, RHS, Loc, IsCompAssign);
13202
13201
}
0 commit comments