@@ -9372,11 +9372,40 @@ void ResolveNamesVisitor::CreateGeneric(const parser::GenericSpec &x) {
93729372 info.Resolve (&MakeSymbol (symbolName, Attrs{}, std::move (genericDetails)));
93739373}
93749374
9375+ static void SetImplicitCUDADevice (bool inDeviceSubprogram, Symbol &symbol) {
9376+ if (inDeviceSubprogram && symbol.has <ObjectEntityDetails>()) {
9377+ auto *object{symbol.detailsIf <ObjectEntityDetails>()};
9378+ if (!object->cudaDataAttr () && !IsValue (symbol) &&
9379+ (IsDummy (symbol) || object->IsArray ())) {
9380+ // Implicitly set device attribute if none is set in device context.
9381+ object->set_cudaDataAttr (common::CUDADataAttr::Device);
9382+ }
9383+ }
9384+ }
9385+
93759386void ResolveNamesVisitor::FinishSpecificationPart (
93769387 const std::list<parser::DeclarationConstruct> &decls) {
93779388 misparsedStmtFuncFound_ = false ;
93789389 funcResultStack ().CompleteFunctionResultType ();
93799390 CheckImports ();
9391+ bool inDeviceSubprogram{false };
9392+ Symbol *scopeSym{currScope ().symbol ()};
9393+ if (currScope ().kind () == Scope::Kind::BlockConstruct) {
9394+ scopeSym = currScope ().parent ().symbol ();
9395+ }
9396+ if (scopeSym) {
9397+ if (auto *details{scopeSym->detailsIf <SubprogramDetails>()}) {
9398+ // Check the current procedure is a device procedure to apply implicit
9399+ // attribute at the end.
9400+ if (auto attrs{details->cudaSubprogramAttrs ()}) {
9401+ if (*attrs == common::CUDASubprogramAttrs::Device ||
9402+ *attrs == common::CUDASubprogramAttrs::Global ||
9403+ *attrs == common::CUDASubprogramAttrs::Grid_Global) {
9404+ inDeviceSubprogram = true ;
9405+ }
9406+ }
9407+ }
9408+ }
93809409 for (auto &pair : currScope ()) {
93819410 auto &symbol{*pair.second };
93829411 if (inInterfaceBlock ()) {
@@ -9411,6 +9440,11 @@ void ResolveNamesVisitor::FinishSpecificationPart(
94119440 SetBindNameOn (symbol);
94129441 }
94139442 }
9443+ if (currScope ().kind () == Scope::Kind::BlockConstruct) {
9444+ // Only look for specification in BlockConstruct. Other cases are done in
9445+ // ResolveSpecificationParts.
9446+ SetImplicitCUDADevice (inDeviceSubprogram, symbol);
9447+ }
94149448 }
94159449 currScope ().InstantiateDerivedTypes ();
94169450 for (const auto &decl : decls) {
@@ -9970,14 +10004,7 @@ void ResolveNamesVisitor::ResolveSpecificationParts(ProgramTree &node) {
997010004 }
997110005 ApplyImplicitRules (symbol);
997210006 // Apply CUDA implicit attributes if needed.
9973- if (inDeviceSubprogram && symbol.has <ObjectEntityDetails>()) {
9974- auto *object{symbol.detailsIf <ObjectEntityDetails>()};
9975- if (!object->cudaDataAttr () && !IsValue (symbol) &&
9976- (IsDummy (symbol) || object->IsArray ())) {
9977- // Implicitly set device attribute if none is set in device context.
9978- object->set_cudaDataAttr (common::CUDADataAttr::Device);
9979- }
9980- }
10007+ SetImplicitCUDADevice (inDeviceSubprogram, symbol);
998110008 // Main program local objects usually don't have an implied SAVE attribute,
998210009 // as one might think, but in the exceptional case of a derived type
998310010 // local object that contains a coarray, we have to mark it as an
0 commit comments