[clang] [NFC] Move warning from CodeGen to Sema. (PR #107397)
via cfe-commits
cfe-commits at lists.llvm.org
Mon Sep 9 05:21:16 PDT 2024
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 at +2 {{higher precision floating-point type requested by user size has the same sizethan floating-point type size; overflow may occur}}
+ // div-precision-warning at +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 at +2 {{higher precision floating-point type requested by user size has the same sizethan floating-point type size; overflow may occur}}
+ // div-precision-warning at +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 at +2 {{higher precision floating-point type requested by user size has the same sizethan floating-point type size; overflow may occur}}
+ // div-precision-warning at +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
More information about the cfe-commits
mailing list