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 @@ -251,6 +251,20 @@ if (isDone) { return; // following checks do not apply } + if (symbol.attrs().test(Attr::PROTECTED)) { + if (symbol.owner().kind() != Scope::Kind::Module) { // C854 + messages_.Say( + "A PROTECTED entity must be in the specification part of a module"_err_en_US); + } + if (!evaluate::IsVariable(symbol) && !IsProcedurePointer(symbol)) { // C855 + messages_.Say( + "A PROTECTED entity must be a variable or pointer"_err_en_US); + } + if (InCommonBlock(symbol)) { // C856 + messages_.Say( + "A PROTECTED entity may not be in a common block"_err_en_US); + } + } if (IsPointer(symbol)) { CheckPointer(symbol); } diff --git a/flang/test/Semantics/resolve82.f90 b/flang/test/Semantics/resolve82.f90 --- a/flang/test/Semantics/resolve82.f90 +++ b/flang/test/Semantics/resolve82.f90 @@ -23,6 +23,17 @@ procedure(procFunc), bind(c), pointer, bind(c) :: proc3 !WARNING: Attribute 'PROTECTED' cannot be used more than once procedure(procFunc), protected, pointer, protected :: proc4 + !ERROR: A PROTECTED entity must be a variable or pointer + external extsub + protected extsub + real x + !ERROR: A PROTECTED entity must be a variable or pointer + namelist /nml/ x + protected nml + !ERROR: A PROTECTED entity may not be in a common block + real y + common /blk/ y + protected y contains @@ -43,6 +54,9 @@ procedure(procFunc), pointer, optional, pointer :: arg10 !WARNING: Attribute 'SAVE' cannot be used more than once procedure(procFunc), save, pointer, save :: localProc + !ERROR: A PROTECTED entity must be in the specification part of a module + real x + protected x end subroutine testProcDecl end module m