llvmbot wrote:
<!--LLVM PR SUMMARY COMMENT--> @llvm/pr-subscribers-clang @llvm/pr-subscribers-clang-codegen Author: Zahira Ammarguellat (zahiraam) <details> <summary>Changes</summary> This is a warning that wasn't associated with the source location. Moved it to Sema and changed the warning message to a more verbose one. --- Full diff: https://github.com/llvm/llvm-project/pull/107397.diff 8 Files Affected: - (modified) clang/include/clang/AST/ASTContext.h (+16) - (modified) clang/include/clang/Basic/DiagnosticCommonKinds.td (-5) - (modified) clang/include/clang/Basic/DiagnosticSemaKinds.td (+4) - (modified) clang/lib/CodeGen/CGExprComplex.cpp (+8-21) - (modified) clang/lib/Sema/SemaExpr.cpp (+26) - (modified) clang/test/AST/ByteCode/complex.cpp (+3-1) - (modified) clang/test/Sema/complex-arithmetic.c (+12-2) - (modified) clang/test/SemaCXX/complex-folding.cpp (+1) ``````````diff diff --git a/clang/include/clang/AST/ASTContext.h b/clang/include/clang/AST/ASTContext.h index 89bb5768dbd40d..e203568230e491 100644 --- a/clang/include/clang/AST/ASTContext.h +++ b/clang/include/clang/AST/ASTContext.h @@ -780,6 +780,22 @@ class ASTContext : public RefCountedBase<ASTContext> { const TargetInfo &getTargetInfo() const { return *Target; } const TargetInfo *getAuxTargetInfo() const { return AuxTarget; } + const QualType GetHigherPrecisionFPType(QualType ElementType) const { + const auto *CurrentBT = cast<BuiltinType>(ElementType); + switch (CurrentBT->getKind()) { + case BuiltinType::Kind::Float16: + return FloatTy; + case BuiltinType::Kind::Float: + case BuiltinType::Kind::BFloat16: + return DoubleTy; + case BuiltinType::Kind::Double: + return LongDoubleTy; + default: + return ElementType; + } + return ElementType; + } + /// getIntTypeForBitwidth - /// sets integer QualTy according to specified details: /// bitwidth, signed/unsigned. diff --git a/clang/include/clang/Basic/DiagnosticCommonKinds.td b/clang/include/clang/Basic/DiagnosticCommonKinds.td index 33b1d58bb5b099..ae709e45a700a1 100644 --- a/clang/include/clang/Basic/DiagnosticCommonKinds.td +++ b/clang/include/clang/Basic/DiagnosticCommonKinds.td @@ -45,11 +45,6 @@ def note_using : Note<"using">; def note_possibility : Note<"one possibility">; def note_also_found : Note<"also found">; -def warn_next_larger_fp_type_same_size_than_fp : Warning< - "higher precision floating-point type size has the same size than " - "floating-point type size">, - InGroup<DiagGroup<"higher-precision-fp">>; - // Parse && Lex let CategoryName = "Lexical or Preprocessor Issue" in { diff --git a/clang/include/clang/Basic/DiagnosticSemaKinds.td b/clang/include/clang/Basic/DiagnosticSemaKinds.td index dcb49d8a67604a..2aaf8dc3b7ecc1 100644 --- a/clang/include/clang/Basic/DiagnosticSemaKinds.td +++ b/clang/include/clang/Basic/DiagnosticSemaKinds.td @@ -6784,6 +6784,10 @@ def warn_arc_lifetime_result_type : Warning< "ARC %select{unused|__unsafe_unretained|__strong|__weak|__autoreleasing}0 " "lifetime qualifier on return type is ignored">, InGroup<IgnoredQualifiers>; +def warn_next_larger_fp_type_same_size_than_fp : Warning< + "higher precision floating-point type requested by user size has the same size" + "than floating-point type size; overflow may occur">, + InGroup<DiagGroup<"higher-precision-fp">>; let CategoryName = "ARC Retain Cycle" in { diff --git a/clang/lib/CodeGen/CGExprComplex.cpp b/clang/lib/CodeGen/CGExprComplex.cpp index 828a09856099ac..fef26e7b4ccdbd 100644 --- a/clang/lib/CodeGen/CGExprComplex.cpp +++ b/clang/lib/CodeGen/CGExprComplex.cpp @@ -288,28 +288,15 @@ class ComplexExprEmitter ComplexPairTy EmitComplexBinOpLibCall(StringRef LibCallName, const BinOpInfo &Op); - QualType GetHigherPrecisionFPType(QualType ElementType) { - const auto *CurrentBT = cast<BuiltinType>(ElementType); - switch (CurrentBT->getKind()) { - case BuiltinType::Kind::Float16: - return CGF.getContext().FloatTy; - case BuiltinType::Kind::Float: - case BuiltinType::Kind::BFloat16: - return CGF.getContext().DoubleTy; - case BuiltinType::Kind::Double: - return CGF.getContext().LongDoubleTy; - default: - return ElementType; - } - } - QualType HigherPrecisionTypeForComplexArithmetic(QualType ElementType, bool IsDivOpCode) { - QualType HigherElementType = GetHigherPrecisionFPType(ElementType); + ASTContext &Ctx = CGF.getContext(); + const QualType HigherElementType = + Ctx.GetHigherPrecisionFPType(ElementType); const llvm::fltSemantics &ElementTypeSemantics = - CGF.getContext().getFloatTypeSemantics(ElementType); + Ctx.getFloatTypeSemantics(ElementType); const llvm::fltSemantics &HigherElementTypeSemantics = - CGF.getContext().getFloatTypeSemantics(HigherElementType); + Ctx.getFloatTypeSemantics(HigherElementType); // Check that the promoted type can handle the intermediate values without // overflowing. This can be interpreted as: // (SmallerType.LargestFiniteVal * SmallerType.LargestFiniteVal) * 2 <= @@ -320,10 +307,10 @@ class ComplexExprEmitter if (llvm::APFloat::semanticsMaxExponent(ElementTypeSemantics) * 2 + 1 <= llvm::APFloat::semanticsMaxExponent(HigherElementTypeSemantics)) { FPHasBeenPromoted = true; - return CGF.getContext().getComplexType(HigherElementType); + return Ctx.getComplexType(HigherElementType); } else { - DiagnosticsEngine &Diags = CGF.CGM.getDiags(); - Diags.Report(diag::warn_next_larger_fp_type_same_size_than_fp); + // The intermediate values can't be represented in the promoted type + // without overflowing. return QualType(); } } diff --git a/clang/lib/Sema/SemaExpr.cpp b/clang/lib/Sema/SemaExpr.cpp index 94bb938b53b441..8f2699ea66793f 100644 --- a/clang/lib/Sema/SemaExpr.cpp +++ b/clang/lib/Sema/SemaExpr.cpp @@ -15083,6 +15083,27 @@ static void DiagnoseBinOpPrecedence(Sema &Self, BinaryOperatorKind Opc, DiagnoseShiftCompare(Self, OpLoc, LHSExpr, RHSExpr); } +static void DiagnosePrecisionLossInComplexDivision(Sema &S, + SourceLocation OpLoc, + Expr *Operand) { + if (auto *CT = Operand->getType()->getAs<ComplexType>()) { + QualType ElementType = CT->getElementType(); + bool IsComplexRangePromoted = S.getLangOpts().getComplexRange() == + LangOptions::ComplexRangeKind::CX_Promoted; + if (ElementType->isFloatingType() && IsComplexRangePromoted) { + ASTContext &Ctx = S.getASTContext(); + QualType HigherElementType = Ctx.GetHigherPrecisionFPType(ElementType); + const llvm::fltSemantics &ElementTypeSemantics = + Ctx.getFloatTypeSemantics(ElementType); + const llvm::fltSemantics &HigherElementTypeSemantics = + Ctx.getFloatTypeSemantics(HigherElementType); + if (llvm::APFloat::semanticsMaxExponent(ElementTypeSemantics) * 2 + 1 > + llvm::APFloat::semanticsMaxExponent(HigherElementTypeSemantics)) + S.Diag(OpLoc, diag::warn_next_larger_fp_type_same_size_than_fp); + } + } +} + ExprResult Sema::ActOnBinOp(Scope *S, SourceLocation TokLoc, tok::TokenKind Kind, Expr *LHSExpr, Expr *RHSExpr) { @@ -15093,6 +15114,11 @@ ExprResult Sema::ActOnBinOp(Scope *S, SourceLocation TokLoc, // Emit warnings for tricky precedence issues, e.g. "bitfield & 0x4 == 0" DiagnoseBinOpPrecedence(*this, Opc, TokLoc, LHSExpr, RHSExpr); + // Emit warnings if the requested higher precision type equal to the current + // type precision. + if (Kind == tok::TokenKind::slash) + DiagnosePrecisionLossInComplexDivision(*this, TokLoc, LHSExpr); + return BuildBinOp(S, TokLoc, Opc, LHSExpr, RHSExpr); } diff --git a/clang/test/AST/ByteCode/complex.cpp b/clang/test/AST/ByteCode/complex.cpp index dc93c786dac7ae..03e72f429e44ea 100644 --- a/clang/test/AST/ByteCode/complex.cpp +++ b/clang/test/AST/ByteCode/complex.cpp @@ -40,12 +40,14 @@ constexpr _Complex int IIMC = IIMA * IIMB; static_assert(__real(IIMC) == -30, ""); static_assert(__imag(IIMC) == 40, ""); -static_assert(1.0j / 0.0 == 1); // both-error {{static assertion}} \ +static_assert(1.0j / 0.0 == 1); // both-error {{static assertion}} \ // both-note {{division by zero}} + static_assert(__builtin_isinf_sign(__real__((1.0 + 1.0j) / (0.0 + 0.0j))) == 1); static_assert(__builtin_isinf_sign(__real__((1.0 + 1.0j) / 0.0)) == 1); // both-error {{static assertion}} \ // both-note {{division by zero}} static_assert(__builtin_isinf_sign(__real__((__builtin_inf() + 1.0j) / (0.0 + 0.0j))) == 1); + static_assert(__builtin_isinf_sign(__imag__((1.0 + InfC) / (0.0 + 0.0j))) == 1); static_assert(__builtin_isinf_sign(__imag__((InfInf) / (0.0 + 0.0j))) == 1); diff --git a/clang/test/Sema/complex-arithmetic.c b/clang/test/Sema/complex-arithmetic.c index c9e84da6daa9dc..a9ff001d60a8b6 100644 --- a/clang/test/Sema/complex-arithmetic.c +++ b/clang/test/Sema/complex-arithmetic.c @@ -1,5 +1,9 @@ -// RUN: %clang_cc1 -verify %s -// expected-no-diagnostics +// RUN: %clang_cc1 -verify=no-diag %s +// RUN: %clang_cc1 -complex-range=promoted -triple x86_64-unknown-linux \ +// RUN: -verify=no-diag %s +// RUN: %clang_cc1 -complex-range=promoted -triple x86_64-unknown-windows \ +// RUN: -verify=div-precision %s +// no-diag-no-diagnostics // This tests evaluation of _Complex arithmetic at compile time. @@ -21,6 +25,8 @@ void a() { EVALF((2. + 3i) + (4. + 5i), 6. + 8i); EVALF((2. + 3i) - (4. + 5i), -2. - 2i); EVALF((2. + 3i) * (4. + 5i), -7. + 22i); + // div-precision-warning@+2 {{higher precision floating-point type requested by user size has the same sizethan floating-point type size; overflow may occur}} + // div-precision-warning@+1 {{higher precision floating-point type requested by user size has the same sizethan floating-point type size; overflow may occur}} EVALF((2. + 3i) / (4. + 5i), .5609 + .0487i); } @@ -47,6 +53,8 @@ void c() { EVALF((2. + 4i) + 3., 5. + 4i); EVALF((2. + 4i) - 3., -1. + 4i); EVALF((2. + 4i) * 3., 6. + 12i); + // div-precision-warning@+2 {{higher precision floating-point type requested by user size has the same sizethan floating-point type size; overflow may occur}} + // div-precision-warning@+1 {{higher precision floating-point type requested by user size has the same sizethan floating-point type size; overflow may occur}} EVALF((2. + 4i) / 2., 1. + 2i); EVALF(3. + (2. + 4i), 5. + 4i); @@ -83,6 +91,8 @@ void e() { EVALF((2. + 4i) + 3, 5. + 4i); EVALF((2. + 4i) - 3, -1. + 4i); EVALF((2. + 4i) * 3, 6. + 12i); + // div-precision-warning@+2 {{higher precision floating-point type requested by user size has the same sizethan floating-point type size; overflow may occur}} + // div-precision-warning@+1 {{higher precision floating-point type requested by user size has the same sizethan floating-point type size; overflow may occur}} EVALF((2. + 4i) / 2, 1. + 2i); EVALF(3 + (2. + 4i), 5. + 4i); diff --git a/clang/test/SemaCXX/complex-folding.cpp b/clang/test/SemaCXX/complex-folding.cpp index f2fa93ad4795b9..bb54fa92689d9d 100644 --- a/clang/test/SemaCXX/complex-folding.cpp +++ b/clang/test/SemaCXX/complex-folding.cpp @@ -90,6 +90,7 @@ static_assert(((1.0 + 1.0j) / (__builtin_inf() + 1.0j)) == (0.0 + 0.0j)); static_assert(((1.0 + 1.0j) / (1.0 + InfC)) == (0.0 + 0.0j)); static_assert(((1.0 + 1.0j) / (InfInf)) == (0.0 + 0.0j)); static_assert(((1.0 + 1.0j) / __builtin_inf()) == (0.0 + 0.0j)); + static_assert(1.0j / 0.0 == 1); // expected-error {{static assertion}} \ // expected-note {{division by zero}} static_assert(__builtin_isinf_sign(__real__((1.0 + 1.0j) / (0.0 + 0.0j))) == 1); `````````` </details> https://github.com/llvm/llvm-project/pull/107397 _______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits