@@ -9372,11 +9372,40 @@ void ResolveNamesVisitor::CreateGeneric(const parser::GenericSpec &x) {
9372
9372
info.Resolve (&MakeSymbol (symbolName, Attrs{}, std::move (genericDetails)));
9373
9373
}
9374
9374
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
+
9375
9386
void ResolveNamesVisitor::FinishSpecificationPart (
9376
9387
const std::list<parser::DeclarationConstruct> &decls) {
9377
9388
misparsedStmtFuncFound_ = false ;
9378
9389
funcResultStack ().CompleteFunctionResultType ();
9379
9390
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
+ }
9380
9409
for (auto &pair : currScope ()) {
9381
9410
auto &symbol{*pair.second };
9382
9411
if (inInterfaceBlock ()) {
@@ -9411,6 +9440,11 @@ void ResolveNamesVisitor::FinishSpecificationPart(
9411
9440
SetBindNameOn (symbol);
9412
9441
}
9413
9442
}
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
+ }
9414
9448
}
9415
9449
currScope ().InstantiateDerivedTypes ();
9416
9450
for (const auto &decl : decls) {
@@ -9970,14 +10004,7 @@ void ResolveNamesVisitor::ResolveSpecificationParts(ProgramTree &node) {
9970
10004
}
9971
10005
ApplyImplicitRules (symbol);
9972
10006
// 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);
9981
10008
// Main program local objects usually don't have an implied SAVE attribute,
9982
10009
// as one might think, but in the exceptional case of a derived type
9983
10010
// local object that contains a coarray, we have to mark it as an
0 commit comments