From 2694234c2982c57b9442ad1a1b4ffb2100f4ff34 Mon Sep 17 00:00:00 2001 From: Jean Perier Date: Tue, 13 Sep 2022 10:39:33 +0200 Subject: [PATCH] [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 --- flang/runtime/character.cpp | 7 +++++-- flang/unittests/Runtime/CharacterTest.cpp | 2 ++ 2 files changed, 7 insertions(+), 2 deletions(-) diff --git a/flang/runtime/character.cpp b/flang/runtime/character.cpp index 16f3933..dd522f1 100644 --- a/flang/runtime/character.cpp +++ b/flang/runtime/character.cpp @@ -20,11 +20,14 @@ namespace Fortran::runtime { template inline int CompareToBlankPadding(const CHAR *x, std::size_t chars) { + using UNSIGNED_CHAR = std::make_unsigned_t; + const auto blank{static_cast(' ')}; for (; chars-- > 0; ++x) { - if (*x < ' ') { + const UNSIGNED_CHAR ux{*reinterpret_cast(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 6e14ebd..e54fd8a 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), -- 2.7.4