From ff768d92dd68426385db1623ba2c336803c25ede Mon Sep 17 00:00:00 2001 From: Tim Keith Date: Tue, 13 Aug 2019 13:50:24 -0700 Subject: [PATCH] [flang] Special handling for VOLATILE and ASYNCHRONOUS The VOLATILE and ASYNCHRONOUS attributes are special in two ways: - they can be applied to use-associated variables - if they are applied to a host-associated variable in a block, that variable has the attribute only within the scope of the block The latter is implemented by making a new `HostAssocDetails` symbol within the block where the attribute can be set without affecting the variable in the outer scope. This is similar to how the SHARED locality spec is implemented. Fixes flang-compiler/f18#649. Original-commit: flang-compiler/f18@471aba451341a65ff6014bbe30cb2c64cf905da6 Reviewed-on: https://github.com/flang-compiler/f18/pull/655 --- flang/lib/semantics/resolve-names.cc | 23 ++++++++++++++--------- flang/test/semantics/symbol05.f90 | 32 ++++++++++++++++++++++++++++++++ 2 files changed, 46 insertions(+), 9 deletions(-) diff --git a/flang/lib/semantics/resolve-names.cc b/flang/lib/semantics/resolve-names.cc index 0697ff9..234fa0c 100644 --- a/flang/lib/semantics/resolve-names.cc +++ b/flang/lib/semantics/resolve-names.cc @@ -2768,16 +2768,21 @@ Symbol &DeclarationVisitor::HandleAttributeStmt( Say(name.source, "'%s' is not a known intrinsic procedure"_err_en_US); } auto *symbol{FindInScope(currScope(), name)}; - if (symbol) { - // symbol was already there: set attribute on it - if (attr == Attr::ASYNCHRONOUS || attr == Attr::VOLATILE) { - // TODO: if in a BLOCK, attribute should only be set while in the block - } else if (symbol->has()) { - Say(*currStmtSource(), - "Cannot change %s attribute on use-associated '%s'"_err_en_US, - EnumToString(attr), name.source); + if (attr == Attr::ASYNCHRONOUS || attr == Attr::VOLATILE) { + // these can be set on a symbol that is host-assoc into block or use-assoc + if (!symbol && currScope().kind() == Scope::Kind::Block) { + if (auto *hostSymbol{FindSymbol(name)}) { + name.symbol = nullptr; + symbol = &MakeSymbol(name, HostAssocDetails{*hostSymbol}); + } } - } else { + } else if (symbol && symbol->has()) { + Say(*currStmtSource(), + "Cannot change %s attribute on use-associated '%s'"_err_en_US, + EnumToString(attr), name.source); + return *symbol; + } + if (!symbol) { symbol = &MakeSymbol(name, EntityDetails{}); } symbol->attrs().set(attr); diff --git a/flang/test/semantics/symbol05.f90 b/flang/test/semantics/symbol05.f90 index 14c346b..559b654 100644 --- a/flang/test/semantics/symbol05.f90 +++ b/flang/test/semantics/symbol05.f90 @@ -96,3 +96,35 @@ subroutine s5 !DEF: /s5/x (implicit) ObjectEntity REAL(4) x = 1.0 end subroutine + +!DEF: /s6 Subprogram +subroutine s6 + !DEF: /s6/i ObjectEntity INTEGER(4) + !DEF: /s6/j ObjectEntity INTEGER(4) + !DEF: /s6/k ObjectEntity INTEGER(4) + integer i, j, k + block + !DEF: /s6/Block1/i ASYNCHRONOUS, VOLATILE HostAssoc INTEGER(4) + volatile :: i + !DEF: /s6/Block1/j ASYNCHRONOUS HostAssoc INTEGER(4) + asynchronous :: j + !REF: /s6/Block1/i + asynchronous :: i + !DEF: /s6/Block1/k TARGET(implicit) ObjectEntity INTEGER(4) + target :: k + end block +end subroutine + +!DEF: /m7 Module +module m7 + !DEF: /m7/i PUBLIC ObjectEntity INTEGER(4) + !DEF: /m7/j PUBLIC ObjectEntity INTEGER(4) + integer i, j +end module +!DEF: /s7 Subprogram +subroutine s7 + !REF: /m7 + use :: m7 + !DEF: /s7/j VOLATILE Use INTEGER(4) + volatile :: j +end subroutine -- 2.7.4