[flang] Fix LEN(char array), it is not elemental.

Original-commit: flang-compiler/f18@b44eb2e7b1
Reviewed-on: https://github.com/flang-compiler/f18/pull/477
Tree-same-pre-rewrite: false
This commit is contained in:
peter klausler 2019-06-04 10:09:54 -07:00
parent b50170c99d
commit fb1fcbb9cd
2 changed files with 22 additions and 7 deletions

View File

@ -410,7 +410,8 @@ static const IntrinsicInterface genericIntrinsicFunction[]{
{{"array", Anything, Rank::anyOrAssumedRank}, SubscriptDefaultKIND},
KINDInt, Rank::vector},
{"leadz", {{"i", AnyInt}}, DefaultInt},
{"len", {{"string", AnyChar}, SubscriptDefaultKIND}, KINDInt},
{"len", {{"string", AnyChar, Rank::anyOrAssumedRank}, SubscriptDefaultKIND},
KINDInt},
{"len_trim", {{"string", AnyChar}, SubscriptDefaultKIND}, KINDInt},
{"lge", {{"string_a", SameChar}, {"string_b", SameChar}}, DefaultLogical},
{"lgt", {{"string_a", SameChar}, {"string_b", SameChar}}, DefaultLogical},
@ -733,7 +734,7 @@ static const SpecificIntrinsicInterface specificIntrinsicFunction[]{
{{"index", {{"string", DefaultChar}, {"substring", DefaultChar}},
DefaultInt}},
{{"isign", {{"a", DefaultInt}, {"b", DefaultInt}}, DefaultInt}, "sign"},
{{"len", {{"string", DefaultChar}}, DefaultInt}},
{{"len", {{"string", DefaultChar, Rank::anyOrAssumedRank}}, DefaultInt}},
{{"log", {{"x", DefaultReal}}, DefaultReal}},
{{"log10", {{"x", DefaultReal}}, DefaultReal}},
{{"max0",

View File

@ -1,4 +1,4 @@
// Copyright (c) 2018, NVIDIA CORPORATION. All rights reserved.
// Copyright (c) 2018-2019, NVIDIA CORPORATION. All rights reserved.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
@ -20,12 +20,18 @@
namespace Fortran::evaluate::value {
template<int BITS> class Logical {
template<int BITS, bool IS_LIKE_C = false> class Logical {
public:
static constexpr int bits{BITS};
// Module ISO_C_BINDING kind C_BOOL is LOGICAL(KIND=1) and must have
// C's bit representation (.TRUE. -> 1, .FALSE. -> 0).
static constexpr bool IsLikeC{BITS <= 8 || IS_LIKE_C};
constexpr Logical() {} // .FALSE.
constexpr Logical(const Logical &that) = default;
constexpr Logical(bool truth) : word_{-std::uint64_t{truth}} {}
constexpr Logical(bool truth)
: word_{truth ? canonicalTrue : canonicalFalse} {}
constexpr Logical &operator=(const Logical &) = default;
template<int B> constexpr bool operator==(const Logical<B> &that) const {
@ -33,9 +39,15 @@ public:
}
// For static expression evaluation, all the bits will have the same value.
constexpr bool IsTrue() const { return word_.BTEST(0); }
constexpr bool IsTrue() const {
if constexpr (IsLikeC) {
return !word_.IsZero();
} else {
return word_.BTEST(0);
}
}
constexpr Logical NOT() const { return {word_.NOT()}; }
constexpr Logical NOT() const { return {word_.IEOR(canonicalTrue)}; }
constexpr Logical AND(const Logical &that) const {
return {word_.IAND(that.word_)};
@ -53,6 +65,8 @@ public:
private:
using Word = Integer<bits>;
static constexpr Word canonicalTrue{IsLikeC ? -std::uint64_t{1} : 1};
static constexpr Word canonicalFalse{0};
constexpr Logical(const Word &w) : word_{w} {}
Word word_;
};