[flang-commits] [flang] [flang] Fix crash in error recovery (PR #92786)
via flang-commits
flang-commits at lists.llvm.org
Mon May 20 09:47:59 PDT 2024
llvmbot wrote:
<!--LLVM PR SUMMARY COMMENT-->
@llvm/pr-subscribers-flang-semantics
Author: Peter Klausler (klausler)
<details>
<summary>Changes</summary>
EQUIVALENCE set processing assumes that any arrays have explicit shape and constant lower bounds. When an erroneous program violates those assumptions, the compiler crashes. Fix.
Fixes https://github.com/llvm/llvm-project/issues/92636.
---
Full diff: https://github.com/llvm/llvm-project/pull/92786.diff
4 Files Affected:
- (modified) flang/include/flang/Semantics/symbol.h (+1)
- (modified) flang/lib/Semantics/resolve-names-utils.cpp (+27-17)
- (modified) flang/lib/Semantics/resolve-names.cpp (+1-1)
- (modified) flang/lib/Semantics/symbol.cpp (+10-2)
``````````diff
diff --git a/flang/include/flang/Semantics/symbol.h b/flang/include/flang/Semantics/symbol.h
index 50f7b68d80cb1..f130036d949d7 100644
--- a/flang/include/flang/Semantics/symbol.h
+++ b/flang/include/flang/Semantics/symbol.h
@@ -815,6 +815,7 @@ class Symbol {
void SetIsExplicitBindName(bool);
bool IsFuncResult() const;
bool IsObjectArray() const;
+ const ArraySpec *GetShape() const;
bool IsSubprogram() const;
bool IsFromModFile() const;
bool HasExplicitInterface() const {
diff --git a/flang/lib/Semantics/resolve-names-utils.cpp b/flang/lib/Semantics/resolve-names-utils.cpp
index 3ca460b8e46ac..e27a54361749f 100644
--- a/flang/lib/Semantics/resolve-names-utils.cpp
+++ b/flang/lib/Semantics/resolve-names-utils.cpp
@@ -376,25 +376,35 @@ static void PropagateSaveAttr(const EquivalenceSet &src, EquivalenceSet &dst) {
void EquivalenceSets::AddToSet(const parser::Designator &designator) {
if (CheckDesignator(designator)) {
- Symbol &symbol{*currObject_.symbol};
- if (!currSet_.empty()) {
- // check this symbol against first of set for compatibility
- Symbol &first{currSet_.front().symbol};
- CheckCanEquivalence(designator.source, first, symbol) &&
- CheckCanEquivalence(designator.source, symbol, first);
- }
- auto subscripts{currObject_.subscripts};
- if (subscripts.empty() && symbol.IsObjectArray()) {
- // record a whole array as its first element
- for (const ShapeSpec &spec : symbol.get<ObjectEntityDetails>().shape()) {
- auto &lbound{spec.lbound().GetExplicit().value()};
- subscripts.push_back(evaluate::ToInt64(lbound).value());
+ if (Symbol * symbol{currObject_.symbol}) {
+ if (!currSet_.empty()) {
+ // check this symbol against first of set for compatibility
+ Symbol &first{currSet_.front().symbol};
+ CheckCanEquivalence(designator.source, first, *symbol) &&
+ CheckCanEquivalence(designator.source, *symbol, first);
+ }
+ auto subscripts{currObject_.subscripts};
+ if (subscripts.empty()) {
+ if (const ArraySpec * shape{symbol->GetShape()};
+ shape && shape->IsExplicitShape()) {
+ // record a whole array as its first element
+ for (const ShapeSpec &spec : *shape) {
+ if (auto lbound{spec.lbound().GetExplicit()}) {
+ if (auto lbValue{evaluate::ToInt64(*lbound)}) {
+ subscripts.push_back(*lbValue);
+ continue;
+ }
+ }
+ subscripts.clear(); // error recovery
+ break;
+ }
+ }
}
+ auto substringStart{currObject_.substringStart};
+ currSet_.emplace_back(
+ *symbol, subscripts, substringStart, designator.source);
+ PropagateSaveAttr(currSet_.back(), currSet_);
}
- auto substringStart{currObject_.substringStart};
- currSet_.emplace_back(
- symbol, subscripts, substringStart, designator.source);
- PropagateSaveAttr(currSet_.back(), currSet_);
}
currObject_ = {};
}
diff --git a/flang/lib/Semantics/resolve-names.cpp b/flang/lib/Semantics/resolve-names.cpp
index a46c0f378d5d0..2622fa1e50747 100644
--- a/flang/lib/Semantics/resolve-names.cpp
+++ b/flang/lib/Semantics/resolve-names.cpp
@@ -6227,7 +6227,7 @@ void DeclarationVisitor::CheckEquivalenceSets() {
}
for (const parser::EquivalenceObject &object : *set) {
const auto &designator{object.v.value()};
- // The designator was not resolved when it was encountered so do it now.
+ // The designator was not resolved when it was encountered, so do it now.
// AnalyzeExpr causes array sections to be changed to substrings as needed
Walk(designator);
if (AnalyzeExpr(context(), designator)) {
diff --git a/flang/lib/Semantics/symbol.cpp b/flang/lib/Semantics/symbol.cpp
index 381905b89fb2d..3eb120fd962fa 100644
--- a/flang/lib/Semantics/symbol.cpp
+++ b/flang/lib/Semantics/symbol.cpp
@@ -385,9 +385,17 @@ bool Symbol::IsFuncResult() const {
details_);
}
+const ArraySpec *Symbol::GetShape() const {
+ if (const auto *details{std::get_if<ObjectEntityDetails>(&details_)}) {
+ return &details->shape();
+ } else {
+ return nullptr;
+ }
+}
+
bool Symbol::IsObjectArray() const {
- const auto *details{std::get_if<ObjectEntityDetails>(&details_)};
- return details && details->IsArray();
+ const ArraySpec *shape{GetShape()};
+ return shape && !shape->empty();
}
bool Symbol::IsSubprogram() const {
``````````
</details>
https://github.com/llvm/llvm-project/pull/92786
More information about the flang-commits
mailing list