@@ -102,16 +102,16 @@ class DataVarChecker : public evaluate::AllTraverse<DataVarChecker, true> {
102
102
lastSymbol.name ().ToString ());
103
103
return false ;
104
104
}
105
- RestrictPointer ();
105
+ auto restorer{common::ScopedSet (isPointerAllowed_, false )};
106
+ return (*this )(component.base ()) && (*this )(lastSymbol);
107
+ } else if (IsPointer (lastSymbol)) { // C877
108
+ context_.Say (source_,
109
+ " Data object must not contain pointer '%s' as a non-rightmost part" _err_en_US,
110
+ lastSymbol.name ().ToString ());
111
+ return false ;
106
112
} else {
107
- if (IsPointer (lastSymbol)) { // C877
108
- context_.Say (source_,
109
- " Data object must not contain pointer '%s' as a non-rightmost part" _err_en_US,
110
- lastSymbol.name ().ToString ());
111
- return false ;
112
- }
113
+ return (*this )(component.base ()) && (*this )(lastSymbol);
113
114
}
114
- return (*this )(component.base ()) && (*this )(lastSymbol);
115
115
}
116
116
bool operator ()(const evaluate::ArrayRef &arrayRef) {
117
117
hasSubscript_ = true ;
@@ -128,29 +128,32 @@ class DataVarChecker : public evaluate::AllTraverse<DataVarChecker, true> {
128
128
return false ;
129
129
}
130
130
bool operator ()(const evaluate::Subscript &subs) {
131
- DataVarChecker subscriptChecker{context_, source_ };
132
- subscriptChecker. RestrictPointer () ;
131
+ auto restorer1{ common::ScopedSet (isPointerAllowed_, false ) };
132
+ auto restorer2{ common::ScopedSet (isFunctionAllowed_, true )} ;
133
133
return common::visit (
134
- common::visitors{
135
- [&](const evaluate::IndirectSubscriptIntegerExpr &expr) {
136
- return CheckSubscriptExpr (expr);
137
- },
138
- [&](const evaluate::Triplet &triplet) {
139
- return CheckSubscriptExpr (triplet.lower ()) &&
140
- CheckSubscriptExpr (triplet.upper ()) &&
141
- CheckSubscriptExpr (triplet.stride ());
142
- },
143
- },
144
- subs.u ) &&
145
- subscriptChecker (subs.u );
134
+ common::visitors{
135
+ [&](const evaluate::IndirectSubscriptIntegerExpr &expr) {
136
+ return CheckSubscriptExpr (expr);
137
+ },
138
+ [&](const evaluate::Triplet &triplet) {
139
+ return CheckSubscriptExpr (triplet.lower ()) &&
140
+ CheckSubscriptExpr (triplet.upper ()) &&
141
+ CheckSubscriptExpr (triplet.stride ());
142
+ },
143
+ },
144
+ subs.u );
146
145
}
147
146
template <typename T>
148
147
bool operator ()(const evaluate::FunctionRef<T> &) const { // C875
149
- context_.Say (source_,
150
- " Data object variable must not be a function reference" _err_en_US);
151
- return false ;
148
+ if (isFunctionAllowed_) {
149
+ // Must have been validated as a constant expression
150
+ return true ;
151
+ } else {
152
+ context_.Say (source_,
153
+ " Data object variable must not be a function reference" _err_en_US);
154
+ return false ;
155
+ }
152
156
}
153
- void RestrictPointer () { isPointerAllowed_ = false ; }
154
157
155
158
private:
156
159
bool CheckSubscriptExpr (
@@ -178,6 +181,7 @@ class DataVarChecker : public evaluate::AllTraverse<DataVarChecker, true> {
178
181
bool hasSubscript_{false };
179
182
bool isPointerAllowed_{true };
180
183
bool isFirstSymbol_{true };
184
+ bool isFunctionAllowed_{false };
181
185
};
182
186
183
187
static bool IsValidDataObject (const SomeExpr &expr) { // C878, C879
0 commit comments