forked from OSchip/llvm-project
[flang] Don't crash on some bogus expressions
Recover more gracefully from user errors in expressions. Differential Revision: https://reviews.llvm.org/D104326
This commit is contained in:
parent
560636e549
commit
3061334e0d
|
@ -174,7 +174,8 @@ private:
|
|||
// Wraps a data reference in a typed Designator<>, and a procedure
|
||||
// or procedure pointer reference in a ProcedureDesignator.
|
||||
MaybeExpr ExpressionAnalyzer::Designate(DataRef &&ref) {
|
||||
const Symbol &symbol{ref.GetLastSymbol().GetUltimate()};
|
||||
const Symbol &last{ref.GetLastSymbol()};
|
||||
const Symbol &symbol{last.GetUltimate()};
|
||||
if (semantics::IsProcedure(symbol)) {
|
||||
if (auto *component{std::get_if<Component>(&ref.u)}) {
|
||||
return Expr<SomeType>{ProcedureDesignator{std::move(*component)}};
|
||||
|
@ -193,8 +194,17 @@ MaybeExpr ExpressionAnalyzer::Designate(DataRef &&ref) {
|
|||
symbol.name());
|
||||
}
|
||||
return std::nullopt;
|
||||
} else if (MaybeExpr result{AsGenericExpr(std::move(ref))}) {
|
||||
return result;
|
||||
} else {
|
||||
return AsGenericExpr(std::move(ref));
|
||||
if (!context_.HasError(last) && !context_.HasError(symbol)) {
|
||||
AttachDeclaration(
|
||||
Say("'%s' is not an object that can appear in an expression"_err_en_US,
|
||||
last.name()),
|
||||
symbol);
|
||||
context_.SetError(last);
|
||||
}
|
||||
return std::nullopt;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -3361,7 +3361,8 @@ void DeclarationVisitor::EndDecl() {
|
|||
}
|
||||
|
||||
bool DeclarationVisitor::CheckUseError(const parser::Name &name) {
|
||||
const auto *details{name.symbol->detailsIf<UseErrorDetails>()};
|
||||
const auto *details{
|
||||
name.symbol ? name.symbol->detailsIf<UseErrorDetails>() : nullptr};
|
||||
if (!details) {
|
||||
return false;
|
||||
}
|
||||
|
@ -3370,6 +3371,7 @@ bool DeclarationVisitor::CheckUseError(const parser::Name &name) {
|
|||
msg.Attach(location, "'%s' was use-associated from module '%s'"_en_US,
|
||||
name.source, module->GetName().value());
|
||||
}
|
||||
context().SetError(*name.symbol);
|
||||
return true;
|
||||
}
|
||||
|
||||
|
@ -5247,6 +5249,7 @@ void ConstructVisitor::ResolveIndexName(
|
|||
!prevRoot.has<EntityDetails>()) {
|
||||
Say2(name, "Index name '%s' conflicts with existing identifier"_err_en_US,
|
||||
*prev, "Previous declaration of '%s'"_en_US);
|
||||
context().SetError(symbol);
|
||||
return;
|
||||
} else {
|
||||
if (const auto *type{prevRoot.GetType()}) {
|
||||
|
|
|
@ -220,9 +220,11 @@ contains
|
|||
SELECT RANK(ptr=>x)
|
||||
RANK (3)
|
||||
PRINT *, "PRINT RANK 3"
|
||||
!ERROR: 'ptr' is not an object that can appear in an expression
|
||||
j = INT(0, KIND=MERGE(KIND(0), -1, RANK(ptr) == 0))
|
||||
RANK (1)
|
||||
PRINT *, "PRINT RANK 1"
|
||||
!ERROR: 'ptr' is not an object that can appear in an expression
|
||||
j = INT(0, KIND=MERGE(KIND(0), -1, RANK(ptr) == 1))
|
||||
END SELECT
|
||||
end subroutine
|
||||
|
|
Loading…
Reference in New Issue