From 5e2788ca59daf88e6213cb6b336a618ef480dfe5 Mon Sep 17 00:00:00 2001 From: Peter Klausler Date: Tue, 12 Nov 2024 07:41:09 -0800 Subject: [PATCH] [flang] Fix spurious error messages due to INTRINSIC nested in BLOCK When skimmming executable parts to collect names used in procedure calls, it is important to exclude names that have local declarations in nested BLOCK constructs. The mechanism for handling these nested declarations was catching only names whose declarations include an "entity-decl", and so names appearing in other declaration statements (like INTRINSIC and EXTERNAL statements) were not hidden from the scan, leading to absurd error messages when such names turn out to be procedures in the nested BLOCK construct but to not be procedures outside it. This patch fixes the code that detects local declarations in BLOCK for all of the missed cases that don't use entity-decls; only INTRINSIC and EXTERNAL could affect the procedures whose names are of interest to the executable part skimmer, but perhaps future work will want to collect non-procedures as well, so I plugged all of the holes that I could find. Fixes https://github.com/llvm/llvm-project/issues/115674. --- flang/lib/Semantics/resolve-names.cpp | 53 +++++++++++++++++++++++++-- flang/test/Semantics/bug115674.f90 | 9 +++++ 2 files changed, 59 insertions(+), 3 deletions(-) create mode 100644 flang/test/Semantics/bug115674.f90 diff --git a/flang/lib/Semantics/resolve-names.cpp b/flang/lib/Semantics/resolve-names.cpp index e0a8246ebc752..4b8cd447bcf19 100644 --- a/flang/lib/Semantics/resolve-names.cpp +++ b/flang/lib/Semantics/resolve-names.cpp @@ -4787,10 +4787,13 @@ void DeclarationVisitor::Post(const parser::EntityDecl &x) { } else if (attrs.test(Attr::PARAMETER)) { // C882, C883 Say(name, "Missing initialization for parameter '%s'"_err_en_US); } - if (auto *scopeSymbol{currScope().symbol()}) - if (auto *details{scopeSymbol->detailsIf()}) - if (details->isDECStructure()) + if (auto *scopeSymbol{currScope().symbol()}) { + if (auto *details{scopeSymbol->detailsIf()}) { + if (details->isDECStructure()) { details->add_component(symbol); + } + } + } } void DeclarationVisitor::Post(const parser::PointerDecl &x) { @@ -7660,10 +7663,54 @@ class ExecutionPartSkimmerBase { --blockDepth_; PopScope(); } + // Note declarations of local names in BLOCK constructs. + // Don't have to worry about INTENT(), VALUE, or OPTIONAL + // (pertinent only to dummy arguments), ASYNCHRONOUS/VOLATILE, + // or accessibility attributes, bool Pre(const parser::EntityDecl &x) { Hide(std::get(x.t)); return true; } + bool Pre(const parser::ObjectDecl &x) { + Hide(std::get(x.t)); + return true; + } + bool Pre(const parser::PointerDecl &x) { + Hide(std::get(x.t)); + return true; + } + bool Pre(const parser::BindEntity &x) { + Hide(std::get(x.t)); + return true; + } + bool Pre(const parser::ContiguousStmt &x) { + for (const parser::Name &name : x.v) { + Hide(name); + } + return true; + } + bool Pre(const parser::DimensionStmt::Declaration &x) { + Hide(std::get(x.t)); + return true; + } + bool Pre(const parser::ExternalStmt &x) { + for (const parser::Name &name : x.v) { + Hide(name); + } + return true; + } + bool Pre(const parser::IntrinsicStmt &x) { + for (const parser::Name &name : x.v) { + Hide(name); + } + return true; + } + bool Pre(const parser::CodimensionStmt &x) { + for (const parser::CodimensionDecl &decl : x.v) { + Hide(std::get(decl.t)); + } + return true; + } void Post(const parser::ImportStmt &x) { if (x.kind == common::ImportKind::None || x.kind == common::ImportKind::Only) { diff --git a/flang/test/Semantics/bug115674.f90 b/flang/test/Semantics/bug115674.f90 new file mode 100644 index 0000000000000..87c527bb4297a --- /dev/null +++ b/flang/test/Semantics/bug115674.f90 @@ -0,0 +1,9 @@ +!RUN: %flang_fc1 -fsyntax-only %s 2>&1 | FileCheck --allow-empty %s +!CHECK-NOT: error: +program main + sin = 1 + block + intrinsic sin + print *, sin(0.) + end block +end