Author: camc Date: 2025-09-07T20:59:58+08:00 New Revision: 59d69bfc20f1572936b29181a1cdfa309c4e209a
URL: https://github.com/llvm/llvm-project/commit/59d69bfc20f1572936b29181a1cdfa309c4e209a DIFF: https://github.com/llvm/llvm-project/commit/59d69bfc20f1572936b29181a1cdfa309c4e209a.diff LOG: [clang] Detect int-to-float narrowing when the back-conversion is unspecified (#157174) Resolves #157067 APFloat::convertToInteger returns opInvalidOp when the conversion has unspecified value. The int-to-float narrowing detection logic doesn't check for this when comparing the converted-back integer with the original integer. PR adds a check for this, and test cases. Added: Modified: clang/docs/ReleaseNotes.rst clang/lib/Sema/SemaOverload.cpp clang/test/CXX/dcl.decl/dcl.init/dcl.init.list/p7-0x.cpp Removed: ################################################################################ diff --git a/clang/docs/ReleaseNotes.rst b/clang/docs/ReleaseNotes.rst index aa661c533ed34..d1ef91b7e7c14 100644 --- a/clang/docs/ReleaseNotes.rst +++ b/clang/docs/ReleaseNotes.rst @@ -347,6 +347,8 @@ Bug Fixes to C++ Support unknown bound during constant evaluation. (#GH151716) - Support the dynamic_cast to final class optimization with pointer authentication enabled. (#GH152601) +- Fix the check for narrowing int-to-float conversions, so that they are detected in + cases where converting the float back to an integer is undefined behaviour (#GH157067). Bug Fixes to AST Handling ^^^^^^^^^^^^^^^^^^^^^^^^^ diff --git a/clang/lib/Sema/SemaOverload.cpp b/clang/lib/Sema/SemaOverload.cpp index 14fa8478fe317..941542247e240 100644 --- a/clang/lib/Sema/SemaOverload.cpp +++ b/clang/lib/Sema/SemaOverload.cpp @@ -412,10 +412,12 @@ NarrowingKind StandardConversionSequence::getNarrowingKind( // And back. llvm::APSInt ConvertedValue = *IntConstantValue; bool ignored; - Result.convertToInteger(ConvertedValue, - llvm::APFloat::rmTowardZero, &ignored); - // If the resulting value is diff erent, this was a narrowing conversion. - if (*IntConstantValue != ConvertedValue) { + llvm::APFloat::opStatus Status = Result.convertToInteger( + ConvertedValue, llvm::APFloat::rmTowardZero, &ignored); + // If the converted-back integer has unspecified value, or if the + // resulting value is diff erent, this was a narrowing conversion. + if (Status == llvm::APFloat::opInvalidOp || + *IntConstantValue != ConvertedValue) { ConstantValue = APValue(*IntConstantValue); ConstantType = Initializer->getType(); return NK_Constant_Narrowing; diff --git a/clang/test/CXX/dcl.decl/dcl.init/dcl.init.list/p7-0x.cpp b/clang/test/CXX/dcl.decl/dcl.init/dcl.init.list/p7-0x.cpp index 2bceb3e267790..5bb4708f869f8 100644 --- a/clang/test/CXX/dcl.decl/dcl.init/dcl.init.list/p7-0x.cpp +++ b/clang/test/CXX/dcl.decl/dcl.init/dcl.init.list/p7-0x.cpp @@ -137,6 +137,8 @@ void int_to_float() { Agg<float> f7 = {12345678}; // OK (exactly fits in a float) Agg<float> f8 = {EnumVal}; // OK Agg<float> f9 = {123456789}; // expected-error {{ cannot be narrowed }} expected-note {{silence}} + Agg<float> f10 = {2147483646}; // expected-error {{constant expression evaluates to 2147483646 which cannot be narrowed to type 'float'}} expected-note {{silence}} + Agg<float> f11 = {2147483647}; // expected-error {{constant expression evaluates to 2147483647 which cannot be narrowed to type 'float'}} expected-note {{silence}} Agg<float> ce1 = { Convert<int>(123456789) }; // expected-error {{constant expression evaluates to 123456789 which cannot be narrowed to type 'float'}} expected-note {{silence}} Agg<double> ce2 = { ConvertVar<long long>() }; // expected-error {{non-constant-expression cannot be narrowed from type 'long long' to 'double'}} expected-note {{silence}} _______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits