[flang-commits] [flang] 8065e48 - [flang] Inner INTRINSIC must not shadow host generic

Peter Klausler via flang-commits flang-commits at lists.llvm.org
Thu Apr 14 15:42:54 PDT 2022


Author: Peter Klausler
Date: 2022-04-14T15:42:44-07:00
New Revision: 8065e482189104af30acf46c16ac6c5f6e270d0a

URL: https://github.com/llvm/llvm-project/commit/8065e482189104af30acf46c16ac6c5f6e270d0a
DIFF: https://github.com/llvm/llvm-project/commit/8065e482189104af30acf46c16ac6c5f6e270d0a.diff

LOG: [flang] Inner INTRINSIC must not shadow host generic

A generic interface (however spelled) can have the same name as
an intrinsic procedure in the same scope.  When an explicit INTRINSIC
attribute statement appears in a nested scope, semantics was
unconditionally declaring a new symbol that hid the generic entirely.
Catch this case and create instead a host association symbol for
the generic that can then be decorated with the INTRINSIC attribute.

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

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 81f8d6e08aa7f..6bcc89f38982a 100644
--- a/flang/lib/Semantics/resolve-names.cpp
+++ b/flang/lib/Semantics/resolve-names.cpp
@@ -3921,7 +3921,8 @@ bool DeclarationVisitor::Pre(const parser::IntrinsicStmt &x) {
     auto &symbol{DEREF(FindSymbol(name))};
     if (symbol.has<GenericDetails>()) {
       // Generic interface is extending intrinsic; ok
-    } else if (!ConvertToProcEntity(symbol)) {
+    } else if (!symbol.has<HostAssocDetails>() &&
+        !ConvertToProcEntity(symbol)) {
       SayWithDecl(
           name, symbol, "INTRINSIC attribute not allowed on '%s'"_err_en_US);
     } else if (symbol.attrs().test(Attr::EXTERNAL)) { // C840
@@ -3965,8 +3966,24 @@ bool DeclarationVisitor::HandleAttributeStmt(
 }
 Symbol &DeclarationVisitor::HandleAttributeStmt(
     Attr attr, const parser::Name &name) {
-  if (attr == Attr::INTRINSIC && !IsIntrinsic(name.source, std::nullopt)) {
-    Say(name.source, "'%s' is not a known intrinsic procedure"_err_en_US);
+  if (attr == Attr::INTRINSIC) {
+    if (!IsIntrinsic(name.source, std::nullopt)) {
+      Say(name.source, "'%s' is not a known intrinsic procedure"_err_en_US);
+    } else if (currScope().kind() == Scope::Kind::Subprogram ||
+        currScope().kind() == Scope::Kind::Block) {
+      if (auto *symbol{FindSymbol(name)}) {
+        if (symbol->GetUltimate().has<GenericDetails>() &&
+            symbol->owner() != currScope()) {
+          // Declaring a name INTRINSIC when there is a generic
+          // interface of the same name in the host scope.
+          // Host-associate the generic and mark it INTRINSIC
+          // rather than completely overriding the generic.
+          symbol = &MakeHostAssocSymbol(name, *symbol);
+          symbol->attrs().set(Attr::INTRINSIC);
+          return *symbol;
+        }
+      }
+    }
   }
   auto *symbol{FindInScope(name)};
   if (attr == Attr::ASYNCHRONOUS || attr == Attr::VOLATILE) {


        


More information about the flang-commits mailing list