Data statements contains expressions but they are not wrapped in one of
the kinds of parse tree nodes that are analyzed, like `parser::Expr`.
So potential errors were not discovered.
Change `ExprChecker` to handle `DataStmtConstant` and analyze any
expressions that are contained in it. Note that the analyzed form of
the expression is not yet saved in the parse tree.
Original-commit: flang-compiler/f18@
8bdaf0a521f6630ec2c369b2c41484eff4803d6e
Reviewed-on: https://github.com/flang-compiler/f18/pull/1044
return Analyze<parser::DataRef>(dr);
}
MaybeExpr Analyze(const parser::StructureComponent &);
+ MaybeExpr Analyze(const parser::SignedIntLiteralConstant &);
+ MaybeExpr Analyze(const parser::SignedRealLiteralConstant &);
+ MaybeExpr Analyze(const parser::SignedComplexLiteralConstant &);
+ MaybeExpr Analyze(const parser::StructureConstructor &);
void Analyze(const parser::CallStmt &);
const Assignment *Analyze(const parser::AssignmentStmt &);
private:
MaybeExpr Analyze(const parser::IntLiteralConstant &);
- MaybeExpr Analyze(const parser::SignedIntLiteralConstant &);
MaybeExpr Analyze(const parser::RealLiteralConstant &);
- MaybeExpr Analyze(const parser::SignedRealLiteralConstant &);
MaybeExpr Analyze(const parser::ComplexPart &);
MaybeExpr Analyze(const parser::ComplexLiteralConstant &);
MaybeExpr Analyze(const parser::LogicalLiteralConstant &);
MaybeExpr Analyze(const parser::CoindexedNamedObject &);
MaybeExpr Analyze(const parser::CharLiteralConstantSubstring &);
MaybeExpr Analyze(const parser::ArrayConstructor &);
- MaybeExpr Analyze(const parser::StructureConstructor &);
MaybeExpr Analyze(const parser::FunctionReference &,
std::optional<parser::StructureConstructor> * = nullptr);
MaybeExpr Analyze(const parser::Expr::Parentheses &);
AnalyzePointerAssignmentStmt(context_, x);
return false;
}
+ bool Pre(const parser::DataStmtConstant &);
template<typename A> bool Pre(const parser::Scalar<A> &x) {
AnalyzeExpr(context_, x);
}
MaybeExpr ExpressionAnalyzer::Analyze(const parser::IntLiteralConstant &x) {
+ auto restorer{
+ GetContextualMessages().SetLocation(std::get<parser::CharBlock>(x.t))};
return IntLiteralConstant(x);
}
MaybeExpr ExpressionAnalyzer::Analyze(
const parser::SignedIntLiteralConstant &x) {
+ auto restorer{GetContextualMessages().SetLocation(x.source)};
return IntLiteralConstant(x);
}
return std::nullopt;
}
+MaybeExpr ExpressionAnalyzer::Analyze(
+ const parser::SignedComplexLiteralConstant &x) {
+ auto result{Analyze(std::get<parser::ComplexLiteralConstant>(x.t))};
+ if (!result) {
+ return std::nullopt;
+ } else if (std::get<parser::Sign>(x.t) == parser::Sign::Negative) {
+ return AsGenericExpr(-std::move(std::get<Expr<SomeComplex>>(result->u)));
+ } else {
+ return result;
+ }
+}
+
MaybeExpr ExpressionAnalyzer::Analyze(const parser::ComplexPart &x) {
return Analyze(x.u);
}
parser::Walk(program, *this);
return !context_.AnyFatalError();
}
+
+bool ExprChecker::Pre(const parser::DataStmtConstant &x) {
+ std::visit(
+ common::visitors{
+ [&](const parser::NullInit &) {},
+ [&](const parser::InitialDataTarget &y) {
+ AnalyzeExpr(context_, y.value());
+ },
+ [&](const auto &y) { AnalyzeExpr(context_, y); },
+ },
+ x.u);
+ return false;
+}
+
}
block-data01.f90
complex01.f90
data01.f90
+ data02.f90
namelist01.f90
)
--- /dev/null
+! Check that expressions are analyzed in data statements
+
+subroutine s1
+ type :: t
+ character(1) :: c
+ end type
+ type(t) :: x
+ !ERROR: Value in structure constructor of type INTEGER(4) is incompatible with component 'c' of type CHARACTER(KIND=1,LEN=1_4)
+ data x /t(1)/
+end
+
+subroutine s2
+ real :: x1, x2
+ integer :: i1, i2
+ !ERROR: Unsupported REAL(KIND=99)
+ data x1 /1.0_99/
+ !ERROR: Unsupported REAL(KIND=99)
+ data x2 /-1.0_99/
+ !ERROR: INTEGER(KIND=99) is not a supported type
+ data i1 /1_99/
+ !ERROR: INTEGER(KIND=99) is not a supported type
+ data i2 /-1_99/
+end
+
+subroutine s3
+ complex :: z1, z2
+ !ERROR: Unsupported REAL(KIND=99)
+ data z1 /(1.0, 2.0_99)/
+ !ERROR: Unsupported REAL(KIND=99)
+ data z2 /-(1.0, 2.0_99)/
+end