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

via flang-commits flang-commits at lists.llvm.org
Sat Aug 29 20:51:05 PDT 2026


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

>From 378a70bfa97ae9325c7a883fe8cf0290bde15a43 Mon Sep 17 00:00:00 2001
From: yixiao <yixiao at hygon.cn>
Date: Fri, 21 Aug 2026 16:58:50 +0800
Subject: [PATCH] [Flang] Avoid crash resolving restricted specific intrinsics

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.
---
 flang/lib/Semantics/resolve-names.cpp | 24 +++++++++++++-----------
 flang/test/Semantics/resolve46.f90    | 12 ++++++++++++
 2 files changed, 25 insertions(+), 11 deletions(-)

diff --git a/flang/lib/Semantics/resolve-names.cpp b/flang/lib/Semantics/resolve-names.cpp
index 17abba65bdae5..949bdf3c0ef51 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);
@@ -8274,10 +8274,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())}) {
@@ -8286,17 +8286,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
+



More information about the flang-commits mailing list