Skip to content

Commit

Permalink
[flang] Align same_type_as result to other compilers
Browse files Browse the repository at this point in the history
Unallocated unlimited polymorphic entities do not have a dynamic type set
and do not have declared type. The standard notes that the result is
processor dependent when one of the arguments of same_type_as is in this
case. Align the result to other compiler (gfortran, nvfortran).

Reviewed By: jeanPerier, PeteSteinfeld

Differential Revision: https://reviews.llvm.org/D145384
  • Loading branch information
clementval committed Mar 8, 2023
1 parent 78e4897 commit 173e54c
Show file tree
Hide file tree
Showing 3 changed files with 58 additions and 2 deletions.
15 changes: 13 additions & 2 deletions flang/runtime/derived-api.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -87,11 +87,22 @@ static const typeInfo::DerivedType *GetDerivedType(const Descriptor &desc) {
}

bool RTNAME(SameTypeAs)(const Descriptor &a, const Descriptor &b) {
// Unlimited polymorphic with intrinsic dynamic type.
if (a.raw().type != CFI_type_struct && a.raw().type != CFI_type_other &&
b.raw().type != CFI_type_struct && b.raw().type != CFI_type_other)
return a.raw().type == b.raw().type;

const typeInfo::DerivedType *derivedTypeA{GetDerivedType(a)};
const typeInfo::DerivedType *derivedTypeB{GetDerivedType(b)};
if (derivedTypeA == nullptr || derivedTypeB == nullptr) {
return false;

// One of the descriptor is an unallocated unlimited polymorphic descriptor.
// This is processor depedent according to the standard. Align the result
// with other compilers.
if ((!a.IsAllocated() && derivedTypeA == nullptr) ||
(!b.IsAllocated() && derivedTypeB == nullptr)) {
return true;
}

// Exact match of derived type.
if (derivedTypeA == derivedTypeB) {
return true;
Expand Down
1 change: 1 addition & 0 deletions flang/unittests/Runtime/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ add_flang_unittest(FlangRuntimeTests
CommandTest.cpp
Complex.cpp
CrashHandlerFixture.cpp
Derived.cpp
ExternalIOTest.cpp
Format.cpp
Inquiry.cpp
Expand Down
44 changes: 44 additions & 0 deletions flang/unittests/Runtime/Derived.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
//===-- 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 "gtest/gtest.h"
#include "tools.h"
#include "flang/Runtime/derived-api.h"
#include "flang/Runtime/descriptor.h"

using namespace Fortran::runtime;

TEST(Derived, SameTypeAs) {
// INTEGER, POINTER :: i1
auto i1{
Descriptor::Create(TypeCode{Fortran::common::TypeCategory::Integer, 4}, 4,
nullptr, 0, nullptr, CFI_attribute_pointer)};
EXPECT_TRUE(RTNAME(SameTypeAs)(*i1, *i1));

auto r1{Descriptor::Create(TypeCode{Fortran::common::TypeCategory::Real, 4},
4, nullptr, 0, nullptr, CFI_attribute_pointer)};
EXPECT_FALSE(RTNAME(SameTypeAs)(*i1, *r1));

// CLASS(*), ALLOCATABLE :: p1
auto p1{Descriptor::Create(TypeCode{Fortran::common::TypeCategory::Real, 4},
4, nullptr, 0, nullptr, CFI_attribute_allocatable)};
p1->raw().elem_len = 0;
p1->raw().type = CFI_type_other;

EXPECT_TRUE(RTNAME(SameTypeAs)(*i1, *p1));
EXPECT_TRUE(RTNAME(SameTypeAs)(*p1, *i1));
EXPECT_TRUE(RTNAME(SameTypeAs)(*r1, *p1));

// CLASS(*), ALLOCATABLE :: p2
auto p2{Descriptor::Create(TypeCode{Fortran::common::TypeCategory::Real, 4},
4, nullptr, 0, nullptr, CFI_attribute_allocatable)};
p2->raw().elem_len = 0;
p2->raw().type = CFI_type_other;

EXPECT_TRUE(RTNAME(SameTypeAs)(*p1, *p2));
}

0 comments on commit 173e54c

Please sign in to comment.