[flang-commits] [flang] 8f0f9ea - [flang] Fix CHARACTER length folding problem
peter klausler via flang-commits
flang-commits at lists.llvm.org
Tue Jul 7 16:39:16 PDT 2020
Author: peter klausler
Date: 2020-07-07T16:38:36-07:00
New Revision: 8f0f9eaddf9ea8cbab418a64fb6557928b3c907a
URL: https://github.com/llvm/llvm-project/commit/8f0f9eaddf9ea8cbab418a64fb6557928b3c907a
DIFF: https://github.com/llvm/llvm-project/commit/8f0f9eaddf9ea8cbab418a64fb6557928b3c907a.diff
LOG: [flang] Fix CHARACTER length folding problem
Do not rewrite LEN(x) or x%len to the expression that specifies
the length of x when that length is not a constant expression.
Its value may have changed since the value of the expression was
first captured in the definition of the object.
Reviewed By: tskeith, sscalpone
Differential Revision: https://reviews.llvm.org/D83352
Added:
Modified:
flang/include/flang/Evaluate/type.h
flang/lib/Evaluate/fold-integer.cpp
flang/lib/Evaluate/shape.cpp
flang/lib/Evaluate/type.cpp
flang/lib/Evaluate/variable.cpp
Removed:
################################################################################
diff --git a/flang/include/flang/Evaluate/type.h b/flang/include/flang/Evaluate/type.h
index 197fb3291dd4..c62d63356343 100644
--- a/flang/include/flang/Evaluate/type.h
+++ b/flang/include/flang/Evaluate/type.h
@@ -146,7 +146,7 @@ class DynamicType {
DynamicType ResultTypeForMultiply(const DynamicType &) const;
bool IsAssumedLengthCharacter() const;
- bool IsUnknownLengthCharacter() const;
+ bool IsNonConstantLengthCharacter() const;
bool IsTypelessIntrinsicArgument() const;
constexpr bool IsAssumedType() const { // TYPE(*)
return kind_ == AssumedTypeKind;
diff --git a/flang/lib/Evaluate/fold-integer.cpp b/flang/lib/Evaluate/fold-integer.cpp
index 5b07eaa454d8..9b96a479df59 100644
--- a/flang/lib/Evaluate/fold-integer.cpp
+++ b/flang/lib/Evaluate/fold-integer.cpp
@@ -612,7 +612,9 @@ Expr<Type<TypeCategory::Integer, KIND>> FoldOperation(
if (iter != scope->end()) {
const Symbol &symbol{*iter->second};
const auto *details{symbol.detailsIf<semantics::TypeParamDetails>()};
- if (details && details->init()) {
+ if (details && details->init() &&
+ (details->attr() == common::TypeParamAttr::Kind ||
+ IsConstantExpr(*details->init()))) {
Expr<SomeInteger> expr{*details->init()};
return Fold(context,
Expr<IntKIND>{
diff --git a/flang/lib/Evaluate/shape.cpp b/flang/lib/Evaluate/shape.cpp
index e943b49fcf1b..90d864466e2d 100644
--- a/flang/lib/Evaluate/shape.cpp
+++ b/flang/lib/Evaluate/shape.cpp
@@ -205,7 +205,7 @@ auto GetLowerBoundHelper::operator()(const Symbol &symbol0) -> Result {
if (j++ == dimension_) {
if (const auto &bound{shapeSpec.lbound().GetExplicit()}) {
return Fold(context_, common::Clone(*bound));
- } else if (semantics::IsDescriptor(symbol)) {
+ } else if (IsDescriptor(symbol)) {
return ExtentExpr{DescriptorInquiry{NamedEntity{symbol0},
DescriptorInquiry::Field::LowerBound, dimension_}};
} else {
@@ -230,7 +230,7 @@ auto GetLowerBoundHelper::operator()(const Component &component) -> Result {
if (j++ == dimension_) {
if (const auto &bound{shapeSpec.lbound().GetExplicit()}) {
return Fold(context_, common::Clone(*bound));
- } else if (semantics::IsDescriptor(symbol)) {
+ } else if (IsDescriptor(symbol)) {
return ExtentExpr{
DescriptorInquiry{NamedEntity{common::Clone(component)},
DescriptorInquiry::Field::LowerBound, dimension_}};
diff --git a/flang/lib/Evaluate/type.cpp b/flang/lib/Evaluate/type.cpp
index 0a823cd20398..293cd1864814 100644
--- a/flang/lib/Evaluate/type.cpp
+++ b/flang/lib/Evaluate/type.cpp
@@ -22,17 +22,21 @@
// IsDescriptor() predicate: true when a symbol is implemented
// at runtime with a descriptor.
-// TODO there's probably a better place for this predicate than here
namespace Fortran::semantics {
-static bool IsDescriptor(const ObjectEntityDetails &details) {
- if (const auto *type{details.type()}) {
+static bool IsDescriptor(const DeclTypeSpec *type) {
+ if (type) {
if (auto dynamicType{evaluate::DynamicType::From(*type)}) {
- if (dynamicType->RequiresDescriptor()) {
- return true;
- }
+ return dynamicType->RequiresDescriptor();
}
}
+ return false;
+}
+
+static bool IsDescriptor(const ObjectEntityDetails &details) {
+ if (IsDescriptor(details.type())) {
+ return true;
+ }
// TODO: Automatic (adjustable) arrays - are they descriptors?
for (const ShapeSpec &shapeSpec : details.shape()) {
const auto &lb{shapeSpec.lbound().GetExplicit()};
@@ -62,6 +66,7 @@ bool IsDescriptor(const Symbol &symbol) {
symbol.attrs().test(Attr::EXTERNAL)) &&
IsDescriptor(d);
},
+ [&](const EntityDetails &d) { return IsDescriptor(d.type()); },
[](const AssocEntityDetails &d) {
if (const auto &expr{d.expr()}) {
if (expr->Rank() > 0) {
@@ -149,7 +154,7 @@ bool DynamicType::IsAssumedLengthCharacter() const {
charLength_->isAssumed();
}
-bool DynamicType::IsUnknownLengthCharacter() const {
+bool DynamicType::IsNonConstantLengthCharacter() const {
if (category_ != TypeCategory::Character) {
return false;
} else if (!charLength_) {
@@ -471,7 +476,7 @@ DynamicType DynamicType::ResultTypeForMultiply(const DynamicType &that) const {
}
bool DynamicType::RequiresDescriptor() const {
- return IsPolymorphic() || IsUnknownLengthCharacter() ||
+ return IsPolymorphic() || IsNonConstantLengthCharacter() ||
(derived_ && CountNonConstantLenParameters(*derived_) > 0);
}
diff --git a/flang/lib/Evaluate/variable.cpp b/flang/lib/Evaluate/variable.cpp
index 3a6cf560384c..8c9bd18285af 100644
--- a/flang/lib/Evaluate/variable.cpp
+++ b/flang/lib/Evaluate/variable.cpp
@@ -8,6 +8,7 @@
#include "flang/Evaluate/variable.h"
#include "flang/Common/idioms.h"
+#include "flang/Evaluate/check-expression.h"
#include "flang/Evaluate/fold.h"
#include "flang/Evaluate/tools.h"
#include "flang/Parser/char-block.h"
@@ -259,16 +260,13 @@ static std::optional<Expr<SubscriptInteger>> SymbolLEN(const Symbol &sym) {
if (const semantics::ParamValue * len{dyType->charLength()}) {
if (len->isExplicit()) {
if (auto intExpr{len->GetExplicit()}) {
- return ConvertToType<SubscriptInteger>(*std::move(intExpr));
- } else {
- // There was an error constructing this symbol's type. It should
- // have a length expression, but we couldn't retrieve it
- return std::nullopt;
+ if (IsConstantExpr(*intExpr)) {
+ return ConvertToType<SubscriptInteger>(*std::move(intExpr));
+ }
}
- } else {
- return Expr<SubscriptInteger>{
- DescriptorInquiry{NamedEntity{sym}, DescriptorInquiry::Field::Len}};
}
+ return Expr<SubscriptInteger>{
+ DescriptorInquiry{NamedEntity{sym}, DescriptorInquiry::Field::Len}};
}
}
return std::nullopt;
More information about the flang-commits
mailing list