Skip to content

Commit 59d69bf

Browse files
authored
[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.
1 parent 6d6122e commit 59d69bf

File tree

3 files changed

+10
-4
lines changed

3 files changed

+10
-4
lines changed

clang/docs/ReleaseNotes.rst

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -347,6 +347,8 @@ Bug Fixes to C++ Support
347347
unknown bound during constant evaluation. (#GH151716)
348348
- Support the dynamic_cast to final class optimization with pointer
349349
authentication enabled. (#GH152601)
350+
- Fix the check for narrowing int-to-float conversions, so that they are detected in
351+
cases where converting the float back to an integer is undefined behaviour (#GH157067).
350352

351353
Bug Fixes to AST Handling
352354
^^^^^^^^^^^^^^^^^^^^^^^^^

clang/lib/Sema/SemaOverload.cpp

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -412,10 +412,12 @@ NarrowingKind StandardConversionSequence::getNarrowingKind(
412412
// And back.
413413
llvm::APSInt ConvertedValue = *IntConstantValue;
414414
bool ignored;
415-
Result.convertToInteger(ConvertedValue,
416-
llvm::APFloat::rmTowardZero, &ignored);
417-
// If the resulting value is different, this was a narrowing conversion.
418-
if (*IntConstantValue != ConvertedValue) {
415+
llvm::APFloat::opStatus Status = Result.convertToInteger(
416+
ConvertedValue, llvm::APFloat::rmTowardZero, &ignored);
417+
// If the converted-back integer has unspecified value, or if the
418+
// resulting value is different, this was a narrowing conversion.
419+
if (Status == llvm::APFloat::opInvalidOp ||
420+
*IntConstantValue != ConvertedValue) {
419421
ConstantValue = APValue(*IntConstantValue);
420422
ConstantType = Initializer->getType();
421423
return NK_Constant_Narrowing;

clang/test/CXX/dcl.decl/dcl.init/dcl.init.list/p7-0x.cpp

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -137,6 +137,8 @@ void int_to_float() {
137137
Agg<float> f7 = {12345678}; // OK (exactly fits in a float)
138138
Agg<float> f8 = {EnumVal}; // OK
139139
Agg<float> f9 = {123456789}; // expected-error {{ cannot be narrowed }} expected-note {{silence}}
140+
Agg<float> f10 = {2147483646}; // expected-error {{constant expression evaluates to 2147483646 which cannot be narrowed to type 'float'}} expected-note {{silence}}
141+
Agg<float> f11 = {2147483647}; // expected-error {{constant expression evaluates to 2147483647 which cannot be narrowed to type 'float'}} expected-note {{silence}}
140142

141143
Agg<float> ce1 = { Convert<int>(123456789) }; // expected-error {{constant expression evaluates to 123456789 which cannot be narrowed to type 'float'}} expected-note {{silence}}
142144
Agg<double> ce2 = { ConvertVar<long long>() }; // expected-error {{non-constant-expression cannot be narrowed from type 'long long' to 'double'}} expected-note {{silence}}

0 commit comments

Comments
 (0)