@@ -2173,6 +2173,25 @@ bool IsAutomatic(const Symbol &original) {
21732173 return false ;
21742174}
21752175
2176+ bool CanCUDASymbolHaveSaveAttr (const Symbol &sym) {
2177+ if (const auto *details{
2178+ sym.GetUltimate ().detailsIf <semantics::ObjectEntityDetails>()}) {
2179+ const Fortran::semantics::DeclTypeSpec *type{details->type ()};
2180+ const Fortran::semantics::DerivedTypeSpec *derived{
2181+ type ? type->AsDerived () : nullptr };
2182+ if (derived) {
2183+ if (FindCUDADeviceAllocatableUltimateComponent (*derived)) {
2184+ return false ;
2185+ }
2186+ }
2187+ if (details->cudaDataAttr () &&
2188+ *details->cudaDataAttr () != common::CUDADataAttr::Unified) {
2189+ return false ;
2190+ }
2191+ }
2192+ return true ;
2193+ }
2194+
21762195bool IsSaved (const Symbol &original) {
21772196 const Symbol &symbol{GetAssociationRoot (original)};
21782197 const Scope &scope{symbol.owner ()};
@@ -2195,7 +2214,7 @@ bool IsSaved(const Symbol &original) {
21952214 } else if (scopeKind == Scope::Kind::Module ||
21962215 (scopeKind == Scope::Kind::MainProgram &&
21972216 (symbol.attrs ().test (Attr::TARGET) || evaluate::IsCoarray (symbol)) &&
2198- Fortran::evaluate:: CanCUDASymbolHaveSaveAttr (symbol))) {
2217+ CanCUDASymbolHaveSaveAttr (symbol))) {
21992218 // 8.5.16p4
22002219 // In main programs, implied SAVE matters only for pointer
22012220 // initialization targets and coarrays.
@@ -2205,7 +2224,7 @@ bool IsSaved(const Symbol &original) {
22052224 (features.IsEnabled (
22062225 common::LanguageFeature::SaveBigMainProgramVariables) &&
22072226 symbol.size () > 32 )) &&
2208- Fortran::evaluate:: CanCUDASymbolHaveSaveAttr (symbol)) {
2227+ CanCUDASymbolHaveSaveAttr (symbol)) {
22092228 // With SaveBigMainProgramVariables, keeping all unsaved main program
22102229 // variables of 32 bytes or less on the stack allows keeping numerical and
22112230 // logical scalars, small scalar characters or derived, small arrays, and
@@ -2223,15 +2242,15 @@ bool IsSaved(const Symbol &original) {
22232242 } else if (symbol.test (Symbol::Flag::InDataStmt)) {
22242243 return true ;
22252244 } else if (const auto *object{symbol.detailsIf <ObjectEntityDetails>()};
2226- object && object->init ()) {
2245+ object && object->init ()) {
22272246 return true ;
22282247 } else if (IsProcedurePointer (symbol) && symbol.has <ProcEntityDetails>() &&
22292248 symbol.get <ProcEntityDetails>().init ()) {
22302249 return true ;
22312250 } else if (scope.hasSAVE ()) {
22322251 return true ; // bare SAVE statement
2233- } else if (const Symbol * block{FindCommonBlockContaining (symbol)};
2234- block && block->attrs ().test (Attr::SAVE)) {
2252+ } else if (const Symbol *block{FindCommonBlockContaining (symbol)};
2253+ block && block->attrs ().test (Attr::SAVE)) {
22352254 return true ; // in COMMON with SAVE
22362255 } else {
22372256 return false ;
0 commit comments