forked from OSchip/llvm-project
[flang] Expression analysis on DataStmtConstant
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@8bdaf0a521 Reviewed-on: https://github.com/flang-compiler/f18/pull/1044
This commit is contained in:
parent
015075840d
commit
2a00c617d6
|
@ -230,6 +230,10 @@ public:
|
|||
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 &);
|
||||
|
@ -240,9 +244,7 @@ protected:
|
|||
|
||||
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 &);
|
||||
|
@ -255,7 +257,6 @@ private:
|
|||
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 &);
|
||||
|
@ -448,6 +449,7 @@ public:
|
|||
AnalyzePointerAssignmentStmt(context_, x);
|
||||
return false;
|
||||
}
|
||||
bool Pre(const parser::DataStmtConstant &);
|
||||
|
||||
template<typename A> bool Pre(const parser::Scalar<A> &x) {
|
||||
AnalyzeExpr(context_, x);
|
||||
|
|
|
@ -454,11 +454,14 @@ MaybeExpr ExpressionAnalyzer::IntLiteralConstant(const PARSED &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);
|
||||
}
|
||||
|
||||
|
@ -553,6 +556,18 @@ MaybeExpr ExpressionAnalyzer::Analyze(
|
|||
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);
|
||||
}
|
||||
|
@ -2949,4 +2964,18 @@ bool ExprChecker::Walk(const parser::Program &program) {
|
|||
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;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -213,6 +213,7 @@ set(ERROR_TESTS
|
|||
block-data01.f90
|
||||
complex01.f90
|
||||
data01.f90
|
||||
data02.f90
|
||||
namelist01.f90
|
||||
)
|
||||
|
||||
|
|
|
@ -0,0 +1,31 @@
|
|||
! 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
|
Loading…
Reference in New Issue