@@ -91,6 +91,37 @@ struct DeviceExprChecker
91
91
}
92
92
};
93
93
94
+ struct FindHostArray
95
+ : public evaluate::AnyTraverse<FindHostArray, const Symbol *> {
96
+ using Result = const Symbol *;
97
+ using Base = evaluate::AnyTraverse<FindHostArray, Result>;
98
+ FindHostArray () : Base(*this ) {}
99
+ using Base::operator ();
100
+ Result operator ()(const evaluate::Component &x) const {
101
+ const Symbol &symbol{x.GetLastSymbol ()};
102
+ if (IsAllocatableOrPointer (symbol)) {
103
+ if (Result hostArray{(*this )(symbol)}) {
104
+ return hostArray;
105
+ }
106
+ }
107
+ return (*this )(x.base ());
108
+ }
109
+ Result operator ()(const Symbol &symbol) const {
110
+ if (const auto *details{
111
+ symbol.GetUltimate ().detailsIf <semantics::ObjectEntityDetails>()}) {
112
+ if (details->IsArray () &&
113
+ (!details->cudaDataAttr () ||
114
+ (details->cudaDataAttr () &&
115
+ *details->cudaDataAttr () != common::CUDADataAttr::Device &&
116
+ *details->cudaDataAttr () != common::CUDADataAttr::Managed &&
117
+ *details->cudaDataAttr () != common::CUDADataAttr::Unified))) {
118
+ return &symbol;
119
+ }
120
+ }
121
+ return nullptr ;
122
+ }
123
+ };
124
+
94
125
template <typename A> static MaybeMsg CheckUnwrappedExpr (const A &x) {
95
126
if (const auto *expr{parser::Unwrap<parser::Expr>(x)}) {
96
127
return DeviceExprChecker{}(expr->typedExpr );
@@ -306,22 +337,11 @@ template <bool IsCUFKernelDo> class DeviceContextChecker {
306
337
}
307
338
}
308
339
template <typename A>
309
- void ErrorIfHostSymbol (const A &expr, const parser::CharBlock &source) {
310
- for (const Symbol &sym : CollectCudaSymbols (expr)) {
311
- if (const auto *details =
312
- sym.GetUltimate ().detailsIf <semantics::ObjectEntityDetails>()) {
313
- if (details->IsArray () &&
314
- (!details->cudaDataAttr () ||
315
- (details->cudaDataAttr () &&
316
- *details->cudaDataAttr () != common::CUDADataAttr::Device &&
317
- *details->cudaDataAttr () != common::CUDADataAttr::Managed &&
318
- *details->cudaDataAttr () !=
319
- common::CUDADataAttr::Unified))) {
320
- context_.Say (source,
321
- " Host array '%s' cannot be present in CUF kernel" _err_en_US,
322
- sym.name ());
323
- }
324
- }
340
+ void ErrorIfHostSymbol (const A &expr, parser::CharBlock source) {
341
+ if (const Symbol * hostArray{FindHostArray{}(expr)}) {
342
+ context_.Say (source,
343
+ " Host array '%s' cannot be present in CUF kernel" _err_en_US,
344
+ hostArray->name ());
325
345
}
326
346
}
327
347
void Check (const parser::ActionStmt &stmt, const parser::CharBlock &source) {
0 commit comments