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 @@ -104,7 +104,7 @@ } } bool IsResultOkToDiffer(const FunctionResult &); - void CheckBindCName(const Symbol &); + void CheckBindC(const Symbol &); // Check functions for defined I/O procedures void CheckDefinedIoProc( const Symbol &, const GenericDetails &, GenericKind::DefinedIo); @@ -236,7 +236,7 @@ if (symbol.attrs().test(Attr::VOLATILE)) { CheckVolatile(symbol, derived); } - CheckBindCName(symbol); + CheckBindC(symbol); if (isDone) { return; // following checks do not apply } @@ -1869,8 +1869,15 @@ } } -// Check that BIND(C) names are distinct -void CheckHelper::CheckBindCName(const Symbol &symbol) { +// Check that BIND(C) names are distinct and BIND(C) variable declared in module +void CheckHelper::CheckBindC(const Symbol &symbol) { + if (!symbol.attrs().test(Attr::BIND_C)) { + return; + } + if (symbol.has() && !symbol.owner().IsModule()) { + messages_.Say(symbol.name(), + "A variable with BIND(C) attribute may only appear in the specification part of a module"_err_en_US); + } if (const std::string * name{DefinesBindCName(symbol)}) { auto pair{bindC_.emplace(*name, symbol)}; if (!pair.second) { diff --git a/flang/test/Semantics/resolve113.f90 b/flang/test/Semantics/resolve113.f90 new file mode 100644 --- /dev/null +++ b/flang/test/Semantics/resolve113.f90 @@ -0,0 +1,34 @@ +! RUN: %python %S/test_errors.py %s %flang_fc1 + +module m +interface + module subroutine dump() + end subroutine +end interface + integer, bind(c, name="a") :: x1 + integer, bind(c) :: x2 +end + +subroutine sub() + !ERROR: A variable with BIND(C) attribute may only appear in the specification part of a module + integer, bind(c, name="b") :: x3 + !ERROR: A variable with BIND(C) attribute may only appear in the specification part of a module + integer, bind(c) :: x4 +end + +program main + !ERROR: A variable with BIND(C) attribute may only appear in the specification part of a module + integer, bind(c, name="c") :: x5 + !ERROR: A variable with BIND(C) attribute may only appear in the specification part of a module + integer, bind(c) :: x6 +end + +submodule(m) m2 + !ERROR: A variable with BIND(C) attribute may only appear in the specification part of a module + integer, bind(c, name="d") :: x7 + !ERROR: A variable with BIND(C) attribute may only appear in the specification part of a module + integer, bind(c) :: x8 +contains + module procedure dump + end procedure +end