Skip to content

[Flang] Fix crash when a derived type with private attribute is specified in extends #151051

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 1 commit into from
Aug 4, 2025

Conversation

ceseo
Copy link
Contributor

@ceseo ceseo commented Jul 28, 2025

While lowering to HLFIR, when a parent type is private, its name is mangled, so we need to get it from the parent symbol.

Fixes #120922

…fied in extends

While lowering to HLFIR, when a parent type is private, its name is mangled, so
we need to get it from the parent symbol.

Fixes llvm#120922
@llvmbot llvmbot added flang Flang issues not falling into any other category flang:fir-hlfir labels Jul 28, 2025
@llvmbot
Copy link
Member

llvmbot commented Jul 28, 2025

@llvm/pr-subscribers-flang-fir-hlfir

Author: Carlos Seo (ceseo)

Changes

While lowering to HLFIR, when a parent type is private, its name is mangled, so we need to get it from the parent symbol.

Fixes #120922


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

4 Files Affected:

  • (modified) flang/include/flang/Lower/ConvertType.h (+3)
  • (modified) flang/lib/Lower/ConvertExprToHLFIR.cpp (+9-2)
  • (modified) flang/lib/Lower/ConvertType.cpp (+12)
  • (added) flang/test/Lower/derived-type-private.f90 (+29)
