diff --git a/flang/include/flang/Runtime/descriptor.h b/flang/include/flang/Runtime/descriptor.h --- a/flang/include/flang/Runtime/descriptor.h +++ b/flang/include/flang/Runtime/descriptor.h @@ -347,7 +347,7 @@ // Deallocates storage, including allocatable and automatic // components. Optionally invokes FINAL subroutines. - int Destroy(bool finalize = false); + int Destroy(bool finalize = false, bool destroyPointers = false); bool IsContiguous(int leadingDimensions = maxRank) const { auto bytes{static_cast(ElementBytes())}; diff --git a/flang/runtime/descriptor.cpp b/flang/runtime/descriptor.cpp --- a/flang/runtime/descriptor.cpp +++ b/flang/runtime/descriptor.cpp @@ -146,8 +146,8 @@ return 0; } -int Descriptor::Destroy(bool finalize) { - if (raw_.attribute == CFI_attribute_pointer) { +int Descriptor::Destroy(bool finalize, bool destroyPointers) { + if (!destroyPointers && raw_.attribute == CFI_attribute_pointer) { return StatOk; } else { if (auto *addendum{Addendum()}) { diff --git a/flang/runtime/pointer.cpp b/flang/runtime/pointer.cpp --- a/flang/runtime/pointer.cpp +++ b/flang/runtime/pointer.cpp @@ -141,7 +141,7 @@ if (!pointer.IsAllocated()) { return ReturnError(terminator, StatBaseNull, errMsg, hasStat); } - return ReturnError(terminator, pointer.Destroy(true), errMsg, hasStat); + return ReturnError(terminator, pointer.Destroy(true, true), errMsg, hasStat); } bool RTNAME(PointerIsAssociated)(const Descriptor &pointer) { diff --git a/flang/unittests/Runtime/CMakeLists.txt b/flang/unittests/Runtime/CMakeLists.txt --- a/flang/unittests/Runtime/CMakeLists.txt +++ b/flang/unittests/Runtime/CMakeLists.txt @@ -12,6 +12,7 @@ Namelist.cpp Numeric.cpp NumericalFormatTest.cpp + Pointer.cpp Ragged.cpp Random.cpp Reduction.cpp diff --git a/flang/unittests/Runtime/Pointer.cpp b/flang/unittests/Runtime/Pointer.cpp new file mode 100644 --- /dev/null +++ b/flang/unittests/Runtime/Pointer.cpp @@ -0,0 +1,32 @@ +//===-- flang/unittests/Runtime/Pointer.cpp--------- -------------*- C++-*-===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// + +#include "flang/Runtime/pointer.h" +#include "gtest/gtest.h" +#include "tools.h" +#include "flang/Runtime/descriptor.h" + +using namespace Fortran::runtime; + +TEST(Pointer, BasicAllocateDeallocate) { + // REAL(4), POINTER :: p(:) + auto p{Descriptor::Create(TypeCode{Fortran::common::TypeCategory::Real, 4}, 4, + nullptr, 1, nullptr, CFI_attribute_pointer)}; + // ALLOCATE(p(2:11)) + RTNAME(PointerSetBounds)(*p, 0, 2, 11); + RTNAME(PointerAllocate) + (*p, /*hasStat=*/false, /*errMsg=*/nullptr, __FILE__, __LINE__); + EXPECT_TRUE(RTNAME(PointerIsAssociated)(*p)); + EXPECT_EQ(p->Elements(), 10u); + EXPECT_EQ(p->GetDimension(0).LowerBound(), 2); + EXPECT_EQ(p->GetDimension(0).UpperBound(), 11); + // DEALLOCATE(p) + RTNAME(PointerDeallocate) + (*p, /*hasStat=*/false, /*errMsg=*/nullptr, __FILE__, __LINE__); + EXPECT_FALSE(RTNAME(PointerIsAssociated)(*p)); +}