forked from OSchip/llvm-project
[flang] Remove redundant checks enforced in the grammar
Expression analysis enforces constraints implied by the grammar, for example scalar-expr, scalar-int-expr, etc. These no longer need to be checked during statement semantics. Original-commit: flang-compiler/f18@35330b9a85 Reviewed-on: https://github.com/flang-compiler/f18/pull/422 Tree-same-pre-rewrite: false
This commit is contained in:
parent
54c42cfa89
commit
a426477d37
|
@ -18,7 +18,6 @@ add_library(FortranSemantics
|
|||
canonicalize-do.cc
|
||||
check-arithmeticif.cc
|
||||
check-coarray.cc
|
||||
check-computed-goto.cc
|
||||
check-deallocate.cc
|
||||
check-do-concurrent.cc
|
||||
check-if-stmt.cc
|
||||
|
|
|
@ -1,38 +0,0 @@
|
|||
// Copyright (c) 2019, NVIDIA CORPORATION. All rights reserved.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
#include "check-computed-goto.h"
|
||||
#include "tools.h"
|
||||
#include "../parser/message.h"
|
||||
#include "../parser/parse-tree.h"
|
||||
|
||||
namespace Fortran::semantics {
|
||||
|
||||
void ComputedGotoStmtChecker::Leave(
|
||||
const parser::ComputedGotoStmt &computedGotoStmt) {
|
||||
// C1169 Labels have already been checked
|
||||
// R1158 Check for scalar-int-expr
|
||||
auto &expr{
|
||||
std::get<parser::ScalarIntExpr>(computedGotoStmt.t).thing.thing.value()};
|
||||
if (expr.typedExpr->v.Rank() > 0) {
|
||||
context_.Say(expr.source,
|
||||
"Computed GOTO expression must be a scalar expression"_err_en_US);
|
||||
} else if (!ExprHasTypeCategory(
|
||||
*expr.typedExpr, common::TypeCategory::Integer)) {
|
||||
context_.Say(expr.source,
|
||||
"Computed GOTO expression must be an integer expression"_err_en_US);
|
||||
}
|
||||
}
|
||||
|
||||
} // namespace Fortran::semantics
|
|
@ -1,34 +0,0 @@
|
|||
// Copyright (c) 2019, NVIDIA CORPORATION. All rights reserved.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
#ifndef FORTRAN_SEMANTICS_CHECK_COMPUTED_GOTO_STMT_H_
|
||||
#define FORTRAN_SEMANTICS_CHECK_COMPUTED_GOTO_STMT_H_
|
||||
|
||||
#include "semantics.h"
|
||||
|
||||
namespace Fortran::parser {
|
||||
struct ComputedGotoStmt;
|
||||
}
|
||||
|
||||
namespace Fortran::semantics {
|
||||
class ComputedGotoStmtChecker : public virtual BaseChecker {
|
||||
public:
|
||||
ComputedGotoStmtChecker(SemanticsContext &context) : context_{context} {}
|
||||
void Leave(const parser::ComputedGotoStmt &);
|
||||
|
||||
private:
|
||||
SemanticsContext &context_;
|
||||
};
|
||||
}
|
||||
#endif // FORTRAN_SEMANTICS_CHECK_COMPUTED_GOTO_STMT_H_
|
|
@ -54,9 +54,6 @@ void DeallocateChecker::Leave(const parser::DeallocateStmt &deallocateStmt) {
|
|||
std::visit(
|
||||
common::visitors{
|
||||
[&](const parser::StatVariable &statVariable) {
|
||||
// ExpressionAnalyzer emits error messages
|
||||
evaluate::ExpressionAnalyzer analyzer{context_};
|
||||
analyzer.Analyze(statVariable.v);
|
||||
if (gotStat) {
|
||||
context_.Say(
|
||||
"STAT may not be duplicated in a DEALLOCATE statement"_err_en_US);
|
||||
|
@ -64,9 +61,6 @@ void DeallocateChecker::Leave(const parser::DeallocateStmt &deallocateStmt) {
|
|||
gotStat = true;
|
||||
},
|
||||
[&](const parser::MsgVariable &msgVariable) {
|
||||
// ExpressionAnalyzer emits error messages
|
||||
evaluate::ExpressionAnalyzer analyzer{context_};
|
||||
analyzer.Analyze(msgVariable.v);
|
||||
if (gotMsg) {
|
||||
context_.Say(
|
||||
"ERRMSG may not be duplicated in a DEALLOCATE statement"_err_en_US);
|
||||
|
|
|
@ -302,9 +302,6 @@ struct GatherSymbols {
|
|||
void Post(const parser::Name &name) { symbols.push_back(name.symbol); }
|
||||
};
|
||||
|
||||
static bool IntegerVariable(const Symbol &variable) {
|
||||
return variable.GetType()->IsNumeric(common::TypeCategory::Integer);
|
||||
}
|
||||
static CS GatherAllVariableNames(
|
||||
const std::list<parser::LocalitySpec> &localitySpecs) {
|
||||
CS names;
|
||||
|
@ -420,29 +417,6 @@ public:
|
|||
parser::Walk(
|
||||
std::get<parser::Block>(doConstruct.t), doConcurrentLabelEnforce);
|
||||
EnforceConcurrentLoopControl(*concurrent);
|
||||
} else if (auto *loopBounds{
|
||||
std::get_if<parser::LoopBounds<parser::ScalarIntExpr>>(
|
||||
&optionalLoopControl->u)}) {
|
||||
// C1120 - FIXME? may be checked before we get here
|
||||
auto *doVariable{loopBounds->name.thing.thing.symbol};
|
||||
CHECK(doVariable);
|
||||
currentStatementSourcePosition_ = loopBounds->name.thing.thing.source;
|
||||
if (!IntegerVariable(*doVariable)) {
|
||||
// warning only: older Fortrans allowed floating-point do-variables
|
||||
messages_.Say(currentStatementSourcePosition_,
|
||||
"do-variable must have INTEGER type"_en_US);
|
||||
}
|
||||
} else {
|
||||
// C1006 - FIXME? may be checked before we get here
|
||||
auto &logicalExpr{
|
||||
std::get<parser::ScalarLogicalExpr>(optionalLoopControl->u)
|
||||
.thing.thing};
|
||||
CHECK(logicalExpr.value().typedExpr);
|
||||
if (!ExprHasTypeCategory(*logicalExpr.value().typedExpr,
|
||||
common::TypeCategory::Logical)) {
|
||||
messages_.Say(currentStatementSourcePosition_,
|
||||
"DO WHILE must have LOGICAL expression"_err_en_US);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -550,17 +524,8 @@ private:
|
|||
CS indexNames;
|
||||
for (auto &c : controls) {
|
||||
auto &indexName{std::get<parser::Name>(c.t)};
|
||||
// C1122 - FIXME? may be checked somewhere else before we get here
|
||||
if (!indexName.symbol) {
|
||||
continue; // XXX - this shouldn't be needed
|
||||
}
|
||||
CHECK(indexName.symbol);
|
||||
indexNames.push_back(indexName.symbol);
|
||||
if (!IntegerVariable(*indexName.symbol)) {
|
||||
messages_.Say(
|
||||
indexName.source, "index-name must have INTEGER type"_err_en_US);
|
||||
return;
|
||||
}
|
||||
}
|
||||
if (!indexNames.empty()) {
|
||||
for (auto &c : controls) {
|
||||
|
|
|
@ -17,7 +17,6 @@
|
|||
#include "canonicalize-do.h"
|
||||
#include "check-arithmeticif.h"
|
||||
#include "check-coarray.h"
|
||||
#include "check-computed-goto.h"
|
||||
#include "check-deallocate.h"
|
||||
#include "check-do-concurrent.h"
|
||||
#include "check-if-stmt.h"
|
||||
|
@ -80,10 +79,9 @@ private:
|
|||
};
|
||||
|
||||
using StatementSemanticsPass1 = ExprChecker;
|
||||
using StatementSemanticsPass2 =
|
||||
SemanticsVisitor<ArithmeticIfStmtChecker, AssignmentChecker, CoarrayChecker,
|
||||
ComputedGotoStmtChecker, DeallocateChecker, DoConcurrentChecker,
|
||||
IfStmtChecker, NullifyChecker, ReturnStmtChecker, StopChecker>;
|
||||
using StatementSemanticsPass2 = SemanticsVisitor<ArithmeticIfStmtChecker,
|
||||
AssignmentChecker, CoarrayChecker, DeallocateChecker, DoConcurrentChecker,
|
||||
IfStmtChecker, NullifyChecker, ReturnStmtChecker, StopChecker>;
|
||||
|
||||
SemanticsContext::SemanticsContext(
|
||||
const common::IntrinsicTypeDefaultKinds &defaultKinds,
|
||||
|
|
Loading…
Reference in New Issue