diff --git a/flang/include/flang/Lower/ConvertType.h b/flang/include/flang/Lower/ConvertType.h
index 179a682584046..3c726595c0f76 100644
--- a/flang/include/flang/Lower/ConvertType.h
+++ b/flang/include/flang/Lower/ConvertType.h
@@ -118,6 +118,9 @@ class ComponentReverseIterator {
   /// Advance iterator to the last components of the current type parent.
   const Fortran::semantics::DerivedTypeSpec &advanceToParentType();
 
+  /// Get the parent component symbol for the current type.
+  const Fortran::semantics::Symbol *getParentComponent() const;
+
 private:
   void setCurrentType(const Fortran::semantics::DerivedTypeSpec &derived);
   const Fortran::semantics::DerivedTypeSpec *currentParentType = nullptr;
diff --git a/flang/lib/Lower/ConvertExprToHLFIR.cpp b/flang/lib/Lower/ConvertExprToHLFIR.cpp
index 46be111242bf7..13cf4e2a5a19f 100644
--- a/flang/lib/Lower/ConvertExprToHLFIR.cpp
+++ b/flang/lib/Lower/ConvertExprToHLFIR.cpp
@@ -1848,8 +1848,15 @@ class HlfirBuilder {
       for (Fortran::lower::ComponentReverseIterator compIterator(
                ctor.result().derivedTypeSpec());
            !compIterator.lookup(compSym.name());) {
-        const auto &parentType = compIterator.advanceToParentType();
-        llvm::StringRef parentName = toStringRef(parentType.name());
+        // Private parent components have mangled names. Get the name from the
+        // parent symbol.
+        const Fortran::semantics::Symbol *parentCompSym =
+            compIterator.getParentComponent();
+        assert(parentCompSym && "failed to get parent component symbol");
+        std::string parentName =
+            converter.getRecordTypeFieldName(*parentCompSym);
+        // Advance the iterator, but don't use its return value.
+        compIterator.advanceToParentType();
         auto baseRecTy = mlir::cast<fir::RecordType>(
             hlfir::getFortranElementType(currentParent.getType()));
         auto parentCompType = baseRecTy.getType(parentName);
diff --git a/flang/lib/Lower/ConvertType.cpp b/flang/lib/Lower/ConvertType.cpp
index 7a2e8e5095186..0fde61465fb85 100644
--- a/flang/lib/Lower/ConvertType.cpp
+++ b/flang/lib/Lower/ConvertType.cpp
@@ -669,6 +669,18 @@ Fortran::lower::ComponentReverseIterator::advanceToParentType() {
   return *currentParentType;
 }
 
+const Fortran::semantics::Symbol *
+Fortran::lower::ComponentReverseIterator::getParentComponent() const {
+  if (!currentTypeDetails->GetParentComponentName())
+    return nullptr;
+  const Fortran::semantics::Scope *scope = currentParentType->GetScope();
+  auto parentComp =
+      DEREF(scope).find(currentTypeDetails->GetParentComponentName().value());
+  if (parentComp == scope->cend())
+    return nullptr;
+  return &*parentComp->second;
+}
+
 void Fortran::lower::ComponentReverseIterator::setCurrentType(
     const Fortran::semantics::DerivedTypeSpec &derived) {
   currentParentType = &derived;
diff --git a/flang/test/Lower/derived-type-private.f90 b/flang/test/Lower/derived-type-private.f90
new file mode 100644
index 0000000000000..8edcdeedad8b2
--- /dev/null
+++ b/flang/test/Lower/derived-type-private.f90
@@ -0,0 +1,29 @@
+! Test lowering of derived type with private attribute
+! RUN: bbc -emit-hlfir %s -o - | FileCheck %s
+
+program main
+  call test02()
+  print *,"pass"
+end program main
+
+module mod2
+  type,private:: tt
+     integer :: ip = 1
+  end type tt
+  type,extends(tt):: ty1
+  ! CHECK: fir.global @_QMmod2Estr : !fir.type<_QMmod2Tty1{_QMmod2Tty1.tt:!fir.type<_QMmod2Ttt{ip:i32}>,i1:i32,i1p:!fir.type<_QMmod2Ttt{ip:i32}>,i1a:!fir.box<!fir.heap<!fir.array<?xi32>>>}>
+     integer :: i1 = 1
+     type(tt) :: i1p = tt(2)
+     integer,allocatable :: i1a(:)
+  end type ty1
+  type(ty1) :: str
+end module mod2
+
+subroutine test02()
+  use mod2
+  integer,allocatable :: ia(:)
+  allocate(ia(10))
+  ia=2
+  str=ty1(i1a=ia)
+  if (str%i1.ne.1) print *,'ng'
+end subroutine test02

@ceseo ceseo requested review from jeanPerier and tblah July 30, 2025 22:16
Copy link
Contributor

@tblah tblah left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thank you for the fix!

@ceseo ceseo merged commit 9bb31e8 into llvm:main Aug 4, 2025
12 checks passed
@tblah tblah added this to the LLVM 21.x Release milestone Aug 4, 2025
@github-project-automation github-project-automation bot moved this to Needs Triage in LLVM Release Status Aug 4, 2025
@tblah
Copy link
Contributor

tblah commented Aug 4, 2025

/cherry-pick 9bb31e8

@llvmbot
Copy link
Member

llvmbot commented Aug 4, 2025

Failed to cherry-pick: 9bb31e8

https://github.com/llvm/llvm-project/actions/runs/16727640016

Please manually backport the fix and push it to your github fork. Once this is done, please create a pull request

@tru tru moved this from Needs Triage to Needs Backport PR in LLVM Release Status Aug 8, 2025
@tru
Copy link
Collaborator

tru commented Aug 8, 2025

Can some one create a pull request for this if it's something we still want to backport?

@tblah tblah removed this from the LLVM 21.x Release milestone Aug 8, 2025
@tblah
Copy link
Contributor

tblah commented Aug 8, 2025

I've removed the milestone. It would have been nice to get this fix in but it isn't critical, and the failure to cherry-pick might mean this is higher risk than I anticipated.

This turns out it wasn't a real merge conflict - just an ambiguous git ref. I will try again.

@tblah tblah added this to the LLVM 21.x Release milestone Aug 8, 2025
@tblah
Copy link
Contributor

tblah commented Aug 8, 2025

/cherry-pick 9bb31e8

@llvmbot
Copy link
Member

llvmbot commented Aug 8, 2025

/pull-request #152687

@llvmbot llvmbot moved this from Needs Backport PR to Done in LLVM Release Status Aug 8, 2025
krishna2803 pushed a commit to krishna2803/llvm-project that referenced this pull request Aug 12, 2025
…fied in extends (llvm#151051)

While lowering to HLFIR, when a parent type is private, its name is
mangled, so we need to get it from the parent symbol.

Fixes llvm#120922
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
flang:fir-hlfir flang Flang issues not falling into any other category
Projects
Development

Successfully merging this pull request may close these issues.

[Flang] Compilation error when a constructor of derived type with extends (derived type with private attribute is specified in extends)
4 participants