[flang-commits] [flang] 6b99dc2 - [flang] Fix crash from a blank BIND(C, NAME="") on subprogram

Peter Klausler via flang-commits flang-commits at lists.llvm.org
Wed May 25 14:48:03 PDT 2022


Author: Peter Klausler
Date: 2022-05-25T14:47:50-07:00
New Revision: 6b99dc29c6efa5d36306dd567c5e972cafb85c17

URL: https://github.com/llvm/llvm-project/commit/6b99dc29c6efa5d36306dd567c5e972cafb85c17
DIFF: https://github.com/llvm/llvm-project/commit/6b99dc29c6efa5d36306dd567c5e972cafb85c17.diff

LOG: [flang] Fix crash from a blank BIND(C,NAME="") on subprogram

A recent change fixed the processing of BIND(C,NAME=expr) character
expressions so that they are evaluated as constants in the scope of
the subprogram.  However, when the character name expression results
in an empty value after trimming, the compiler emits a warning message,
and this message is now causing a crash due to a lack of statement
context.  To fix, extend the deferred processing of the BIND(C,NAME="")
so that a basic statement context exists.

Differential Revision: https://reviews.llvm.org/D126416

Added: 
    

Modified: 
    flang/lib/Semantics/resolve-names.cpp

Removed: 
    


################################################################################
diff  --git a/flang/lib/Semantics/resolve-names.cpp b/flang/lib/Semantics/resolve-names.cpp
index 1fe21ce9bc9c4..9898fe3da57d3 100644
--- a/flang/lib/Semantics/resolve-names.cpp
+++ b/flang/lib/Semantics/resolve-names.cpp
@@ -826,7 +826,7 @@ class SubprogramVisitor : public virtual ScopeHandler, public InterfaceVisitor {
       const ProgramTree::EntryStmtList * = nullptr);
   bool BeginMpSubprogram(const parser::Name &);
   void PushBlockDataScope(const parser::Name &);
-  void EndSubprogram(
+  void EndSubprogram(std::optional<parser::CharBlock> stmtSource = std::nullopt,
       const std::optional<parser::LanguageBindingSpec> * = nullptr);
 
 protected:
@@ -3237,8 +3237,9 @@ bool SubprogramVisitor::Pre(const parser::InterfaceBody::Subroutine &x) {
   return BeginSubprogram(name, Symbol::Flag::Subroutine);
 }
 void SubprogramVisitor::Post(const parser::InterfaceBody::Subroutine &x) {
-  EndSubprogram(&std::get<std::optional<parser::LanguageBindingSpec>>(
-      std::get<parser::Statement<parser::SubroutineStmt>>(x.t).statement.t));
+  const auto &stmt{std::get<parser::Statement<parser::SubroutineStmt>>(x.t)};
+  EndSubprogram(stmt.source,
+      &std::get<std::optional<parser::LanguageBindingSpec>>(stmt.statement.t));
 }
 bool SubprogramVisitor::Pre(const parser::InterfaceBody::Function &x) {
   const auto &name{std::get<parser::Name>(
@@ -3246,9 +3247,10 @@ bool SubprogramVisitor::Pre(const parser::InterfaceBody::Function &x) {
   return BeginSubprogram(name, Symbol::Flag::Function);
 }
 void SubprogramVisitor::Post(const parser::InterfaceBody::Function &x) {
-  const auto &maybeSuffix{std::get<std::optional<parser::Suffix>>(
-      std::get<parser::Statement<parser::FunctionStmt>>(x.t).statement.t)};
-  EndSubprogram(maybeSuffix ? &maybeSuffix->binding : nullptr);
+  const auto &stmt{std::get<parser::Statement<parser::FunctionStmt>>(x.t)};
+  const auto &maybeSuffix{
+      std::get<std::optional<parser::Suffix>>(stmt.statement.t)};
+  EndSubprogram(stmt.source, maybeSuffix ? &maybeSuffix->binding : nullptr);
 }
 
 bool SubprogramVisitor::Pre(const parser::SubroutineStmt &stmt) {
@@ -3598,15 +3600,19 @@ bool SubprogramVisitor::BeginSubprogram(const parser::Name &name,
 }
 
 void SubprogramVisitor::EndSubprogram(
+    std::optional<parser::CharBlock> stmtSource,
     const std::optional<parser::LanguageBindingSpec> *binding) {
   if (binding && *binding && currScope().symbol()) {
     // Finally process the BIND(C,NAME=name) now that symbols in the name
     // expression will resolve local names.
     auto flagRestorer{common::ScopedSet(inSpecificationPart_, false)};
+    auto originalStmtSource{messageHandler().currStmtSource()};
+    messageHandler().set_currStmtSource(stmtSource);
     BeginAttrs();
     Walk(**binding);
     SetBindNameOn(*currScope().symbol());
     currScope().symbol()->attrs() |= EndAttrs();
+    messageHandler().set_currStmtSource(originalStmtSource);
   }
   PopScope();
 }
@@ -7438,27 +7444,31 @@ bool ResolveNamesVisitor::BeginScopeForNode(const ProgramTree &node) {
 }
 
 void ResolveNamesVisitor::EndScopeForNode(const ProgramTree &node) {
-  using BindingPtr = const std::optional<parser::LanguageBindingSpec> *;
-  EndSubprogram(common::visit(
+  std::optional<parser::CharBlock> stmtSource;
+  const std::optional<parser::LanguageBindingSpec> *binding{nullptr};
+  common::visit(
       common::visitors{
-          [](const parser::Statement<parser::FunctionStmt> *stmt) {
+          [&](const parser::Statement<parser::FunctionStmt> *stmt) {
             if (stmt) {
+              stmtSource = stmt->source;
               if (const auto &maybeSuffix{
                       std::get<std::optional<parser::Suffix>>(
                           stmt->statement.t)}) {
-                return &maybeSuffix->binding;
+                binding = &maybeSuffix->binding;
               }
             }
-            return BindingPtr{};
           },
-          [](const parser::Statement<parser::SubroutineStmt> *stmt) {
-            return stmt ? &std::get<std::optional<parser::LanguageBindingSpec>>(
-                              stmt->statement.t)
-                        : BindingPtr{};
+          [&](const parser::Statement<parser::SubroutineStmt> *stmt) {
+            if (stmt) {
+              stmtSource = stmt->source;
+              binding = &std::get<std::optional<parser::LanguageBindingSpec>>(
+                  stmt->statement.t);
+            }
           },
-          [](const auto *) { return BindingPtr{}; },
+          [](const auto *) {},
       },
-      node.stmt()));
+      node.stmt());
+  EndSubprogram(stmtSource, binding);
 }
 
 // Some analyses and checks, such as the processing of initializers of


        


More information about the flang-commits mailing list