diff --git a/flang/include/flang/Semantics/expression.h b/flang/include/flang/Semantics/expression.h --- a/flang/include/flang/Semantics/expression.h +++ b/flang/include/flang/Semantics/expression.h @@ -326,7 +326,8 @@ // Analysis subroutines int AnalyzeKindParam( const std::optional &, int defaultKind); - template MaybeExpr ExprOrVariable(const PARSED &); + template + MaybeExpr ExprOrVariable(const PARSED &, parser::CharBlock source); template MaybeExpr IntLiteralConstant(const PARSED &); MaybeExpr AnalyzeString(std::string &&, int kind); std::optional> AsSubscript(MaybeExpr &&); diff --git a/flang/lib/Evaluate/characteristics.cpp b/flang/lib/Evaluate/characteristics.cpp --- a/flang/lib/Evaluate/characteristics.cpp +++ b/flang/lib/Evaluate/characteristics.cpp @@ -405,14 +405,9 @@ } }, [&](const auto &) { - if (auto type{expr.GetType()}) { - if (auto shape{GetShape(context, expr)}) { - return std::make_optional(std::move(name), - DummyDataObject{TypeAndShape{*type, std::move(*shape)}}); - } else { - return std::make_optional( - std::move(name), DummyDataObject{TypeAndShape{*type}}); - } + if (auto type{TypeAndShape::Characterize(expr, context)}) { + return std::make_optional( + std::move(name), DummyDataObject{std::move(*type)}); } else { return std::optional{}; } diff --git a/flang/lib/Semantics/expression.cpp b/flang/lib/Semantics/expression.cpp --- a/flang/lib/Semantics/expression.cpp +++ b/flang/lib/Semantics/expression.cpp @@ -98,7 +98,8 @@ 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 @@ // Names and named constants MaybeExpr ExpressionAnalyzer::Analyze(const parser::Name &n) { + auto restorer{GetContextualMessages().SetLocation(n.source)}; if (std::optional kind{IsImpliedDo(n.source)}) { return AsMaybeExpr(ConvertToKind( *kind, AsExpr(ImpliedDoIndex{n.source}))); @@ -696,6 +698,7 @@ } MaybeExpr ExpressionAnalyzer::Analyze(const parser::NamedConstant &n) { + auto restorer{GetContextualMessages().SetLocation(n.v.source)}; if (MaybeExpr value{Analyze(n.v)}) { Expr folded{Fold(std::move(*value))}; if (IsConstantExpr(folded)) { @@ -967,11 +970,8 @@ // 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 @@ if (auto *designator{UnwrapExpr>(*dtExpr)}) { if (std::optional 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 @@ new GenericAssignmentWrapper{}, GenericAssignmentWrapper::Deleter); } else { std::optional 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 @@ // Common handling of parse tree node types that retain the // representation of the analyzed expression. template -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 || std::is_same_v) { 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::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 ExpressionAnalyzer::AnalyzeKindSelector( @@ -2652,12 +2654,11 @@ common::visitors{ [&](const parser::ScalarIntConstantExpr &x) { if (MaybeExpr kind{Analyze(x)}) { - Expr folded{Fold(std::move(*kind))}; - if (std::optional code{ToInt64(folded)}) { + if (std::optional code{ToInt64(*kind)}) { if (CheckIntrinsicKind(category, *code)) { return Expr{*code}; } - } else if (auto *intExpr{UnwrapExpr>(folded)}) { + } else if (auto *intExpr{UnwrapExpr>(*kind)}) { return ConvertToType(std::move(*intExpr)); } } @@ -3110,7 +3111,7 @@ "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