mirror of
https://github.com/capstone-engine/llvm-capstone.git
synced 2024-11-23 22:00:10 +00:00
[flang] Preserve component array lower bounds in folding
When a component array of a named constant is extracted as a constant value, ensure that the lower bounds of the array are properly acquired from the declaration of the component. Differential Revision: https://reviews.llvm.org/D134499
This commit is contained in:
parent
0d58a8cd49
commit
3bbb2c2d99
@ -1109,6 +1109,33 @@ std::optional<Expr<SomeType>> DataConstantConversionExtension(
|
||||
std::optional<Expr<SomeType>> HollerithToBOZ(
|
||||
FoldingContext &, const Expr<SomeType> &, const DynamicType &);
|
||||
|
||||
// Set explicit lower bounds on a constant array.
|
||||
class ArrayConstantBoundChanger {
|
||||
public:
|
||||
explicit ArrayConstantBoundChanger(ConstantSubscripts &&lbounds)
|
||||
: lbounds_{std::move(lbounds)} {}
|
||||
|
||||
template <typename A> A ChangeLbounds(A &&x) const {
|
||||
return std::move(x); // default case
|
||||
}
|
||||
template <typename T> Constant<T> ChangeLbounds(Constant<T> &&x) {
|
||||
x.set_lbounds(std::move(lbounds_));
|
||||
return std::move(x);
|
||||
}
|
||||
template <typename T> Expr<T> ChangeLbounds(Parentheses<T> &&x) {
|
||||
return ChangeLbounds(
|
||||
std::move(x.left())); // Constant<> can be parenthesized
|
||||
}
|
||||
template <typename T> Expr<T> ChangeLbounds(Expr<T> &&x) {
|
||||
return common::visit(
|
||||
[&](auto &&x) { return Expr<T>{ChangeLbounds(std::move(x))}; },
|
||||
std::move(x.u)); // recurse until we hit a constant
|
||||
}
|
||||
|
||||
private:
|
||||
ConstantSubscripts &&lbounds_;
|
||||
};
|
||||
|
||||
} // namespace Fortran::evaluate
|
||||
|
||||
namespace Fortran::semantics {
|
||||
|
@ -9,6 +9,7 @@
|
||||
#include "flang/Evaluate/check-expression.h"
|
||||
#include "flang/Evaluate/characteristics.h"
|
||||
#include "flang/Evaluate/intrinsics.h"
|
||||
#include "flang/Evaluate/tools.h"
|
||||
#include "flang/Evaluate/traverse.h"
|
||||
#include "flang/Evaluate/type.h"
|
||||
#include "flang/Semantics/symbol.h"
|
||||
@ -363,32 +364,6 @@ bool IsInitialProcedureTarget(const Expr<SomeType> &expr) {
|
||||
}
|
||||
}
|
||||
|
||||
class ArrayConstantBoundChanger {
|
||||
public:
|
||||
ArrayConstantBoundChanger(ConstantSubscripts &&lbounds)
|
||||
: lbounds_{std::move(lbounds)} {}
|
||||
|
||||
template <typename A> A ChangeLbounds(A &&x) const {
|
||||
return std::move(x); // default case
|
||||
}
|
||||
template <typename T> Constant<T> ChangeLbounds(Constant<T> &&x) {
|
||||
x.set_lbounds(std::move(lbounds_));
|
||||
return std::move(x);
|
||||
}
|
||||
template <typename T> Expr<T> ChangeLbounds(Parentheses<T> &&x) {
|
||||
return ChangeLbounds(
|
||||
std::move(x.left())); // Constant<> can be parenthesized
|
||||
}
|
||||
template <typename T> Expr<T> ChangeLbounds(Expr<T> &&x) {
|
||||
return common::visit(
|
||||
[&](auto &&x) { return Expr<T>{ChangeLbounds(std::move(x))}; },
|
||||
std::move(x.u)); // recurse until we hit a constant
|
||||
}
|
||||
|
||||
private:
|
||||
ConstantSubscripts &&lbounds_;
|
||||
};
|
||||
|
||||
// Converts, folds, and then checks type, rank, and shape of an
|
||||
// initialization expression for a named constant, a non-pointer
|
||||
// variable static initialization, a component default initializer,
|
||||
|
@ -10,6 +10,7 @@
|
||||
#include "fold-implementation.h"
|
||||
#include "flang/Evaluate/characteristics.h"
|
||||
#include "flang/Evaluate/initial-image.h"
|
||||
#include "flang/Evaluate/tools.h"
|
||||
|
||||
namespace Fortran::evaluate {
|
||||
|
||||
@ -92,6 +93,14 @@ Expr<SomeDerived> FoldOperation(
|
||||
} else {
|
||||
isConstant &= *valueShape == *componentShape;
|
||||
}
|
||||
if (*valueShape == *componentShape) {
|
||||
if (auto lbounds{AsConstantExtents(
|
||||
context, GetLBOUNDs(context, NamedEntity{symbol}))}) {
|
||||
expr =
|
||||
ArrayConstantBoundChanger{std::move(*lbounds)}.ChangeLbounds(
|
||||
std::move(expr));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user