summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorPeter Steinfeld <psteinfeld@nvidia.com>2021-03-25 08:04:19 -0700
committerPeter Steinfeld <psteinfeld@nvidia.com>2021-03-29 10:12:35 -0700
commita7afc8a51471bdfd0c597f8e885dbddada7f590a (patch)
tree94f0ff1f955c3891cdd4a5c166ffd15a26d03653
parent54bacaf31127ee9d19e8df7ad7de5c94a4fc7c62 (diff)
downloadllvm-a7afc8a51471bdfd0c597f8e885dbddada7f590a.tar.gz
[flang] Fix CHECK() calls on erroneous procedure declarations
When writing tests for a previous problem, I ran across situations where the compiler was failing calls to CHECK(). In these situations, the compiler had inconsistent semantic information because the programs were erroneous. This inconsistent information was causing the calls to CHECK(). I fixed this by avoiding the code that ended up making the failed calls to CHECK() and making sure that we were only avoiding these situations when the associated symbols were erroneous. I also added tests that would cause the calls to CHECK() without these changes. Differential Revision: https://reviews.llvm.org/D99342
-rw-r--r--flang/lib/Semantics/resolve-names.cpp34
-rw-r--r--flang/test/Semantics/resolve18.f9061
2 files changed, 84 insertions, 11 deletions
diff --git a/flang/lib/Semantics/resolve-names.cpp b/flang/lib/Semantics/resolve-names.cpp
index 6818686f43e7..304a7b9449d0 100644
--- a/flang/lib/Semantics/resolve-names.cpp
+++ b/flang/lib/Semantics/resolve-names.cpp
@@ -681,7 +681,9 @@ public:
bool isAbstract() const;
protected:
- GenericDetails &GetGenericDetails();
+ Symbol &GetGenericSymbol() {
+ return DEREF(genericInfo_.top().symbol);
+ }
// Add to generic the symbol for the subprogram with the same name
void CheckGenericProcedures(Symbol &);
@@ -2681,9 +2683,6 @@ bool InterfaceVisitor::isGeneric() const {
bool InterfaceVisitor::isAbstract() const {
return !genericInfo_.empty() && GetGenericInfo().isAbstract;
}
-GenericDetails &InterfaceVisitor::GetGenericDetails() {
- return GetGenericInfo().symbol->get<GenericDetails>();
-}
void InterfaceVisitor::AddSpecificProcs(
const std::list<parser::Name> &names, ProcedureKind kind) {
@@ -2885,7 +2884,9 @@ void SubprogramVisitor::Post(const parser::ImplicitPart &) {
if (funcInfo_.parsedType) {
messageHandler().set_currStmtSource(funcInfo_.source);
if (const auto *type{ProcessTypeSpec(*funcInfo_.parsedType, true)}) {
- funcInfo_.resultSymbol->SetType(*type);
+ if (!context().HasError(funcInfo_.resultSymbol)) {
+ funcInfo_.resultSymbol->SetType(*type);
+ }
}
}
funcInfo_ = {};
@@ -2945,11 +2946,16 @@ void SubprogramVisitor::Post(const parser::FunctionStmt &stmt) {
funcResultName = &name;
}
// add function result to function scope
- EntityDetails funcResultDetails;
- funcResultDetails.set_funcResult(true);
- funcInfo_.resultSymbol =
- &MakeSymbol(*funcResultName, std::move(funcResultDetails));
- details.set_result(*funcInfo_.resultSymbol);
+ if (details.isFunction()) {
+ CHECK(context().HasError(currScope().symbol()));
+ } else {
+ // add function result to function scope
+ EntityDetails funcResultDetails;
+ funcResultDetails.set_funcResult(true);
+ funcInfo_.resultSymbol =
+ &MakeSymbol(*funcResultName, std::move(funcResultDetails));
+ details.set_result(*funcInfo_.resultSymbol);
+ }
// C1560.
if (funcInfo_.resultName && funcInfo_.resultName->source == name.source) {
@@ -3223,7 +3229,13 @@ Symbol &SubprogramVisitor::PushSubprogramScope(
MakeExternal(*symbol);
}
if (isGeneric()) {
- GetGenericDetails().AddSpecificProc(*symbol, name.source);
+ Symbol &genericSymbol{GetGenericSymbol()};
+ if (genericSymbol.has<GenericDetails>()) {
+ genericSymbol.get<GenericDetails>().AddSpecificProc(
+ *symbol, name.source);
+ } else {
+ CHECK(context().HasError(genericSymbol));
+ }
}
set_inheritFromParent(false);
}
diff --git a/flang/test/Semantics/resolve18.f90 b/flang/test/Semantics/resolve18.f90
index 204f6e7b383d..334bb71c4f08 100644
--- a/flang/test/Semantics/resolve18.f90
+++ b/flang/test/Semantics/resolve18.f90
@@ -121,3 +121,64 @@ module m8
end subroutine f8
end interface g8
end module m8
+
+module m9
+ type f9
+ end type f9
+ !ERROR: 'f9' is already declared in this scoping unit
+ interface f9
+ real function f9()
+ end function f9
+ end interface f9
+contains
+ function f9(x)
+ end function f9
+end module m9
+
+module m10
+ type :: t10
+ end type t10
+ interface f10
+ function f10()
+ end function f10
+ end interface f10
+contains
+ !ERROR: 'f10' is already declared in this scoping unit
+ function f10(x)
+ end function f10
+end module m10
+
+module m11
+ type :: t11
+ end type t11
+ interface i11
+ function f11()
+ end function f11
+ end interface i11
+contains
+ !ERROR: 'f11' is already declared in this scoping unit
+ function f11(x)
+ end function f11
+end module m11
+
+module m12
+ interface f12
+ function f12()
+ end function f12
+ end interface f12
+contains
+ !ERROR: 'f12' is already declared in this scoping unit
+ function f12(x)
+ end function f12
+end module m12
+
+module m13
+ interface f13
+ function f13()
+ end function f13
+ end interface f13
+contains
+ !ERROR: 'f13' is already declared in this scoping unit
+ function f13()
+ end function f13
+end module m13