Index: flang/lib/Lower/PFTBuilder.cpp =================================================================== --- flang/lib/Lower/PFTBuilder.cpp +++ flang/lib/Lower/PFTBuilder.cpp @@ -160,8 +160,6 @@ exitFunction(); } else if constexpr (lower::pft::isConstruct || lower::pft::isDirective) { - if constexpr (lower::pft::isDeclConstruct) - return; exitConstructOrDirective(); } } @@ -245,11 +243,6 @@ if (evaluationListStack.empty()) return; auto evaluationList = evaluationListStack.back(); - if (evaluationList->empty() && - pftParentStack.back().getIf()) { - popEvaluationList(); - return; - } if (evaluationList->empty() || !evaluationList->back().isEndStmt()) { const auto &endStmt = pftParentStack.back().get().endStmt; @@ -279,10 +272,20 @@ lastLexicalEvaluation = nullptr; } + /// Pop the ModuleLikeUnit evaluationList when entering the first module + /// procedure. + void cleanModuleEvaluationList() { + if (evaluationListStack.empty()) + return; + if (pftParentStack.back().isA()) + popEvaluationList(); + } + /// Initialize a new function-like unit and make it the builder's focus. template bool enterFunction(const A &func, const semantics::SemanticsContext &semanticsContext) { + cleanModuleEvaluationList(); endFunctionBody(); // enclosing host subprogram body, if any Fortran::lower::pft::FunctionLikeUnit &unit = addFunction(lower::pft::FunctionLikeUnit{func, pftParentStack.back(), @@ -316,12 +319,6 @@ pushEvaluationList(eval.evaluationList.get()); pftParentStack.emplace_back(eval); constructAndDirectiveStack.emplace_back(&eval); - if constexpr (lower::pft::isDeclConstruct) { - popEvaluationList(); - pftParentStack.pop_back(); - constructAndDirectiveStack.pop_back(); - popEvaluationList(); - } return true; } Index: flang/test/Lower/pre-fir-tree06.f90 =================================================================== --- flang/test/Lower/pre-fir-tree06.f90 +++ flang/test/Lower/pre-fir-tree06.f90 @@ -10,3 +10,45 @@ end ! CHECK: End ModuleLike +! CHECK: ModuleLike +module m2 + integer, save :: i + ! CHECK-NEXT: OpenMPDeclarativeConstruct + !$omp threadprivate(i) +contains + subroutine sub() + i = 1; + end + subroutine sub2() + i = 2; + end +end +! CHECK: End ModuleLike + +! CHECK: Program main +program main + real :: y + ! CHECK-NEXT: OpenMPDeclarativeConstruct + !$omp threadprivate(y) +end +! CHECK: End Program main + +! CHECK: Subroutine sub1 +subroutine sub1() + real, save :: p + ! CHECK-NEXT: OpenMPDeclarativeConstruct + !$omp threadprivate(p) +end +! CHECK: End Subroutine sub1 + +! CHECK: Subroutine sub2 +subroutine sub2() + real, save :: q + ! CHECK-NEXT: OpenMPDeclarativeConstruct + !$omp threadprivate(q) +contains + subroutine sub() + end +end +! CHECK: End Subroutine sub2 +