@@ -10555,6 +10555,43 @@ static void checkArithmeticNull(Sema &S, ExprResult &LHS, ExprResult &RHS,
1055510555 << LHS.get()->getSourceRange() << RHS.get()->getSourceRange();
1055610556}
1055710557
10558+ static void DetectPrecisionLossInComplexDivision(Sema &S, QualType DivisorTy,
10559+ SourceLocation OpLoc) {
10560+ // Either real/real or complex/real division.
10561+ // Either way there can be no precision loss.
10562+ auto *CT = DivisorTy->getAs<ComplexType>();
10563+ if (!CT)
10564+ return;
10565+
10566+ QualType ElementType = CT->getElementType();
10567+ bool IsComplexRangePromoted = S.getLangOpts().getComplexRange() ==
10568+ LangOptions::ComplexRangeKind::CX_Promoted;
10569+ if (!ElementType->isFloatingType() || !IsComplexRangePromoted)
10570+ return;
10571+
10572+ ASTContext &Ctx = S.getASTContext();
10573+ QualType HigherElementType = Ctx.GetHigherPrecisionFPType(ElementType);
10574+ const llvm::fltSemantics &ElementTypeSemantics =
10575+ Ctx.getFloatTypeSemantics(ElementType);
10576+ const llvm::fltSemantics &HigherElementTypeSemantics =
10577+ Ctx.getFloatTypeSemantics(HigherElementType);
10578+
10579+ if (llvm::APFloat::semanticsMaxExponent(ElementTypeSemantics) * 2 + 1 >
10580+ llvm::APFloat::semanticsMaxExponent(HigherElementTypeSemantics)) {
10581+ // Retain the location of the first use of higher precision type.
10582+ if (!S.LocationOfExcessPrecisionNotSatisfied.isValid())
10583+ S.LocationOfExcessPrecisionNotSatisfied = OpLoc;
10584+ for (auto &[Type, Num] : S.ExcessPrecisionNotSatisfied) {
10585+ if (Type == HigherElementType) {
10586+ Num++;
10587+ return;
10588+ }
10589+ }
10590+ S.ExcessPrecisionNotSatisfied.push_back(std::make_pair(
10591+ HigherElementType, S.ExcessPrecisionNotSatisfied.size()));
10592+ }
10593+ }
10594+
1055810595static void DiagnoseDivisionSizeofPointerOrArray(Sema &S, Expr *LHS, Expr *RHS,
1055910596 SourceLocation Loc) {
1056010597 const auto *LUE = dyn_cast<UnaryExprOrTypeTraitExpr>(LHS);
@@ -10649,6 +10686,7 @@ QualType Sema::CheckMultiplyDivideOperands(ExprResult &LHS, ExprResult &RHS,
1064910686 if (compType.isNull() || !compType->isArithmeticType())
1065010687 return InvalidOperands(Loc, LHS, RHS);
1065110688 if (IsDiv) {
10689+ DetectPrecisionLossInComplexDivision(*this, RHS.get()->getType(), Loc);
1065210690 DiagnoseBadDivideOrRemainderValues(*this, LHS, RHS, Loc, IsDiv);
1065310691 DiagnoseDivisionSizeofPointerOrArray(*this, LHS.get(), RHS.get(), Loc);
1065410692 }
@@ -15280,37 +15318,6 @@ static void DiagnoseBinOpPrecedence(Sema &Self, BinaryOperatorKind Opc,
1528015318 DiagnoseShiftCompare(Self, OpLoc, LHSExpr, RHSExpr);
1528115319}
1528215320
15283- static void DetectPrecisionLossInComplexDivision(Sema &S, SourceLocation OpLoc,
15284- Expr *Operand) {
15285- if (auto *CT = Operand->getType()->getAs<ComplexType>()) {
15286- QualType ElementType = CT->getElementType();
15287- bool IsComplexRangePromoted = S.getLangOpts().getComplexRange() ==
15288- LangOptions::ComplexRangeKind::CX_Promoted;
15289- if (ElementType->isFloatingType() && IsComplexRangePromoted) {
15290- ASTContext &Ctx = S.getASTContext();
15291- QualType HigherElementType = Ctx.GetHigherPrecisionFPType(ElementType);
15292- const llvm::fltSemantics &ElementTypeSemantics =
15293- Ctx.getFloatTypeSemantics(ElementType);
15294- const llvm::fltSemantics &HigherElementTypeSemantics =
15295- Ctx.getFloatTypeSemantics(HigherElementType);
15296- if (llvm::APFloat::semanticsMaxExponent(ElementTypeSemantics) * 2 + 1 >
15297- llvm::APFloat::semanticsMaxExponent(HigherElementTypeSemantics)) {
15298- // Retain the location of the first use of higher precision type.
15299- if (!S.LocationOfExcessPrecisionNotSatisfied.isValid())
15300- S.LocationOfExcessPrecisionNotSatisfied = OpLoc;
15301- for (auto &[Type, Num] : S.ExcessPrecisionNotSatisfied) {
15302- if (Type == HigherElementType) {
15303- Num++;
15304- return;
15305- }
15306- }
15307- S.ExcessPrecisionNotSatisfied.push_back(std::make_pair(
15308- HigherElementType, S.ExcessPrecisionNotSatisfied.size()));
15309- }
15310- }
15311- }
15312- }
15313-
1531415321ExprResult Sema::ActOnBinOp(Scope *S, SourceLocation TokLoc,
1531515322 tok::TokenKind Kind,
1531615323 Expr *LHSExpr, Expr *RHSExpr) {
@@ -15321,11 +15328,6 @@ ExprResult Sema::ActOnBinOp(Scope *S, SourceLocation TokLoc,
1532115328 // Emit warnings for tricky precedence issues, e.g. "bitfield & 0x4 == 0"
1532215329 DiagnoseBinOpPrecedence(*this, Opc, TokLoc, LHSExpr, RHSExpr);
1532315330
15324- // Emit warnings if the requested higher precision type equal to the current
15325- // type precision.
15326- if (Kind == tok::TokenKind::slash)
15327- DetectPrecisionLossInComplexDivision(*this, TokLoc, LHSExpr);
15328-
1532915331 BuiltinCountedByRefKind K =
1533015332 BinaryOperator::isAssignmentOp(Opc) ? AssignmentKind : BinaryExprKind;
1533115333
0 commit comments