1 // Copyright (c) 2018-2019, NVIDIA CORPORATION.  All rights reserved.
2 //
3 // Licensed under the Apache License, Version 2.0 (the "License");
4 // you may not use this file except in compliance with the License.
5 // You may obtain a copy of the License at
6 //
7 //     http://www.apache.org/licenses/LICENSE-2.0
8 //
9 // Unless required by applicable law or agreed to in writing, software
10 // distributed under the License is distributed on an "AS IS" BASIS,
11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 // See the License for the specific language governing permissions and
13 // limitations under the License.
14 
15 #include "expression.h"
16 #include "assignment.h"
17 #include "scope.h"
18 #include "semantics.h"
19 #include "symbol.h"
20 #include "tools.h"
21 #include "../common/idioms.h"
22 #include "../evaluate/check-call.h"
23 #include "../evaluate/common.h"
24 #include "../evaluate/fold.h"
25 #include "../evaluate/tools.h"
26 #include "../parser/characters.h"
27 #include "../parser/parse-tree-visitor.h"
28 #include "../parser/parse-tree.h"
29 #include <algorithm>
30 #include <functional>
31 #include <optional>
32 #include <set>
33 
34 // #define DUMP_ON_FAILURE 1
35 // #define CRASH_ON_FAILURE 1
36 #if DUMP_ON_FAILURE
37 #include "../parser/dump-parse-tree.h"
38 #include <iostream>
39 #endif
40 
41 // Typedef for optional generic expressions (ubiquitous in this file)
42 using MaybeExpr =
43     std::optional<Fortran::evaluate::Expr<Fortran::evaluate::SomeType>>;
44 
45 // Much of the code that implements semantic analysis of expressions is
46 // tightly coupled with their typed representations in lib/evaluate,
47 // and appears here in namespace Fortran::evaluate for convenience.
48 namespace Fortran::evaluate {
49 
50 using common::TypeCategory;
51 
52 struct DynamicTypeWithLength : public DynamicType {
DynamicTypeWithLengthFortran::evaluate::DynamicTypeWithLength53   explicit DynamicTypeWithLength(const DynamicType &t) : DynamicType{t} {}
54   std::optional<Expr<SubscriptInteger>> LEN() const;
55   std::optional<Expr<SubscriptInteger>> length;
56 };
57 
LEN() const58 std::optional<Expr<SubscriptInteger>> DynamicTypeWithLength::LEN() const {
59   if (length.has_value()) {
60     return length;
61   }
62   if (auto *lengthParam{charLength()}) {
63     if (const auto &len{lengthParam->GetExplicit()}) {
64       return ConvertToType<SubscriptInteger>(common::Clone(*len));
65     }
66   }
67   return std::nullopt;
68 }
69 
AnalyzeTypeSpec(const std::optional<parser::TypeSpec> & spec)70 static std::optional<DynamicTypeWithLength> AnalyzeTypeSpec(
71     const std::optional<parser::TypeSpec> &spec) {
72   if (spec.has_value()) {
73     if (const semantics::DeclTypeSpec * typeSpec{spec->declTypeSpec}) {
74       // Name resolution sets TypeSpec::declTypeSpec only when it's valid
75       // (viz., an intrinsic type with valid known kind or a non-polymorphic
76       // & non-ABSTRACT derived type).
77       if (const semantics::IntrinsicTypeSpec *
78           intrinsic{typeSpec->AsIntrinsic()}) {
79         TypeCategory category{intrinsic->category()};
80         if (auto optKind{ToInt64(intrinsic->kind())}) {
81           int kind{static_cast<int>(*optKind)};
82           if (category == TypeCategory::Character) {
83             const semantics::CharacterTypeSpec &cts{
84                 typeSpec->characterTypeSpec()};
85             const semantics::ParamValue &len{cts.length()};
86             // N.B. CHARACTER(LEN=*) is allowed in type-specs in ALLOCATE() &
87             // type guards, but not in array constructors.
88             return DynamicTypeWithLength{DynamicType{kind, len}};
89           } else {
90             return DynamicTypeWithLength{DynamicType{category, kind}};
91           }
92         }
93       } else if (const semantics::DerivedTypeSpec *
94           derived{typeSpec->AsDerived()}) {
95         return DynamicTypeWithLength{DynamicType{*derived}};
96       }
97     }
98   }
99   return std::nullopt;
100 }
101 
102 // Wraps a object in an explicitly typed representation (e.g., Designator<>
103 // or FunctionRef<>) that has been instantiated on a dynamically chosen type.
104 template<TypeCategory CATEGORY, template<typename> typename WRAPPER,
105     typename WRAPPED>
WrapperHelper(int kind,WRAPPED && x)106 common::IfNoLvalue<MaybeExpr, WRAPPED> WrapperHelper(int kind, WRAPPED &&x) {
107   return common::SearchTypes(
108       TypeKindVisitor<CATEGORY, WRAPPER, WRAPPED>{kind, std::move(x)});
109 }
110 
111 template<template<typename> typename WRAPPER, typename WRAPPED>
TypedWrapper(const DynamicType & dyType,WRAPPED && x)112 common::IfNoLvalue<MaybeExpr, WRAPPED> TypedWrapper(
113     const DynamicType &dyType, WRAPPED &&x) {
114   switch (dyType.category()) {
115     SWITCH_COVERS_ALL_CASES
116   case TypeCategory::Integer:
117     return WrapperHelper<TypeCategory::Integer, WRAPPER, WRAPPED>(
118         dyType.kind(), std::move(x));
119   case TypeCategory::Real:
120     return WrapperHelper<TypeCategory::Real, WRAPPER, WRAPPED>(
121         dyType.kind(), std::move(x));
122   case TypeCategory::Complex:
123     return WrapperHelper<TypeCategory::Complex, WRAPPER, WRAPPED>(
124         dyType.kind(), std::move(x));
125   case TypeCategory::Character:
126     return WrapperHelper<TypeCategory::Character, WRAPPER, WRAPPED>(
127         dyType.kind(), std::move(x));
128   case TypeCategory::Logical:
129     return WrapperHelper<TypeCategory::Logical, WRAPPER, WRAPPED>(
130         dyType.kind(), std::move(x));
131   case TypeCategory::Derived:
132     return AsGenericExpr(Expr<SomeDerived>{WRAPPER<SomeDerived>{std::move(x)}});
133   }
134 }
135 
136 // Wraps a data reference in a typed Designator<>, and a procedure
137 // or procedure pointer reference in a ProcedureDesignator.
Designate(DataRef && ref)138 MaybeExpr ExpressionAnalyzer::Designate(DataRef &&ref) {
139   const Symbol &symbol{ref.GetLastSymbol().GetUltimate()};
140   if (semantics::IsProcedure(symbol)) {
141     if (auto *component{std::get_if<Component>(&ref.u)}) {
142       return Expr<SomeType>{ProcedureDesignator{std::move(*component)}};
143     } else {
144       CHECK(std::holds_alternative<const Symbol *>(ref.u));
145       return Expr<SomeType>{ProcedureDesignator{symbol}};
146     }
147   } else if (auto dyType{DynamicType::From(symbol)}) {
148     return TypedWrapper<Designator, DataRef>(*dyType, std::move(ref));
149   }
150   return std::nullopt;
151 }
152 
153 // Some subscript semantic checks must be deferred until all of the
154 // subscripts are in hand.
CompleteSubscripts(ArrayRef && ref)155 MaybeExpr ExpressionAnalyzer::CompleteSubscripts(ArrayRef &&ref) {
156   const Symbol &symbol{ref.GetLastSymbol().GetUltimate()};
157   const auto *object{symbol.detailsIf<semantics::ObjectEntityDetails>()};
158   int symbolRank{symbol.Rank()};
159   int subscripts{static_cast<int>(ref.size())};
160   if (subscripts == 0) {
161     // nothing to check
162   } else if (subscripts != symbolRank) {
163     Say("Reference to rank-%d object '%s' has %d subscripts"_err_en_US,
164         symbolRank, symbol.name(), subscripts);
165     return std::nullopt;
166   } else if (Component * component{ref.base().UnwrapComponent()}) {
167     int baseRank{component->base().Rank()};
168     if (baseRank > 0) {
169       int subscriptRank{0};
170       for (const auto &expr : ref.subscript()) {
171         subscriptRank += expr.Rank();
172       }
173       if (subscriptRank > 0) {
174         Say("Subscripts of component '%s' of rank-%d derived type "
175             "array have rank %d but must all be scalar"_err_en_US,
176             symbol.name(), baseRank, subscriptRank);
177         return std::nullopt;
178       }
179     }
180   } else if (object != nullptr) {
181     // C928 & C1002
182     if (Triplet * last{std::get_if<Triplet>(&ref.subscript().back().u)}) {
183       if (!last->upper().has_value() && object->IsAssumedSize()) {
184         Say("Assumed-size array '%s' must have explicit final "
185             "subscript upper bound value"_err_en_US,
186             symbol.name());
187         return std::nullopt;
188       }
189     }
190   }
191   return Designate(DataRef{std::move(ref)});
192 }
193 
194 // Applies subscripts to a data reference.
ApplySubscripts(DataRef && dataRef,std::vector<Subscript> && subscripts)195 MaybeExpr ExpressionAnalyzer::ApplySubscripts(
196     DataRef &&dataRef, std::vector<Subscript> &&subscripts) {
197   return std::visit(
198       common::visitors{
199           [&](const Symbol *symbol) {
200             return CompleteSubscripts(ArrayRef{*symbol, std::move(subscripts)});
201           },
202           [&](Component &&c) {
203             return CompleteSubscripts(
204                 ArrayRef{std::move(c), std::move(subscripts)});
205           },
206           [&](auto &&) -> MaybeExpr {
207             DIE("bad base for ArrayRef");
208             return std::nullopt;
209           },
210       },
211       std::move(dataRef.u));
212 }
213 
214 // Top-level checks for data references.
TopLevelChecks(DataRef && dataRef)215 MaybeExpr ExpressionAnalyzer::TopLevelChecks(DataRef &&dataRef) {
216   if (Component * component{std::get_if<Component>(&dataRef.u)}) {
217     const Symbol &symbol{component->GetLastSymbol()};
218     int componentRank{symbol.Rank()};
219     if (componentRank > 0) {
220       int baseRank{component->base().Rank()};
221       if (baseRank > 0) {
222         Say("Reference to whole rank-%d component '%%%s' of "
223             "rank-%d array of derived type is not allowed"_err_en_US,
224             componentRank, symbol.name(), baseRank);
225       }
226     }
227   }
228   return Designate(std::move(dataRef));
229 }
230 
231 // Parse tree correction after a substring S(j:k) was misparsed as an
232 // array section.  N.B. Fortran substrings have to have a range, not a
233 // single index.
FixMisparsedSubstring(const parser::Designator & d)234 static void FixMisparsedSubstring(const parser::Designator &d) {
235   auto &mutate{const_cast<parser::Designator &>(d)};
236   if (auto *dataRef{std::get_if<parser::DataRef>(&mutate.u)}) {
237     if (auto *ae{std::get_if<common::Indirection<parser::ArrayElement>>(
238             &dataRef->u)}) {
239       parser::ArrayElement &arrElement{ae->value()};
240       if (!arrElement.subscripts.empty()) {
241         auto iter{arrElement.subscripts.begin()};
242         if (auto *triplet{std::get_if<parser::SubscriptTriplet>(&iter->u)}) {
243           if (!std::get<2>(triplet->t).has_value() /* no stride */ &&
244               ++iter == arrElement.subscripts.end() /* one subscript */) {
245             if (Symbol *
246                 symbol{std::visit(
247                     common::visitors{
248                         [](parser::Name &n) { return n.symbol; },
249                         [](common::Indirection<parser::StructureComponent>
250                                 &sc) { return sc.value().component.symbol; },
251                         [](auto &) -> Symbol * { return nullptr; },
252                     },
253                     arrElement.base.u)}) {
254               const Symbol &ultimate{symbol->GetUltimate()};
255               if (const semantics::DeclTypeSpec * type{ultimate.GetType()}) {
256                 if (!ultimate.IsObjectArray() &&
257                     type->category() == semantics::DeclTypeSpec::Character) {
258                   // The ambiguous S(j:k) was parsed as an array section
259                   // reference, but it's now clear that it's a substring.
260                   // Fix the parse tree in situ.
261                   mutate.u = arrElement.ConvertToSubstring();
262                 }
263               }
264             }
265           }
266         }
267       }
268     }
269   }
270 }
271 
Analyze(const parser::Designator & d)272 MaybeExpr ExpressionAnalyzer::Analyze(const parser::Designator &d) {
273   auto save{GetContextualMessages().SetLocation(d.source)};
274   FixMisparsedSubstring(d);
275   // These checks have to be deferred to these "top level" data-refs where
276   // we can be sure that there are no following subscripts (yet).
277   if (MaybeExpr result{Analyze(d.u)}) {
278     if (std::optional<evaluate::DataRef> dataRef{
279             evaluate::ExtractDataRef(std::move(result))}) {
280       return TopLevelChecks(std::move(*dataRef));
281     }
282     return result;
283   }
284   return std::nullopt;
285 }
286 
287 // A utility subroutine to repackage optional expressions of various levels
288 // of type specificity as fully general MaybeExpr values.
AsMaybeExpr(A && x)289 template<typename A> common::IfNoLvalue<MaybeExpr, A> AsMaybeExpr(A &&x) {
290   return std::make_optional(AsGenericExpr(std::move(x)));
291 }
AsMaybeExpr(std::optional<A> && x)292 template<typename A> MaybeExpr AsMaybeExpr(std::optional<A> &&x) {
293   if (x.has_value()) {
294     return AsMaybeExpr(std::move(*x));
295   }
296   return std::nullopt;
297 }
298 
299 // Type kind parameter values for literal constants.
AnalyzeKindParam(const std::optional<parser::KindParam> & kindParam,int defaultKind)300 int ExpressionAnalyzer::AnalyzeKindParam(
301     const std::optional<parser::KindParam> &kindParam, int defaultKind) {
302   if (!kindParam.has_value()) {
303     return defaultKind;
304   }
305   return std::visit(
306       common::visitors{
307           [](std::uint64_t k) { return static_cast<int>(k); },
308           [&](const parser::Scalar<
309               parser::Integer<parser::Constant<parser::Name>>> &n) {
310             if (MaybeExpr ie{Analyze(n)}) {
311               if (std::optional<std::int64_t> i64{ToInt64(*ie)}) {
312                 int iv = *i64;
313                 if (iv == *i64) {
314                   return iv;
315                 }
316               }
317             }
318             return defaultKind;
319           },
320       },
321       kindParam->u);
322 }
323 
324 // Common handling of parser::IntLiteralConstant and SignedIntLiteralConstant
325 struct IntTypeVisitor {
326   using Result = MaybeExpr;
327   using Types = IntegerTypes;
TestFortran::evaluate::IntTypeVisitor328   template<typename T> Result Test() {
329     if (T::kind >= kind) {
330       const char *p{digits.begin()};
331       auto value{T::Scalar::Read(p, 10, true /*signed*/)};
332       if (!value.overflow) {
333         if (T::kind > kind) {
334           if (!isDefaultKind ||
335               !analyzer.context().IsEnabled(
336                   parser::LanguageFeature::BigIntLiterals)) {
337             return std::nullopt;
338           } else if (analyzer.context().ShouldWarn(
339                          parser::LanguageFeature::BigIntLiterals)) {
340             analyzer.Say(digits,
341                 "Integer literal is too large for default INTEGER(KIND=%d); "
342                 "assuming INTEGER(KIND=%d)"_en_US,
343                 kind, T::kind);
344           }
345         }
346         return Expr<SomeType>{
347             Expr<SomeInteger>{Expr<T>{Constant<T>{std::move(value.value)}}}};
348       }
349     }
350     return std::nullopt;
351   }
352   ExpressionAnalyzer &analyzer;
353   parser::CharBlock digits;
354   int kind;
355   bool isDefaultKind;
356 };
357 
358 template<typename PARSED>
IntLiteralConstant(const PARSED & x)359 MaybeExpr ExpressionAnalyzer::IntLiteralConstant(const PARSED &x) {
360   const auto &kindParam{std::get<std::optional<parser::KindParam>>(x.t)};
361   bool isDefaultKind{!kindParam.has_value()};
362   int kind{AnalyzeKindParam(kindParam, GetDefaultKind(TypeCategory::Integer))};
363   if (CheckIntrinsicKind(TypeCategory::Integer, kind)) {
364     auto digits{std::get<parser::CharBlock>(x.t)};
365     if (MaybeExpr result{common::SearchTypes(
366             IntTypeVisitor{*this, digits, kind, isDefaultKind})}) {
367       return result;
368     } else if (isDefaultKind) {
369       Say(digits,
370           "Integer literal is too large for any allowable "
371           "kind of INTEGER"_err_en_US);
372     } else {
373       Say(digits, "Integer literal is too large for INTEGER(KIND=%d)"_err_en_US,
374           kind);
375     }
376   }
377   return std::nullopt;
378 }
379 
Analyze(const parser::IntLiteralConstant & x)380 MaybeExpr ExpressionAnalyzer::Analyze(const parser::IntLiteralConstant &x) {
381   return IntLiteralConstant(x);
382 }
383 
Analyze(const parser::SignedIntLiteralConstant & x)384 MaybeExpr ExpressionAnalyzer::Analyze(
385     const parser::SignedIntLiteralConstant &x) {
386   return IntLiteralConstant(x);
387 }
388 
389 template<typename TYPE>
ReadRealLiteral(parser::CharBlock source,FoldingContext & context)390 Constant<TYPE> ReadRealLiteral(
391     parser::CharBlock source, FoldingContext &context) {
392   const char *p{source.begin()};
393   auto valWithFlags{Scalar<TYPE>::Read(p, context.rounding())};
394   CHECK(p == source.end());
395   RealFlagWarnings(context, valWithFlags.flags, "conversion of REAL literal");
396   auto value{valWithFlags.value};
397   if (context.flushSubnormalsToZero()) {
398     value = value.FlushSubnormalToZero();
399   }
400   return {value};
401 }
402 
403 struct RealTypeVisitor {
404   using Result = std::optional<Expr<SomeReal>>;
405   using Types = RealTypes;
406 
RealTypeVisitorFortran::evaluate::RealTypeVisitor407   RealTypeVisitor(int k, parser::CharBlock lit, FoldingContext &ctx)
408     : kind{k}, literal{lit}, context{ctx} {}
409 
TestFortran::evaluate::RealTypeVisitor410   template<typename T> Result Test() {
411     if (kind == T::kind) {
412       return {AsCategoryExpr(ReadRealLiteral<T>(literal, context))};
413     }
414     return std::nullopt;
415   }
416 
417   int kind;
418   parser::CharBlock literal;
419   FoldingContext &context;
420 };
421 
422 // Reads a real literal constant and encodes it with the right kind.
Analyze(const parser::RealLiteralConstant & x)423 MaybeExpr ExpressionAnalyzer::Analyze(const parser::RealLiteralConstant &x) {
424   // Use a local message context around the real literal for better
425   // provenance on any messages.
426   auto save{GetContextualMessages().SetLocation(x.real.source)};
427   // If a kind parameter appears, it defines the kind of the literal and any
428   // letter used in an exponent part (e.g., the 'E' in "6.02214E+23")
429   // should agree.  In the absence of an explicit kind parameter, any exponent
430   // letter determines the kind.  Otherwise, defaults apply.
431   auto &defaults{context_.defaultKinds()};
432   int defaultKind{defaults.GetDefaultKind(TypeCategory::Real)};
433   const char *end{x.real.source.end()};
434   char expoLetter{' '};
435   std::optional<int> letterKind;
436   for (const char *p{x.real.source.begin()}; p < end; ++p) {
437     if (parser::IsLetter(*p)) {
438       expoLetter = *p;
439       switch (expoLetter) {
440       case 'e': letterKind = defaults.GetDefaultKind(TypeCategory::Real); break;
441       case 'd': letterKind = defaults.doublePrecisionKind(); break;
442       case 'q': letterKind = defaults.quadPrecisionKind(); break;
443       default: Say("Unknown exponent letter '%c'"_err_en_US, expoLetter);
444       }
445       break;
446     }
447   }
448   if (letterKind.has_value()) {
449     defaultKind = *letterKind;
450   }
451   auto kind{AnalyzeKindParam(x.kind, defaultKind)};
452   if (letterKind.has_value() && kind != *letterKind && expoLetter != 'e') {
453     Say("Explicit kind parameter on real constant disagrees with "
454         "exponent letter '%c'"_en_US,
455         expoLetter);
456   }
457   auto result{common::SearchTypes(
458       RealTypeVisitor{kind, x.real.source, GetFoldingContext()})};
459   if (!result.has_value()) {
460     Say("Unsupported REAL(KIND=%d)"_err_en_US, kind);
461   }
462   return AsMaybeExpr(std::move(result));
463 }
464 
Analyze(const parser::SignedRealLiteralConstant & x)465 MaybeExpr ExpressionAnalyzer::Analyze(
466     const parser::SignedRealLiteralConstant &x) {
467   if (auto result{Analyze(std::get<parser::RealLiteralConstant>(x.t))}) {
468     auto &realExpr{std::get<Expr<SomeReal>>(result->u)};
469     if (auto sign{std::get<std::optional<parser::Sign>>(x.t)}) {
470       if (sign == parser::Sign::Negative) {
471         return {AsGenericExpr(-std::move(realExpr))};
472       }
473     }
474     return result;
475   }
476   return std::nullopt;
477 }
478 
Analyze(const parser::ComplexPart & x)479 MaybeExpr ExpressionAnalyzer::Analyze(const parser::ComplexPart &x) {
480   return Analyze(x.u);
481 }
482 
Analyze(const parser::ComplexLiteralConstant & z)483 MaybeExpr ExpressionAnalyzer::Analyze(const parser::ComplexLiteralConstant &z) {
484   return AsMaybeExpr(
485       ConstructComplex(GetContextualMessages(), Analyze(std::get<0>(z.t)),
486           Analyze(std::get<1>(z.t)), GetDefaultKind(TypeCategory::Real)));
487 }
488 
489 // CHARACTER literal processing.
AnalyzeString(std::string && string,int kind)490 MaybeExpr ExpressionAnalyzer::AnalyzeString(std::string &&string, int kind) {
491   if (!CheckIntrinsicKind(TypeCategory::Character, kind)) {
492     return std::nullopt;
493   }
494   switch (kind) {
495   case 1:
496     return AsGenericExpr(Constant<Type<TypeCategory::Character, 1>>{
497         parser::DecodeString<std::string, parser::Encoding::LATIN_1>(
498             string, true)});
499   case 2:
500     return AsGenericExpr(Constant<Type<TypeCategory::Character, 2>>{
501         parser::DecodeString<std::u16string, parser::Encoding::UTF_8>(
502             string, true)});
503   case 4:
504     return AsGenericExpr(Constant<Type<TypeCategory::Character, 4>>{
505         parser::DecodeString<std::u32string, parser::Encoding::UTF_8>(
506             string, true)});
507   default: CRASH_NO_CASE;
508   }
509 }
510 
Analyze(const parser::CharLiteralConstant & x)511 MaybeExpr ExpressionAnalyzer::Analyze(const parser::CharLiteralConstant &x) {
512   int kind{
513       AnalyzeKindParam(std::get<std::optional<parser::KindParam>>(x.t), 1)};
514   auto value{std::get<std::string>(x.t)};
515   return AnalyzeString(std::move(value), kind);
516 }
517 
Analyze(const parser::HollerithLiteralConstant & x)518 MaybeExpr ExpressionAnalyzer::Analyze(
519     const parser::HollerithLiteralConstant &x) {
520   int kind{GetDefaultKind(TypeCategory::Character)};
521   auto value{x.v};
522   return AnalyzeString(std::move(value), kind);
523 }
524 
525 // .TRUE. and .FALSE. of various kinds
Analyze(const parser::LogicalLiteralConstant & x)526 MaybeExpr ExpressionAnalyzer::Analyze(const parser::LogicalLiteralConstant &x) {
527   auto kind{AnalyzeKindParam(std::get<std::optional<parser::KindParam>>(x.t),
528       GetDefaultKind(TypeCategory::Logical))};
529   bool value{std::get<bool>(x.t)};
530   auto result{common::SearchTypes(
531       TypeKindVisitor<TypeCategory::Logical, Constant, bool>{
532           kind, std::move(value)})};
533   if (!result.has_value()) {
534     Say("unsupported LOGICAL(KIND=%d)"_err_en_US, kind);
535   }
536   return result;
537 }
538 
539 // BOZ typeless literals
Analyze(const parser::BOZLiteralConstant & x)540 MaybeExpr ExpressionAnalyzer::Analyze(const parser::BOZLiteralConstant &x) {
541   const char *p{x.v.c_str()};
542   std::uint64_t base{16};
543   switch (*p++) {
544   case 'b': base = 2; break;
545   case 'o': base = 8; break;
546   case 'z': break;
547   case 'x': break;
548   default: CRASH_NO_CASE;
549   }
550   CHECK(*p == '"');
551   ++p;
552   auto value{BOZLiteralConstant::Read(p, base, false /*unsigned*/)};
553   if (*p != '"') {
554     Say("Invalid digit ('%c') in BOZ literal '%s'"_err_en_US, *p, x.v);
555     return std::nullopt;
556   }
557   if (value.overflow) {
558     Say("BOZ literal '%s' too large"_err_en_US, x.v);
559     return std::nullopt;
560   }
561   return {AsGenericExpr(std::move(value.value))};
562 }
563 
564 // For use with SearchTypes to create a TypeParamInquiry with the
565 // right integer kind.
566 struct TypeParamInquiryVisitor {
567   using Result = std::optional<Expr<SomeInteger>>;
568   using Types = IntegerTypes;
TypeParamInquiryVisitorFortran::evaluate::TypeParamInquiryVisitor569   TypeParamInquiryVisitor(int k, NamedEntity &&b, const Symbol &param)
570     : kind{k}, base{std::move(b)}, parameter{param} {}
TypeParamInquiryVisitorFortran::evaluate::TypeParamInquiryVisitor571   TypeParamInquiryVisitor(int k, const Symbol &param)
572     : kind{k}, parameter{param} {}
TestFortran::evaluate::TypeParamInquiryVisitor573   template<typename T> Result Test() {
574     if (kind == T::kind) {
575       return Expr<SomeInteger>{
576           Expr<T>{TypeParamInquiry<T::kind>{std::move(base), parameter}}};
577     }
578     return std::nullopt;
579   }
580   int kind;
581   std::optional<NamedEntity> base;
582   const Symbol &parameter;
583 };
584 
MakeBareTypeParamInquiry(const Symbol * symbol)585 static std::optional<Expr<SomeInteger>> MakeBareTypeParamInquiry(
586     const Symbol *symbol) {
587   if (std::optional<DynamicType> dyType{DynamicType::From(symbol)}) {
588     if (dyType->category() == TypeCategory::Integer) {
589       return common::SearchTypes(
590           TypeParamInquiryVisitor{dyType->kind(), *symbol});
591     }
592   }
593   return std::nullopt;
594 }
595 
596 // Names and named constants
Analyze(const parser::Name & n)597 MaybeExpr ExpressionAnalyzer::Analyze(const parser::Name &n) {
598   if (std::optional<int> kind{IsAcImpliedDo(n.source)}) {
599     return AsMaybeExpr(ConvertToKind<TypeCategory::Integer>(
600         *kind, AsExpr(ImpliedDoIndex{n.source})));
601   } else if (context_.HasError(n)) {
602     return std::nullopt;
603   } else {
604     const Symbol &ultimate{n.symbol->GetUltimate()};
605     if (ultimate.has<semantics::TypeParamDetails>()) {
606       // A bare reference to a derived type parameter (within a parameterized
607       // derived type definition)
608       return AsMaybeExpr(MakeBareTypeParamInquiry(&ultimate));
609     } else {
610       return Designate(DataRef{*n.symbol});
611     }
612   }
613 }
614 
Analyze(const parser::NamedConstant & n)615 MaybeExpr ExpressionAnalyzer::Analyze(const parser::NamedConstant &n) {
616   if (MaybeExpr value{Analyze(n.v)}) {
617     Expr<SomeType> folded{Fold(GetFoldingContext(), std::move(*value))};
618     if (IsConstantExpr(folded)) {
619       return {folded};
620     }
621     Say(n.v.source, "must be a constant"_err_en_US);
622   }
623   return std::nullopt;
624 }
625 
626 // Substring references
GetSubstringBound(const std::optional<parser::ScalarIntExpr> & bound)627 std::optional<Expr<SubscriptInteger>> ExpressionAnalyzer::GetSubstringBound(
628     const std::optional<parser::ScalarIntExpr> &bound) {
629   if (bound.has_value()) {
630     if (MaybeExpr expr{Analyze(*bound)}) {
631       if (expr->Rank() > 1) {
632         Say("substring bound expression has rank %d"_err_en_US, expr->Rank());
633       }
634       if (auto *intExpr{std::get_if<Expr<SomeInteger>>(&expr->u)}) {
635         if (auto *ssIntExpr{std::get_if<Expr<SubscriptInteger>>(&intExpr->u)}) {
636           return {std::move(*ssIntExpr)};
637         }
638         return {Expr<SubscriptInteger>{
639             Convert<SubscriptInteger, TypeCategory::Integer>{
640                 std::move(*intExpr)}}};
641       } else {
642         Say("substring bound expression is not INTEGER"_err_en_US);
643       }
644     }
645   }
646   return std::nullopt;
647 }
648 
Analyze(const parser::Substring & ss)649 MaybeExpr ExpressionAnalyzer::Analyze(const parser::Substring &ss) {
650   if (MaybeExpr baseExpr{Analyze(std::get<parser::DataRef>(ss.t))}) {
651     if (std::optional<DataRef> dataRef{ExtractDataRef(std::move(*baseExpr))}) {
652       if (MaybeExpr newBaseExpr{TopLevelChecks(std::move(*dataRef))}) {
653         if (std::optional<DataRef> checked{
654                 ExtractDataRef(std::move(*newBaseExpr))}) {
655           const parser::SubstringRange &range{
656               std::get<parser::SubstringRange>(ss.t)};
657           std::optional<Expr<SubscriptInteger>> first{
658               GetSubstringBound(std::get<0>(range.t))};
659           std::optional<Expr<SubscriptInteger>> last{
660               GetSubstringBound(std::get<1>(range.t))};
661           const Symbol &symbol{checked->GetLastSymbol()};
662           if (std::optional<DynamicType> dynamicType{
663                   DynamicType::From(symbol)}) {
664             if (dynamicType->category() == TypeCategory::Character) {
665               return WrapperHelper<TypeCategory::Character, Designator,
666                   Substring>(dynamicType->kind(),
667                   Substring{std::move(checked.value()), std::move(first),
668                       std::move(last)});
669             }
670           }
671           Say("substring may apply only to CHARACTER"_err_en_US);
672         }
673       }
674     }
675   }
676   return std::nullopt;
677 }
678 
679 // CHARACTER literal substrings
Analyze(const parser::CharLiteralConstantSubstring & x)680 MaybeExpr ExpressionAnalyzer::Analyze(
681     const parser::CharLiteralConstantSubstring &x) {
682   const parser::SubstringRange &range{std::get<parser::SubstringRange>(x.t)};
683   std::optional<Expr<SubscriptInteger>> lower{
684       GetSubstringBound(std::get<0>(range.t))};
685   std::optional<Expr<SubscriptInteger>> upper{
686       GetSubstringBound(std::get<1>(range.t))};
687   if (MaybeExpr string{Analyze(std::get<parser::CharLiteralConstant>(x.t))}) {
688     if (auto *charExpr{std::get_if<Expr<SomeCharacter>>(&string->u)}) {
689       Expr<SubscriptInteger> length{
690           std::visit([](const auto &ckExpr) { return ckExpr.LEN().value(); },
691               charExpr->u)};
692       if (!lower.has_value()) {
693         lower = Expr<SubscriptInteger>{1};
694       }
695       if (!upper.has_value()) {
696         upper = Expr<SubscriptInteger>{
697             static_cast<std::int64_t>(ToInt64(length).value())};
698       }
699       return std::visit(
700           [&](auto &&ckExpr) -> MaybeExpr {
701             using Result = ResultType<decltype(ckExpr)>;
702             auto *cp{std::get_if<Constant<Result>>(&ckExpr.u)};
703             CHECK(DEREF(cp).size() == 1);
704             StaticDataObject::Pointer staticData{StaticDataObject::Create()};
705             staticData->set_alignment(Result::kind)
706                 .set_itemBytes(Result::kind)
707                 .Push(cp->GetScalarValue().value());
708             Substring substring{std::move(staticData), std::move(lower.value()),
709                 std::move(upper.value())};
710             return AsGenericExpr(Expr<SomeCharacter>{
711                 Expr<Result>{Designator<Result>{std::move(substring)}}});
712           },
713           std::move(charExpr->u));
714     }
715   }
716   return std::nullopt;
717 }
718 
719 // Subscripted array references
AsSubscript(MaybeExpr && expr)720 std::optional<Expr<SubscriptInteger>> ExpressionAnalyzer::AsSubscript(
721     MaybeExpr &&expr) {
722   if (expr.has_value()) {
723     if (expr->Rank() > 1) {
724       Say("subscript expression has rank %d"_err_en_US, expr->Rank());
725     }
726     if (auto *intExpr{std::get_if<Expr<SomeInteger>>(&expr->u)}) {
727       if (auto *ssIntExpr{std::get_if<Expr<SubscriptInteger>>(&intExpr->u)}) {
728         return {std::move(*ssIntExpr)};
729       }
730       return {Expr<SubscriptInteger>{
731           Convert<SubscriptInteger, TypeCategory::Integer>{
732               std::move(*intExpr)}}};
733     } else {
734       Say("subscript expression is not INTEGER"_err_en_US);
735     }
736   }
737   return std::nullopt;
738 }
739 
TripletPart(const std::optional<parser::Subscript> & s)740 std::optional<Expr<SubscriptInteger>> ExpressionAnalyzer::TripletPart(
741     const std::optional<parser::Subscript> &s) {
742   if (s.has_value()) {
743     return AsSubscript(Analyze(*s));
744   }
745   return std::nullopt;
746 }
747 
AnalyzeSectionSubscript(const parser::SectionSubscript & ss)748 std::optional<Subscript> ExpressionAnalyzer::AnalyzeSectionSubscript(
749     const parser::SectionSubscript &ss) {
750   return std::visit(
751       common::visitors{
752           [&](const parser::SubscriptTriplet &t) {
753             return std::make_optional(Subscript{Triplet{
754                 TripletPart(std::get<0>(t.t)), TripletPart(std::get<1>(t.t)),
755                 TripletPart(std::get<2>(t.t))}});
756           },
757           [&](const auto &s) -> std::optional<Subscript> {
758             if (auto subscriptExpr{AsSubscript(Analyze(s))}) {
759               return Subscript{std::move(*subscriptExpr)};
760             } else {
761               return std::nullopt;
762             }
763           },
764       },
765       ss.u);
766 }
767 
768 // Empty result means an error occurred
AnalyzeSectionSubscripts(const std::list<parser::SectionSubscript> & sss)769 std::vector<Subscript> ExpressionAnalyzer::AnalyzeSectionSubscripts(
770     const std::list<parser::SectionSubscript> &sss) {
771   bool error{false};
772   std::vector<Subscript> subscripts;
773   for (const auto &s : sss) {
774     if (auto subscript{AnalyzeSectionSubscript(s)}) {
775       subscripts.emplace_back(std::move(*subscript));
776     } else {
777       error = true;
778     }
779   }
780   return !error ? subscripts : std::vector<Subscript>{};
781 }
782 
Analyze(const parser::ArrayElement & ae)783 MaybeExpr ExpressionAnalyzer::Analyze(const parser::ArrayElement &ae) {
784   std::vector<Subscript> subscripts{AnalyzeSectionSubscripts(ae.subscripts)};
785   if (MaybeExpr baseExpr{Analyze(ae.base)}) {
786     if (std::optional<DataRef> dataRef{ExtractDataRef(std::move(*baseExpr))}) {
787       if (!subscripts.empty()) {
788         return ApplySubscripts(std::move(*dataRef), std::move(subscripts));
789       }
790     } else {
791       Say("Subscripts may be applied only to an object, component, or array constant"_err_en_US);
792     }
793   }
794   return std::nullopt;
795 }
796 
797 // Type parameter inquiries apply to data references, but don't depend
798 // on any trailing (co)subscripts.
IgnoreAnySubscripts(Designator<SomeDerived> && designator)799 static NamedEntity IgnoreAnySubscripts(Designator<SomeDerived> &&designator) {
800   return std::visit(
801       common::visitors{
802           [](const Symbol *symbol) { return NamedEntity{*symbol}; },
803           [](Component &&component) {
804             return NamedEntity{std::move(component)};
805           },
806           [](ArrayRef &&arrayRef) { return std::move(arrayRef.base()); },
807           [](CoarrayRef &&coarrayRef) {
808             return NamedEntity{coarrayRef.GetLastSymbol()};
809           },
810       },
811       std::move(designator.u));
812 }
813 
814 // Components of parent derived types are explicitly represented as such.
CreateComponent(DataRef && base,const Symbol & component,const semantics::Scope & scope)815 static std::optional<Component> CreateComponent(
816     DataRef &&base, const Symbol &component, const semantics::Scope &scope) {
817   if (&component.owner() == &scope) {
818     return Component{std::move(base), component};
819   }
820   if (const semantics::Scope * parentScope{scope.GetDerivedTypeParent()}) {
821     if (const Symbol * parentComponent{parentScope->GetSymbol()}) {
822       return CreateComponent(
823           DataRef{Component{std::move(base), *parentComponent}}, component,
824           *parentScope);
825     }
826   }
827   return std::nullopt;
828 }
829 
830 // Derived type component references and type parameter inquiries
Analyze(const parser::StructureComponent & sc)831 MaybeExpr ExpressionAnalyzer::Analyze(const parser::StructureComponent &sc) {
832   MaybeExpr base{Analyze(sc.base)};
833   if (!base) {
834     return std::nullopt;
835   }
836   Symbol *sym{sc.component.symbol};
837   if (context_.HasError(sym)) {
838     return std::nullopt;
839   }
840   const auto &name{sc.component.source};
841   if (auto *dtExpr{UnwrapExpr<Expr<SomeDerived>>(*base)}) {
842     const semantics::DerivedTypeSpec *dtSpec{nullptr};
843     if (std::optional<DynamicType> dtDyTy{dtExpr->GetType()}) {
844       if (!dtDyTy->IsUnlimitedPolymorphic()) {
845         dtSpec = &dtDyTy->GetDerivedTypeSpec();
846       }
847     }
848     if (sym->detailsIf<semantics::TypeParamDetails>()) {
849       if (auto *designator{UnwrapExpr<Designator<SomeDerived>>(*dtExpr)}) {
850         if (std::optional<DynamicType> dyType{DynamicType::From(*sym)}) {
851           if (dyType->category() == TypeCategory::Integer) {
852             return AsMaybeExpr(
853                 common::SearchTypes(TypeParamInquiryVisitor{dyType->kind(),
854                     IgnoreAnySubscripts(std::move(*designator)), *sym}));
855           }
856         }
857         Say(name, "Type parameter is not INTEGER"_err_en_US);
858       } else {
859         Say(name,
860             "A type parameter inquiry must be applied to "
861             "a designator"_err_en_US);
862       }
863     } else if (dtSpec == nullptr || dtSpec->scope() == nullptr) {
864       CHECK(context_.AnyFatalError());
865       return std::nullopt;
866     } else if (std::optional<DataRef> dataRef{
867                    ExtractDataRef(std::move(*dtExpr))}) {
868       if (auto component{
869               CreateComponent(std::move(*dataRef), *sym, *dtSpec->scope())}) {
870         return Designate(DataRef{std::move(*component)});
871       } else {
872         Say(name, "Component is not in scope of derived TYPE(%s)"_err_en_US,
873             dtSpec->typeSymbol().name());
874       }
875     } else {
876       Say(name,
877           "Base of component reference must be a data reference"_err_en_US);
878     }
879   } else if (auto *details{sym->detailsIf<semantics::MiscDetails>()}) {
880     // special part-ref: %re, %im, %kind, %len
881     // Type errors are detected and reported in semantics.
882     using MiscKind = semantics::MiscDetails::Kind;
883     MiscKind kind{details->kind()};
884     if (kind == MiscKind::ComplexPartRe || kind == MiscKind::ComplexPartIm) {
885       if (auto *zExpr{std::get_if<Expr<SomeComplex>>(&base->u)}) {
886         if (std::optional<DataRef> dataRef{ExtractDataRef(std::move(*zExpr))}) {
887           Expr<SomeReal> realExpr{std::visit(
888               [&](const auto &z) {
889                 using PartType = typename ResultType<decltype(z)>::Part;
890                 auto part{kind == MiscKind::ComplexPartRe
891                         ? ComplexPart::Part::RE
892                         : ComplexPart::Part::IM};
893                 return AsCategoryExpr(Designator<PartType>{
894                     ComplexPart{std::move(*dataRef), part}});
895               },
896               zExpr->u)};
897           return {AsGenericExpr(std::move(realExpr))};
898         }
899       }
900     } else if (kind == MiscKind::KindParamInquiry ||
901         kind == MiscKind::LenParamInquiry) {
902       // Convert x%KIND -> intrinsic KIND(x), x%LEN -> intrinsic LEN(x)
903       return MakeFunctionRef(
904           name, ActualArguments{ActualArgument{std::move(*base)}});
905     } else {
906       DIE("unexpected MiscDetails::Kind");
907     }
908   } else {
909     Say(name, "derived type required before component reference"_err_en_US);
910   }
911   return std::nullopt;
912 }
913 
Analyze(const parser::CoindexedNamedObject & x)914 MaybeExpr ExpressionAnalyzer::Analyze(const parser::CoindexedNamedObject &x) {
915   if (auto dataRef{ExtractDataRef(Analyze(x.base))}) {
916     std::vector<Subscript> subscripts;
917     std::vector<const Symbol *> reversed;
918     if (auto *aRef{std::get_if<ArrayRef>(&dataRef->u)}) {
919       subscripts = std::move(aRef->subscript());
920       reversed.push_back(&aRef->GetLastSymbol());
921       if (Component * component{aRef->base().UnwrapComponent()}) {
922         *dataRef = std::move(component->base());
923       } else {
924         dataRef.reset();
925       }
926     }
927     if (dataRef.has_value()) {
928       while (auto *component{std::get_if<Component>(&dataRef->u)}) {
929         reversed.push_back(&component->GetLastSymbol());
930         *dataRef = std::move(component->base());
931       }
932       if (auto *baseSym{std::get_if<const Symbol *>(&dataRef->u)}) {
933         reversed.push_back(*baseSym);
934       } else {
935         Say("Base of coindexed named object has subscripts or cosubscripts"_err_en_US);
936       }
937     }
938     std::vector<Expr<SubscriptInteger>> cosubscripts;
939     bool cosubsOk{true};
940     for (const auto &cosub :
941         std::get<std::list<parser::Cosubscript>>(x.imageSelector.t)) {
942       MaybeExpr coex{Analyze(cosub)};
943       if (auto *intExpr{UnwrapExpr<Expr<SomeInteger>>(coex)}) {
944         cosubscripts.push_back(
945             ConvertToType<SubscriptInteger>(std::move(*intExpr)));
946       } else {
947         cosubsOk = false;
948       }
949     }
950     if (cosubsOk && !reversed.empty()) {
951       int numCosubscripts{static_cast<int>(cosubscripts.size())};
952       const Symbol &symbol{*reversed.front()};
953       if (numCosubscripts != symbol.Corank()) {
954         Say("'%s' has corank %d, but coindexed reference has %d cosubscripts"_err_en_US,
955             symbol.name(), symbol.Corank(), numCosubscripts);
956       }
957     }
958     // TODO: stat=/team=/team_number=
959     // Reverse the chain of symbols so that the base is first and coarray
960     // ultimate component is last.
961     return Designate(DataRef{CoarrayRef{
962         std::vector<const Symbol *>{reversed.crbegin(), reversed.crend()},
963         std::move(subscripts), std::move(cosubscripts)}});
964   }
965   return std::nullopt;
966 }
967 
IntegerTypeSpecKind(const parser::IntegerTypeSpec & spec)968 int ExpressionAnalyzer::IntegerTypeSpecKind(
969     const parser::IntegerTypeSpec &spec) {
970   Expr<SubscriptInteger> value{
971       AnalyzeKindSelector(TypeCategory::Integer, spec.v)};
972   if (auto kind{ToInt64(value)}) {
973     return static_cast<int>(*kind);
974   }
975   SayAt(spec, "Constant INTEGER kind value required here"_err_en_US);
976   return GetDefaultKind(TypeCategory::Integer);
977 }
978 
979 // Array constructors
980 
981 class ArrayConstructorContext : private ExpressionAnalyzer {
982 public:
ArrayConstructorContext(ExpressionAnalyzer & c,std::optional<DynamicTypeWithLength> & t)983   ArrayConstructorContext(
984       ExpressionAnalyzer &c, std::optional<DynamicTypeWithLength> &t)
985     : ExpressionAnalyzer{c}, type_{t} {}
986   ArrayConstructorContext(ArrayConstructorContext &) = default;
987   void Push(MaybeExpr &&);
988   void Add(const parser::AcValue &);
type() const989   std::optional<DynamicTypeWithLength> &type() const { return type_; }
values()990   const ArrayConstructorValues<SomeType> &values() { return values_; }
991 
992 private:
993   template<int KIND, typename A>
GetSpecificIntExpr(const A & x)994   std::optional<Expr<Type<TypeCategory::Integer, KIND>>> GetSpecificIntExpr(
995       const A &x) {
996     if (MaybeExpr y{Analyze(x)}) {
997       Expr<SomeInteger> *intExpr{UnwrapExpr<Expr<SomeInteger>>(*y)};
998       CHECK(intExpr != nullptr);
999       return ConvertToType<Type<TypeCategory::Integer, KIND>>(
1000           std::move(*intExpr));
1001     }
1002     return std::nullopt;
1003   }
1004 
1005   std::optional<DynamicTypeWithLength> &type_;
1006   bool explicitType_{type_.has_value()};
1007   std::optional<std::int64_t> constantLength_;
1008   ArrayConstructorValues<SomeType> values_;
1009 };
1010 
Push(MaybeExpr && x)1011 void ArrayConstructorContext::Push(MaybeExpr &&x) {
1012   if (!x.has_value()) {
1013     return;
1014   }
1015   if (auto dyType{x->GetType()}) {
1016     DynamicTypeWithLength xType{*dyType};
1017     if (Expr<SomeCharacter> * charExpr{UnwrapExpr<Expr<SomeCharacter>>(*x)}) {
1018       CHECK(xType.category() == TypeCategory::Character);
1019       xType.length =
1020           std::visit([](const auto &kc) { return kc.LEN(); }, charExpr->u);
1021     }
1022     if (!type_.has_value()) {
1023       // If there is no explicit type-spec in an array constructor, the type
1024       // of the array is the declared type of all of the elements, which must
1025       // be well-defined and all match.
1026       // TODO: Possible language extension: use the most general type of
1027       // the values as the type of a numeric constructed array, convert all
1028       // of the other values to that type.  Alternative: let the first value
1029       // determine the type, and convert the others to that type.
1030       CHECK(!explicitType_);
1031       type_ = std::move(xType);
1032       constantLength_ = ToInt64(type_->length);
1033       values_.Push(std::move(*x));
1034     } else if (!explicitType_) {
1035       if (static_cast<const DynamicType &>(*type_) ==
1036           static_cast<const DynamicType &>(xType)) {
1037         values_.Push(std::move(*x));
1038         if (auto thisLen{ToInt64(xType.LEN())}) {
1039           if (constantLength_.has_value()) {
1040             if (context().warnOnNonstandardUsage() &&
1041                 *thisLen != *constantLength_) {
1042               Say("Character literal in array constructor without explicit "
1043                   "type has different length than earlier element"_en_US);
1044             }
1045             if (*thisLen > *constantLength_) {
1046               // Language extension: use the longest literal to determine the
1047               // length of the array constructor's character elements, not the
1048               // first, when there is no explicit type.
1049               *constantLength_ = *thisLen;
1050               type_->length = xType.LEN();
1051             }
1052           } else {
1053             constantLength_ = *thisLen;
1054             type_->length = xType.LEN();
1055           }
1056         }
1057       } else {
1058         Say("Values in array constructor must have the same declared type "
1059             "when no explicit type appears"_err_en_US);
1060       }
1061     } else {
1062       if (auto cast{ConvertToType(*type_, std::move(*x))}) {
1063         values_.Push(std::move(*cast));
1064       } else {
1065         Say("Value in array constructor could not be converted to the type "
1066             "of the array"_err_en_US);
1067       }
1068     }
1069   }
1070 }
1071 
Add(const parser::AcValue & x)1072 void ArrayConstructorContext::Add(const parser::AcValue &x) {
1073   using IntType = ResultType<ImpliedDoIndex>;
1074   std::visit(
1075       common::visitors{
1076           [&](const parser::AcValue::Triplet &triplet) {
1077             // Transform l:u(:s) into (_,_=l,u(,s)) with an anonymous index '_'
1078             std::optional<Expr<IntType>> lower{
1079                 GetSpecificIntExpr<IntType::kind>(std::get<0>(triplet.t))};
1080             std::optional<Expr<IntType>> upper{
1081                 GetSpecificIntExpr<IntType::kind>(std::get<1>(triplet.t))};
1082             std::optional<Expr<IntType>> stride{
1083                 GetSpecificIntExpr<IntType::kind>(std::get<2>(triplet.t))};
1084             if (lower.has_value() && upper.has_value()) {
1085               if (!stride.has_value()) {
1086                 stride = Expr<IntType>{1};
1087               }
1088               if (!type_.has_value()) {
1089                 type_ = DynamicTypeWithLength{IntType::GetType()};
1090               }
1091               ArrayConstructorContext nested{*this};
1092               parser::CharBlock name;
1093               nested.Push(Expr<SomeType>{
1094                   Expr<SomeInteger>{Expr<IntType>{ImpliedDoIndex{name}}}});
1095               values_.Push(ImpliedDo<SomeType>{name, std::move(*lower),
1096                   std::move(*upper), std::move(*stride),
1097                   std::move(nested.values_)});
1098             }
1099           },
1100           [&](const common::Indirection<parser::Expr> &expr) {
1101             auto restorer{
1102                 GetContextualMessages().SetLocation(expr.value().source)};
1103             if (MaybeExpr v{Analyze(expr.value())}) {
1104               Push(std::move(*v));
1105             }
1106           },
1107           [&](const common::Indirection<parser::AcImpliedDo> &impliedDo) {
1108             const auto &control{
1109                 std::get<parser::AcImpliedDoControl>(impliedDo.value().t)};
1110             const auto &bounds{
1111                 std::get<parser::AcImpliedDoControl::Bounds>(control.t)};
1112             Analyze(bounds.name);
1113             parser::CharBlock name{bounds.name.thing.thing.source};
1114             const Symbol *symbol{bounds.name.thing.thing.symbol};
1115             int kind{IntType::kind};
1116             if (const auto dynamicType{DynamicType::From(symbol)}) {
1117               kind = dynamicType->kind();
1118             }
1119             bool inserted{AddAcImpliedDo(name, kind)};
1120             if (!inserted) {
1121               SayAt(name,
1122                   "Implied DO index is active in surrounding implied DO loop "
1123                   "and may not have the same name"_err_en_US);
1124             }
1125             std::optional<Expr<IntType>> lower{
1126                 GetSpecificIntExpr<IntType::kind>(bounds.lower)};
1127             std::optional<Expr<IntType>> upper{
1128                 GetSpecificIntExpr<IntType::kind>(bounds.upper)};
1129             std::optional<Expr<IntType>> stride{
1130                 GetSpecificIntExpr<IntType::kind>(bounds.step)};
1131             ArrayConstructorContext nested{*this};
1132             for (const auto &value :
1133                 std::get<std::list<parser::AcValue>>(impliedDo.value().t)) {
1134               nested.Add(value);
1135             }
1136             if (lower.has_value() && upper.has_value()) {
1137               if (!stride.has_value()) {
1138                 stride = Expr<IntType>{1};
1139               }
1140               values_.Push(ImpliedDo<SomeType>{name, std::move(*lower),
1141                   std::move(*upper), std::move(*stride),
1142                   std::move(nested.values_)});
1143             }
1144             if (inserted) {
1145               RemoveAcImpliedDo(name);
1146             }
1147           },
1148       },
1149       x.u);
1150 }
1151 
1152 // Inverts a collection of generic ArrayConstructorValues<SomeType> that
1153 // all happen to have the same actual type T into one ArrayConstructor<T>.
1154 template<typename T>
MakeSpecific(ArrayConstructorValues<SomeType> && from)1155 ArrayConstructorValues<T> MakeSpecific(
1156     ArrayConstructorValues<SomeType> &&from) {
1157   ArrayConstructorValues<T> to;
1158   for (ArrayConstructorValue<SomeType> &x : from) {
1159     std::visit(
1160         common::visitors{
1161             [&](common::CopyableIndirection<Expr<SomeType>> &&expr) {
1162               auto *typed{UnwrapExpr<Expr<T>>(expr.value())};
1163               CHECK(typed != nullptr);
1164               to.Push(std::move(*typed));
1165             },
1166             [&](ImpliedDo<SomeType> &&impliedDo) {
1167               to.Push(ImpliedDo<T>{impliedDo.name(),
1168                   std::move(impliedDo.lower()), std::move(impliedDo.upper()),
1169                   std::move(impliedDo.stride()),
1170                   MakeSpecific<T>(std::move(impliedDo.values()))});
1171             },
1172         },
1173         std::move(x.u));
1174   }
1175   return to;
1176 }
1177 
1178 struct ArrayConstructorTypeVisitor {
1179   using Result = MaybeExpr;
1180   using Types = AllTypes;
TestFortran::evaluate::ArrayConstructorTypeVisitor1181   template<typename T> Result Test() {
1182     if (type.category() == T::category) {
1183       if constexpr (T::category == TypeCategory::Derived) {
1184         return AsMaybeExpr(ArrayConstructor<T>{
1185             type.GetDerivedTypeSpec(), MakeSpecific<T>(std::move(values))});
1186       } else if (type.kind() == T::kind) {
1187         if constexpr (T::category == TypeCategory::Character) {
1188           if (auto len{type.LEN()}) {
1189             return AsMaybeExpr(ArrayConstructor<T>{
1190                 *std::move(len), MakeSpecific<T>(std::move(values))});
1191           }
1192         } else {
1193           return AsMaybeExpr(
1194               ArrayConstructor<T>{MakeSpecific<T>(std::move(values))});
1195         }
1196       }
1197     }
1198     return std::nullopt;
1199   }
1200   DynamicTypeWithLength type;
1201   ArrayConstructorValues<SomeType> values;
1202 };
1203 
Analyze(const parser::ArrayConstructor & array)1204 MaybeExpr ExpressionAnalyzer::Analyze(const parser::ArrayConstructor &array) {
1205   const parser::AcSpec &acSpec{array.v};
1206   std::optional<DynamicTypeWithLength> type{AnalyzeTypeSpec(acSpec.type)};
1207   ArrayConstructorContext context{*this, type};
1208   for (const parser::AcValue &value : acSpec.values) {
1209     context.Add(value);
1210   }
1211   if (type.has_value()) {
1212     ArrayConstructorTypeVisitor visitor{
1213         std::move(*type), std::move(context.values())};
1214     return common::SearchTypes(std::move(visitor));
1215   }
1216   return std::nullopt;
1217 }
1218 
Analyze(const parser::StructureConstructor & structure)1219 MaybeExpr ExpressionAnalyzer::Analyze(
1220     const parser::StructureConstructor &structure) {
1221   auto &parsedType{std::get<parser::DerivedTypeSpec>(structure.t)};
1222   parser::CharBlock typeName{std::get<parser::Name>(parsedType.t).source};
1223   if (parsedType.derivedTypeSpec == nullptr) {
1224     return std::nullopt;
1225   }
1226   const auto &spec{*parsedType.derivedTypeSpec};
1227   const Symbol &typeSymbol{spec.typeSymbol()};
1228   if (spec.scope() == nullptr ||
1229       !typeSymbol.has<semantics::DerivedTypeDetails>()) {
1230     return std::nullopt;  // error recovery
1231   }
1232   const auto &typeDetails{typeSymbol.get<semantics::DerivedTypeDetails>()};
1233   const Symbol *parentComponent{typeDetails.GetParentComponent(*spec.scope())};
1234 
1235   if (typeSymbol.attrs().test(semantics::Attr::ABSTRACT)) {  // C796
1236     if (auto *msg{Say(typeName,
1237             "ABSTRACT derived type '%s' may not be used in a "
1238             "structure constructor"_err_en_US,
1239             typeName)}) {
1240       msg->Attach(
1241           typeSymbol.name(), "Declaration of ABSTRACT derived type"_en_US);
1242     }
1243   }
1244 
1245   // This iterator traverses all of the components in the derived type and its
1246   // parents.  The symbols for whole parent components appear after their
1247   // own components and before the components of the types that extend them.
1248   // E.g., TYPE :: A; REAL X; END TYPE
1249   //       TYPE, EXTENDS(A) :: B; REAL Y; END TYPE
1250   // produces the component list X, A, Y.
1251   // The order is important below because a structure constructor can
1252   // initialize X or A by name, but not both.
1253   auto components{semantics::OrderedComponentIterator{spec}};
1254   auto nextAnonymous{components.begin()};
1255 
1256   std::set<parser::CharBlock> unavailable;
1257   bool anyKeyword{false};
1258   StructureConstructor result{spec};
1259   bool checkConflicts{true};  // until we hit one
1260 
1261   for (const auto &component :
1262       std::get<std::list<parser::ComponentSpec>>(structure.t)) {
1263     const parser::Expr &expr{
1264         std::get<parser::ComponentDataSource>(component.t).v.value()};
1265     parser::CharBlock source{expr.source};
1266     auto &messages{GetContextualMessages()};
1267     auto restorer{messages.SetLocation(source)};
1268     const Symbol *symbol{nullptr};
1269     MaybeExpr value{Analyze(expr)};
1270     std::optional<DynamicType> valueType{DynamicType::From(value)};
1271     if (const auto &kw{std::get<std::optional<parser::Keyword>>(component.t)}) {
1272       anyKeyword = true;
1273       source = kw->v.source;
1274       symbol = kw->v.symbol;
1275       if (symbol == nullptr) {
1276         auto componentIter{std::find_if(components.begin(), components.end(),
1277             [=](const Symbol *symbol) { return symbol->name() == source; })};
1278         if (componentIter != components.end()) {
1279           symbol = *componentIter;
1280         }
1281       }
1282       if (symbol == nullptr) {  // C7101
1283         Say(source,
1284             "Keyword '%s=' does not name a component of derived type '%s'"_err_en_US,
1285             source, typeName);
1286       }
1287     } else {
1288       if (anyKeyword) {  // C7100
1289         Say(source,
1290             "Value in structure constructor lacks a component name"_err_en_US);
1291         checkConflicts = false;  // stem cascade
1292       }
1293       // Here's a regrettably common extension of the standard: anonymous
1294       // initialization of parent components, e.g., T(PT(1)) rather than
1295       // T(1) or T(PT=PT(1)).
1296       if (nextAnonymous == components.begin() && parentComponent != nullptr &&
1297           valueType == DynamicType::From(*parentComponent) &&
1298           context().IsEnabled(parser::LanguageFeature::AnonymousParents)) {
1299         auto iter{
1300             std::find(components.begin(), components.end(), parentComponent)};
1301         if (iter != components.end()) {
1302           symbol = parentComponent;
1303           nextAnonymous = ++iter;
1304           if (context().ShouldWarn(parser::LanguageFeature::AnonymousParents)) {
1305             Say(source,
1306                 "Whole parent component '%s' in structure "
1307                 "constructor should not be anonymous"_en_US,
1308                 symbol->name());
1309           }
1310         }
1311       }
1312       while (symbol == nullptr && nextAnonymous != components.end()) {
1313         const Symbol *nextSymbol{*nextAnonymous++};
1314         if (!nextSymbol->test(Symbol::Flag::ParentComp)) {
1315           symbol = nextSymbol;
1316         }
1317       }
1318       if (symbol == nullptr) {
1319         Say(source, "Unexpected value in structure constructor"_err_en_US);
1320       }
1321     }
1322     if (symbol != nullptr) {
1323       if (checkConflicts) {
1324         auto componentIter{
1325             std::find(components.begin(), components.end(), symbol)};
1326         if (unavailable.find(symbol->name()) != unavailable.cend()) {
1327           // C797, C798
1328           Say(source,
1329               "Component '%s' conflicts with another component earlier in "
1330               "this structure constructor"_err_en_US,
1331               symbol->name());
1332         } else if (symbol->test(Symbol::Flag::ParentComp)) {
1333           // Make earlier components unavailable once a whole parent appears.
1334           for (auto it{components.begin()}; it != componentIter; ++it) {
1335             unavailable.insert((*it)->name());
1336           }
1337         } else {
1338           // Make whole parent components unavailable after any of their
1339           // constituents appear.
1340           for (auto it{componentIter}; it != components.end(); ++it) {
1341             if ((*it)->test(Symbol::Flag::ParentComp)) {
1342               unavailable.insert((*it)->name());
1343             }
1344           }
1345         }
1346       }
1347       unavailable.insert(symbol->name());
1348       if (value.has_value()) {
1349         if (symbol->has<semantics::ProcEntityDetails>()) {
1350           CHECK(IsPointer(*symbol));
1351         } else if (symbol->has<semantics::ObjectEntityDetails>()) {
1352           // C1594(4)
1353           const auto &innermost{context_.FindScope(expr.source)};
1354           if (const auto *pureProc{
1355                   semantics::FindPureProcedureContaining(&innermost)}) {
1356             if (const Symbol *
1357                 pointer{semantics::FindPointerComponent(*symbol)}) {
1358               if (const Symbol *
1359                   object{semantics::FindExternallyVisibleObject(
1360                       *value, *pureProc)}) {
1361                 if (auto *msg{Say(expr.source,
1362                         "Externally visible object '%s' must not be "
1363                         "associated with pointer component '%s' in a "
1364                         "PURE procedure"_err_en_US,
1365                         object->name(), pointer->name())}) {
1366                   msg->Attach(object->name(), "Object declaration"_en_US)
1367                       .Attach(pointer->name(), "Pointer declaration"_en_US);
1368                 }
1369               }
1370             }
1371           }
1372         } else if (symbol->has<semantics::TypeParamDetails>()) {
1373           Say(expr.source,
1374               "Type parameter '%s' may not appear as a component "
1375               "of a structure constructor"_err_en_US,
1376               symbol->name());
1377           continue;
1378         } else {
1379           Say(expr.source,
1380               "Component '%s' is neither a procedure pointer "
1381               "nor a data object"_err_en_US,
1382               symbol->name());
1383           continue;
1384         }
1385         if (IsPointer(*symbol)) {
1386           CheckPointerAssignment(messages, context_.intrinsics(), *symbol,
1387               *value);  // C7104, C7105
1388           result.Add(*symbol, Fold(GetFoldingContext(), std::move(*value)));
1389         } else if (MaybeExpr converted{
1390                        ConvertToType(*symbol, std::move(*value))}) {
1391           result.Add(*symbol, std::move(*converted));
1392         } else if (IsAllocatable(*symbol) &&
1393             std::holds_alternative<NullPointer>(value->u)) {
1394           // NULL() with no arguments allowed by 7.5.10 para 6 for ALLOCATABLE
1395         } else if (auto symType{DynamicType::From(symbol)}) {
1396           if (valueType.has_value()) {
1397             if (auto *msg{Say(expr.source,
1398                     "Value in structure constructor of type %s is "
1399                     "incompatible with component '%s' of type %s"_err_en_US,
1400                     valueType->AsFortran(), symbol->name(),
1401                     symType->AsFortran())}) {
1402               msg->Attach(symbol->name(), "Component declaration"_en_US);
1403             }
1404           } else {
1405             if (auto *msg{Say(expr.source,
1406                     "Value in structure constructor is incompatible with "
1407                     " component '%s' of type %s"_err_en_US,
1408                     symbol->name(), symType->AsFortran())}) {
1409               msg->Attach(symbol->name(), "Component declaration"_en_US);
1410             }
1411           }
1412         }
1413       }
1414     }
1415   }
1416 
1417   // Ensure that unmentioned component objects have default initializers.
1418   for (const Symbol *symbol : components) {
1419     if (!symbol->test(Symbol::Flag::ParentComp) &&
1420         unavailable.find(symbol->name()) == unavailable.cend() &&
1421         !IsAllocatable(*symbol)) {
1422       if (const auto *details{
1423               symbol->detailsIf<semantics::ObjectEntityDetails>()}) {
1424         if (details->init().has_value()) {
1425           result.Add(*symbol, common::Clone(*details->init()));
1426         } else {  // C799
1427           if (auto *msg{Say(typeName,
1428                   "Structure constructor lacks a value for "
1429                   "component '%s'"_err_en_US,
1430                   symbol->name())}) {
1431             msg->Attach(symbol->name(), "Absent component"_en_US);
1432           }
1433         }
1434       }
1435     }
1436   }
1437 
1438   return AsMaybeExpr(Expr<SomeDerived>{std::move(result)});
1439 }
1440 
GetPassInfo(const semantics::Symbol & symbol)1441 static const semantics::WithPassArg *GetPassInfo(
1442     const semantics::Symbol &symbol) {
1443   if (const auto *binding{symbol.detailsIf<semantics::ProcBindingDetails>()}) {
1444     return binding;
1445   } else if (const auto *proc{
1446                  symbol.detailsIf<semantics::ProcEntityDetails>()}) {
1447     return proc;
1448   } else {
1449     return nullptr;
1450   }
1451 }
1452 
AnalyzeProcedureComponentRef(const parser::ProcComponentRef & pcr,ActualArguments && arguments)1453 auto ExpressionAnalyzer::AnalyzeProcedureComponentRef(
1454     const parser::ProcComponentRef &pcr, ActualArguments &&arguments)
1455     -> std::optional<CalleeAndArguments> {
1456   const parser::StructureComponent &sc{pcr.v.thing};
1457   const auto &name{sc.component.source};
1458   if (MaybeExpr base{Analyze(sc.base)}) {
1459     if (Symbol * sym{sc.component.symbol}) {
1460       if (auto *dtExpr{UnwrapExpr<Expr<SomeDerived>>(*base)}) {
1461         const semantics::DerivedTypeSpec *dtSpec{nullptr};
1462         if (std::optional<DynamicType> dtDyTy{dtExpr->GetType()}) {
1463           if (!dtDyTy->IsUnlimitedPolymorphic()) {
1464             dtSpec = &dtDyTy->GetDerivedTypeSpec();
1465           }
1466         }
1467         if (dtSpec != nullptr && dtSpec->scope() != nullptr) {
1468           if (std::optional<DataRef> dataRef{
1469                   ExtractDataRef(std::move(*dtExpr))}) {
1470             if (auto component{CreateComponent(
1471                     std::move(*dataRef), *sym, *dtSpec->scope())}) {
1472               if (const auto *pass{GetPassInfo(*sym)}) {
1473                 if (auto passIndex{pass->passIndex()}) {
1474                   // There's a PASS argument by which the base of the procedure
1475                   // component reference must be passed.  Append or insert it to
1476                   // the list of effective arguments.
1477                   auto iter{arguments.begin()};
1478                   int at{0};
1479                   while (iter < arguments.end() && at < *passIndex) {
1480                     if (iter->has_value() && (*iter)->keyword.has_value()) {
1481                       iter = arguments.end();
1482                       break;
1483                     }
1484                     ++iter;
1485                     ++at;
1486                   }
1487                   ActualArgument passed{AsGenericExpr(std::move(*dtExpr))};
1488                   if (iter == arguments.end() && pass->passName().has_value()) {
1489                     passed.keyword = *pass->passName();
1490                   }
1491                   arguments.emplace(iter, std::move(passed));
1492                 }
1493               }
1494               return CalleeAndArguments{
1495                   ProcedureDesignator{std::move(*component)},
1496                   std::move(arguments)};
1497             } else {
1498               Say(name,
1499                   "Procedure component is not in scope of derived TYPE(%s)"_err_en_US,
1500                   dtSpec->typeSymbol().name());
1501             }
1502           } else {
1503             Say(name,
1504                 "Base of procedure component reference must be a data reference"_err_en_US);
1505           }
1506         }
1507       } else {
1508         Say(name,
1509             "Base of procedure component reference is not a derived type object"_err_en_US);
1510       }
1511     }
1512   }
1513   CHECK(context_.messages().AnyFatalError());
1514   return std::nullopt;
1515 }
1516 
1517 // Can actual be argument associated with dummy?
CheckCompatibleArgument(bool isElemental,const ActualArgument & actual,const characteristics::DummyArgument & dummy)1518 static bool CheckCompatibleArgument(bool isElemental,
1519     const ActualArgument &actual, const characteristics::DummyArgument &dummy) {
1520   return std::visit(
1521       common::visitors{
1522           [&](const characteristics::DummyDataObject &x) {
1523             characteristics::TypeAndShape dummyTypeAndShape{x.type};
1524             if (!isElemental && actual.Rank() != dummyTypeAndShape.Rank()) {
1525               return false;
1526             } else if (auto actualType{actual.GetType()}) {
1527               return dummyTypeAndShape.type().IsTkCompatibleWith(*actualType);
1528             } else {
1529               return false;
1530             }
1531           },
1532           [&](const characteristics::DummyProcedure &) {
1533             const auto *expr{actual.UnwrapExpr()};
1534             return expr && IsProcedurePointer(*expr);
1535           },
1536           [&](const characteristics::AlternateReturn &) {
1537             return actual.isAlternateReturn;
1538           },
1539       },
1540       dummy.u);
1541 }
1542 
1543 // Are the actual arguments compatible with the dummy arguments of procedure?
CheckCompatibleArguments(const characteristics::Procedure & procedure,const ActualArguments & actuals)1544 static bool CheckCompatibleArguments(
1545     const characteristics::Procedure &procedure,
1546     const ActualArguments &actuals) {
1547   bool isElemental{procedure.IsElemental()};
1548   const auto &dummies{procedure.dummyArguments};
1549   CHECK(dummies.size() == actuals.size());
1550   for (std::size_t i{0}; i < dummies.size(); ++i) {
1551     const characteristics::DummyArgument &dummy{dummies[i]};
1552     const std::optional<ActualArgument> &actual{actuals[i]};
1553     if (actual && !CheckCompatibleArgument(isElemental, *actual, dummy)) {
1554       return false;
1555     }
1556   }
1557   return true;
1558 }
1559 
ResolveGeneric(const Symbol & symbol,ActualArguments & actuals)1560 const Symbol *ExpressionAnalyzer::ResolveGeneric(
1561     const Symbol &symbol, ActualArguments &actuals) {
1562   const Symbol *elemental{nullptr};  // matching elemental specific proc
1563   const auto &details{symbol.get<semantics::GenericDetails>()};
1564   for (const Symbol *specific : details.specificProcs()) {
1565     if (std::optional<characteristics::Procedure> procedure{
1566             characteristics::Procedure::Characterize(
1567                 ProcedureDesignator{*specific}, context_.intrinsics())}) {
1568       parser::Messages buffer;
1569       parser::ContextualMessages messages{
1570           context_.foldingContext().messages().at(), &buffer};
1571       FoldingContext localContext{context_.foldingContext(), messages};
1572       ActualArguments localActuals{actuals};
1573       if (CheckExplicitInterface(*procedure, localActuals, localContext) &&
1574           CheckCompatibleArguments(*procedure, localActuals)) {
1575         if (!procedure->IsElemental()) {
1576           return specific;  // takes priority over elemental match
1577         }
1578         elemental = specific;
1579       }
1580     }
1581   }
1582   if (elemental) {
1583     return elemental;
1584   } else {
1585     Say("No specific procedure of generic '%s' matches the actual arguments"_err_en_US,
1586         symbol.name());
1587     return nullptr;
1588   }
1589 }
1590 
GetCalleeAndArguments(const parser::ProcedureDesignator & pd,ActualArguments && arguments,bool isSubroutine)1591 auto ExpressionAnalyzer::GetCalleeAndArguments(
1592     const parser::ProcedureDesignator &pd, ActualArguments &&arguments,
1593     bool isSubroutine) -> std::optional<CalleeAndArguments> {
1594   return std::visit(
1595       common::visitors{
1596           [&](const parser::Name &n) -> std::optional<CalleeAndArguments> {
1597             const Symbol *symbol{n.symbol};
1598             if (context_.HasError(symbol)) {
1599               return std::nullopt;
1600             }
1601             const Symbol &ultimate{symbol->GetUltimate()};
1602             if (ultimate.attrs().test(semantics::Attr::INTRINSIC)) {
1603               if (std::optional<SpecificCall> specificCall{
1604                       context_.intrinsics().Probe(
1605                           CallCharacteristics{n.source, isSubroutine},
1606                           arguments, GetFoldingContext())}) {
1607                 return CalleeAndArguments{ProcedureDesignator{std::move(
1608                                               specificCall->specificIntrinsic)},
1609                     std::move(specificCall->arguments)};
1610               } else {
1611                 return std::nullopt;
1612               }
1613             }
1614             CheckForBadRecursion(n.source, ultimate);
1615             if (ultimate.has<semantics::GenericDetails>()) {
1616               symbol = ResolveGeneric(ultimate, arguments);
1617             }
1618             if (symbol) {
1619               return CalleeAndArguments{
1620                   ProcedureDesignator{*symbol}, std::move(arguments)};
1621             } else {
1622               return std::nullopt;
1623             }
1624           },
1625           [&](const parser::ProcComponentRef &pcr) {
1626             return AnalyzeProcedureComponentRef(pcr, std::move(arguments));
1627           },
1628       },
1629       pd.u);
1630 }
1631 
CheckForBadRecursion(parser::CharBlock callSite,const semantics::Symbol & proc)1632 void ExpressionAnalyzer::CheckForBadRecursion(
1633     parser::CharBlock callSite, const semantics::Symbol &proc) {
1634   if (const auto *scope{proc.scope()}) {
1635     if (scope->sourceRange().Contains(callSite)) {
1636       parser::Message *msg{nullptr};
1637       if (proc.attrs().test(semantics::Attr::NON_RECURSIVE)) {  // 15.6.2.1(3)
1638         msg = Say("NON_RECURSIVE procedure '%s' cannot call itself"_err_en_US,
1639             callSite);
1640       } else if (IsAssumedLengthCharacterFunction(proc)) {  // 15.6.2.1(3)
1641         msg = Say(
1642             "Assumed-length CHARACTER(*) function '%s' cannot call itself"_err_en_US,
1643             callSite);
1644       }
1645       if (msg != nullptr) {
1646         msg->Attach(proc.name(), "definition of '%s'"_en_US, callSite);
1647       }
1648     }
1649   }
1650 }
1651 
AssumedTypeDummy(const A & x)1652 template<typename A> static const Symbol *AssumedTypeDummy(const A &x) {
1653   if (const auto *designator{
1654           std::get_if<common::Indirection<parser::Designator>>(&x.u)}) {
1655     if (const auto *dataRef{
1656             std::get_if<parser::DataRef>(&designator->value().u)}) {
1657       if (const auto *name{std::get_if<parser::Name>(&dataRef->u)}) {
1658         if (const Symbol * symbol{name->symbol}) {
1659           if (const auto *type{symbol->GetType()}) {
1660             if (type->category() == semantics::DeclTypeSpec::TypeStar) {
1661               return symbol;
1662             }
1663           }
1664         }
1665       }
1666     }
1667   }
1668   return nullptr;
1669 }
1670 
AnalyzeActualArgument(const parser::Expr & expr)1671 std::optional<ActualArgument> ExpressionAnalyzer::AnalyzeActualArgument(
1672     const parser::Expr &expr) {
1673   if (const Symbol * assumedTypeDummy{AssumedTypeDummy(expr)}) {
1674     return ActualArgument{ActualArgument::AssumedType{*assumedTypeDummy}};
1675   } else if (MaybeExpr argExpr{Analyze(expr)}) {
1676     Expr<SomeType> x{Fold(GetFoldingContext(), std::move(*argExpr))};
1677     if (const auto *proc{std::get_if<ProcedureDesignator>(&x.u)}) {
1678       if (!std::holds_alternative<SpecificIntrinsic>(proc->u) &&
1679           proc->IsElemental()) {  // C1533
1680         Say(expr.source,
1681             "Non-intrinsic ELEMENTAL procedure cannot be passed as argument"_err_en_US);
1682       }
1683     }
1684     if (auto coarrayRef{ExtractCoarrayRef(x)}) {
1685       const Symbol &coarray{coarrayRef->GetLastSymbol()};
1686       if (const semantics::DeclTypeSpec * type{coarray.GetType()}) {
1687         if (const semantics::DerivedTypeSpec * derived{type->AsDerived()}) {
1688           if (auto ptr{semantics::FindPointerUltimateComponent(*derived)}) {
1689             if (auto *msg{Say(expr.source,
1690                     "Coindexed object '%s' with POINTER ultimate component '%s' cannot be passed as argument"_err_en_US,
1691                     coarray.name(), (*ptr)->name())}) {
1692               msg->Attach((*ptr)->name(),
1693                   "Declaration of POINTER '%s' component of %s"_en_US,
1694                   (*ptr)->name(), type->AsFortran());
1695             }
1696           }
1697         }
1698       }
1699     }
1700     return ActualArgument{std::move(x)};
1701   } else {
1702     return std::nullopt;
1703   }
1704 }
1705 
Analyze(const parser::FunctionReference & funcRef)1706 MaybeExpr ExpressionAnalyzer::Analyze(
1707     const parser::FunctionReference &funcRef) {
1708   return AnalyzeCall(funcRef.v, false);
1709 }
1710 
Analyze(const parser::CallStmt & call)1711 void ExpressionAnalyzer::Analyze(const parser::CallStmt &call) {
1712   AnalyzeCall(call.v, true);
1713 }
1714 
AnalyzeCall(const parser::Call & call,bool isSubroutine)1715 MaybeExpr ExpressionAnalyzer::AnalyzeCall(
1716     const parser::Call &call, bool isSubroutine) {
1717   auto save{GetContextualMessages().SetLocation(call.source)};
1718   if (auto arguments{AnalyzeArguments(call, isSubroutine)}) {
1719     // TODO: map non-intrinsic generic procedure to specific procedure
1720     if (std::optional<CalleeAndArguments> callee{
1721             GetCalleeAndArguments(std::get<parser::ProcedureDesignator>(call.t),
1722                 std::move(*arguments), isSubroutine)}) {
1723       if (isSubroutine) {
1724         CheckCall(call.source, callee->procedureDesignator, callee->arguments);
1725         // TODO: Package the subroutine call as an expr in the parse tree
1726       } else {
1727         return MakeFunctionRef(call.source,
1728             std::move(callee->procedureDesignator),
1729             std::move(callee->arguments));
1730       }
1731     }
1732   }
1733   return std::nullopt;
1734 }
1735 
AnalyzeArguments(const parser::Call & call,bool isSubroutine)1736 std::optional<ActualArguments> ExpressionAnalyzer::AnalyzeArguments(
1737     const parser::Call &call, bool isSubroutine) {
1738   evaluate::ActualArguments arguments;
1739   // TODO: C1002: Allow a whole assumed-size array to appear if the dummy
1740   // argument would accept it.  Handle by special-casing the context
1741   // ActualArg -> Variable -> Designator.
1742   // TODO: Actual arguments that are procedures and procedure pointers need to
1743   // be detected and represented (they're not expressions).
1744   // TODO: C1534: Don't allow a "restricted" specific intrinsic to be passed.
1745   // TODO: map non-intrinsic generic procedure to specific procedure
1746   for (const auto &arg : std::get<std::list<parser::ActualArgSpec>>(call.t)) {
1747     std::optional<evaluate::ActualArgument> actual;
1748     std::visit(
1749         common::visitors{
1750             [&](const common::Indirection<parser::Expr> &x) {
1751               // TODO: Distinguish & handle procedure name and
1752               // proc-component-ref
1753               actual = AnalyzeActualArgument(x.value());
1754             },
1755             [&](const parser::AltReturnSpec &) {
1756               if (!isSubroutine) {
1757                 Say("alternate return specification may not appear on function reference"_err_en_US);
1758               }
1759             },
1760             [&](const parser::ActualArg::PercentRef &) {
1761               Say("TODO: %REF() argument"_err_en_US);
1762             },
1763             [&](const parser::ActualArg::PercentVal &) {
1764               Say("TODO: %VAL() argument"_err_en_US);
1765             },
1766         },
1767         std::get<parser::ActualArg>(arg.t).u);
1768     if (actual.has_value()) {
1769       arguments.emplace_back(std::move(actual));
1770       if (const auto &argKW{std::get<std::optional<parser::Keyword>>(arg.t)}) {
1771         arguments.back()->keyword = argKW->v.source;
1772       }
1773     } else {
1774       return std::nullopt;
1775     }
1776   }
1777   return arguments;
1778 }
1779 
IsExternalCalledImplicitly(parser::CharBlock callSite,const ProcedureDesignator & proc)1780 static bool IsExternalCalledImplicitly(
1781     parser::CharBlock callSite, const ProcedureDesignator &proc) {
1782   if (const auto *symbol{proc.GetSymbol()}) {
1783     return symbol->has<semantics::SubprogramDetails>() &&
1784         symbol->owner().IsGlobal() &&
1785         !symbol->scope()->sourceRange().Contains(callSite);
1786   } else {
1787     return false;
1788   }
1789 }
1790 
CheckCall(parser::CharBlock callSite,const ProcedureDesignator & proc,ActualArguments & arguments)1791 std::optional<characteristics::Procedure> ExpressionAnalyzer::CheckCall(
1792     parser::CharBlock callSite, const ProcedureDesignator &proc,
1793     ActualArguments &arguments) {
1794   auto chars{
1795       characteristics::Procedure::Characterize(proc, context_.intrinsics())};
1796   if (chars.has_value()) {
1797     bool treatExternalAsImplicit{IsExternalCalledImplicitly(callSite, proc)};
1798     if (treatExternalAsImplicit && !chars->CanBeCalledViaImplicitInterface()) {
1799       Say(callSite,
1800           "References to the procedure '%s' require an explicit interface"_en_US,
1801           DEREF(proc.GetSymbol()).name());
1802     }
1803     CheckArguments(
1804         *chars, arguments, GetFoldingContext(), treatExternalAsImplicit);
1805   }
1806   return chars;
1807 }
1808 
1809 // Unary operations
1810 
Analyze(const parser::Expr::Parentheses & x)1811 MaybeExpr ExpressionAnalyzer::Analyze(const parser::Expr::Parentheses &x) {
1812   if (MaybeExpr operand{Analyze(x.v.value())}) {
1813     if (const semantics::Symbol * symbol{GetLastSymbol(*operand)}) {
1814       if (const semantics::Symbol * result{FindFunctionResult(*symbol)}) {
1815         if (semantics::IsProcedurePointer(*result)) {
1816           Say("A function reference that returns a procedure "
1817               "pointer may not be parenthesized"_err_en_US);  // C1003
1818         }
1819       }
1820     }
1821     return std::visit(
1822         [&](auto &&x) -> MaybeExpr {
1823           using xTy = std::decay_t<decltype(x)>;
1824           if constexpr (common::HasMember<xTy, TypelessExpression>) {
1825             return operand;  // ignore parentheses around typeless
1826           } else if constexpr (std::is_same_v<xTy, Expr<SomeDerived>>) {
1827             return operand;  // ignore parentheses around derived type
1828           } else {
1829             return std::visit(
1830                 [](auto &&y) -> MaybeExpr {
1831                   using Ty = ResultType<decltype(y)>;
1832                   return {AsGenericExpr(Parentheses<Ty>{std::move(y)})};
1833                 },
1834                 std::move(x.u));
1835           }
1836         },
1837         std::move(operand->u));
1838   }
1839   return std::nullopt;
1840 }
1841 
Analyze(const parser::Expr::UnaryPlus & x)1842 MaybeExpr ExpressionAnalyzer::Analyze(const parser::Expr::UnaryPlus &x) {
1843   MaybeExpr value{Analyze(x.v.value())};
1844   if (value.has_value()) {
1845     if (!std::visit(
1846             [&](const auto &y) {
1847               using yTy = std::decay_t<decltype(y)>;
1848               if constexpr (std::is_same_v<yTy, BOZLiteralConstant>) {
1849                 // allow and ignore +Z'1', it's harmless
1850                 return true;
1851               } else if constexpr (!IsNumericCategoryExpr<yTy>()) {
1852                 Say("Operand of unary + must have numeric type"_err_en_US);
1853                 return false;
1854               } else {
1855                 return true;
1856               }
1857             },
1858             value->u)) {
1859       return std::nullopt;
1860     }
1861   }
1862   return value;
1863 }
1864 
Analyze(const parser::Expr::Negate & x)1865 MaybeExpr ExpressionAnalyzer::Analyze(const parser::Expr::Negate &x) {
1866   if (MaybeExpr operand{Analyze(x.v.value())}) {
1867     return Negation(GetContextualMessages(), std::move(*operand));
1868   }
1869   return std::nullopt;
1870 }
1871 
Analyze(const parser::Expr::NOT & x)1872 MaybeExpr ExpressionAnalyzer::Analyze(const parser::Expr::NOT &x) {
1873   if (MaybeExpr operand{Analyze(x.v.value())}) {
1874     return std::visit(
1875         common::visitors{
1876             [](Expr<SomeLogical> &&lx) -> MaybeExpr {
1877               return {AsGenericExpr(LogicalNegation(std::move(lx)))};
1878             },
1879             [&](auto &&) -> MaybeExpr {
1880               Say("Operand of .NOT. must be LOGICAL"_err_en_US);
1881               return std::nullopt;
1882             },
1883         },
1884         std::move(operand->u));
1885   }
1886   return std::nullopt;
1887 }
1888 
Analyze(const parser::Expr::PercentLoc & x)1889 MaybeExpr ExpressionAnalyzer::Analyze(const parser::Expr::PercentLoc &x) {
1890   // Represent %LOC() exactly as if it had been a call to the LOC() extension
1891   // intrinsic function.
1892   // Use the actual source for the name of the call for error reporting.
1893   std::optional<ActualArgument> arg;
1894   if (const Symbol * assumedTypeDummy{AssumedTypeDummy(x.v.value())}) {
1895     arg = ActualArgument{ActualArgument::AssumedType{*assumedTypeDummy}};
1896   } else if (MaybeExpr argExpr{Analyze(x.v.value())}) {
1897     arg = ActualArgument{std::move(*argExpr)};
1898   } else {
1899     return std::nullopt;
1900   }
1901   parser::CharBlock at{GetContextualMessages().at()};
1902   CHECK(at.size() >= 4);
1903   parser::CharBlock loc{at.begin() + 1, 3};
1904   CHECK(loc == "loc");
1905   return MakeFunctionRef(loc, ActualArguments{std::move(*arg)});
1906 }
1907 
Analyze(const parser::Expr::DefinedUnary &)1908 MaybeExpr ExpressionAnalyzer::Analyze(const parser::Expr::DefinedUnary &) {
1909   Say("TODO: DefinedUnary unimplemented"_err_en_US);
1910   return std::nullopt;
1911 }
1912 
1913 // Binary (dyadic) operations
1914 
1915 // TODO: check defined operators for illegal intrinsic operator cases
1916 template<template<typename> class OPR, typename PARSED>
BinaryOperationHelper(ExpressionAnalyzer & context,const PARSED & x)1917 MaybeExpr BinaryOperationHelper(ExpressionAnalyzer &context, const PARSED &x) {
1918   if (auto both{common::AllPresent(context.Analyze(std::get<0>(x.t).value()),
1919           context.Analyze(std::get<1>(x.t).value()))}) {
1920     ConformabilityCheck(context.GetContextualMessages(), std::get<0>(*both),
1921         std::get<1>(*both));
1922     return NumericOperation<OPR>(context.GetContextualMessages(),
1923         std::get<0>(std::move(*both)), std::get<1>(std::move(*both)),
1924         context.GetDefaultKind(TypeCategory::Real));
1925   }
1926   return std::nullopt;
1927 }
1928 
Analyze(const parser::Expr::Power & x)1929 MaybeExpr ExpressionAnalyzer::Analyze(const parser::Expr::Power &x) {
1930   return BinaryOperationHelper<Power>(*this, x);
1931 }
1932 
Analyze(const parser::Expr::Multiply & x)1933 MaybeExpr ExpressionAnalyzer::Analyze(const parser::Expr::Multiply &x) {
1934   return BinaryOperationHelper<Multiply>(*this, x);
1935 }
1936 
Analyze(const parser::Expr::Divide & x)1937 MaybeExpr ExpressionAnalyzer::Analyze(const parser::Expr::Divide &x) {
1938   return BinaryOperationHelper<Divide>(*this, x);
1939 }
1940 
Analyze(const parser::Expr::Add & x)1941 MaybeExpr ExpressionAnalyzer::Analyze(const parser::Expr::Add &x) {
1942   return BinaryOperationHelper<Add>(*this, x);
1943 }
1944 
Analyze(const parser::Expr::Subtract & x)1945 MaybeExpr ExpressionAnalyzer::Analyze(const parser::Expr::Subtract &x) {
1946   return BinaryOperationHelper<Subtract>(*this, x);
1947 }
1948 
Analyze(const parser::Expr::ComplexConstructor & x)1949 MaybeExpr ExpressionAnalyzer::Analyze(
1950     const parser::Expr::ComplexConstructor &x) {
1951   auto re{Analyze(std::get<0>(x.t).value())};
1952   auto im{Analyze(std::get<1>(x.t).value())};
1953   if (re.has_value() && im.has_value()) {
1954     ConformabilityCheck(GetContextualMessages(), *re, *im);
1955   }
1956   return AsMaybeExpr(ConstructComplex(GetContextualMessages(), std::move(re),
1957       std::move(im), GetDefaultKind(TypeCategory::Real)));
1958 }
1959 
Analyze(const parser::Expr::Concat & x)1960 MaybeExpr ExpressionAnalyzer::Analyze(const parser::Expr::Concat &x) {
1961   if (auto both{common::AllPresent(Analyze(std::get<0>(x.t).value()),
1962           Analyze(std::get<1>(x.t).value()))}) {
1963     ConformabilityCheck(
1964         GetContextualMessages(), std::get<0>(*both), std::get<1>(*both));
1965     return std::visit(
1966         common::visitors{
1967             [&](Expr<SomeCharacter> &&cx, Expr<SomeCharacter> &&cy) {
1968               return std::visit(
1969                   [&](auto &&cxk, auto &&cyk) -> MaybeExpr {
1970                     using Ty = ResultType<decltype(cxk)>;
1971                     if constexpr (std::is_same_v<Ty,
1972                                       ResultType<decltype(cyk)>>) {
1973                       return {AsGenericExpr(
1974                           Concat<Ty::kind>{std::move(cxk), std::move(cyk)})};
1975                     } else {
1976                       Say("Operands of // must be the same kind of CHARACTER"_err_en_US);
1977                       return std::nullopt;
1978                     }
1979                   },
1980                   std::move(cx.u), std::move(cy.u));
1981             },
1982             [&](auto &&, auto &&) -> MaybeExpr {
1983               Say("Operands of // must be CHARACTER"_err_en_US);
1984               return std::nullopt;
1985             },
1986         },
1987         std::move(std::get<0>(*both).u), std::move(std::get<1>(*both).u));
1988   }
1989   return std::nullopt;
1990 }
1991 
1992 // TODO: check defined operators for illegal intrinsic operator cases
1993 template<typename PARSED>
RelationHelper(ExpressionAnalyzer & context,RelationalOperator opr,const PARSED & x)1994 MaybeExpr RelationHelper(
1995     ExpressionAnalyzer &context, RelationalOperator opr, const PARSED &x) {
1996   if (auto both{common::AllPresent(context.Analyze(std::get<0>(x.t).value()),
1997           context.Analyze(std::get<1>(x.t).value()))}) {
1998     ConformabilityCheck(context.GetContextualMessages(), std::get<0>(*both),
1999         std::get<1>(*both));
2000     return AsMaybeExpr(Relate(context.GetContextualMessages(), opr,
2001         std::get<0>(std::move(*both)), std::get<1>(std::move(*both))));
2002   }
2003   return std::nullopt;
2004 }
2005 
Analyze(const parser::Expr::LT & x)2006 MaybeExpr ExpressionAnalyzer::Analyze(const parser::Expr::LT &x) {
2007   return RelationHelper(*this, RelationalOperator::LT, x);
2008 }
2009 
Analyze(const parser::Expr::LE & x)2010 MaybeExpr ExpressionAnalyzer::Analyze(const parser::Expr::LE &x) {
2011   return RelationHelper(*this, RelationalOperator::LE, x);
2012 }
2013 
Analyze(const parser::Expr::EQ & x)2014 MaybeExpr ExpressionAnalyzer::Analyze(const parser::Expr::EQ &x) {
2015   return RelationHelper(*this, RelationalOperator::EQ, x);
2016 }
2017 
Analyze(const parser::Expr::NE & x)2018 MaybeExpr ExpressionAnalyzer::Analyze(const parser::Expr::NE &x) {
2019   return RelationHelper(*this, RelationalOperator::NE, x);
2020 }
2021 
Analyze(const parser::Expr::GE & x)2022 MaybeExpr ExpressionAnalyzer::Analyze(const parser::Expr::GE &x) {
2023   return RelationHelper(*this, RelationalOperator::GE, x);
2024 }
2025 
Analyze(const parser::Expr::GT & x)2026 MaybeExpr ExpressionAnalyzer::Analyze(const parser::Expr::GT &x) {
2027   return RelationHelper(*this, RelationalOperator::GT, x);
2028 }
2029 
2030 // TODO: check defined operators for illegal intrinsic operator cases
2031 template<typename PARSED>
LogicalHelper(ExpressionAnalyzer & context,LogicalOperator opr,const PARSED & x)2032 MaybeExpr LogicalHelper(
2033     ExpressionAnalyzer &context, LogicalOperator opr, const PARSED &x) {
2034   if (auto both{common::AllPresent(context.Analyze(std::get<0>(x.t).value()),
2035           context.Analyze(std::get<1>(x.t).value()))}) {
2036     return std::visit(
2037         common::visitors{
2038             [&](Expr<SomeLogical> &&lx, Expr<SomeLogical> &&ly) -> MaybeExpr {
2039               ConformabilityCheck(context.GetContextualMessages(), lx, ly);
2040               return {AsGenericExpr(
2041                   BinaryLogicalOperation(opr, std::move(lx), std::move(ly)))};
2042             },
2043             [&](auto &&, auto &&) -> MaybeExpr {
2044               // TODO: extension: INTEGER and typeless operands
2045               // ifort and PGI accept them if not overridden
2046               // need to define IAND, IOR, IEOR intrinsic representation
2047               context.Say(
2048                   "operands to LOGICAL operation must be LOGICAL"_err_en_US);
2049               return {};
2050             },
2051         },
2052         std::move(std::get<0>(*both).u), std::move(std::get<1>(*both).u));
2053   }
2054   return std::nullopt;
2055 }
2056 
Analyze(const parser::Expr::AND & x)2057 MaybeExpr ExpressionAnalyzer::Analyze(const parser::Expr::AND &x) {
2058   return LogicalHelper(*this, LogicalOperator::And, x);
2059 }
2060 
Analyze(const parser::Expr::OR & x)2061 MaybeExpr ExpressionAnalyzer::Analyze(const parser::Expr::OR &x) {
2062   return LogicalHelper(*this, LogicalOperator::Or, x);
2063 }
2064 
Analyze(const parser::Expr::EQV & x)2065 MaybeExpr ExpressionAnalyzer::Analyze(const parser::Expr::EQV &x) {
2066   return LogicalHelper(*this, LogicalOperator::Eqv, x);
2067 }
2068 
Analyze(const parser::Expr::NEQV & x)2069 MaybeExpr ExpressionAnalyzer::Analyze(const parser::Expr::NEQV &x) {
2070   return LogicalHelper(*this, LogicalOperator::Neqv, x);
2071 }
2072 
Analyze(const parser::Expr::XOR & x)2073 MaybeExpr ExpressionAnalyzer::Analyze(const parser::Expr::XOR &x) {
2074   return LogicalHelper(*this, LogicalOperator::Neqv, x);
2075 }
2076 
Analyze(const parser::Expr::DefinedBinary &)2077 MaybeExpr ExpressionAnalyzer::Analyze(const parser::Expr::DefinedBinary &) {
2078   Say("TODO: DefinedBinary unimplemented"_err_en_US);
2079   return std::nullopt;
2080 }
2081 
CheckFuncRefToArrayElementRefHasSubscripts(semantics::SemanticsContext & context,const parser::FunctionReference & funcRef)2082 static void CheckFuncRefToArrayElementRefHasSubscripts(
2083     semantics::SemanticsContext &context,
2084     const parser::FunctionReference &funcRef) {
2085   // Emit message if the function reference fix will end-up an array element
2086   // reference with no subscripts because it will not be possible to later tell
2087   // the difference in expressions between empty subscript list due to bad
2088   // subscripts error recovery or because the user did not put any.
2089   if (std::get<std::list<parser::ActualArgSpec>>(funcRef.v.t).empty()) {
2090     auto &proc{std::get<parser::ProcedureDesignator>(funcRef.v.t)};
2091     const auto *name{std::get_if<parser::Name>(&proc.u)};
2092     if (name == nullptr) {
2093       name = &std::get<parser::ProcComponentRef>(proc.u).v.thing.component;
2094     }
2095     auto &msg{context.Say(funcRef.v.source,
2096         "Reference to array '%s' with empty subscript list"_err_en_US,
2097         name->source)};
2098     if (name->symbol) {
2099       if (semantics::IsFunctionResultWithSameNameAsFunction(*name->symbol)) {
2100         msg.Attach(name->source,
2101             "A result variable must be declared with RESULT to allow recursive "
2102             "function calls"_en_US);
2103       } else {
2104         msg.Attach(
2105             name->symbol->name(), "'%s' was declared here"_en_US, name->source);
2106       }
2107     }
2108   }
2109 }
2110 
2111 // Converts, if appropriate, an original misparse of ambiguous syntax like
2112 // A(1) as a function reference into an array reference or a structure
2113 // constructor.
2114 template<typename... A>
FixMisparsedFunctionReference(semantics::SemanticsContext & context,const std::variant<A...> & constU)2115 static void FixMisparsedFunctionReference(
2116     semantics::SemanticsContext &context, const std::variant<A...> &constU) {
2117   // The parse tree is updated in situ when resolving an ambiguous parse.
2118   using uType = std::decay_t<decltype(constU)>;
2119   auto &u{const_cast<uType &>(constU)};
2120   if (auto *func{
2121           std::get_if<common::Indirection<parser::FunctionReference>>(&u)}) {
2122     parser::FunctionReference &funcRef{func->value()};
2123     auto &proc{std::get<parser::ProcedureDesignator>(funcRef.v.t)};
2124     if (Symbol *
2125         origSymbol{std::visit(
2126             common::visitors{
2127                 [&](parser::Name &name) { return name.symbol; },
2128                 [&](parser::ProcComponentRef &pcr) {
2129                   return pcr.v.thing.component.symbol;
2130                 },
2131             },
2132             proc.u)}) {
2133       Symbol &symbol{origSymbol->GetUltimate()};
2134       if (symbol.has<semantics::ObjectEntityDetails>() ||
2135           symbol.has<semantics::AssocEntityDetails>()) {
2136         // Note that expression in AssocEntityDetails cannot be a procedure
2137         // pointer as per C1105 so this cannot be a function reference.
2138         if constexpr (common::HasMember<common::Indirection<parser::Designator>,
2139                           uType>) {
2140           CheckFuncRefToArrayElementRefHasSubscripts(context, funcRef);
2141           u = common::Indirection{funcRef.ConvertToArrayElementRef()};
2142         } else {
2143           DIE("can't fix misparsed function as array reference");
2144         }
2145       } else if (const auto *name{std::get_if<parser::Name>(&proc.u)}) {
2146         // A procedure component reference can't be a structure
2147         // constructor; only check calls to bare names.
2148         const Symbol *derivedType{nullptr};
2149         if (symbol.has<semantics::DerivedTypeDetails>()) {
2150           derivedType = &symbol;
2151         } else if (const auto *generic{
2152                        symbol.detailsIf<semantics::GenericDetails>()}) {
2153           derivedType = generic->derivedType();
2154         }
2155         if (derivedType != nullptr) {
2156           if constexpr (common::HasMember<parser::StructureConstructor,
2157                             uType>) {
2158             auto &scope{context.FindScope(name->source)};
2159             const semantics::DeclTypeSpec &type{
2160                 semantics::FindOrInstantiateDerivedType(scope,
2161                     semantics::DerivedTypeSpec{
2162                         origSymbol->name(), *derivedType},
2163                     context)};
2164             u = funcRef.ConvertToStructureConstructor(type.derivedTypeSpec());
2165           } else {
2166             DIE("can't fix misparsed function as structure constructor");
2167           }
2168         }
2169       }
2170     }
2171   }
2172 }
2173 
2174 // Common handling of parser::Expr and parser::Variable
2175 template<typename PARSED>
ExprOrVariable(const PARSED & x)2176 MaybeExpr ExpressionAnalyzer::ExprOrVariable(const PARSED &x) {
2177   if (!x.typedExpr) {  // not yet analyzed
2178     FixMisparsedFunctionReference(context_, x.u);
2179     MaybeExpr result;
2180     if constexpr (std::is_same_v<PARSED, parser::Expr>) {
2181       // Analyze the expression in a specified source position context for
2182       // better error reporting.
2183       auto save{GetContextualMessages().SetLocation(x.source)};
2184       result = Analyze(x.u);
2185       result = Fold(GetFoldingContext(), std::move(result));
2186     } else {
2187       result = Analyze(x.u);
2188     }
2189     x.typedExpr.reset(new GenericExprWrapper{std::move(result)});
2190     if (!x.typedExpr->v.has_value()) {
2191       if (!context_.AnyFatalError()) {
2192 #if DUMP_ON_FAILURE
2193         parser::DumpTree(std::cout << "Expression analysis failed on: ", x);
2194 #elif CRASH_ON_FAILURE
2195         common::die("Expression analysis failed without emitting an error");
2196 #endif
2197       }
2198       fatalErrors_ = true;
2199     }
2200   }
2201   return x.typedExpr->v;
2202 }
2203 
Analyze(const parser::Expr & expr)2204 MaybeExpr ExpressionAnalyzer::Analyze(const parser::Expr &expr) {
2205   return ExprOrVariable(expr);
2206 }
2207 
Analyze(const parser::Variable & variable)2208 MaybeExpr ExpressionAnalyzer::Analyze(const parser::Variable &variable) {
2209   return ExprOrVariable(variable);
2210 }
2211 
AnalyzeKindSelector(TypeCategory category,const std::optional<parser::KindSelector> & selector)2212 Expr<SubscriptInteger> ExpressionAnalyzer::AnalyzeKindSelector(
2213     TypeCategory category,
2214     const std::optional<parser::KindSelector> &selector) {
2215   int defaultKind{GetDefaultKind(category)};
2216   if (!selector.has_value()) {
2217     return Expr<SubscriptInteger>{defaultKind};
2218   }
2219   return std::visit(
2220       common::visitors{
2221           [&](const parser::ScalarIntConstantExpr &x)
2222               -> Expr<SubscriptInteger> {
2223             if (MaybeExpr kind{Analyze(x)}) {
2224               Expr<SomeType> folded{
2225                   Fold(GetFoldingContext(), std::move(*kind))};
2226               if (std::optional<std::int64_t> code{ToInt64(folded)}) {
2227                 if (CheckIntrinsicKind(category, *code)) {
2228                   return Expr<SubscriptInteger>{*code};
2229                 }
2230               } else if (auto *intExpr{UnwrapExpr<Expr<SomeInteger>>(folded)}) {
2231                 return ConvertToType<SubscriptInteger>(std::move(*intExpr));
2232               }
2233             }
2234             return Expr<SubscriptInteger>{defaultKind};
2235           },
2236           [&](const parser::KindSelector::StarSize &x)
2237               -> Expr<SubscriptInteger> {
2238             std::intmax_t size = x.v;
2239             if (!CheckIntrinsicSize(category, size)) {
2240               size = defaultKind;
2241             } else if (category == TypeCategory::Complex) {
2242               size /= 2;
2243             }
2244             return Expr<SubscriptInteger>{size};
2245           },
2246       },
2247       selector->u);
2248 }
2249 
GetDefaultKind(common::TypeCategory category)2250 int ExpressionAnalyzer::GetDefaultKind(common::TypeCategory category) {
2251   return context_.GetDefaultKind(category);
2252 }
2253 
GetDefaultKindOfType(common::TypeCategory category)2254 DynamicType ExpressionAnalyzer::GetDefaultKindOfType(
2255     common::TypeCategory category) {
2256   return {category, GetDefaultKind(category)};
2257 }
2258 
CheckIntrinsicKind(TypeCategory category,std::int64_t kind)2259 bool ExpressionAnalyzer::CheckIntrinsicKind(
2260     TypeCategory category, std::int64_t kind) {
2261   if (IsValidKindOfIntrinsicType(category, kind)) {
2262     return true;
2263   } else {
2264     Say("%s(KIND=%jd) is not a supported type"_err_en_US,
2265         parser::ToUpperCaseLetters(EnumToString(category)), kind);
2266     return false;
2267   }
2268 }
2269 
CheckIntrinsicSize(TypeCategory category,std::int64_t size)2270 bool ExpressionAnalyzer::CheckIntrinsicSize(
2271     TypeCategory category, std::int64_t size) {
2272   if (category == TypeCategory::Complex) {
2273     // COMPLEX*16 == COMPLEX(KIND=8)
2274     if (size % 2 == 0 && IsValidKindOfIntrinsicType(category, size / 2)) {
2275       return true;
2276     }
2277   } else if (IsValidKindOfIntrinsicType(category, size)) {
2278     return true;
2279   }
2280   Say("%s*%jd is not a supported type"_err_en_US,
2281       parser::ToUpperCaseLetters(EnumToString(category)), size);
2282   return false;
2283 }
2284 
AddAcImpliedDo(parser::CharBlock name,int kind)2285 bool ExpressionAnalyzer::AddAcImpliedDo(parser::CharBlock name, int kind) {
2286   return acImpliedDos_.insert(std::make_pair(name, kind)).second;
2287 }
2288 
RemoveAcImpliedDo(parser::CharBlock name)2289 void ExpressionAnalyzer::RemoveAcImpliedDo(parser::CharBlock name) {
2290   auto iter{acImpliedDos_.find(name)};
2291   if (iter != acImpliedDos_.end()) {
2292     acImpliedDos_.erase(iter);
2293   }
2294 }
2295 
IsAcImpliedDo(parser::CharBlock name) const2296 std::optional<int> ExpressionAnalyzer::IsAcImpliedDo(
2297     parser::CharBlock name) const {
2298   auto iter{acImpliedDos_.find(name)};
2299   if (iter != acImpliedDos_.cend()) {
2300     return {iter->second};
2301   } else {
2302     return std::nullopt;
2303   }
2304 }
2305 
EnforceTypeConstraint(parser::CharBlock at,const MaybeExpr & result,TypeCategory category,bool defaultKind)2306 bool ExpressionAnalyzer::EnforceTypeConstraint(parser::CharBlock at,
2307     const MaybeExpr &result, TypeCategory category, bool defaultKind) {
2308   if (result.has_value()) {
2309     if (auto type{result->GetType()}) {
2310       if (type->category() != category) {
2311         Say(at, "Must have %s type, but is %s"_err_en_US,
2312             parser::ToUpperCaseLetters(EnumToString(category)),
2313             parser::ToUpperCaseLetters(type->AsFortran()));
2314         return false;
2315       } else if (defaultKind) {
2316         int kind{context_.GetDefaultKind(category)};
2317         if (type->kind() != kind) {
2318           Say(at, "Must have default kind(%d) of %s type, but is %s"_err_en_US,
2319               kind, parser::ToUpperCaseLetters(EnumToString(category)),
2320               parser::ToUpperCaseLetters(type->AsFortran()));
2321           return false;
2322         }
2323       }
2324     } else {
2325       Say(at, "Must have %s type, but is typeless"_err_en_US,
2326           parser::ToUpperCaseLetters(EnumToString(category)));
2327       return false;
2328     }
2329   }
2330   return true;
2331 }
2332 
MakeFunctionRef(parser::CharBlock callSite,ProcedureDesignator && proc,ActualArguments && arguments)2333 MaybeExpr ExpressionAnalyzer::MakeFunctionRef(parser::CharBlock callSite,
2334     ProcedureDesignator &&proc, ActualArguments &&arguments) {
2335   if (const auto *intrinsic{std::get_if<SpecificIntrinsic>(&proc.u)}) {
2336     if (intrinsic->name == "null" && arguments.empty()) {
2337       return Expr<SomeType>{NullPointer{}};
2338     }
2339   }
2340   if (auto chars{CheckCall(callSite, proc, arguments)}) {
2341     if (chars->functionResult.has_value()) {
2342       const auto &result{*chars->functionResult};
2343       if (result.IsProcedurePointer()) {
2344         return Expr<SomeType>{
2345             ProcedureRef{std::move(proc), std::move(arguments)}};
2346       } else {
2347         // Not a procedure pointer, so type and shape are known.
2348         return TypedWrapper<FunctionRef, ProcedureRef>(
2349             DEREF(result.GetTypeAndShape()).type(),
2350             ProcedureRef{std::move(proc), std::move(arguments)});
2351       }
2352     }
2353   }
2354   if (const Symbol * symbol{proc.GetSymbol()}) {
2355     if (const auto *details{
2356             symbol->detailsIf<semantics::SubprogramNameDetails>()}) {
2357       // If this symbol is still a SubprogramNameDetails, we must be
2358       // checking a specification expression in a sibling module or internal
2359       // procedure.  Since recursion is disallowed in specification
2360       // expressions, we should handle such references by processing the
2361       // sibling procedure's specification part right now (recursively),
2362       // but until we can do so, just complain about the forward reference.
2363       // TODO: recursively process sibling's specification part.
2364       if (details->kind() == semantics::SubprogramKind::Module) {
2365         Say("The module function '%s' must have been previously defined "
2366             "when referenced in a specification expression"_err_en_US,
2367             symbol->name());
2368       } else {
2369         Say("The internal function '%s' cannot be referenced in "
2370             "a specification expression"_err_en_US,
2371             symbol->name());
2372       }
2373       return std::nullopt;
2374     }
2375   }
2376   return std::nullopt;
2377 }
2378 
MakeFunctionRef(parser::CharBlock intrinsic,ActualArguments && arguments)2379 MaybeExpr ExpressionAnalyzer::MakeFunctionRef(
2380     parser::CharBlock intrinsic, ActualArguments &&arguments) {
2381   if (std::optional<SpecificCall> specificCall{
2382           context_.intrinsics().Probe(CallCharacteristics{intrinsic}, arguments,
2383               context_.foldingContext())}) {
2384     return MakeFunctionRef(intrinsic,
2385         ProcedureDesignator{std::move(specificCall->specificIntrinsic)},
2386         std::move(specificCall->arguments));
2387   } else {
2388     return std::nullopt;
2389   }
2390 }
2391 }
2392 
2393 namespace Fortran::semantics {
AnalyzeKindSelector(SemanticsContext & context,common::TypeCategory category,const std::optional<parser::KindSelector> & selector)2394 evaluate::Expr<evaluate::SubscriptInteger> AnalyzeKindSelector(
2395     SemanticsContext &context, common::TypeCategory category,
2396     const std::optional<parser::KindSelector> &selector) {
2397   evaluate::ExpressionAnalyzer analyzer{context};
2398   auto save{
2399       analyzer.GetContextualMessages().SetLocation(context.location().value())};
2400   return analyzer.AnalyzeKindSelector(category, selector);
2401 }
2402 
AnalyzeCallStmt(SemanticsContext & context,const parser::CallStmt & call)2403 void AnalyzeCallStmt(SemanticsContext &context, const parser::CallStmt &call) {
2404   evaluate::ExpressionAnalyzer{context}.Analyze(call);
2405 }
2406 
ExprChecker(SemanticsContext & context)2407 ExprChecker::ExprChecker(SemanticsContext &context) : context_{context} {}
2408 
Walk(const parser::Program & program)2409 bool ExprChecker::Walk(const parser::Program &program) {
2410   parser::Walk(program, *this);
2411   return !context_.AnyFatalError();
2412 }
2413 }
2414