@@ -757,23 +757,27 @@ mlir::Value OpenACCPointerLikeModel<Ty>::genAllocate(
757757 llvm::StringRef varName, mlir::Type varType, mlir::Value originalVar,
758758 bool &needsFree) const {
759759
760- // Get the element type from the pointer type
761- mlir::Type eleTy = mlir::cast<Ty>(pointer).getElementType ();
760+ // Unwrap to get the pointee type.
761+ mlir::Type pointeeTy = fir::dyn_cast_ptrEleTy (pointer);
762+ assert (pointeeTy && " expected pointee type to be extractable" );
763+
764+ // Box types are descriptors that contain both metadata and a pointer to data.
765+ // The `genAllocate` API is designed for simple allocations and cannot
766+ // properly handle the dual nature of boxes. Using `generatePrivateInit`
767+ // instead can allocate both the descriptor and its referenced data. For use
768+ // cases that require an empty descriptor storage, potentially this could be
769+ // implemented here.
770+ if (fir::isa_box_type (pointeeTy))
771+ return {};
762772
763773 // Unlimited polymorphic (class(*)) cannot be handled - size unknown
764- if (fir::isUnlimitedPolymorphicType (eleTy ))
774+ if (fir::isUnlimitedPolymorphicType (pointeeTy ))
765775 return {};
766776
767- // Character types with dynamic length cannot be handled without a descriptor.
768- if (auto charTy = mlir::dyn_cast<fir::CharacterType>(eleTy))
769- if (charTy.hasDynamicLen ())
770- return {};
771-
772- // Return null for dynamic or unknown shape arrays because the size of the
777+ // Return null for dynamic size types because the size of the
773778 // allocation cannot be determined simply from the type.
774- if (auto seqTy = mlir::dyn_cast<fir::SequenceType>(eleTy))
775- if (seqTy.hasDynamicExtents () || seqTy.hasUnknownShape ())
776- return {};
779+ if (fir::hasDynamicSize (pointeeTy))
780+ return {};
777781
778782 // Use heap allocation for fir.heap, stack allocation for others (fir.ref,
779783 // fir.ptr, fir.llvm_ptr). For fir.ptr, which is supposed to represent a
@@ -783,10 +787,10 @@ mlir::Value OpenACCPointerLikeModel<Ty>::genAllocate(
783787 mlir::Value allocation;
784788 if (std::is_same_v<Ty, fir::HeapType>) {
785789 needsFree = true ;
786- allocation = fir::AllocMemOp::create (builder, loc, eleTy );
790+ allocation = fir::AllocMemOp::create (builder, loc, pointeeTy );
787791 } else {
788792 needsFree = false ;
789- allocation = fir::AllocaOp::create (builder, loc, eleTy );
793+ allocation = fir::AllocaOp::create (builder, loc, pointeeTy );
790794 }
791795
792796 // Convert to the requested pointer type if needed.
@@ -862,6 +866,17 @@ bool OpenACCPointerLikeModel<Ty>::genFree(
862866 mlir::TypedValue<mlir::acc::PointerLikeType> varToFree,
863867 mlir::Value allocRes, mlir::Type varType) const {
864868
869+ // Unwrap to get the pointee type.
870+ mlir::Type pointeeTy = fir::dyn_cast_ptrEleTy (pointer);
871+ assert (pointeeTy && " expected pointee type to be extractable" );
872+
873+ // Box types contain both a descriptor and data. The `genFree` API
874+ // handles simple deallocations and cannot properly manage both parts.
875+ // Using `generatePrivateDestroy` instead can free both the descriptor and
876+ // its referenced data.
877+ if (fir::isa_box_type (pointeeTy))
878+ return false ;
879+
865880 // If pointer type is HeapType, assume it's a heap allocation
866881 if (std::is_same_v<Ty, fir::HeapType>) {
867882 fir::FreeMemOp::create (builder, loc, varToFree);
@@ -925,22 +940,26 @@ bool OpenACCPointerLikeModel<Ty>::genCopy(
925940 if (source.getType () != destination.getType ())
926941 return false ;
927942
928- mlir::Type eleTy = mlir::cast<Ty>(pointer).getElementType ();
943+ // Unwrap to get the pointee type.
944+ mlir::Type pointeeTy = fir::dyn_cast_ptrEleTy (pointer);
945+ assert (pointeeTy && " expected pointee type to be extractable" );
946+
947+ // Box types contain both a descriptor and referenced data. The genCopy API
948+ // handles simple copies and cannot properly manage both parts.
949+ if (fir::isa_box_type (pointeeTy))
950+ return false ;
929951
930952 // Unlimited polymorphic (class(*)) cannot be handled because source and
931953 // destination types are not known.
932- if (fir::isUnlimitedPolymorphicType (eleTy ))
954+ if (fir::isUnlimitedPolymorphicType (pointeeTy ))
933955 return false ;
934956
935- // Dynamic lengths without descriptor do not have size information.
936- if (auto charTy = mlir::dyn_cast<fir::CharacterType>(eleTy))
937- if (charTy.hasDynamicLen ())
938- return false ;
939- if (auto seqTy = mlir::dyn_cast<fir::SequenceType>(eleTy))
940- if (seqTy.hasDynamicExtents () || seqTy.hasUnknownShape ())
941- return false ;
957+ // Return false for dynamic size types because the copy logic
958+ // cannot be determined simply from the type.
959+ if (fir::hasDynamicSize (pointeeTy))
960+ return false ;
942961
943- if (fir::isa_trivial (eleTy )) {
962+ if (fir::isa_trivial (pointeeTy )) {
944963 auto loadVal = fir::LoadOp::create (builder, loc, source);
945964 fir::StoreOp::create (builder, loc, loadVal, destination);
946965 } else {
0 commit comments