[flang] Fix ParamValue attribute (kind/len) of implicit type parameters

While testing fix for issue 581 it appeared that 'ParamValue`
implicit len parameters had incorrect attribute kind.
This commit:
 + Set correct attribute when creating `ParamValue` for implicit
   type parameter.
 + Also set the correct attribute foe charachter lenght `ParamValue`
   though it is currently not used anywhere.
 + Change some std::int64_t to common::ConstantSubscript on the way.

Original-commit: flang-compiler/f18@57a344b256
Reviewed-on: https://github.com/flang-compiler/f18/pull/615
Tree-same-pre-rewrite: false
This commit is contained in:
Jean Perier 2019-08-02 06:38:40 -07:00
parent ba7ed2722a
commit 0eafca9759
4 changed files with 26 additions and 8 deletions

View file

@ -839,6 +839,8 @@ private:
Symbol *MakeTypeSymbol(const parser::Name &, Details &&);
bool OkToAddComponent(const parser::Name &, const Symbol * = nullptr);
ParamValue GetParamValue(const parser::TypeParamValue &);
ParamValue GetLenParamValue(const parser::TypeParamValue &);
ParamValue GetLenParamValue(common::ConstantSubscript);
Symbol &MakeCommonBlockSymbol(const parser::Name &);
void CheckCommonBlockDerivedType(const SourceName &, const Symbol &);
std::optional<MessageFixedText> CheckSaveAttr(const Symbol &);
@ -2871,7 +2873,7 @@ void DeclarationVisitor::Post(const parser::IntrinsicTypeSpec::Logical &x) {
}
void DeclarationVisitor::Post(const parser::IntrinsicTypeSpec::Character &x) {
if (!charInfo_.length) {
charInfo_.length = ParamValue{1};
charInfo_.length = GetLenParamValue(1);
}
if (!charInfo_.kind.has_value()) {
charInfo_.kind =
@ -2884,19 +2886,19 @@ void DeclarationVisitor::Post(const parser::IntrinsicTypeSpec::Character &x) {
void DeclarationVisitor::Post(const parser::CharSelector::LengthAndKind &x) {
charInfo_.kind = EvaluateSubscriptIntExpr(x.kind);
if (x.length) {
charInfo_.length = GetParamValue(*x.length);
charInfo_.length = GetLenParamValue(*x.length);
}
}
void DeclarationVisitor::Post(const parser::CharLength &x) {
if (const auto *length{std::get_if<std::int64_t>(&x.u)}) {
charInfo_.length = ParamValue{*length};
charInfo_.length = GetLenParamValue(*length);
} else {
charInfo_.length = GetParamValue(std::get<parser::TypeParamValue>(x.u));
charInfo_.length = GetLenParamValue(std::get<parser::TypeParamValue>(x.u));
}
}
void DeclarationVisitor::Post(const parser::LengthSelector &x) {
if (const auto *param{std::get_if<parser::TypeParamValue>(&x.u)}) {
charInfo_.length = GetParamValue(*param);
charInfo_.length = GetLenParamValue(*param);
}
}
@ -4067,6 +4069,19 @@ ParamValue DeclarationVisitor::GetParamValue(const parser::TypeParamValue &x) {
x.u);
}
ParamValue DeclarationVisitor::GetLenParamValue(
const parser::TypeParamValue &x) {
ParamValue param{GetParamValue(x)};
param.set_attr(common::TypeParamAttr::Len);
return param;
}
ParamValue DeclarationVisitor::GetLenParamValue(common::ConstantSubscript l) {
ParamValue param{l};
param.set_attr(common::TypeParamAttr::Len);
return param;
}
// ConstructVisitor implementation
void ConstructVisitor::ResolveIndexName(

View file

@ -700,7 +700,10 @@ void ProcessParameterExpressions(
if (paramValue != nullptr) {
paramValue->SetExplicit(std::move(*expr));
} else {
spec.AddParamValue(symbol->name(), ParamValue{std::move(*expr)});
ParamValue implicitParam{std::move(*expr)};
implicitParam.set_attr(details.attr());
spec.AddParamValue(
symbol->name(), ParamValue{std::move(implicitParam)});
}
}
}

View file

@ -129,7 +129,7 @@ bool IsExplicit(const ArraySpec &arraySpec) {
ParamValue::ParamValue(MaybeIntExpr &&expr) : expr_{std::move(expr)} {}
ParamValue::ParamValue(SomeIntExpr &&expr) : expr_{std::move(expr)} {}
ParamValue::ParamValue(std::int64_t value)
ParamValue::ParamValue(common::ConstantSubscript value)
: ParamValue(SomeIntExpr{evaluate::Expr<evaluate::SubscriptInteger>{value}}) {
}

View file

@ -90,7 +90,7 @@ public:
ParamValue(const ParamValue &) = default;
explicit ParamValue(MaybeIntExpr &&);
explicit ParamValue(SomeIntExpr &&);
explicit ParamValue(std::int64_t);
explicit ParamValue(common::ConstantSubscript);
bool isExplicit() const { return category_ == Category::Explicit; }
bool isAssumed() const { return category_ == Category::Assumed; }
bool isDeferred() const { return category_ == Category::Deferred; }