xref: /llvm-project/flang/lib/Semantics/check-data.cpp (revision 1f8790050b0e99e7b46cc69518aa84f46f50738e)
1 //===-- lib/Semantics/check-data.cpp --------------------------------------===//
2 //
3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4 // See https://llvm.org/LICENSE.txt for license information.
5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6 //
7 //===----------------------------------------------------------------------===//
8 
9 #include "check-data.h"
10 
11 namespace Fortran::semantics {
12 
13 void DataChecker::Leave(const parser::DataStmtConstant &dataConst) {
14   if (auto *structure{
15           std::get_if<parser::StructureConstructor>(&dataConst.u)}) {
16     for (const auto &component :
17         std::get<std::list<parser::ComponentSpec>>(structure->t)) {
18       const parser::Expr &parsedExpr{
19           std::get<parser::ComponentDataSource>(component.t).v.value()};
20       if (const auto *expr{GetExpr(parsedExpr)}) {
21         if (!evaluate::IsConstantExpr(*expr)) { // C884
22           context_.Say(parsedExpr.source,
23               "Structure constructor in data value must be a constant expression"_err_en_US);
24         }
25       }
26     }
27   }
28   // TODO: C886 and C887 for data-stmt-constant
29 }
30 
31 // TODO: C874-C881
32 
33 void DataChecker::Leave(const parser::DataStmtRepeat &dataRepeat) {
34   if (const auto *designator{parser::Unwrap<parser::Designator>(dataRepeat)}) {
35     if (auto *dataRef{std::get_if<parser::DataRef>(&designator->u)}) {
36       evaluate::ExpressionAnalyzer exprAnalyzer{context_};
37       if (MaybeExpr checked{exprAnalyzer.Analyze(*dataRef)}) {
38         auto expr{
39             evaluate::Fold(context_.foldingContext(), std::move(checked))};
40         if (auto i64{ToInt64(expr)}) {
41           if (*i64 < 0) { // C882
42             context_.Say(designator->source,
43                 "Repeat count for data value must not be negative"_err_en_US);
44           }
45         }
46       }
47     }
48   }
49 }
50 } // namespace Fortran::semantics
51