Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Summary: Initially on github I worked on semantic checks.Then I tried some compile-time test of the rank value, they were failing as there were no symbols generated for them inside SELECT RANK's scope.So I went further to add new symbol in each scope, also added the respective 'rank: ' field for a symbol when we dump the symboltable. I added a field to keep track of the rank in AssocEntityDetails class.This caused shape analysis framework to become inconsistent. So shape analysis framework was updated to handle this new representation. * I added more tests for above changes. * On phabricator I addressed some minor changes. * Lastly I worked on review comments. Reviewers: klausler,sscalpone,DavidTruby,kiranchandramohan,tskeith,anchu-rajendran,kiranktp Reviewed By:klausler, DavidTruby, tskeith Subscribers:#flang-commits, #llvm-commits Tags: #flang, #llvm Differential Revision: https://reviews.llvm.org/D78623
- Loading branch information
1 parent
4ae537c
commit 332e6ae
Showing
11 changed files
with
554 additions
and
17 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,129 @@ | ||
//===-- lib/Semantics/check-select-rank.cpp -------------------------------===// | ||
// | ||
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. | ||
// See https://llvm.org/LICENSE.txt for license information. | ||
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception | ||
// | ||
//===----------------------------------------------------------------------===// | ||
|
||
#include "check-select-rank.h" | ||
#include "flang/Common/Fortran.h" | ||
#include "flang/Common/idioms.h" | ||
#include "flang/Parser/message.h" | ||
#include "flang/Parser/tools.h" | ||
#include "flang/Semantics/tools.h" | ||
#include <list> | ||
#include <optional> | ||
#include <set> | ||
#include <tuple> | ||
#include <variant> | ||
|
||
namespace Fortran::semantics { | ||
|
||
void SelectRankConstructChecker::Leave( | ||
const parser::SelectRankConstruct &selectRankConstruct) { | ||
const auto &selectRankStmt{ | ||
std::get<parser::Statement<parser::SelectRankStmt>>( | ||
selectRankConstruct.t)}; | ||
const auto &selectRankStmtSel{ | ||
std::get<parser::Selector>(selectRankStmt.statement.t)}; | ||
|
||
// R1149 select-rank-stmt checks | ||
const Symbol *saveSelSymbol{nullptr}; | ||
if (const auto selExpr{GetExprFromSelector(selectRankStmtSel)}) { | ||
if (const Symbol * sel{evaluate::UnwrapWholeSymbolDataRef(*selExpr)}) { | ||
if (!IsAssumedRankArray(*sel)) { // C1150 | ||
context_.Say(parser::FindSourceLocation(selectRankStmtSel), | ||
"Selector '%s' is not an assumed-rank array variable"_err_en_US, | ||
sel->name().ToString()); | ||
} else { | ||
saveSelSymbol = sel; | ||
} | ||
} else { | ||
context_.Say(parser::FindSourceLocation(selectRankStmtSel), | ||
"Selector '%s' is not an assumed-rank array variable"_err_en_US, | ||
parser::FindSourceLocation(selectRankStmtSel).ToString()); | ||
} | ||
} | ||
|
||
// R1150 select-rank-case-stmt checks | ||
auto &rankCaseList{std::get<std::list<parser::SelectRankConstruct::RankCase>>( | ||
selectRankConstruct.t)}; | ||
bool defaultRankFound{false}; | ||
bool starRankFound{false}; | ||
parser::CharBlock prevLocDefault; | ||
parser::CharBlock prevLocStar; | ||
std::optional<parser::CharBlock> caseForRank[common::maxRank + 1]; | ||
|
||
for (const auto &rankCase : rankCaseList) { | ||
const auto &rankCaseStmt{ | ||
std::get<parser::Statement<parser::SelectRankCaseStmt>>(rankCase.t)}; | ||
const auto &rank{ | ||
std::get<parser::SelectRankCaseStmt::Rank>(rankCaseStmt.statement.t)}; | ||
std::visit( | ||
common::visitors{ | ||
[&](const parser::Default &) { // C1153 | ||
if (!defaultRankFound) { | ||
defaultRankFound = true; | ||
prevLocDefault = rankCaseStmt.source; | ||
} else { | ||
context_ | ||
.Say(rankCaseStmt.source, | ||
"Not more than one of the selectors of SELECT RANK " | ||
"statement may be DEFAULT"_err_en_US) | ||
.Attach(prevLocDefault, "Previous use"_err_en_US); | ||
} | ||
}, | ||
[&](const parser::Star &) { // C1153 | ||
if (!starRankFound) { | ||
starRankFound = true; | ||
prevLocStar = rankCaseStmt.source; | ||
} else { | ||
context_ | ||
.Say(rankCaseStmt.source, | ||
"Not more than one of the selectors of SELECT RANK " | ||
"statement may be '*'"_err_en_US) | ||
.Attach(prevLocStar, "Previous use"_err_en_US); | ||
} | ||
if (saveSelSymbol && | ||
IsAllocatableOrPointer(*saveSelSymbol)) { // C1155 | ||
context_.Say(parser::FindSourceLocation(selectRankStmtSel), | ||
"RANK (*) cannot be used when selector is " | ||
"POINTER or ALLOCATABLE"_err_en_US); | ||
} | ||
}, | ||
[&](const parser::ScalarIntConstantExpr &init) { | ||
if (auto val{GetIntValue(init)}) { | ||
// If value is in valid range, then only show | ||
// value repeat error, else stack smashing occurs | ||
if (*val < 0 || *val > common::maxRank) { // C1151 | ||
context_.Say(rankCaseStmt.source, | ||
"The value of the selector must be " | ||
"between zero and %d"_err_en_US, | ||
common::maxRank); | ||
|
||
} else { | ||
if (!caseForRank[*val].has_value()) { | ||
caseForRank[*val] = rankCaseStmt.source; | ||
} else { | ||
auto prevloc{caseForRank[*val].value()}; | ||
context_ | ||
.Say(rankCaseStmt.source, | ||
"Same rank value (%d) not allowed more than once"_err_en_US, | ||
*val) | ||
.Attach(prevloc, "Previous use"_err_en_US); | ||
} | ||
} | ||
} | ||
}, | ||
}, | ||
rank.u); | ||
} | ||
} | ||
|
||
const SomeExpr *SelectRankConstructChecker::GetExprFromSelector( | ||
const parser::Selector &selector) { | ||
return std::visit([](const auto &x) { return GetExpr(x); }, selector.u); | ||
} | ||
|
||
} // namespace Fortran::semantics |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,26 @@ | ||
//===-- lib/Semantics/check-select-rank.h -----------------------*- C++ -*-===// | ||
// | ||
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. | ||
// See https://llvm.org/LICENSE.txt for license information. | ||
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception | ||
// | ||
//===----------------------------------------------------------------------===// | ||
|
||
#ifndef FORTRAN_SEMANTICS_CHECK_SELECT_STMT_H_ | ||
#define FORTRAN_SEMANTICS_CHECK_SELECT_STMT_H_ | ||
|
||
#include "flang/Parser/parse-tree.h" | ||
#include "flang/Semantics/semantics.h" | ||
|
||
namespace Fortran::semantics { | ||
class SelectRankConstructChecker : public virtual BaseChecker { | ||
public: | ||
SelectRankConstructChecker(SemanticsContext &context) : context_{context} {} | ||
void Leave(const parser::SelectRankConstruct &); | ||
|
||
private: | ||
const SomeExpr *GetExprFromSelector(const parser::Selector &); | ||
SemanticsContext &context_; | ||
}; | ||
} // namespace Fortran::semantics | ||
#endif // FORTRAN_SEMANTICS_CHECK_SELECT_STMT_H_ |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.