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 @@ -1886,6 +1886,7 @@ 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); + context_.SetError(symbol); } if (const std::string * name{DefinesBindCName(symbol)}) { auto pair{bindC_.emplace(*name, symbol)}; @@ -1911,6 +1912,7 @@ !proc->interface().symbol()->attrs().test(Attr::BIND_C)) { messages_.Say(symbol.name(), "An interface name with BIND attribute must be specified if the BIND attribute is specified in a procedure declaration statement"_err_en_US); + context_.SetError(symbol); } } } diff --git a/flang/lib/Semantics/resolve-names.cpp b/flang/lib/Semantics/resolve-names.cpp --- a/flang/lib/Semantics/resolve-names.cpp +++ b/flang/lib/Semantics/resolve-names.cpp @@ -3910,7 +3910,17 @@ symbol = &MakeCommonBlockSymbol(name); symbol->attrs().set(Attr::BIND_C); } - SetBindNameOn(*symbol); + // 8.6.4(1) + // Some entities such as named constant or module name need to checked + // elsewhere. This is to skip the ICE caused by setting Bind name for non-name + // things such as data type and also checks for procedures. + if (symbol->has() || symbol->has() || + symbol->has()) { + SetBindNameOn(*symbol); + } else { + Say(name, + "Only variable and named common block can be in BIND statement"_err_en_US); + } return false; } bool DeclarationVisitor::Pre(const parser::OldParameterStmt &x) { diff --git a/flang/test/Semantics/bind-c02.f90 b/flang/test/Semantics/bind-c02.f90 new file mode 100644 --- /dev/null +++ b/flang/test/Semantics/bind-c02.f90 @@ -0,0 +1,47 @@ +! RUN: %python %S/test_errors.py %s %flang_fc1 +! Check for 8.6.4(1) +! The BIND statement specifies the BIND attribute for a list of variables and +! common blocks. + +module m + + interface + subroutine proc() bind(c) + end + end interface + procedure(proc), bind(c) :: pc1 + !ERROR: Only variable and named common block can be in BIND statement + bind(c) :: proc + !ERROR: Only variable and named common block can be in BIND statement + bind(c) :: pc1 + + !ERROR: Only variable and named common block can be in BIND statement + bind(c) :: sub + + bind(c) :: m ! no error for implicit type variable + + type my_type + integer :: i + end type + !ERROR: Only variable and named common block can be in BIND statement + bind(c) :: my_type + + enum, bind(c) ! no error + enumerator :: SUNDAY, MONDAY + end enum + + integer :: x, y, z = 1 + common /blk/ y + bind(c) :: x, /blk/, z ! no error for variable and common block + + bind(c) :: implicit_i ! no error for implicit type variable + + !ERROR: 'implicit_blk' appears as a COMMON block in a BIND statement but not in a COMMON statement + bind(c) :: /implicit_blk/ + +contains + + subroutine sub() bind(c) + end + +end