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