[flang-commits] [flang] 2694234 - [flang][runtime] ensure character compares to blank are unsigned

Jean Perier via flang-commits flang-commits at lists.llvm.org
Tue Sep 13 01:43:21 PDT 2022


Author: Jean Perier
Date: 2022-09-13T10:42:53+02:00
New Revision: 2694234c2982c57b9442ad1a1b4ffb2100f4ff34

URL: https://github.com/llvm/llvm-project/commit/2694234c2982c57b9442ad1a1b4ffb2100f4ff34
DIFF: https://github.com/llvm/llvm-project/commit/2694234c2982c57b9442ad1a1b4ffb2100f4ff34.diff

LOG: [flang][runtime] ensure character compares to blank are unsigned

CompareToBlankPadding was doing signed compare on architecture where
`char` is signed. This caused `'abc'//char(128) > 'abc'` to evaluate
to false at runtime instead of true.

Differential Revision: https://reviews.llvm.org/D133693

Added: 
    

Modified: 
    flang/runtime/character.cpp
    flang/unittests/Runtime/CharacterTest.cpp

Removed: 
    


################################################################################
diff  --git a/flang/runtime/character.cpp b/flang/runtime/character.cpp
index 16f39332cc60..dd522f19a7ed 100644
--- a/flang/runtime/character.cpp
+++ b/flang/runtime/character.cpp
@@ -20,11 +20,14 @@ namespace Fortran::runtime {
 
 template <typename CHAR>
 inline int CompareToBlankPadding(const CHAR *x, std::size_t chars) {
+  using UNSIGNED_CHAR = std::make_unsigned_t<CHAR>;
+  const auto blank{static_cast<UNSIGNED_CHAR>(' ')};
   for (; chars-- > 0; ++x) {
-    if (*x < ' ') {
+    const UNSIGNED_CHAR ux{*reinterpret_cast<const UNSIGNED_CHAR *>(x)};
+    if (ux < blank) {
       return -1;
     }
-    if (*x > ' ') {
+    if (ux > blank) {
       return 1;
     }
   }

diff  --git a/flang/unittests/Runtime/CharacterTest.cpp b/flang/unittests/Runtime/CharacterTest.cpp
index 6e14ebdf725c..e54fd8a5075f 100644
--- a/flang/unittests/Runtime/CharacterTest.cpp
+++ b/flang/unittests/Runtime/CharacterTest.cpp
@@ -171,6 +171,8 @@ static ComparisonTestCasesTy comparisonTestCases{
         std::make_tuple("abc", "def", 3, 3, -1),
         std::make_tuple("ab ", "abc", 3, 2, 0),
         std::make_tuple("abc", "abc", 2, 3, -1),
+        std::make_tuple("ab\xff", "ab ", 3, 2, 1),
+        std::make_tuple("ab ", "ab\xff", 2, 3, -1),
     },
     {
         std::make_tuple(u"abc", u"abc", 3, 3, 0),


        


More information about the flang-commits mailing list