diff --git a/flang/lib/Semantics/check-call.cpp b/flang/lib/Semantics/check-call.cpp --- a/flang/lib/Semantics/check-call.cpp +++ b/flang/lib/Semantics/check-call.cpp @@ -253,6 +253,26 @@ } } +// Automatic conversion of different-kind LOGICAL scalar actual argument +// expressions (not variables) to LOGICAL scalar dummies when the dummy is of +// default logical kind. This allows expressions in dummy arguments to work when +// the default logical kind is not the one used in LogicalResult. This will +// always be safe even when downconverting so no warning is needed. +static void ConvertLogicalActual(evaluate::Expr &actual, + const characteristics::TypeAndShape &dummyType, + characteristics::TypeAndShape &actualType) { + if (dummyType.type().category() == TypeCategory::Logical && + actualType.type().category() == TypeCategory::Logical && + dummyType.type().kind() != actualType.type().kind() && + !evaluate::IsVariable(actual)) { + auto converted{ + evaluate::ConvertToType(dummyType.type(), std::move(actual))}; + CHECK(converted); + actual = std::move(*converted); + actualType = dummyType; + } +} + static bool DefersSameTypeParameters( const DerivedTypeSpec &actual, const DerivedTypeSpec &dummy) { for (const auto &pair : actual.parameters()) { @@ -294,6 +314,7 @@ if (allowActualArgumentConversions) { ConvertIntegerActual(actual, dummy.type, actualType, messages); } + ConvertLogicalActual(actual, dummy.type, actualType); bool typesCompatible{typesCompatibleWithIgnoreTKR || dummy.type.type().IsTkCompatibleWith(actualType.type())}; int dummyRank{dummy.type.Rank()}; diff --git a/flang/test/Evaluate/logical-args.f90 b/flang/test/Evaluate/logical-args.f90 new file mode 100644 --- /dev/null +++ b/flang/test/Evaluate/logical-args.f90 @@ -0,0 +1,22 @@ +! Test that actual logical arguments convert to the right kind when it is non-default +! RUN: %flang_fc1 -fdebug-unparse %s 2>&1 | FileCheck %s +! RUN: %flang_fc1 -fdebug-unparse -fdefault-integer-8 %s 2>&1 | FileCheck %s --check-prefixes CHECK-8 + +program main + integer :: x(10), y + ! CHECK: CALL foo(.true._4) + ! CHECK-8: CALL foo(logical(.true._4,kind=8)) + call foo(1 < 2) + ! CHECK: CALL fooa(x>y) + ! CHECK-8: CALL fooa(logical(x>y,kind=8)) + call fooa(x > y) + + contains + subroutine foo(l) + logical :: l + end subroutine foo + + subroutine fooa(l) + logical :: l(10) + end subroutine fooa +end program main