@@ -243,6 +243,31 @@ void CheckHelper::Check(
243
243
}
244
244
}
245
245
246
+ // Checks an elemental function result type parameter specification
247
+ // expression for an unacceptable use of a dummy argument.
248
+ class BadDummyChecker : public evaluate ::AnyTraverse<BadDummyChecker, bool > {
249
+ public:
250
+ using Base = evaluate::AnyTraverse<BadDummyChecker, bool >;
251
+ BadDummyChecker (parser::ContextualMessages &messages, const Scope &scope)
252
+ : Base{*this }, messages_{messages}, scope_{scope} {}
253
+ using Base::operator ();
254
+ bool operator ()(const evaluate::DescriptorInquiry &) {
255
+ return false ; // shield base() of inquiry from further checking
256
+ }
257
+ bool operator ()(const Symbol &symbol) {
258
+ if (&symbol.owner () == &scope_ && IsDummy (symbol)) {
259
+ messages_.Say (
260
+ " Specification expression for elemental function result may not depend on dummy argument '%s''s value" _err_en_US,
261
+ symbol.name ());
262
+ }
263
+ return false ;
264
+ }
265
+
266
+ private:
267
+ parser::ContextualMessages &messages_;
268
+ const Scope &scope_;
269
+ };
270
+
246
271
void CheckHelper::Check (const Symbol &symbol) {
247
272
if (symbol.name ().size () > common::maxNameLen &&
248
273
&symbol == &symbol.GetUltimate ()) {
@@ -378,24 +403,31 @@ void CheckHelper::Check(const Symbol &symbol) {
378
403
} else {
379
404
Check (*type, canHaveAssumedParameter);
380
405
}
381
- if (InPure () && InFunction () && IsFunctionResult (symbol)) {
382
- if (type->IsPolymorphic () && IsAllocatable (symbol)) { // C1585
383
- messages_.Say (
384
- " Result of pure function may not be both polymorphic and ALLOCATABLE" _err_en_US);
385
- }
386
- if (derived) {
387
- // These cases would be caught be the general validation of local
388
- // variables in a pure context, but these messages are more specific.
389
- if (HasImpureFinal (symbol)) { // C1584
406
+ if (InFunction () && IsFunctionResult (symbol)) {
407
+ if (InPure ()) {
408
+ if (type->IsPolymorphic () && IsAllocatable (symbol)) { // C1585
390
409
messages_.Say (
391
- " Result of pure function may not have an impure FINAL subroutine " _err_en_US);
410
+ " Result of pure function may not be both polymorphic and ALLOCATABLE " _err_en_US);
392
411
}
393
- if (auto bad{FindPolymorphicAllocatableUltimateComponent (*derived)}) {
394
- SayWithDeclaration (*bad,
395
- " Result of pure function may not have polymorphic ALLOCATABLE ultimate component '%s'" _err_en_US,
396
- bad.BuildResultDesignatorName ());
412
+ if (derived) {
413
+ // These cases would be caught be the general validation of local
414
+ // variables in a pure context, but these messages are more specific.
415
+ if (HasImpureFinal (symbol)) { // C1584
416
+ messages_.Say (
417
+ " Result of pure function may not have an impure FINAL subroutine" _err_en_US);
418
+ }
419
+ if (auto bad{FindPolymorphicAllocatableUltimateComponent (*derived)}) {
420
+ SayWithDeclaration (*bad,
421
+ " Result of pure function may not have polymorphic ALLOCATABLE ultimate component '%s'" _err_en_US,
422
+ bad.BuildResultDesignatorName ());
423
+ }
397
424
}
398
425
}
426
+ if (InElemental () && isChar) { // F'2023 C15121
427
+ BadDummyChecker{messages_, symbol.owner ()}(
428
+ type->characterTypeSpec ().length ().GetExplicit ());
429
+ // TODO: check PDT LEN parameters
430
+ }
399
431
}
400
432
}
401
433
if (IsAssumedLengthCharacter (symbol) && IsFunction (symbol)) { // C723
0 commit comments