Skip to content

Commit 7068497

Browse files
authored
[AsmParser] Fix crash when hex literal exceeds 16-bit float range (#172669)
Fixes #172650.
1 parent 2c02e4c commit 7068497

File tree

2 files changed

+38
-6
lines changed

2 files changed

+38
-6
lines changed

llvm/lib/AsmParser/LLLexer.cpp

Lines changed: 16 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1129,16 +1129,26 @@ lltok::Kind LLLexer::Lex0x() {
11291129
HexToIntPair(TokStart+3, CurPtr, Pair);
11301130
APFloatVal = APFloat(APFloat::PPCDoubleDouble(), APInt(128, Pair));
11311131
return lltok::APFloat;
1132-
case 'H':
1133-
APFloatVal = APFloat(APFloat::IEEEhalf(),
1134-
APInt(16,HexIntToVal(TokStart+3, CurPtr)));
1132+
case 'H': {
1133+
uint64_t Val = HexIntToVal(TokStart + 3, CurPtr);
1134+
if (!llvm::isUInt<16>(Val)) {
1135+
LexError("hexadecimal constant too large for half (16-bit)");
1136+
return lltok::Error;
1137+
}
1138+
APFloatVal = APFloat(APFloat::IEEEhalf(), APInt(16, Val));
11351139
return lltok::APFloat;
1136-
case 'R':
1140+
}
1141+
case 'R': {
11371142
// Brain floating point
1138-
APFloatVal = APFloat(APFloat::BFloat(),
1139-
APInt(16, HexIntToVal(TokStart + 3, CurPtr)));
1143+
uint64_t Val = HexIntToVal(TokStart + 3, CurPtr);
1144+
if (!llvm::isUInt<16>(Val)) {
1145+
LexError("hexadecimal constant too large for bfloat (16-bit)");
1146+
return lltok::Error;
1147+
}
1148+
APFloatVal = APFloat(APFloat::BFloat(), APInt(16, Val));
11401149
return lltok::APFloat;
11411150
}
1151+
}
11421152
}
11431153

11441154
/// Lex tokens for a label or a numeric constant, possibly starting with -.
Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --version 6
2+
; RUN: split-file %s %t
3+
; RUN: not opt -S -disable-output < %t/half.ll 2>&1 | FileCheck %s --check-prefix=HALF
4+
; RUN: not opt -S -disable-output < %t/bfloat.ll 2>&1 | FileCheck %s --check-prefix=BFLOAT
5+
6+
; Test that providing a hex literal larger than 16 bits for half-precision
7+
; triggers a proper error message instead of a compiler crash.
8+
9+
;--- half.ll
10+
define half @test_half_overflow() {
11+
; HALF: error: hexadecimal constant too large for half (16-bit)
12+
%1 = fadd half 0xH5F2F00, 0xH0000
13+
ret half %1
14+
}
15+
16+
;--- bfloat.ll
17+
define bfloat @test_bfloat_overflow() {
18+
; BFLOAT: error: hexadecimal constant too large for bfloat (16-bit)
19+
%1 = fadd bfloat 0xR5F2F00, 0xR0000
20+
ret bfloat %1
21+
}
22+

0 commit comments

Comments
 (0)