diff --git a/flang/docs/Extensions.md b/flang/docs/Extensions.md --- a/flang/docs/Extensions.md +++ b/flang/docs/Extensions.md @@ -266,6 +266,9 @@ enforce it and the constraint is not necessary for a correct implementation. * A label may follow a semicolon in fixed form source. +* A scalar logical dummy argument to a `BIND(C)` procedure does + not have to have `KIND=C_BOOL` since it can be converted to/from + `_Bool` without loss of information. ### Extensions supported when enabled by options diff --git a/flang/lib/Semantics/check-declarations.cpp b/flang/lib/Semantics/check-declarations.cpp --- a/flang/lib/Semantics/check-declarations.cpp +++ b/flang/lib/Semantics/check-declarations.cpp @@ -2269,7 +2269,8 @@ "A variable with BIND(C) attribute may only appear in the specification part of a module"_err_en_US); context_.SetError(symbol); } - if (auto shape{evaluate::GetShape(foldingContext_, symbol)}) { + auto shape{evaluate::GetShape(foldingContext_, symbol)}; + if (shape) { if (evaluate::GetRank(*shape) == 0) { // 18.3.4 if (isExplicitBindC && IsAllocatableOrPointer(symbol)) { messages_.Say(symbol.name(), @@ -2310,6 +2311,13 @@ // ok; F'2018 18.3.6 p2(6) } else if (derived || IsInteroperableIntrinsicType(*type)) { // F'2018 18.3.6 p2(4,5) + } else if (type->category() == DeclTypeSpec::Logical && IsDummy(symbol) && + evaluate::GetRank(*shape) == 0) { + // Special exception: LOGICAL scalar dummy arguments can be converted + // before a call -- & after if not INTENT(IN) -- without loss of + // information, and are accepted by some older compilers. + messages_.Say(symbol.name(), + "A BIND(C) LOGICAL dummy argument should have the interoperable KIND=C_BOOL"_port_en_US); } else if (symbol.attrs().test(Attr::VALUE)) { messages_.Say(symbol.name(), "A BIND(C) VALUE dummy argument must have an interoperable type"_err_en_US); diff --git a/flang/test/Semantics/bind-c11.f90 b/flang/test/Semantics/bind-c11.f90 --- a/flang/test/Semantics/bind-c11.f90 +++ b/flang/test/Semantics/bind-c11.f90 @@ -8,7 +8,7 @@ real, allocatable, bind(c) :: x3(:) contains subroutine s1(x) bind(c) - !ERROR: A BIND(C) VALUE dummy argument must have an interoperable type + !PORTABILITY: A BIND(C) LOGICAL dummy argument should have the interoperable KIND=C_BOOL logical(2), intent(in), value :: x end subroutine s2(x) bind(c)