aboutsummaryrefslogtreecommitdiff
path: root/flang/lib/Semantics/resolve-names-utils.cpp
diff options
context:
space:
mode:
authorPeter Klausler <35819229+klausler@users.noreply.github.com>2024-05-23 13:31:25 -0700
committerGitHub <noreply@github.com>2024-05-23 13:31:25 -0700
commit70d1844abebb786c1510f72f79558ff3e8710d39 (patch)
treec9cde39ed9eee0951c9fbbcc93c5f4209d3cdac8 /flang/lib/Semantics/resolve-names-utils.cpp
parent208544fc70d2cfd5b2c13232a267048108da1978 (diff)
downloadllvm-70d1844abebb786c1510f72f79558ff3e8710d39.zip
llvm-70d1844abebb786c1510f72f79558ff3e8710d39.tar.gz
llvm-70d1844abebb786c1510f72f79558ff3e8710d39.tar.bz2
[flang] Fix crash in error recovery (#92786)
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.
Diffstat (limited to 'flang/lib/Semantics/resolve-names-utils.cpp')
-rw-r--r--flang/lib/Semantics/resolve-names-utils.cpp44
1 files changed, 27 insertions, 17 deletions
diff --git a/flang/lib/Semantics/resolve-names-utils.cpp b/flang/lib/Semantics/resolve-names-utils.cpp
index 3ca460b..e27a543 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_ = {};
}