[flang] Add semantic checks for interoperability of derived type (C1806)

As Fortran 2018 C1806, each component of a derived type with the BIND
attribute shall be a nonpointer, nonallocatable data component with
interoperable type.

Reviewed By: klausler

Differential Revision: https://reviews.llvm.org/D131585
This commit is contained in:
Peixin Qiao 2022-08-20 23:34:47 +08:00
parent aa41460311
commit 6d1a685172
3 changed files with 34 additions and 3 deletions

View File

@ -1920,8 +1920,7 @@ void CheckHelper::CheckBindC(const Symbol &symbol) {
"An interface name with BIND attribute must be specified if the BIND attribute is specified in a procedure declaration statement"_err_en_US); "An interface name with BIND attribute must be specified if the BIND attribute is specified in a procedure declaration statement"_err_en_US);
context_.SetError(symbol); context_.SetError(symbol);
} }
} } else if (const auto *derived{symbol.detailsIf<DerivedTypeDetails>()}) {
if (const auto *derived{symbol.detailsIf<DerivedTypeDetails>()}) {
if (derived->sequence()) { // C1801 if (derived->sequence()) { // C1801
messages_.Say(symbol.name(), messages_.Say(symbol.name(),
"A derived type with the BIND attribute cannot have the SEQUENCE attribute"_err_en_US); "A derived type with the BIND attribute cannot have the SEQUENCE attribute"_err_en_US);
@ -1942,6 +1941,18 @@ void CheckHelper::CheckBindC(const Symbol &symbol) {
"A derived type with the BIND attribute cannot have a type bound procedure"_err_en_US); "A derived type with the BIND attribute cannot have a type bound procedure"_err_en_US);
context_.SetError(symbol); context_.SetError(symbol);
break; break;
} else if (IsAllocatableOrPointer(*component)) { // C1806
messages_.Say(symbol.name(),
"A derived type with the BIND attribute cannot have a pointer or allocatable component"_err_en_US);
context_.SetError(symbol);
break;
} else if (component->GetType() && component->GetType()->AsDerived() &&
!component->GetType()->AsDerived()->typeSymbol().attrs().test(
Attr::BIND_C)) {
messages_.Say(component->GetType()->AsDerived()->typeSymbol().name(),
"The component of the interoperable derived type must have the BIND attribute"_err_en_US);
context_.SetError(symbol);
break;
} }
} }
} }

View File

@ -23,7 +23,7 @@ module __Fortran_builtins
integer(kind=int64) :: __address integer(kind=int64) :: __address
end type end type
type :: __builtin_c_funptr type, bind(c) :: __builtin_c_funptr
integer(kind=int64) :: __address integer(kind=int64) :: __address
end type end type

View File

@ -42,4 +42,24 @@ program main
type, bind(c) :: t5 type, bind(c) :: t5
end type end type
! ERROR: A derived type with the BIND attribute cannot have a pointer or allocatable component
type, bind(c) :: t6
integer, pointer :: x
end type
! ERROR: A derived type with the BIND attribute cannot have a pointer or allocatable component
type, bind(c) :: t7
integer, allocatable :: y
end type
! ERROR: The component of the interoperable derived type must have the BIND attribute
type :: t8
integer :: x
end type
type, bind(c) :: t9
type(t8) :: y
integer :: z
end type
end end