From: peter klausler Date: Fri, 30 Oct 2020 21:18:20 +0000 (-0700) Subject: [flang] Plug error recovery hole for erroneous subscripts X-Git-Tag: llvmorg-13-init~7523 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=93d10919c8e360847d7f5a7773bbe9e4fe0585cb;p=platform%2Fupstream%2Fllvm.git [flang] Plug error recovery hole for erroneous subscripts Avoid a crash in folding an empty vector of subscripts that resulted from a semantic error. Differential revision: https://reviews.llvm.org/D90499 --- diff --git a/flang/lib/Semantics/expression.cpp b/flang/lib/Semantics/expression.cpp index 21b7687..73534c3 100644 --- a/flang/lib/Semantics/expression.cpp +++ b/flang/lib/Semantics/expression.cpp @@ -205,11 +205,10 @@ MaybeExpr ExpressionAnalyzer::Designate(DataRef &&ref) { // subscripts are in hand. MaybeExpr ExpressionAnalyzer::CompleteSubscripts(ArrayRef &&ref) { const Symbol &symbol{ref.GetLastSymbol().GetUltimate()}; - const auto *object{symbol.detailsIf()}; int symbolRank{symbol.Rank()}; int subscripts{static_cast(ref.size())}; if (subscripts == 0) { - // nothing to check + return std::nullopt; // error recovery } else if (subscripts != symbolRank) { if (symbolRank != 0) { Say("Reference to rank-%d object '%s' has %d subscripts"_err_en_US, @@ -230,7 +229,8 @@ MaybeExpr ExpressionAnalyzer::CompleteSubscripts(ArrayRef &&ref) { return std::nullopt; } } - } else if (object) { + } else if (const auto *object{ + symbol.detailsIf()}) { // C928 & C1002 if (Triplet * last{std::get_if(&ref.subscript().back().u)}) { if (!last->upper() && object->IsAssumedSize()) { @@ -240,6 +240,11 @@ MaybeExpr ExpressionAnalyzer::CompleteSubscripts(ArrayRef &&ref) { return std::nullopt; } } + } else { + // Shouldn't get here from Analyze(ArrayElement) without a valid base, + // which, if not an object, must be a construct entity from + // SELECT TYPE/RANK or ASSOCIATE. + CHECK(symbol.has()); } return Designate(DataRef{std::move(ref)}); } @@ -247,6 +252,9 @@ MaybeExpr ExpressionAnalyzer::CompleteSubscripts(ArrayRef &&ref) { // Applies subscripts to a data reference. MaybeExpr ExpressionAnalyzer::ApplySubscripts( DataRef &&dataRef, std::vector &&subscripts) { + if (subscripts.empty()) { + return std::nullopt; // error recovery + } return std::visit( common::visitors{ [&](SymbolRef &&symbol) { @@ -902,7 +910,6 @@ MaybeExpr ExpressionAnalyzer::Analyze(const parser::ArrayElement &ae) { if (baseExpr) { if (ae.subscripts.empty()) { // will be converted to function call later or error reported - return std::nullopt; } else if (baseExpr->Rank() == 0) { if (const Symbol * symbol{GetLastSymbol(*baseExpr)}) { if (!context_.HasError(symbol)) { diff --git a/flang/test/Semantics/expr-errors03.f90 b/flang/test/Semantics/expr-errors03.f90 new file mode 100644 index 0000000..059e80a --- /dev/null +++ b/flang/test/Semantics/expr-errors03.f90 @@ -0,0 +1,20 @@ +! RUN: %S/test_errors.sh %s %t %f18 +! Regression test for subscript error recovery +module m + implicit none + integer, parameter :: n = 3 + integer, parameter :: pc(n) = [0, 5, 6] + contains + logical function f(u) + integer :: u + !ERROR: No explicit type declared for 'i' + do i = 1, n + !ERROR: No explicit type declared for 'i' + if (pc(i) == u) then + f = .true. + return + end if + end do + f = .false. + end +end module