[clang] [clang] Add fix for GH issue 83050 (PR #83071)
https://github.com/PiJoules updated https://github.com/llvm/llvm-project/pull/83071 >From 306394b5e0386701f577ec2aa9a021492fbae734 Mon Sep 17 00:00:00 2001 From: Leonard Chan Date: Mon, 26 Feb 2024 14:11:45 -0800 Subject: [PATCH] [clang] Fixes inf loop parsing fixed point literal Clang was incorrectly finding the start of the exponent in a fixed point hex literal. It would unconditionally find the first `e/E/p/P` in a constant regardless of if it were hex or not and parser the remaining digits as an APInt. In a debug build, this would be caught by an assertion, but in a release build, the assertion is removed and we'd end up in an infinite loop. Fixes #83050 --- clang/lib/Lex/LiteralSupport.cpp | 9 ++--- clang/test/Frontend/fixed_point_declarations.c | 18 ++ 2 files changed, 24 insertions(+), 3 deletions(-) diff --git a/clang/lib/Lex/LiteralSupport.cpp b/clang/lib/Lex/LiteralSupport.cpp index 571a984884029d..438c6d772e6e04 100644 --- a/clang/lib/Lex/LiteralSupport.cpp +++ b/clang/lib/Lex/LiteralSupport.cpp @@ -1513,8 +1513,10 @@ NumericLiteralParser::GetFloatValue(llvm::APFloat &Result) { : APFloat::opInvalidOp; } -static inline bool IsExponentPart(char c) { - return c == 'p' || c == 'P' || c == 'e' || c == 'E'; +static inline bool IsExponentPart(char c, bool isHex) { + if (isHex) +return c == 'p' || c == 'P'; + return c == 'e' || c == 'E'; } bool NumericLiteralParser::GetFixedPointValue(llvm::APInt &StoreVal, unsigned Scale) { @@ -1533,7 +1535,8 @@ bool NumericLiteralParser::GetFixedPointValue(llvm::APInt &StoreVal, unsigned Sc if (saw_exponent) { const char *Ptr = DigitsBegin; -while (!IsExponentPart(*Ptr)) ++Ptr; +while (!IsExponentPart(*Ptr, radix == 16)) + ++Ptr; ExponentBegin = Ptr; ++Ptr; NegativeExponent = *Ptr == '-'; diff --git a/clang/test/Frontend/fixed_point_declarations.c b/clang/test/Frontend/fixed_point_declarations.c index 04ed25d227ca52..c8045767442739 100644 --- a/clang/test/Frontend/fixed_point_declarations.c +++ b/clang/test/Frontend/fixed_point_declarations.c @@ -125,3 +125,21 @@ long _Fract long_fract_zero = 0.0lr;// CHECK-DAG: @long_fract_ unsigned short _Fract u_short_fract_zero = 0.0uhr; // CHECK-DAG: @u_short_fract_zero = {{.*}}global i8 0, align 1 unsigned _Fract u_fract_zero= 0.0ur;// CHECK-DAG: @u_fract_zero = {{.*}}global i16 0, align 2 unsigned long _Fract u_long_fract_zero = 0.0ulr; // CHECK-DAG: @u_long_fract_zero= {{.*}}global i32 0, align 4 + +// Hex exponent suffix with E in hex digit sequence. +unsigned short _Fract e1 = 0x1.e8p-1uhr; // CHECK-DAG: @e1 = {{.*}}global i8 -12 +unsigned short _Fract e2 = 0x1.8ep-1uhr; // CHECK-DAG: @e2 = {{.*}}global i8 -57 +unsigned short _Fract e3 = 0x1.ep-1uhr; // CHECK-DAG: @e3 = {{.*}}global i8 -16 +unsigned _Accum e4 = 0xep-1uk; // CHECK-DAG: @e4 = {{.*}}global i32 458752 +unsigned _Accum e5 = 0xe.1p-1uk; // CHECK-DAG: @e5 = {{.*}}global i32 460800 +unsigned _Accum e6 = 0xe.ep-1uk; // CHECK-DAG: @e6 = {{.*}}global i32 487424 +unsigned _Accum e7 = 0xe.e8p-1uk; // CHECK-DAG: @e7 = {{.*}}global i32 488448 +unsigned _Accum e8 = 0xe.8ep-1uk; // CHECK-DAG: @e8 = {{.*}}global i32 476928 +unsigned short _Fract E1 = 0x1.E8p-1uhr; // CHECK-DAG: @E1 = {{.*}}global i8 -12 +unsigned short _Fract E2 = 0x1.8Ep-1uhr; // CHECK-DAG: @E2 = {{.*}}global i8 -57 +unsigned short _Fract E3 = 0x1.Ep-1uhr; // CHECK-DAG: @E3 = {{.*}}global i8 -16 +unsigned _Accum E4 = 0xEp-1uk; // CHECK-DAG: @E4 = {{.*}}global i32 458752 +unsigned _Accum E5 = 0xE.1p-1uk; // CHECK-DAG: @E5 = {{.*}}global i32 460800 +unsigned _Accum E6 = 0xE.Ep-1uk; // CHECK-DAG: @E6 = {{.*}}global i32 487424 +unsigned _Accum E7 = 0xE.E8p-1uk; // CHECK-DAG: @E7 = {{.*}}global i32 488448 +unsigned _Accum E8 = 0xE.8Ep-1uk; // CHECK-DAG: @E8 = {{.*}}global i32 476928 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [clang] Add fix for GH issue 83050 (PR #83071)
@@ -0,0 +1,11 @@ +/// This is the regression test for https://github.com/llvm/llvm-project/issues/83050. +/// This just needs to compile. +// RUN: %clang_cc1 -x c++ -ffixed-point -S %s -o /dev/null -triple=x86_64-linux -ffixed-point +static constexpr unsigned short _Fract SQRT_FIRST_APPROX[12][2] = { +{0x1.e8p-1uhr, 0x1.0cp-2uhr}, {0x1.bap-1uhr, 0x1.28p-2uhr}, +{0x1.94p-1uhr, 0x1.44p-2uhr}, {0x1.74p-1uhr, 0x1.6p-2uhr}, +{0x1.6p-1uhr, 0x1.74p-2uhr}, {0x1.4ep-1uhr, 0x1.88p-2uhr}, +{0x1.3ep-1uhr, 0x1.9cp-2uhr}, {0x1.32p-1uhr, 0x1.acp-2uhr}, +{0x1.22p-1uhr, 0x1.c4p-2uhr}, {0x1.18p-1uhr, 0x1.d4p-2uhr}, +{0x1.08p-1uhr, 0x1.fp-2uhr}, {0x1.04p-1uhr, 0x1.f8p-2uhr}, PiJoules wrote: Oh, no they both aren't so I'll just remove this one. https://github.com/llvm/llvm-project/pull/83071 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [clang] Add fix for GH issue 83050 (PR #83071)
@@ -0,0 +1,11 @@ +/// This is the regression test for https://github.com/llvm/llvm-project/issues/83050. +/// This just needs to compile. +// RUN: %clang_cc1 -x c++ -ffixed-point -S %s -o /dev/null -triple=x86_64-linux -ffixed-point +static constexpr unsigned short _Fract SQRT_FIRST_APPROX[12][2] = { +{0x1.e8p-1uhr, 0x1.0cp-2uhr}, {0x1.bap-1uhr, 0x1.28p-2uhr}, +{0x1.94p-1uhr, 0x1.44p-2uhr}, {0x1.74p-1uhr, 0x1.6p-2uhr}, +{0x1.6p-1uhr, 0x1.74p-2uhr}, {0x1.4ep-1uhr, 0x1.88p-2uhr}, +{0x1.3ep-1uhr, 0x1.9cp-2uhr}, {0x1.32p-1uhr, 0x1.acp-2uhr}, +{0x1.22p-1uhr, 0x1.c4p-2uhr}, {0x1.18p-1uhr, 0x1.d4p-2uhr}, +{0x1.08p-1uhr, 0x1.fp-2uhr}, {0x1.04p-1uhr, 0x1.f8p-2uhr}, nickdesaulniers wrote: I think what you added to clang/test/Frontend/fixed_point_declarations.c covers the same thing as the newly added test file? Are both necessary? https://github.com/llvm/llvm-project/pull/83071 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [clang] Add fix for GH issue 83050 (PR #83071)
nickdesaulniers wrote: For the commit message and PR description, please consider: 1. using a subject that describes more of what the patch does, such as "[clang] fixes inf loop parsing fixed point literal" 2. put "Fixes #83050" in the commit body; when merged, github will auto close the corresponding issue. https://github.com/llvm/llvm-project/pull/83071 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [clang] Add fix for GH issue 83050 (PR #83071)
https://github.com/PiJoules updated https://github.com/llvm/llvm-project/pull/83071 >From f14ff8098b748944cdc10bc1421c9002dd6ef16e Mon Sep 17 00:00:00 2001 From: Leonard Chan Date: Mon, 26 Feb 2024 14:11:45 -0800 Subject: [PATCH] [clang] Add fix for GH issue 83050 Clang was incorrectly finding the start of the exponent in a fixed point hex literal. It would unconditionally find the first `e/E/p/P` in a constant regardless of if it were hex or not and parser the remaining digits as an APInt. In a debug build, this would be caught by an assertion, but in a release build, the assertion is removed and we'd end up in an infinite loop. --- clang/lib/Lex/LiteralSupport.cpp | 9 ++--- clang/test/Frontend/GH83050.cpp| 6 ++ clang/test/Frontend/fixed_point_declarations.c | 18 ++ 3 files changed, 30 insertions(+), 3 deletions(-) create mode 100644 clang/test/Frontend/GH83050.cpp diff --git a/clang/lib/Lex/LiteralSupport.cpp b/clang/lib/Lex/LiteralSupport.cpp index 571a984884029d..438c6d772e6e04 100644 --- a/clang/lib/Lex/LiteralSupport.cpp +++ b/clang/lib/Lex/LiteralSupport.cpp @@ -1513,8 +1513,10 @@ NumericLiteralParser::GetFloatValue(llvm::APFloat &Result) { : APFloat::opInvalidOp; } -static inline bool IsExponentPart(char c) { - return c == 'p' || c == 'P' || c == 'e' || c == 'E'; +static inline bool IsExponentPart(char c, bool isHex) { + if (isHex) +return c == 'p' || c == 'P'; + return c == 'e' || c == 'E'; } bool NumericLiteralParser::GetFixedPointValue(llvm::APInt &StoreVal, unsigned Scale) { @@ -1533,7 +1535,8 @@ bool NumericLiteralParser::GetFixedPointValue(llvm::APInt &StoreVal, unsigned Sc if (saw_exponent) { const char *Ptr = DigitsBegin; -while (!IsExponentPart(*Ptr)) ++Ptr; +while (!IsExponentPart(*Ptr, radix == 16)) + ++Ptr; ExponentBegin = Ptr; ++Ptr; NegativeExponent = *Ptr == '-'; diff --git a/clang/test/Frontend/GH83050.cpp b/clang/test/Frontend/GH83050.cpp new file mode 100644 index 00..4ba9d96f1257e6 --- /dev/null +++ b/clang/test/Frontend/GH83050.cpp @@ -0,0 +1,6 @@ +/// This is the regression test for https://github.com/llvm/llvm-project/issues/83050. +/// This just needs to compile. +// RUN: %clang_cc1 -x c++ -ffixed-point %s -fsyntax-only -triple=x86_64-linux +static constexpr unsigned short _Fract SQRT_FIRST_APPROX[12][2] = { +{0x1.e8p-1uhr, 0x1.0cp-2uhr}, +}; diff --git a/clang/test/Frontend/fixed_point_declarations.c b/clang/test/Frontend/fixed_point_declarations.c index 04ed25d227ca52..c8045767442739 100644 --- a/clang/test/Frontend/fixed_point_declarations.c +++ b/clang/test/Frontend/fixed_point_declarations.c @@ -125,3 +125,21 @@ long _Fract long_fract_zero = 0.0lr;// CHECK-DAG: @long_fract_ unsigned short _Fract u_short_fract_zero = 0.0uhr; // CHECK-DAG: @u_short_fract_zero = {{.*}}global i8 0, align 1 unsigned _Fract u_fract_zero= 0.0ur;// CHECK-DAG: @u_fract_zero = {{.*}}global i16 0, align 2 unsigned long _Fract u_long_fract_zero = 0.0ulr; // CHECK-DAG: @u_long_fract_zero= {{.*}}global i32 0, align 4 + +// Hex exponent suffix with E in hex digit sequence. +unsigned short _Fract e1 = 0x1.e8p-1uhr; // CHECK-DAG: @e1 = {{.*}}global i8 -12 +unsigned short _Fract e2 = 0x1.8ep-1uhr; // CHECK-DAG: @e2 = {{.*}}global i8 -57 +unsigned short _Fract e3 = 0x1.ep-1uhr; // CHECK-DAG: @e3 = {{.*}}global i8 -16 +unsigned _Accum e4 = 0xep-1uk; // CHECK-DAG: @e4 = {{.*}}global i32 458752 +unsigned _Accum e5 = 0xe.1p-1uk; // CHECK-DAG: @e5 = {{.*}}global i32 460800 +unsigned _Accum e6 = 0xe.ep-1uk; // CHECK-DAG: @e6 = {{.*}}global i32 487424 +unsigned _Accum e7 = 0xe.e8p-1uk; // CHECK-DAG: @e7 = {{.*}}global i32 488448 +unsigned _Accum e8 = 0xe.8ep-1uk; // CHECK-DAG: @e8 = {{.*}}global i32 476928 +unsigned short _Fract E1 = 0x1.E8p-1uhr; // CHECK-DAG: @E1 = {{.*}}global i8 -12 +unsigned short _Fract E2 = 0x1.8Ep-1uhr; // CHECK-DAG: @E2 = {{.*}}global i8 -57 +unsigned short _Fract E3 = 0x1.Ep-1uhr; // CHECK-DAG: @E3 = {{.*}}global i8 -16 +unsigned _Accum E4 = 0xEp-1uk; // CHECK-DAG: @E4 = {{.*}}global i32 458752 +unsigned _Accum E5 = 0xE.1p-1uk; // CHECK-DAG: @E5 = {{.*}}global i32 460800 +unsigned _Accum E6 = 0xE.Ep-1uk; // CHECK-DAG: @E6 = {{.*}}global i32 487424 +unsigned _Accum E7 = 0xE.E8p-1uk; // CHECK-DAG: @E7 = {{.*}}global i32 488448 +unsigned _Accum E8 = 0xE.8Ep-1uk; // CHECK-DAG: @E8 = {{.*}}global i32 476928 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [clang] Add fix for GH issue 83050 (PR #83071)
@@ -0,0 +1,11 @@ +/// This is the regression test for https://github.com/llvm/llvm-project/issues/83050. +/// This just needs to compile. +// RUN: %clang_cc1 -x c++ -ffixed-point -S %s -o /dev/null -triple=x86_64-linux -ffixed-point +static constexpr unsigned short _Fract SQRT_FIRST_APPROX[12][2] = { +{0x1.e8p-1uhr, 0x1.0cp-2uhr}, {0x1.bap-1uhr, 0x1.28p-2uhr}, +{0x1.94p-1uhr, 0x1.44p-2uhr}, {0x1.74p-1uhr, 0x1.6p-2uhr}, +{0x1.6p-1uhr, 0x1.74p-2uhr}, {0x1.4ep-1uhr, 0x1.88p-2uhr}, +{0x1.3ep-1uhr, 0x1.9cp-2uhr}, {0x1.32p-1uhr, 0x1.acp-2uhr}, +{0x1.22p-1uhr, 0x1.c4p-2uhr}, {0x1.18p-1uhr, 0x1.d4p-2uhr}, +{0x1.08p-1uhr, 0x1.fp-2uhr}, {0x1.04p-1uhr, 0x1.f8p-2uhr}, PiJoules wrote: Right, we don't need the whole list since it's only ones with an `e` before the exponent that trigger this. I copied this since the original godbolt reproducer had it, but we can just have the first element to reproduce. https://github.com/llvm/llvm-project/pull/83071 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [clang] Add fix for GH issue 83050 (PR #83071)
@@ -0,0 +1,11 @@ +/// This is the regression test for https://github.com/llvm/llvm-project/issues/83050. +/// This just needs to compile. +// RUN: %clang_cc1 -x c++ -ffixed-point -S %s -o /dev/null -triple=x86_64-linux -ffixed-point +static constexpr unsigned short _Fract SQRT_FIRST_APPROX[12][2] = { +{0x1.e8p-1uhr, 0x1.0cp-2uhr}, {0x1.bap-1uhr, 0x1.28p-2uhr}, +{0x1.94p-1uhr, 0x1.44p-2uhr}, {0x1.74p-1uhr, 0x1.6p-2uhr}, +{0x1.6p-1uhr, 0x1.74p-2uhr}, {0x1.4ep-1uhr, 0x1.88p-2uhr}, +{0x1.3ep-1uhr, 0x1.9cp-2uhr}, {0x1.32p-1uhr, 0x1.acp-2uhr}, +{0x1.22p-1uhr, 0x1.c4p-2uhr}, {0x1.18p-1uhr, 0x1.d4p-2uhr}, +{0x1.08p-1uhr, 0x1.fp-2uhr}, {0x1.04p-1uhr, 0x1.f8p-2uhr}, nickdesaulniers wrote: Also, do we need the full list of constants to expose this issue? I would have expected one such literal to expose this. https://github.com/llvm/llvm-project/pull/83071 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [clang] Add fix for GH issue 83050 (PR #83071)
https://github.com/lntue approved this pull request. https://github.com/llvm/llvm-project/pull/83071 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [clang] Add fix for GH issue 83050 (PR #83071)
@@ -0,0 +1,11 @@ +/// This is the regression test for https://github.com/llvm/llvm-project/issues/83050. +/// This just needs to compile. +// RUN: %clang_cc1 -x c++ -ffixed-point -S %s -o /dev/null -triple=x86_64-linux -ffixed-point nickdesaulniers wrote: Consider making this an `-fsyntax-only` test then since we don't care about codegen. https://github.com/llvm/llvm-project/pull/83071 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [clang] Add fix for GH issue 83050 (PR #83071)
llvmbot wrote: @llvm/pr-subscribers-clang Author: None (PiJoules) Changes Clang was incorrectly finding the start of the exponent in a fixed point hex literal. It would unconditionally find the first `e/E/p/P` in a constant regardless of if it were hex or not and parser the remaining digits as an APInt. In a debug build, this would be caught by an assertion, but in a release build, the assertion is removed and we'd end up in an infinite loop. --- Full diff: https://github.com/llvm/llvm-project/pull/83071.diff 3 Files Affected: - (modified) clang/lib/Lex/LiteralSupport.cpp (+6-3) - (added) clang/test/Frontend/GH83050.cpp (+11) - (modified) clang/test/Frontend/fixed_point_declarations.c (+18) ``diff diff --git a/clang/lib/Lex/LiteralSupport.cpp b/clang/lib/Lex/LiteralSupport.cpp index 571a984884029d..438c6d772e6e04 100644 --- a/clang/lib/Lex/LiteralSupport.cpp +++ b/clang/lib/Lex/LiteralSupport.cpp @@ -1513,8 +1513,10 @@ NumericLiteralParser::GetFloatValue(llvm::APFloat &Result) { : APFloat::opInvalidOp; } -static inline bool IsExponentPart(char c) { - return c == 'p' || c == 'P' || c == 'e' || c == 'E'; +static inline bool IsExponentPart(char c, bool isHex) { + if (isHex) +return c == 'p' || c == 'P'; + return c == 'e' || c == 'E'; } bool NumericLiteralParser::GetFixedPointValue(llvm::APInt &StoreVal, unsigned Scale) { @@ -1533,7 +1535,8 @@ bool NumericLiteralParser::GetFixedPointValue(llvm::APInt &StoreVal, unsigned Sc if (saw_exponent) { const char *Ptr = DigitsBegin; -while (!IsExponentPart(*Ptr)) ++Ptr; +while (!IsExponentPart(*Ptr, radix == 16)) + ++Ptr; ExponentBegin = Ptr; ++Ptr; NegativeExponent = *Ptr == '-'; diff --git a/clang/test/Frontend/GH83050.cpp b/clang/test/Frontend/GH83050.cpp new file mode 100644 index 00..df55d848a5fd5f --- /dev/null +++ b/clang/test/Frontend/GH83050.cpp @@ -0,0 +1,11 @@ +/// This is the regression test for https://github.com/llvm/llvm-project/issues/83050. +/// This just needs to compile. +// RUN: %clang_cc1 -x c++ -ffixed-point -S %s -o /dev/null -triple=x86_64-linux -ffixed-point +static constexpr unsigned short _Fract SQRT_FIRST_APPROX[12][2] = { +{0x1.e8p-1uhr, 0x1.0cp-2uhr}, {0x1.bap-1uhr, 0x1.28p-2uhr}, +{0x1.94p-1uhr, 0x1.44p-2uhr}, {0x1.74p-1uhr, 0x1.6p-2uhr}, +{0x1.6p-1uhr, 0x1.74p-2uhr}, {0x1.4ep-1uhr, 0x1.88p-2uhr}, +{0x1.3ep-1uhr, 0x1.9cp-2uhr}, {0x1.32p-1uhr, 0x1.acp-2uhr}, +{0x1.22p-1uhr, 0x1.c4p-2uhr}, {0x1.18p-1uhr, 0x1.d4p-2uhr}, +{0x1.08p-1uhr, 0x1.fp-2uhr}, {0x1.04p-1uhr, 0x1.f8p-2uhr}, +}; diff --git a/clang/test/Frontend/fixed_point_declarations.c b/clang/test/Frontend/fixed_point_declarations.c index 04ed25d227ca52..c8045767442739 100644 --- a/clang/test/Frontend/fixed_point_declarations.c +++ b/clang/test/Frontend/fixed_point_declarations.c @@ -125,3 +125,21 @@ long _Fract long_fract_zero = 0.0lr;// CHECK-DAG: @long_fract_ unsigned short _Fract u_short_fract_zero = 0.0uhr; // CHECK-DAG: @u_short_fract_zero = {{.*}}global i8 0, align 1 unsigned _Fract u_fract_zero= 0.0ur;// CHECK-DAG: @u_fract_zero = {{.*}}global i16 0, align 2 unsigned long _Fract u_long_fract_zero = 0.0ulr; // CHECK-DAG: @u_long_fract_zero= {{.*}}global i32 0, align 4 + +// Hex exponent suffix with E in hex digit sequence. +unsigned short _Fract e1 = 0x1.e8p-1uhr; // CHECK-DAG: @e1 = {{.*}}global i8 -12 +unsigned short _Fract e2 = 0x1.8ep-1uhr; // CHECK-DAG: @e2 = {{.*}}global i8 -57 +unsigned short _Fract e3 = 0x1.ep-1uhr; // CHECK-DAG: @e3 = {{.*}}global i8 -16 +unsigned _Accum e4 = 0xep-1uk; // CHECK-DAG: @e4 = {{.*}}global i32 458752 +unsigned _Accum e5 = 0xe.1p-1uk; // CHECK-DAG: @e5 = {{.*}}global i32 460800 +unsigned _Accum e6 = 0xe.ep-1uk; // CHECK-DAG: @e6 = {{.*}}global i32 487424 +unsigned _Accum e7 = 0xe.e8p-1uk; // CHECK-DAG: @e7 = {{.*}}global i32 488448 +unsigned _Accum e8 = 0xe.8ep-1uk; // CHECK-DAG: @e8 = {{.*}}global i32 476928 +unsigned short _Fract E1 = 0x1.E8p-1uhr; // CHECK-DAG: @E1 = {{.*}}global i8 -12 +unsigned short _Fract E2 = 0x1.8Ep-1uhr; // CHECK-DAG: @E2 = {{.*}}global i8 -57 +unsigned short _Fract E3 = 0x1.Ep-1uhr; // CHECK-DAG: @E3 = {{.*}}global i8 -16 +unsigned _Accum E4 = 0xEp-1uk; // CHECK-DAG: @E4 = {{.*}}global i32 458752 +unsigned _Accum E5 = 0xE.1p-1uk; // CHECK-DAG: @E5 = {{.*}}global i32 460800 +unsigned _Accum E6 = 0xE.Ep-1uk; // CHECK-DAG: @E6 = {{.*}}global i32 487424 +unsigned _Accum E7 = 0xE.E8p-1uk; // CHECK-DAG: @E7 = {{.*}}global i32 488448 +unsigned _Accum E8 = 0xE.8Ep-1uk; // CHECK-DAG: @E8 = {{.*}}global i32 476928 `` https://github.com/llvm/llvm-project/pull/83071 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [clang] Add fix for GH issue 83050 (PR #83071)
https://github.com/PiJoules created https://github.com/llvm/llvm-project/pull/83071 Clang was incorrectly finding the start of the exponent in a fixed point hex literal. It would unconditionally find the first `e/E/p/P` in a constant regardless of if it were hex or not and parser the remaining digits as an APInt. In a debug build, this would be caught by an assertion, but in a release build, the assertion is removed and we'd end up in an infinite loop. >From 26b6f600f8ebe7751f68af78f714f8b4ae24071c Mon Sep 17 00:00:00 2001 From: Leonard Chan Date: Mon, 26 Feb 2024 14:11:45 -0800 Subject: [PATCH] [clang] Add fix for GH issue 83050 Clang was incorrectly finding the start of the exponent in a fixed point hex literal. It would unconditionally find the first `e/E/p/P` in a constant regardless of if it were hex or not and parser the remaining digits as an APInt. In a debug build, this would be caught by an assertion, but in a release build, the assertion is removed and we'd end up in an infinite loop. --- clang/lib/Lex/LiteralSupport.cpp | 9 ++--- clang/test/Frontend/GH83050.cpp| 11 +++ clang/test/Frontend/fixed_point_declarations.c | 18 ++ 3 files changed, 35 insertions(+), 3 deletions(-) create mode 100644 clang/test/Frontend/GH83050.cpp diff --git a/clang/lib/Lex/LiteralSupport.cpp b/clang/lib/Lex/LiteralSupport.cpp index 571a984884029d..438c6d772e6e04 100644 --- a/clang/lib/Lex/LiteralSupport.cpp +++ b/clang/lib/Lex/LiteralSupport.cpp @@ -1513,8 +1513,10 @@ NumericLiteralParser::GetFloatValue(llvm::APFloat &Result) { : APFloat::opInvalidOp; } -static inline bool IsExponentPart(char c) { - return c == 'p' || c == 'P' || c == 'e' || c == 'E'; +static inline bool IsExponentPart(char c, bool isHex) { + if (isHex) +return c == 'p' || c == 'P'; + return c == 'e' || c == 'E'; } bool NumericLiteralParser::GetFixedPointValue(llvm::APInt &StoreVal, unsigned Scale) { @@ -1533,7 +1535,8 @@ bool NumericLiteralParser::GetFixedPointValue(llvm::APInt &StoreVal, unsigned Sc if (saw_exponent) { const char *Ptr = DigitsBegin; -while (!IsExponentPart(*Ptr)) ++Ptr; +while (!IsExponentPart(*Ptr, radix == 16)) + ++Ptr; ExponentBegin = Ptr; ++Ptr; NegativeExponent = *Ptr == '-'; diff --git a/clang/test/Frontend/GH83050.cpp b/clang/test/Frontend/GH83050.cpp new file mode 100644 index 00..df55d848a5fd5f --- /dev/null +++ b/clang/test/Frontend/GH83050.cpp @@ -0,0 +1,11 @@ +/// This is the regression test for https://github.com/llvm/llvm-project/issues/83050. +/// This just needs to compile. +// RUN: %clang_cc1 -x c++ -ffixed-point -S %s -o /dev/null -triple=x86_64-linux -ffixed-point +static constexpr unsigned short _Fract SQRT_FIRST_APPROX[12][2] = { +{0x1.e8p-1uhr, 0x1.0cp-2uhr}, {0x1.bap-1uhr, 0x1.28p-2uhr}, +{0x1.94p-1uhr, 0x1.44p-2uhr}, {0x1.74p-1uhr, 0x1.6p-2uhr}, +{0x1.6p-1uhr, 0x1.74p-2uhr}, {0x1.4ep-1uhr, 0x1.88p-2uhr}, +{0x1.3ep-1uhr, 0x1.9cp-2uhr}, {0x1.32p-1uhr, 0x1.acp-2uhr}, +{0x1.22p-1uhr, 0x1.c4p-2uhr}, {0x1.18p-1uhr, 0x1.d4p-2uhr}, +{0x1.08p-1uhr, 0x1.fp-2uhr}, {0x1.04p-1uhr, 0x1.f8p-2uhr}, +}; diff --git a/clang/test/Frontend/fixed_point_declarations.c b/clang/test/Frontend/fixed_point_declarations.c index 04ed25d227ca52..c8045767442739 100644 --- a/clang/test/Frontend/fixed_point_declarations.c +++ b/clang/test/Frontend/fixed_point_declarations.c @@ -125,3 +125,21 @@ long _Fract long_fract_zero = 0.0lr;// CHECK-DAG: @long_fract_ unsigned short _Fract u_short_fract_zero = 0.0uhr; // CHECK-DAG: @u_short_fract_zero = {{.*}}global i8 0, align 1 unsigned _Fract u_fract_zero= 0.0ur;// CHECK-DAG: @u_fract_zero = {{.*}}global i16 0, align 2 unsigned long _Fract u_long_fract_zero = 0.0ulr; // CHECK-DAG: @u_long_fract_zero= {{.*}}global i32 0, align 4 + +// Hex exponent suffix with E in hex digit sequence. +unsigned short _Fract e1 = 0x1.e8p-1uhr; // CHECK-DAG: @e1 = {{.*}}global i8 -12 +unsigned short _Fract e2 = 0x1.8ep-1uhr; // CHECK-DAG: @e2 = {{.*}}global i8 -57 +unsigned short _Fract e3 = 0x1.ep-1uhr; // CHECK-DAG: @e3 = {{.*}}global i8 -16 +unsigned _Accum e4 = 0xep-1uk; // CHECK-DAG: @e4 = {{.*}}global i32 458752 +unsigned _Accum e5 = 0xe.1p-1uk; // CHECK-DAG: @e5 = {{.*}}global i32 460800 +unsigned _Accum e6 = 0xe.ep-1uk; // CHECK-DAG: @e6 = {{.*}}global i32 487424 +unsigned _Accum e7 = 0xe.e8p-1uk; // CHECK-DAG: @e7 = {{.*}}global i32 488448 +unsigned _Accum e8 = 0xe.8ep-1uk; // CHECK-DAG: @e8 = {{.*}}global i32 476928 +unsigned short _Fract E1 = 0x1.E8p-1uhr; // CHECK-DAG: @E1 = {{.*}}global i8 -12 +unsigned short _Fract E2 = 0x1.8Ep-1uhr; // CHECK-DAG: @E2 = {{.*}}global i8 -57 +unsigned short _Fract E3 = 0x1.Ep-1uhr; // CHECK-DAG: @E3 = {{.*}}global i8 -16 +unsigned _Accum E4 = 0xEp-1uk; // CHECK-DAG: @E4 =