[flang-commits] [flang] b690597 - [flang] Fixes several bugs relating to initialization expressions. An (#1493)

Valentin Clement via flang-commits flang-commits at lists.llvm.org
Wed Jun 22 21:55:43 PDT 2022


Author: Valentin Clement
Date: 2022-06-23T06:55:33+02:00
New Revision: b690597936c96f9dcebaeca9cf76223023a52d01

URL: https://github.com/llvm/llvm-project/commit/b690597936c96f9dcebaeca9cf76223023a52d01
DIFF: https://github.com/llvm/llvm-project/commit/b690597936c96f9dcebaeca9cf76223023a52d01.diff

LOG: [flang] Fixes several bugs relating to initialization expressions. An (#1493)

Fixes several bugs relating to initialization expressions. An
initialization expression has no access to dynamic resources like the
stack or the heap. It must reduce to a relocatable expression that the
loader can complete at runtime.

Adds regression test.

This patch is part of the upstreaming effort from fir-dev branch.

Reviewed By: PeteSteinfeld

Differential Revision: https://reviews.llvm.org/D128380

Co-authored-by: Jean Perier <jperier at nvidia.com>
Co-authored-by: Eric Schweitz <eschweitz at nvidia.com>

Added: 
    

Modified: 
    flang/lib/Lower/PFTBuilder.cpp

Removed: 
    


################################################################################
diff  --git a/flang/lib/Lower/PFTBuilder.cpp b/flang/lib/Lower/PFTBuilder.cpp
index bba55709647eb..49ae53118473b 100644
--- a/flang/lib/Lower/PFTBuilder.cpp
+++ b/flang/lib/Lower/PFTBuilder.cpp
@@ -30,6 +30,13 @@ static llvm::cl::opt<bool> nonRecursiveProcedures(
                    "default for all Fortran standards prior to 2018."),
     llvm::cl::init(/*2018 standard=*/false));
 
+static llvm::cl::opt<bool> mainProgramGlobals(
+    "main-program-globals",
+    llvm::cl::desc(
+        "Allocate all variables in the main program as global variables and "
+        "not on the stack regardless of type, kind, and rank."),
+    llvm::cl::init(/*2018 standard=*/false), llvm::cl::Hidden);
+
 using namespace Fortran;
 
 namespace {
@@ -416,6 +423,8 @@ class PFTBuilder {
     } else if (const auto *entryStmt = p->getIf<parser::EntryStmt>()) {
       const semantics::Symbol *sym =
           std::get<parser::Name>(entryStmt->t).symbol;
+      if (auto *details = sym->detailsIf<semantics::GenericDetails>())
+        sym = details->specific();
       assert(sym->has<semantics::SubprogramDetails>() &&
              "entry must be a subprogram");
       entryPointList.push_back(std::pair{sym, p});
@@ -1257,7 +1266,7 @@ bool Fortran::lower::definedInCommonBlock(const semantics::Symbol &sym) {
   return semantics::FindCommonBlockContaining(sym);
 }
 
-static bool isReEntrant(const Fortran::semantics::Scope &scope) {
+static bool isReentrant(const Fortran::semantics::Scope &scope) {
   if (scope.kind() == Fortran::semantics::Scope::Kind::MainProgram)
     return false;
   if (scope.kind() == Fortran::semantics::Scope::Kind::Subprogram) {
@@ -1277,7 +1286,7 @@ bool Fortran::lower::symbolIsGlobal(const semantics::Symbol &sym) {
   if (const auto *details = sym.detailsIf<semantics::ObjectEntityDetails>()) {
     if (details->init())
       return true;
-    if (!isReEntrant(sym.owner())) {
+    if (!isReentrant(sym.owner())) {
       // Turn array and character of non re-entrant programs (like the main
       // program) into global memory.
       if (const Fortran::semantics::DeclTypeSpec *symTy = sym.GetType())
@@ -1287,6 +1296,9 @@ bool Fortran::lower::symbolIsGlobal(const semantics::Symbol &sym) {
       if (!details->shape().empty() || !details->coshape().empty())
         return true;
     }
+    if (mainProgramGlobals &&
+        sym.owner().kind() == Fortran::semantics::Scope::Kind::MainProgram)
+      return true;
   }
   return semantics::IsSaved(sym) || lower::definedInCommonBlock(sym) ||
          semantics::IsNamedConstant(sym);
@@ -1821,10 +1833,9 @@ struct SymbolVisitor {
           if (std::optional<Fortran::evaluate::ExtentExpr> length =
                   dynamicType->GetCharLength())
             visitExpr(*length);
-        } else if (dynamicType->category() == common::TypeCategory::Derived) {
-          const Fortran::semantics::DerivedTypeSpec &derivedTypeSpec =
-              dynamicType->GetDerivedTypeSpec();
-          for (const auto &[_, param] : derivedTypeSpec.parameters())
+        } else if (const Fortran::semantics::DerivedTypeSpec *derivedTypeSpec =
+                       Fortran::evaluate::GetDerivedTypeSpec(dynamicType)) {
+          for (const auto &[_, param] : derivedTypeSpec->parameters())
             if (const Fortran::semantics::MaybeIntExpr &expr =
                     param.GetExplicit())
               visitExpr(expr.value());


        


More information about the flang-commits mailing list