[flang] Fix crashes in ResolveOmpObject and RewriteOpenMPLoopConstruct

Using debug build of f18, `omp-resolve01.f90` sometimes crashed in
`OmpVisitor::ResolveOmpObject`. This was because when the designator was
analyzed it could be rewritten from an `ArrayElement` to a `Substring`.
That made the reference to the `Name` inside the designator no longer
valid so the crash happened when it was referenced later. The fix is to
return when the substring is detected so the name is not referenced.

Also, the name returned from `ResolveDesignator` can but null so it must
be checked.

The crash in `RewriteOpenMPLoopConstruct` happened intermittently on
`omp-loop-association.f90`. It happened when the DO construct was the
last element of the block. In that case `block.erase()` returns an
iterator pointing to `block.end()` which must not be dereferenced.

Original-commit: flang-compiler/f18@3299972d04
Reviewed-on: https://github.com/flang-compiler/f18/pull/824
This commit is contained in:
Tim Keith 2019-11-14 15:01:20 -08:00
parent 3efb332af2
commit b5c7193769
2 changed files with 13 additions and 12 deletions

View File

@ -90,13 +90,14 @@ private:
std::get<std::optional<parser::DoConstruct>>(x.t) =
std::move(*doCons);
nextIt = block.erase(nextIt);
// try to match OmpEndLoopDirective
if (auto *endDir{
GetConstructIf<parser::OmpEndLoopDirective>(*nextIt)}) {
std::get<std::optional<parser::OmpEndLoopDirective>>(x.t) =
std::move(*endDir);
nextIt = block.erase(nextIt);
if (nextIt != block.end()) {
if (auto *endDir{
GetConstructIf<parser::OmpEndLoopDirective>(*nextIt)}) {
std::get<std::optional<parser::OmpEndLoopDirective>>(x.t) =
std::move(*endDir);
block.erase(nextIt);
}
}
} else {
messages_.Say(dir.source,

View File

@ -1161,23 +1161,23 @@ void OmpVisitor::ResolveOmpObject(
if (dataSharingAttributeFlags.test(ompFlag)) {
CheckMultipleAppearances(*name, symbol, ompFlag);
}
} else if (const auto *designatorName{
ResolveDesignator(designator)};
designatorName->symbol) {
} else if (const auto *name{ResolveDesignator(designator)};
name && name->symbol) {
// Array sections to be changed to substrings as needed
if (AnalyzeExpr(context(), designator)) {
if (std::holds_alternative<parser::Substring>(designator.u)) {
Say(designator.source,
"Substrings are not allowed on OpenMP "
"directives or clauses"_err_en_US);
return;
}
}
// other checks, more TBD
if (const auto *details{designatorName->symbol
->detailsIf<ObjectEntityDetails>()}) {
if (const auto *details{
name->symbol->detailsIf<ObjectEntityDetails>()}) {
if (details->IsArray()) {
// TODO: check Array Sections
} else if (designatorName->symbol->owner().IsDerivedType()) {
} else if (name->symbol->owner().IsDerivedType()) {
// TODO: check Structure Component
}
}