@@ -2955,13 +2955,6 @@ struct VariableFinder : public evaluate::AnyTraverse<VariableFinder> {
2955
2955
};
2956
2956
} // namespace atomic
2957
2957
2958
- static bool IsAllocatable (const SomeExpr &expr) {
2959
- std::vector<SomeExpr> dsgs{atomic::DesignatorCollector{}(expr)};
2960
- assert (dsgs.size () == 1 && " Should have a single top-level designator" );
2961
- evaluate::SymbolVector syms{evaluate::GetSymbolVector (dsgs.front ())};
2962
- return !syms.empty () && IsAllocatable (syms.back ()) && !IsArrayElement (expr);
2963
- }
2964
-
2965
2958
static bool IsPointerAssignment (const evaluate::Assignment &x) {
2966
2959
return std::holds_alternative<evaluate::Assignment::BoundsSpec>(x.u ) ||
2967
2960
std::holds_alternative<evaluate::Assignment::BoundsRemapping>(x.u );
@@ -3149,30 +3142,69 @@ void OmpStructureChecker::ErrorShouldBeVariable(
3149
3142
// / function references with scalar data pointer result of non-character
3150
3143
// / intrinsic type or variables that are non-polymorphic scalar pointers
3151
3144
// / and any length type parameter must be constant.
3152
- void OmpStructureChecker::CheckAtomicVariable (
3153
- const SomeExpr &atom, parser::CharBlock source) {
3154
- if (atom.Rank () != 0 ) {
3155
- context_.Say (source, " Atomic variable %s should be a scalar" _err_en_US,
3156
- atom.AsFortran ());
3145
+ void OmpStructureChecker::CheckAtomicType (SymbolRef sym,
3146
+ parser::CharBlock source,
3147
+ std::string_view name) {
3148
+ const DeclTypeSpec *typeSpec{sym->GetType ()};
3149
+ if (!typeSpec) {
3150
+ return ;
3157
3151
}
3158
3152
3159
- if (std::optional<evaluate::DynamicType> dtype{atom.GetType ()}) {
3160
- if (dtype->category () == TypeCategory::Character) {
3153
+ if (!IsPointer (sym)) {
3154
+ using Category = DeclTypeSpec::Category;
3155
+ Category cat{typeSpec->category ()};
3156
+ if (cat == Category::Character) {
3161
3157
context_.Say (source,
3162
- " Atomic variable %s cannot have CHARACTER type" _err_en_US,
3163
- atom. AsFortran () );
3164
- } else if (dtype-> IsPolymorphic () ) {
3158
+ " Atomic variable %s cannot have CHARACTER type" _err_en_US,
3159
+ name );
3160
+ } else if (cat != Category::Numeric && cat != Category::Logical ) {
3165
3161
context_.Say (source,
3166
- " Atomic variable %s cannot have a polymorphic type" _err_en_US,
3167
- atom. AsFortran () );
3162
+ " Atomic variable %s should have an intrinsic type" _err_en_US,
3163
+ name );
3168
3164
}
3169
- // TODO: Check non-constant type parameters for non-character types.
3170
- // At the moment there don't seem to be any.
3165
+ return ;
3166
+ }
3167
+
3168
+ // Variable is a pointer.
3169
+ if (typeSpec->IsPolymorphic ()) {
3170
+ context_.Say (
3171
+ source,
3172
+ " Atomic variable %s cannot be a pointer to a polymorphic type" _err_en_US,
3173
+ name);
3174
+ return ;
3171
3175
}
3172
3176
3173
- if (IsAllocatable (atom)) {
3177
+ // Go over all length parameters, if any, and check if they are
3178
+ // explicit.
3179
+ if (const DerivedTypeSpec *derived{typeSpec->AsDerived ()}) {
3180
+ if (llvm::any_of (derived->parameters (), [](auto &&entry) {
3181
+ // "entry" is a map entry
3182
+ return entry.second .isLen () && !entry.second .isExplicit ();
3183
+ })) {
3184
+ context_.Say (
3185
+ source,
3186
+ " Atomic variable %s is a pointer to a type with non-constant length parameter" _err_en_US,
3187
+ name);
3188
+ }
3189
+ }
3190
+ }
3191
+
3192
+ void OmpStructureChecker::CheckAtomicVariable (const SomeExpr &atom,
3193
+ parser::CharBlock source) {
3194
+ if (atom.Rank () != 0 ) {
3195
+ context_.Say (source, " Atomic variable %s should be a scalar" _err_en_US,
3196
+ atom.AsFortran ());
3197
+ }
3198
+
3199
+ std::vector<SomeExpr> dsgs{atomic::DesignatorCollector{}(atom)};
3200
+ assert (dsgs.size () == 1 && " Should have a single top-level designator" );
3201
+ evaluate::SymbolVector syms{evaluate::GetSymbolVector (dsgs.front ())};
3202
+
3203
+ CheckAtomicType (syms.back (), source, atom.AsFortran ());
3204
+
3205
+ if (IsAllocatable (syms.back ()) && !IsArrayElement (atom)) {
3174
3206
context_.Say (source, " Atomic variable %s cannot be ALLOCATABLE" _err_en_US,
3175
- atom.AsFortran ());
3207
+ atom.AsFortran ());
3176
3208
}
3177
3209
}
3178
3210
0 commit comments