Index: flang/include/flang/Semantics/tools.h =================================================================== --- flang/include/flang/Semantics/tools.h +++ flang/include/flang/Semantics/tools.h @@ -175,6 +175,7 @@ return details && details->IsAssumedSize(); } bool IsAssumedLengthCharacter(const Symbol &); +bool IsConstantLengthCharacter(const Symbol &); bool IsExternal(const Symbol &); bool IsModuleProcedure(const Symbol &); bool HasCoarray(const parser::Expr &); Index: flang/lib/Semantics/check-declarations.cpp =================================================================== --- flang/lib/Semantics/check-declarations.cpp +++ flang/lib/Semantics/check-declarations.cpp @@ -112,6 +112,7 @@ } bool IsResultOkToDiffer(const FunctionResult &); void CheckBindC(const Symbol &); + void CheckBindCFunctionResult(const Symbol &); // Check functions for defined I/O procedures void CheckDefinedIoProc( const Symbol &, const GenericDetails &, GenericKind::DefinedIo); @@ -380,6 +381,7 @@ messages_.Say( "A function result may not have the SAVE attribute"_err_en_US); } + CheckBindCFunctionResult(symbol); } if (symbol.owner().IsDerivedType() && (symbol.attrs().test(Attr::CONTIGUOUS) && @@ -397,6 +399,28 @@ void CheckHelper::CheckCommonBlock(const Symbol &symbol) { CheckBindC(symbol); } +void CheckHelper::CheckBindCFunctionResult(const Symbol &symbol) { // C1553 + if (!innermostSymbol_ || !IsBindCProcedure(*innermostSymbol_)) { + return; + } + if (IsPointer(symbol) || IsAllocatable(symbol)) { + messages_.Say( + "BIND(C) function result cannot have ALLOCATABLE or POINTER attribute"_err_en_US); + } + if (const DeclTypeSpec * type{symbol.GetType()}; type && + type->category() == DeclTypeSpec::Character && + !IsConstantLengthCharacter(symbol)) { + messages_.Say( + "BIND(C) function result cannot have character type with non-constant length"_err_en_US); + } + if (symbol.Rank() > 0) { + messages_.Say("BIND(C) function result must be scalar"_err_en_US); + } + if (symbol.Corank()) { + messages_.Say("BIND(C) function result cannot be a coarray"_err_en_US); + } +} + void CheckHelper::CheckValue( const Symbol &symbol, const DerivedTypeSpec *derived) { // C863 - C865 if (!IsDummy(symbol)) { Index: flang/lib/Semantics/tools.cpp =================================================================== --- flang/lib/Semantics/tools.cpp +++ flang/lib/Semantics/tools.cpp @@ -730,6 +730,18 @@ } } +bool IsConstantLengthCharacter(const Symbol &symbol) { + if (const DeclTypeSpec * type{symbol.GetType()}) { + if (type->category() != DeclTypeSpec::Character) { + return false; + } + if (const auto &len{type->characterTypeSpec().length().GetExplicit()}) { + return evaluate::IsConstantExpr(*len); + } + } + return false; +} + bool IsInBlankCommon(const Symbol &symbol) { const Symbol *block{FindCommonBlockContaining(symbol)}; return block && block->name().empty(); Index: flang/test/Semantics/bind-c09.f90 =================================================================== --- /dev/null +++ flang/test/Semantics/bind-c09.f90 @@ -0,0 +1,48 @@ +! RUN: %python %S/test_errors.py %s %flang_fc1 +! Check for C1553 and 18.3.4(1) + +function func1() result(res) bind(c) + ! ERROR: BIND(C) function result cannot have ALLOCATABLE or POINTER attribute + integer, pointer :: res +end + +function func2() result(res) bind(c) + ! ERROR: BIND(C) function result cannot have ALLOCATABLE or POINTER attribute + integer, allocatable :: res +end + +function func3() result(res) bind(c) + ! ERROR: BIND(C) function result must be scalar + integer :: res(2) +end + +function func4() result(res) bind(c) + ! ERROR: BIND(C) function result cannot have character type with non-constant length + character(*) :: res +end + +function func5(n) result(res) bind(c) + integer :: n + ! ERROR: BIND(C) function result cannot have character type with non-constant length + character(n) :: res +end + +function func6() result(res) bind(c) + character(1) :: res ! OK +end + +function func7() result(res) bind(c) + integer, parameter :: n = 1 + character(n) :: res ! OK +end + +function func8() result(res) bind(c) + ! ERROR: BIND(C) function result cannot have ALLOCATABLE or POINTER attribute + ! ERROR: BIND(C) function result cannot have character type with non-constant length + character(:), pointer :: res +end + +function func9() result(res) bind(c) + ! ERROR: BIND(C) function result cannot be a coarray + integer :: res[10, *] +end