[clang] [clang] Add fix for GH issue 83050 (PR #83071)

2024-02-26 Thread via cfe-commits

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 
) {
: 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 , unsigned 
Scale) {
@@ -1533,7 +1535,8 @@ bool NumericLiteralParser::GetFixedPointValue(llvm::APInt 
, 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)

2024-02-26 Thread via cfe-commits


@@ -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)

2024-02-26 Thread Nick Desaulniers via cfe-commits


@@ -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)

2024-02-26 Thread Nick Desaulniers via cfe-commits

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)

2024-02-26 Thread via cfe-commits

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 
) {
: 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 , unsigned 
Scale) {
@@ -1533,7 +1535,8 @@ bool NumericLiteralParser::GetFixedPointValue(llvm::APInt 
, 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)

2024-02-26 Thread via cfe-commits


@@ -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)

2024-02-26 Thread Nick Desaulniers via cfe-commits


@@ -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)

2024-02-26 Thread via cfe-commits

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)

2024-02-26 Thread Nick Desaulniers via cfe-commits


@@ -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)

2024-02-26 Thread via cfe-commits

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 
) {
: 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 , unsigned 
Scale) {
@@ -1533,7 +1535,8 @@ bool NumericLiteralParser::GetFixedPointValue(llvm::APInt 
, 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)

2024-02-26 Thread via cfe-commits

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 
) {
: 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 , unsigned 
Scale) {
@@ -1533,7 +1535,8 @@ bool NumericLiteralParser::GetFixedPointValue(llvm::APInt 
, 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