[flang-dev] [Semantic][Select Rank] Semantic checks fails with fatal internal error
sameeran joshi via flang-dev
flang-dev at lists.llvm.org
Thu Dec 5 11:20:42 PST 2019
Hi Community,
I am trying to implement semantic checks for Select Rank (R1148) Construct.
I tried successfully C1150 constraint implementation.
For C1151 I am facing an issue as below,
$ f18 negative_rank.F90 -fdebug-semantics
fatal internal error: CHECK(x) failed at
~/Workspace/tool-chain/F18/f18/lib/semantics/tools.h(213)
Aborted (core dumped)
Debugging with GDB shows core dump in
GetIntValue(*i) Function, where the value of variable i, I suppose is
not an expression, which causes it to fail in
CHECK(x): in lib/semantics/tools.h
1)
Is there somthing fundamental I am missing in below function?
void ConstructVisitor::Post(const parser::SelectRankConstruct &)
2)
Is void ConstructVisitor::Post(const parser::SelectRankCaseStmt::Rank
&) a more appropriate function to do C1151 checks?
Below is the attached patch and program.
Thanks,
Sameeran
+++++++++++++++++++
program
+++++++++++++++++++
$ cat negative_rank.F90
program rank_new
implicit none
integer, DIMENSION(3) :: array
call CALL_ME(array)
contains
SUBROUTINE CALL_ME(x)
integer :: x(..) !ASSUMED RANK ARRAY should be a dummy argument
for subrotine
SELECT RANK(x)
RANK (3)
print *, "one"
RANK (2)
print *, "two"
rank(*)
print *, "rank:"
END SELECT
END SUBROUTINE
end program
+++++++++++++++++++++++
Patch
+++++++++++++++++++++++
diff --git a/lib/semantics/resolve-names.cc b/lib/semantics/resolve-names.cc
index c779a891..fe81f2c6 100644
--- a/lib/semantics/resolve-names.cc
+++ b/lib/semantics/resolve-names.cc
@@ -43,7 +43,7 @@
#include <ostream>
#include <set>
#include <stack>
-
+#include <iostream>
namespace Fortran::semantics {
using namespace parser::literals;
@@ -957,6 +957,7 @@ public:
bool Pre(const parser::SelectTypeConstruct::TypeCase &);
void Post(const parser::SelectTypeConstruct::TypeCase &);
void Post(const parser::TypeGuardStmt::Guard &);
+ void Post(const parser::SelectRankCaseStmt::Rank &);
bool Pre(const parser::ChangeTeamStmt &);
void Post(const parser::EndChangeTeamStmt &);
void Post(const parser::CoarrayAssociation &);
@@ -976,6 +977,7 @@ public:
bool Pre(const parser::SelectRankStmt &x) {
return CheckDef(std::get<0>(x.t));
}
+ void Post(const parser::SelectRankStmt &);
bool Pre(const parser::SelectTypeStmt &x) {
return CheckDef(std::get<0>(x.t));
}
@@ -4898,6 +4900,24 @@ bool ConstructVisitor::Pre(const
parser::SelectTypeConstruct &) {
void ConstructVisitor::Post(const parser::SelectTypeConstruct &) {
PopAssociation();
}
+void ConstructVisitor::Post(const parser::SelectRankStmt &x){
+ auto &association{GetCurrentAssociation()};
+ if (const std::optional<parser::Name> &name{std::get<1>(x.t)}) {
+ MakePlaceholder(*name, MiscDetails::Kind::SelectTypeAssociateName);
+ association.name = &*name;
+ }
+ else {
+ if (const Symbol *
+ whole{UnwrapWholeSymbolDataRef(association.selector.expr)}) {
+ ConvertToObjectEntity(const_cast<Symbol &>(*whole));
+ if (!IsAssumedRankArray(*whole)) {
+ Say(association.selector.source, // C1150
+ "Selector is not an assumed rank variable"_err_en_US);
+ association = {};
+ }
+ }
+ }
+}
void ConstructVisitor::Post(const parser::SelectTypeStmt &x) {
auto &association{GetCurrentAssociation()};
@@ -4940,14 +4960,55 @@ void ConstructVisitor::Post(const
parser::TypeGuardStmt::Guard &x) {
SetAttrsFromAssociation(*symbol);
}
}
-
+void ConstructVisitor::Post(const parser::SelectRankCaseStmt::Rank &){
+/* if (auto *symbol{MakeAssocEntity()}) {
+// if (std::holds_alternative<parser::ScalarIntConstantExpr>(x.u)) {
+// SetTypeFromAssociation(*symbol);
+//
+// const auto &i{std::get<parser::ScalarIntConstantExpr>(x.u)};
+// if (const auto v{GetIntValue(i)}){
+// std::cout << "\nV is " << *v;
+// if (*v<0){
+// Say("-ve values not allowed"_err_en_US);
+// }
+// }
+// else{
+// std::cout << "\nInelse";
+//
+// }
+// }
+// }
+*/
+}
bool ConstructVisitor::Pre(const parser::SelectRankConstruct &) {
PushAssociation();
return true;
}
void ConstructVisitor::Post(const parser::SelectRankConstruct &) {
+ auto &values{std::get<std::list<parser::SelectRankConstruct::RankCase>>(x.t)};
+ for (const auto &rankcase_:values){
+ const auto &SelectRankCaseStmt_{
+ std::get<parser::Statement<parser::SelectRankCaseStmt>>(rankcase_.t)};
+ const auto
&Rank_{std::get<parser::SelectRankCaseStmt::Rank>(SelectRankCaseStmt_.statement.t)};
+
+// Retriving the construct-name is successful
+// if (const auto
&name_{std::get<std::optional<parser::Name>>(SelectRankCaseStmt_.statement.t)}){
+// std::cout << "\nNAME:" <<name_->source;
+//
+//
+ if ( const auto *i{std::get_if<parser::ScalarIntConstantExpr>(&Rank_.u)} ) {
+ if (const auto v{GetIntValue(*i)}){
+ std::cout << "\nRANK is " << *v;
+ //Do negative and beyond max possible permissible range checks
+ }
+ }
+ else{
+ std::cout << "\nEnter default or *";
+ }
+ }
PopAssociation();
+
}
bool ConstructVisitor::CheckDef(const std::optional<parser::Name> &x) {
diff --git a/lib/semantics/tools.h b/lib/semantics/tools.h
index 2aa94fa7..07169937 100644
--- a/lib/semantics/tools.h
+++ b/lib/semantics/tools.h
@@ -128,6 +128,11 @@ inline bool IsAssumedSizeArray(const Symbol &symbol) {
const auto *details{symbol.detailsIf<ObjectEntityDetails>()};
return details && details->IsAssumedSize();
}
+inline bool IsAssumedRankArray(const Symbol &symbol) {
+ const auto *details{symbol.detailsIf<ObjectEntityDetails>()};
+ return details && details->IsAssumedRank();
+}
+
bool IsAssumedLengthCharacter(const Symbol &);
bool IsAssumedLengthCharacterFunction(const Symbol &);
// Is the symbol modifiable in this scope
More information about the flang-dev
mailing list