[flang-commits] [flang] 934b27a - [flang] Fix actual argument character length and length error reporting
peter klausler via flang-commits
flang-commits at lists.llvm.org
Mon Nov 2 13:39:34 PST 2020
Author: peter klausler
Date: 2020-11-02T13:39:15-08:00
New Revision: 934b27a9daf6cff8cb32d6e49eaf6ff8f69c7727
URL: https://github.com/llvm/llvm-project/commit/934b27a9daf6cff8cb32d6e49eaf6ff8f69c7727
DIFF: https://github.com/llvm/llvm-project/commit/934b27a9daf6cff8cb32d6e49eaf6ff8f69c7727.diff
LOG: [flang] Fix actual argument character length and length error reporting
Ensure that character length is properly calculated for
actual arguments to intrinsics, and that source provenance
information is available when expression analysis calls
folding in cases where the length is invalid.
Differential revision: https://reviews.llvm.org/D90636
Added:
Modified:
flang/include/flang/Semantics/expression.h
flang/lib/Evaluate/characteristics.cpp
flang/lib/Semantics/expression.cpp
Removed:
################################################################################
diff --git a/flang/include/flang/Semantics/expression.h b/flang/include/flang/Semantics/expression.h
index 4862e98a0bdc..f49408e81446 100644
--- a/flang/include/flang/Semantics/expression.h
+++ b/flang/include/flang/Semantics/expression.h
@@ -326,7 +326,8 @@ class ExpressionAnalyzer {
// Analysis subroutines
int AnalyzeKindParam(
const std::optional<parser::KindParam> &, int defaultKind);
- template <typename PARSED> MaybeExpr ExprOrVariable(const PARSED &);
+ template <typename PARSED>
+ MaybeExpr ExprOrVariable(const PARSED &, parser::CharBlock source);
template <typename PARSED> MaybeExpr IntLiteralConstant(const PARSED &);
MaybeExpr AnalyzeString(std::string &&, int kind);
std::optional<Expr<SubscriptInteger>> AsSubscript(MaybeExpr &&);
diff --git a/flang/lib/Evaluate/characteristics.cpp b/flang/lib/Evaluate/characteristics.cpp
index 3ebcfbcc8043..e4e904cc1bbb 100644
--- a/flang/lib/Evaluate/characteristics.cpp
+++ b/flang/lib/Evaluate/characteristics.cpp
@@ -405,14 +405,9 @@ std::optional<DummyArgument> DummyArgument::FromActual(
}
},
[&](const auto &) {
- if (auto type{expr.GetType()}) {
- if (auto shape{GetShape(context, expr)}) {
- return std::make_optional<DummyArgument>(std::move(name),
- DummyDataObject{TypeAndShape{*type, std::move(*shape)}});
- } else {
- return std::make_optional<DummyArgument>(
- std::move(name), DummyDataObject{TypeAndShape{*type}});
- }
+ if (auto type{TypeAndShape::Characterize(expr, context)}) {
+ return std::make_optional<DummyArgument>(
+ std::move(name), DummyDataObject{std::move(*type)});
} else {
return std::optional<DummyArgument>{};
}
diff --git a/flang/lib/Semantics/expression.cpp b/flang/lib/Semantics/expression.cpp
index 8ffa54758d8c..98f0c3653e3b 100644
--- a/flang/lib/Semantics/expression.cpp
+++ b/flang/lib/Semantics/expression.cpp
@@ -98,7 +98,8 @@ static std::optional<DynamicTypeWithLength> AnalyzeTypeSpec(
class ArgumentAnalyzer {
public:
explicit ArgumentAnalyzer(ExpressionAnalyzer &context)
- : context_{context}, isProcedureCall_{false} {}
+ : context_{context}, source_{context.GetContextualMessages().at()},
+ isProcedureCall_{false} {}
ArgumentAnalyzer(ExpressionAnalyzer &context, parser::CharBlock source,
bool isProcedureCall = false)
: context_{context}, source_{source}, isProcedureCall_{isProcedureCall} {}
@@ -656,6 +657,7 @@ MaybeExpr ExpressionAnalyzer::Analyze(const parser::BOZLiteralConstant &x) {
// Names and named constants
MaybeExpr ExpressionAnalyzer::Analyze(const parser::Name &n) {
+ auto restorer{GetContextualMessages().SetLocation(n.source)};
if (std::optional<int> kind{IsImpliedDo(n.source)}) {
return AsMaybeExpr(ConvertToKind<TypeCategory::Integer>(
*kind, AsExpr(ImpliedDoIndex{n.source})));
@@ -696,6 +698,7 @@ MaybeExpr ExpressionAnalyzer::Analyze(const parser::Name &n) {
}
MaybeExpr ExpressionAnalyzer::Analyze(const parser::NamedConstant &n) {
+ auto restorer{GetContextualMessages().SetLocation(n.v.source)};
if (MaybeExpr value{Analyze(n.v)}) {
Expr<SomeType> folded{Fold(std::move(*value))};
if (IsConstantExpr(folded)) {
@@ -967,11 +970,8 @@ static std::optional<Component> CreateComponent(
// Derived type component references and type parameter inquiries
MaybeExpr ExpressionAnalyzer::Analyze(const parser::StructureComponent &sc) {
MaybeExpr base{Analyze(sc.base)};
- if (!base) {
- return std::nullopt;
- }
Symbol *sym{sc.component.symbol};
- if (context_.HasError(sym)) {
+ if (!base || !sym || context_.HasError(sym)) {
return std::nullopt;
}
const auto &name{sc.component.source};
@@ -981,6 +981,7 @@ MaybeExpr ExpressionAnalyzer::Analyze(const parser::StructureComponent &sc) {
if (auto *designator{UnwrapExpr<Designator<SomeDerived>>(*dtExpr)}) {
if (std::optional<DynamicType> dyType{DynamicType::From(*sym)}) {
if (dyType->category() == TypeCategory::Integer) {
+ auto restorer{GetContextualMessages().SetLocation(name)};
return Fold(ConvertToType(*dyType,
AsGenericExpr(TypeParamInquiry{
IgnoreAnySubscripts(std::move(*designator)), *sym})));
@@ -2155,8 +2156,7 @@ const Assignment *ExpressionAnalyzer::Analyze(const parser::AssignmentStmt &x) {
new GenericAssignmentWrapper{}, GenericAssignmentWrapper::Deleter);
} else {
std::optional<ProcedureRef> procRef{analyzer.TryDefinedAssignment()};
- Assignment assignment{
- Fold(analyzer.MoveExpr(0)), Fold(analyzer.MoveExpr(1))};
+ Assignment assignment{analyzer.MoveExpr(0), analyzer.MoveExpr(1)};
if (procRef) {
assignment.u = std::move(*procRef);
}
@@ -2601,18 +2601,20 @@ static void FixMisparsedFunctionReference(
// Common handling of parse tree node types that retain the
// representation of the analyzed expression.
template <typename PARSED>
-MaybeExpr ExpressionAnalyzer::ExprOrVariable(const PARSED &x) {
+MaybeExpr ExpressionAnalyzer::ExprOrVariable(
+ const PARSED &x, parser::CharBlock source) {
if (useSavedTypedExprs_ && x.typedExpr) {
return x.typedExpr->v;
}
+ auto restorer{GetContextualMessages().SetLocation(source)};
if constexpr (std::is_same_v<PARSED, parser::Expr> ||
std::is_same_v<PARSED, parser::Variable>) {
FixMisparsedFunctionReference(context_, x.u);
}
if (AssumedTypeDummy(x)) { // C710
Say("TYPE(*) dummy argument may only be used as an actual argument"_err_en_US);
- } else if (MaybeExpr result{evaluate::Fold(foldingContext_, Analyze(x.u))}) {
- SetExpr(x, std::move(*result));
+ } else if (MaybeExpr result{Analyze(x.u)}) {
+ SetExpr(x, Fold(std::move(*result)));
return x.typedExpr->v;
}
ResetExpr(x);
@@ -2628,17 +2630,17 @@ MaybeExpr ExpressionAnalyzer::ExprOrVariable(const PARSED &x) {
MaybeExpr ExpressionAnalyzer::Analyze(const parser::Expr &expr) {
auto restorer{GetContextualMessages().SetLocation(expr.source)};
- return ExprOrVariable(expr);
+ return ExprOrVariable(expr, expr.source);
}
MaybeExpr ExpressionAnalyzer::Analyze(const parser::Variable &variable) {
auto restorer{GetContextualMessages().SetLocation(variable.GetSource())};
- return ExprOrVariable(variable);
+ return ExprOrVariable(variable, variable.GetSource());
}
MaybeExpr ExpressionAnalyzer::Analyze(const parser::DataStmtConstant &x) {
auto restorer{GetContextualMessages().SetLocation(x.source)};
- return ExprOrVariable(x);
+ return ExprOrVariable(x, x.source);
}
Expr<SubscriptInteger> ExpressionAnalyzer::AnalyzeKindSelector(
@@ -2652,12 +2654,11 @@ Expr<SubscriptInteger> ExpressionAnalyzer::AnalyzeKindSelector(
common::visitors{
[&](const parser::ScalarIntConstantExpr &x) {
if (MaybeExpr kind{Analyze(x)}) {
- Expr<SomeType> folded{Fold(std::move(*kind))};
- if (std::optional<std::int64_t> code{ToInt64(folded)}) {
+ if (std::optional<std::int64_t> code{ToInt64(*kind)}) {
if (CheckIntrinsicKind(category, *code)) {
return Expr<SubscriptInteger>{*code};
}
- } else if (auto *intExpr{UnwrapExpr<Expr<SomeInteger>>(folded)}) {
+ } else if (auto *intExpr{UnwrapExpr<Expr<SomeInteger>>(*kind)}) {
return ConvertToType<SubscriptInteger>(std::move(*intExpr));
}
}
@@ -3110,7 +3111,7 @@ std::optional<ActualArgument> ArgumentAnalyzer::AnalyzeExpr(
"TYPE(*) dummy argument may only be used as an actual argument"_err_en_US);
} else if (MaybeExpr argExpr{AnalyzeExprOrWholeAssumedSizeArray(expr)}) {
if (isProcedureCall_ || !IsProcedure(*argExpr)) {
- return ActualArgument{context_.Fold(std::move(*argExpr))};
+ return ActualArgument{std::move(*argExpr)};
}
context_.SayAt(expr.source,
IsFunction(*argExpr) ? "Function call must have argument list"_err_en_US
More information about the flang-commits
mailing list