From f3d8335383672df3b3b950a082c2b11a80cbdb9d Mon Sep 17 00:00:00 2001 From: PeixinQiao Date: Tue, 31 May 2022 23:26:00 +0800 Subject: [PATCH] [flang] Support BIND(C) variable scope check As Fortran 2018 C819, a variable with the BIND attribute shall be declared in the specification part of a module. Add the support for this check. Reviewed By: klausler Differential Revision: https://reviews.llvm.org/D126653 --- flang/lib/Semantics/check-declarations.cpp | 15 +++++++++---- flang/test/Semantics/resolve113.f90 | 34 ++++++++++++++++++++++++++++++ 2 files changed, 45 insertions(+), 4 deletions(-) create mode 100644 flang/test/Semantics/resolve113.f90 diff --git a/flang/lib/Semantics/check-declarations.cpp b/flang/lib/Semantics/check-declarations.cpp index 25f4b29..6b55954 100644 --- a/flang/lib/Semantics/check-declarations.cpp +++ b/flang/lib/Semantics/check-declarations.cpp @@ -104,7 +104,7 @@ private: } } 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 @@ void CheckHelper::Check(const Symbol &symbol) { 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 @@ static const std::string *DefinesBindCName(const Symbol &symbol) { } } -// 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 index 0000000..9755e28 --- /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 -- 2.7.4