[flang-commits] [flang] [Flang] Avoid crash resolving restricted specific intrinsics (PR #217852)

via flang-commits flang-commits at lists.llvm.org
Fri Aug 21 02:04:40 PDT 2026


llvmorg-github-actions[bot] wrote:


<!--LLVM PR SUMMARY COMMENT-->

@llvm/pr-subscribers-flang-semantics

Author: nudt_yixiao (keepyixiao)

<details>
<summary>Changes</summary>

Name resolution assumed that every specific intrinsic function handled in a procedure context was unrestricted and had a numeric result. An undeclared LLT used as a procedure pointer target therefore triggered a CHECK because LLT is restricted and returns LOGICAL.

Rename the handler to reflect that it resolves both restricted and unrestricted specific intrinsic functions. Preserve result types only for unrestricted intrinsics; restricted intrinsics retain an untyped symbol so later semantic checks can issue the appropriate diagnostic.

Fixes https://github.com/llvm/llvm-project/issues/208825

---
Full diff: https://github.com/llvm/llvm-project/pull/217852.diff


2 Files Affected:

- (modified) flang/lib/Semantics/resolve-names.cpp (+13-11) 
- (modified) flang/test/Semantics/resolve46.f90 (+12) 


``````````diff
diff --git a/flang/lib/Semantics/resolve-names.cpp b/flang/lib/Semantics/resolve-names.cpp
index 27c4e96d269aa..80285eb2eb2e4 100644
--- a/flang/lib/Semantics/resolve-names.cpp
+++ b/flang/lib/Semantics/resolve-names.cpp
@@ -1329,7 +1329,7 @@ class DeclarationVisitor : public ArraySpecVisitor,
       const parser::TypeParamValue &, common::TypeParamAttr attr);
   Attrs HandleSaveName(const SourceName &, Attrs);
   void AddSaveName(std::set<SourceName> &, const SourceName &);
-  bool HandleUnrestrictedSpecificIntrinsicFunction(const parser::Name &);
+  bool HandleSpecificIntrinsicFunction(const parser::Name &);
   const parser::Name *FindComponent(const parser::Name *, const parser::Name &);
   void Initialization(const parser::Name &, const parser::Initialization &,
       bool inComponentDecl);
@@ -8144,10 +8144,10 @@ Symbol &DeclarationVisitor::MakeCommonBlockSymbol(
 }
 
 bool DeclarationVisitor::NameIsKnownOrIntrinsic(const parser::Name &name) {
-  return FindSymbol(name) || HandleUnrestrictedSpecificIntrinsicFunction(name);
+  return FindSymbol(name) || HandleSpecificIntrinsicFunction(name);
 }
 
-bool DeclarationVisitor::HandleUnrestrictedSpecificIntrinsicFunction(
+bool DeclarationVisitor::HandleSpecificIntrinsicFunction(
     const parser::Name &name) {
   if (auto interface{context().intrinsics().IsSpecificIntrinsicFunction(
           name.source.ToString())}) {
@@ -8156,17 +8156,19 @@ bool DeclarationVisitor::HandleUnrestrictedSpecificIntrinsicFunction(
     // INTRINSIC flag will cause this symbol to have a complete interface
     // recreated for it later on demand, but capturing its result type here
     // will make GetType() return a correct result without having to
-    // probe the intrinsics table again.
+    // probe the intrinsics table again.  Restricted specific intrinsic
+    // function names are also resolved here so that their use can be
+    // diagnosed later, but they do not need a result type.
     Symbol &symbol{MakeSymbol(InclusiveScope(), name.source, Attrs{})};
     SetImplicitAttr(symbol, Attr::INTRINSIC);
-    CHECK(interface->functionResult.has_value());
-    evaluate::DynamicType dyType{
-        DEREF(interface->functionResult->GetTypeAndShape()).type()};
-    CHECK(common::IsNumericTypeCategory(dyType.category()));
-    const DeclTypeSpec &typeSpec{
-        MakeNumericType(dyType.category(), dyType.kind())};
     ProcEntityDetails details;
-    details.set_type(typeSpec);
+    if (!interface->isRestrictedSpecific) {
+      CHECK(interface->functionResult.has_value());
+      evaluate::DynamicType dyType{
+          DEREF(interface->functionResult->GetTypeAndShape()).type()};
+      CHECK(common::IsNumericTypeCategory(dyType.category()));
+      details.set_type(MakeNumericType(dyType.category(), dyType.kind()));
+    }
     symbol.set_details(std::move(details));
     symbol.set(Symbol::Flag::Function);
     if (interface->IsElemental()) {
diff --git a/flang/test/Semantics/resolve46.f90 b/flang/test/Semantics/resolve46.f90
index d473226edaabe..efe3814c5a7e9 100644
--- a/flang/test/Semantics/resolve46.f90
+++ b/flang/test/Semantics/resolve46.f90
@@ -45,3 +45,15 @@ end function chrcmp
   !ERROR: 'llt' is not an unrestricted specific intrinsic procedure
   u => llt
 end program main
+
+subroutine testRestrictedSpecificWithoutIntrinsicStmt
+  procedure(), pointer :: p
+  !ERROR: 'llt' is not an unrestricted specific intrinsic procedure
+  p => llt
+end subroutine
+
+subroutine testRestrictedSpecificWithoutIntrinsicStmt1
+  !ERROR: 'llt' is not an unrestricted specific intrinsic procedure
+  u => llt
+end subroutine
+

``````````

</details>


https://github.com/llvm/llvm-project/pull/217852


More information about the flang-commits mailing list