@@ -10591,6 +10591,45 @@ static void checkArithmeticNull(Sema &S, ExprResult &LHS, ExprResult &RHS,
1059110591 << LHS.get()->getSourceRange() << RHS.get()->getSourceRange();
1059210592}
1059310593
10594+ static void DetectPrecisionLossInComplexDivision(Sema &S, QualType DivisorTy,
10595+ SourceLocation OpLoc) {
10596+ // Either real/real or complex/real division.
10597+ // Either way there can be no precision loss.
10598+ auto *CT = DivisorTy->getAs<ComplexType>();
10599+ if (!CT)
10600+ return;
10601+
10602+ QualType ElementType = CT->getElementType();
10603+ bool IsComplexRangePromoted = S.getLangOpts().getComplexRange() ==
10604+ LangOptions::ComplexRangeKind::CX_Promoted;
10605+ if (!ElementType->isFloatingType() || !IsComplexRangePromoted)
10606+ return;
10607+
10608+ ASTContext &Ctx = S.getASTContext();
10609+ QualType HigherElementType = Ctx.GetHigherPrecisionFPType(ElementType);
10610+ const llvm::fltSemantics &ElementTypeSemantics =
10611+ Ctx.getFloatTypeSemantics(ElementType);
10612+ const llvm::fltSemantics &HigherElementTypeSemantics =
10613+ Ctx.getFloatTypeSemantics(HigherElementType);
10614+
10615+ if ((llvm::APFloat::semanticsMaxExponent(ElementTypeSemantics) * 2 + 1 >
10616+ llvm::APFloat::semanticsMaxExponent(HigherElementTypeSemantics)) ||
10617+ (HigherElementType == Ctx.LongDoubleTy &&
10618+ !Ctx.getTargetInfo().hasLongDoubleType())) {
10619+ // Retain the location of the first use of higher precision type.
10620+ if (!S.LocationOfExcessPrecisionNotSatisfied.isValid())
10621+ S.LocationOfExcessPrecisionNotSatisfied = OpLoc;
10622+ for (auto &[Type, Num] : S.ExcessPrecisionNotSatisfied) {
10623+ if (Type == HigherElementType) {
10624+ Num++;
10625+ return;
10626+ }
10627+ }
10628+ S.ExcessPrecisionNotSatisfied.push_back(std::make_pair(
10629+ HigherElementType, S.ExcessPrecisionNotSatisfied.size()));
10630+ }
10631+ }
10632+
1059410633static void DiagnoseDivisionSizeofPointerOrArray(Sema &S, Expr *LHS, Expr *RHS,
1059510634 SourceLocation Loc) {
1059610635 const auto *LUE = dyn_cast<UnaryExprOrTypeTraitExpr>(LHS);
@@ -10685,6 +10724,7 @@ QualType Sema::CheckMultiplyDivideOperands(ExprResult &LHS, ExprResult &RHS,
1068510724 if (compType.isNull() || !compType->isArithmeticType())
1068610725 return InvalidOperands(Loc, LHS, RHS);
1068710726 if (IsDiv) {
10727+ DetectPrecisionLossInComplexDivision(*this, RHS.get()->getType(), Loc);
1068810728 DiagnoseBadDivideOrRemainderValues(*this, LHS, RHS, Loc, IsDiv);
1068910729 DiagnoseDivisionSizeofPointerOrArray(*this, LHS.get(), RHS.get(), Loc);
1069010730 }
@@ -15314,39 +15354,6 @@ static void DiagnoseBinOpPrecedence(Sema &Self, BinaryOperatorKind Opc,
1531415354 DiagnoseShiftCompare(Self, OpLoc, LHSExpr, RHSExpr);
1531515355}
1531615356
15317- static void DetectPrecisionLossInComplexDivision(Sema &S, SourceLocation OpLoc,
15318- Expr *Operand) {
15319- if (auto *CT = Operand->getType()->getAs<ComplexType>()) {
15320- QualType ElementType = CT->getElementType();
15321- bool IsComplexRangePromoted = S.getLangOpts().getComplexRange() ==
15322- LangOptions::ComplexRangeKind::CX_Promoted;
15323- if (ElementType->isFloatingType() && IsComplexRangePromoted) {
15324- ASTContext &Ctx = S.getASTContext();
15325- QualType HigherElementType = Ctx.GetHigherPrecisionFPType(ElementType);
15326- const llvm::fltSemantics &ElementTypeSemantics =
15327- Ctx.getFloatTypeSemantics(ElementType);
15328- const llvm::fltSemantics &HigherElementTypeSemantics =
15329- Ctx.getFloatTypeSemantics(HigherElementType);
15330- if ((llvm::APFloat::semanticsMaxExponent(ElementTypeSemantics) * 2 + 1 >
15331- llvm::APFloat::semanticsMaxExponent(HigherElementTypeSemantics)) ||
15332- (HigherElementType == Ctx.LongDoubleTy &&
15333- !Ctx.getTargetInfo().hasLongDoubleType())) {
15334- // Retain the location of the first use of higher precision type.
15335- if (!S.LocationOfExcessPrecisionNotSatisfied.isValid())
15336- S.LocationOfExcessPrecisionNotSatisfied = OpLoc;
15337- for (auto &[Type, Num] : S.ExcessPrecisionNotSatisfied) {
15338- if (Type == HigherElementType) {
15339- Num++;
15340- return;
15341- }
15342- }
15343- S.ExcessPrecisionNotSatisfied.push_back(std::make_pair(
15344- HigherElementType, S.ExcessPrecisionNotSatisfied.size()));
15345- }
15346- }
15347- }
15348- }
15349-
1535015357ExprResult Sema::ActOnBinOp(Scope *S, SourceLocation TokLoc,
1535115358 tok::TokenKind Kind,
1535215359 Expr *LHSExpr, Expr *RHSExpr) {
@@ -15357,11 +15364,6 @@ ExprResult Sema::ActOnBinOp(Scope *S, SourceLocation TokLoc,
1535715364 // Emit warnings for tricky precedence issues, e.g. "bitfield & 0x4 == 0"
1535815365 DiagnoseBinOpPrecedence(*this, Opc, TokLoc, LHSExpr, RHSExpr);
1535915366
15360- // Emit warnings if the requested higher precision type equal to the current
15361- // type precision.
15362- if (Kind == tok::TokenKind::slash)
15363- DetectPrecisionLossInComplexDivision(*this, TokLoc, LHSExpr);
15364-
1536515367 BuiltinCountedByRefKind K =
1536615368 BinaryOperator::isAssignmentOp(Opc) ? AssignmentKind : BinaryExprKind;
1536715369
0 commit comments