https://github.com/atigdng created https://github.com/llvm/llvm-project/pull/235481
Closes #93288. This change adds a fix-it suggestion for -Wimplicit-float-conversion diagnostics. The suggested explicit cast wraps the expression being converted, preserving the precision used in its intermediate calculations. The diagnostic location is moved to the beginning of the expression. Tests: Added C and C++ regression tests under clang/test/FixIt/. Tested the new fix-it on scalar, arithmetic, vector, and macro examples. The targeted tests and broader Clang FixIt, Sema, and SemaCXX suites passed. >From 15ede17f0f4b41748918c77a52d775ee1920abb0 Mon Sep 17 00:00:00 2001 From: atigdng <[email protected]> Date: Sun, 25 Oct 2026 21:59:19 +0530 Subject: [PATCH] clang: Add fix-it for implicit float conversion --- clang/lib/Sema/SemaChecking.cpp | 31 +++++++++++++++++-- .../FixIt/fixit-implicit-float-conversion.c | 9 ++++++ .../FixIt/fixit-implicit-float-conversion.cpp | 9 ++++++ 3 files changed, 47 insertions(+), 2 deletions(-) create mode 100644 clang/test/FixIt/fixit-implicit-float-conversion.c create mode 100644 clang/test/FixIt/fixit-implicit-float-conversion.cpp diff --git a/clang/lib/Sema/SemaChecking.cpp b/clang/lib/Sema/SemaChecking.cpp index 675975168e5048..22aa6b56aa8306 100644 --- a/clang/lib/Sema/SemaChecking.cpp +++ b/clang/lib/Sema/SemaChecking.cpp @@ -13193,8 +13193,35 @@ static void DiagnoseImpCast(Sema &S, const Expr *E, QualType SourceType, << SourceRange(CContext)); return; } - S.Diag(E->getExprLoc(), diag) - << SourceType << T << E->getSourceRange() << SourceRange(CContext); + if (diag == clang::diag::warn_impcast_float_precision) { + // Suggest explicit cast without changing the expression's intermediate + // calculations. + SmallString<32> CastBuf; + llvm::raw_svector_ostream CastFix(CastBuf); + + // Apply cast syntax appropriate to the language. + CastFix << (S.LangOpts.CPlusPlus ? "static_cast<" : "("); + T.print(CastFix, S.Context.getPrintingPolicy()); + CastFix << (S.LangOpts.CPlusPlus ? ">(" : ")("); + + auto DB = S.Diag(E->getBeginLoc(), diag); + DB << SourceType << T << E->getSourceRange() << SourceRange(CContext); + + // Avoid suggesting edits when either boundary comes from a macro expansion. + if (E->getBeginLoc().isValid() && E->getEndLoc().isValid() && + !E->getBeginLoc().isMacroID() && !E->getEndLoc().isMacroID()) { + SourceLocation EndLoc = S.SourceMgr.getSpellingLoc(E->getEndLoc()); + SourceLocation After = EndLoc.getLocWithOffset( + Lexer::MeasureTokenLength(EndLoc, S.SourceMgr, S.LangOpts)); + + // Enclose the expression in explicit cast. + DB << FixItHint::CreateInsertion(E->getBeginLoc(), CastFix.str()) + << FixItHint::CreateInsertion(After, ")"); + } + } else { + S.Diag(E->getExprLoc(), diag) + << SourceType << T << E->getSourceRange() << SourceRange(CContext); + } } /// Diagnose an implicit cast; purely a helper for CheckImplicitConversion. diff --git a/clang/test/FixIt/fixit-implicit-float-conversion.c b/clang/test/FixIt/fixit-implicit-float-conversion.c new file mode 100644 index 00000000000000..7af82992edef5a --- /dev/null +++ b/clang/test/FixIt/fixit-implicit-float-conversion.c @@ -0,0 +1,9 @@ +// RUN: %clang_cc1 -std=c11 -Wimplicit-float-conversion -fsyntax-only \ +// RUN: -fdiagnostics-parseable-fixits %s 2>&1 | FileCheck %s + +// Issue #93288 example +float f = 48 * (1.0 / 255.0); + +// CHECK: {{.*}}:5:11: warning: implicit conversion loses floating-point precision: 'double' to 'float' +// CHECK: fix-it:"{{.*}}":{5:11-5:11}:"(float)(" +// CHECK-NEXT: fix-it:"{{.*}}":{5:29-5:29}:")" diff --git a/clang/test/FixIt/fixit-implicit-float-conversion.cpp b/clang/test/FixIt/fixit-implicit-float-conversion.cpp new file mode 100644 index 00000000000000..b9531b06ed63a4 --- /dev/null +++ b/clang/test/FixIt/fixit-implicit-float-conversion.cpp @@ -0,0 +1,9 @@ +// RUN: %clang_cc1 -std=c++17 -Wimplicit-float-conversion -fsyntax-only \ +// RUN: -fdiagnostics-parseable-fixits %s 2>&1 | FileCheck %s + +// Issue #93288 example +float f = 48 * (1.0 / 255.0); + +// CHECK: {{.*}}:5:11: warning: implicit conversion loses floating-point precision: 'double' to 'float' +// CHECK: fix-it:"{{.*}}":{5:11-5:11}:"static_cast<float>(" +// CHECK-NEXT: fix-it:"{{.*}}":{5:29-5:29}:")" _______________________________________________ cfe-commits mailing list [email protected] https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
