diff --git a/flang/include/flang/Runtime/freestanding-tools.h b/flang/include/flang/Runtime/freestanding-tools.h index 7f8d37d87e0e6..e94cb0a6c938c 100644 --- a/flang/include/flang/Runtime/freestanding-tools.h +++ b/flang/include/flang/Runtime/freestanding-tools.h @@ -12,6 +12,7 @@ #include "flang/Common/api-attrs.h" #include "flang/Runtime/c-or-cpp.h" #include +#include #include // The file defines a set of utilities/classes that might be @@ -57,6 +58,11 @@ #define STD_STRCMP_UNSUPPORTED 1 #endif +#if !defined(STD_TOUPPER_UNSUPPORTED) && \ + (defined(__CUDACC__) || defined(__CUDA__)) && defined(__CUDA_ARCH__) +#define STD_TOUPPER_UNSUPPORTED 1 +#endif + namespace Fortran::runtime { #if STD_FILL_N_UNSUPPORTED @@ -195,5 +201,18 @@ static inline RT_API_ATTRS int strcmp(const char *lhs, const char *rhs) { using std::strcmp; #endif // !STD_STRCMP_UNSUPPORTED +#if STD_TOUPPER_UNSUPPORTED +// Provides alternative implementation for std::toupper(), if +// it is not supported. +static inline RT_API_ATTRS int toupper(int ch) { + if (ch >= 'a' && ch <= 'z') { + return ch - 'a' + 'A'; + } + return ch; +} +#else // !STD_TOUPPER_UNSUPPORTED +using std::toupper; +#endif // !STD_TOUPPER_UNSUPPORTED + } // namespace Fortran::runtime #endif // FORTRAN_RUNTIME_FREESTANDING_TOOLS_H_ diff --git a/flang/lib/Decimal/decimal-to-binary.cpp b/flang/lib/Decimal/decimal-to-binary.cpp index dc4aa82ac6fe4..eebd0736b67ad 100644 --- a/flang/lib/Decimal/decimal-to-binary.cpp +++ b/flang/lib/Decimal/decimal-to-binary.cpp @@ -11,9 +11,9 @@ #include "flang/Common/leading-zero-bit-count.h" #include "flang/Decimal/binary-floating-point.h" #include "flang/Decimal/decimal.h" +#include "flang/Runtime/freestanding-tools.h" #include #include -#include #include namespace Fortran::decimal { @@ -468,8 +468,8 @@ BigRadixFloatingPointNumber::ConvertToBinary( ++q; } } - if ((!limit || limit >= q + 3) && toupper(q[0]) == 'N' && - toupper(q[1]) == 'A' && toupper(q[2]) == 'N') { + if ((!limit || limit >= q + 3) && runtime::toupper(q[0]) == 'N' && + runtime::toupper(q[1]) == 'A' && runtime::toupper(q[2]) == 'N') { // NaN p = q + 3; bool isQuiet{true}; @@ -493,11 +493,11 @@ BigRadixFloatingPointNumber::ConvertToBinary( } return {Real{NaN(isQuiet)}}; } else { // Inf? - if ((!limit || limit >= q + 3) && toupper(q[0]) == 'I' && - toupper(q[1]) == 'N' && toupper(q[2]) == 'F') { - if ((!limit || limit >= q + 8) && toupper(q[3]) == 'I' && - toupper(q[4]) == 'N' && toupper(q[5]) == 'I' && - toupper(q[6]) == 'T' && toupper(q[7]) == 'Y') { + if ((!limit || limit >= q + 3) && runtime::toupper(q[0]) == 'I' && + runtime::toupper(q[1]) == 'N' && runtime::toupper(q[2]) == 'F') { + if ((!limit || limit >= q + 8) && runtime::toupper(q[3]) == 'I' && + runtime::toupper(q[4]) == 'N' && runtime::toupper(q[5]) == 'I' && + runtime::toupper(q[6]) == 'T' && runtime::toupper(q[7]) == 'Y') { p = q + 8; } else { p = q + 3;