[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