[flang-commits] [flang] d6a3607 - [flang] legacy branch target (#75628)

via flang-commits flang-commits at lists.llvm.org
Fri Dec 15 11:21:56 PST 2023


Author: vdonaldson
Date: 2023-12-15T11:21:53-08:00
New Revision: d6a3607ff5ebae6575a713cdf12f1a2dda7cc72f

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

LOG: [flang] legacy branch target (#75628)

Branching to an endif statement from outside of the if is nonconformant:

  subroutine jump(n)
    goto 6
    if (n == 3) then
      goto 7
  6 end if
    print *, 'pass'
    return
  7 print *, 'fail'
  end

However, this branch was permitted up to f90. Account for this usage
when rewriting if constructs and if statements by suppressing rewriting
if the end statement is labeled.

Added: 
    

Modified: 
    flang/lib/Lower/PFTBuilder.cpp

Removed: 
    


################################################################################
diff  --git a/flang/lib/Lower/PFTBuilder.cpp b/flang/lib/Lower/PFTBuilder.cpp
index 8e224c17edad19..0e32e2c7d96a77 100644
--- a/flang/lib/Lower/PFTBuilder.cpp
+++ b/flang/lib/Lower/PFTBuilder.cpp
@@ -541,15 +541,15 @@ class PFTBuilder {
   /// The transformation is only valid for forward branch targets at the same
   /// construct nesting level as the IfConstruct. The result must not violate
   /// construct nesting requirements or contain an EntryStmt. The result
-  /// is subject to normal un/structured code classification analysis. The
-  /// result is allowed to violate the F18 Clause 11.1.2.1 prohibition on
-  /// transfer of control into the interior of a construct block, as that does
-  /// not compromise correct code generation. When two transformation
-  /// candidates overlap, at least one must be disallowed. In such cases,
-  /// the current heuristic favors simple code generation, which happens to
-  /// favor later candidates over earlier candidates. That choice is probably
-  /// not significant, but could be changed.
-  ///
+  /// is subject to normal un/structured code classification analysis. Except
+  /// for a branch to the EndIfStmt, the result is allowed to violate the F18
+  /// Clause 11.1.2.1 prohibition on transfer of control into the interior of
+  /// a construct block, as that does not compromise correct code generation.
+  /// When two transformation candidates overlap, at least one must be
+  /// disallowed. In such cases, the current heuristic favors simple code
+  /// generation, which happens to favor later candidates over earlier
+  /// candidates. That choice is probably not significant, but could be
+  /// changed.
   void rewriteIfGotos() {
     auto &evaluationList = *evaluationListStack.back();
     if (!evaluationList.size())
@@ -616,7 +616,8 @@ class PFTBuilder {
       if (eval.isA<parser::IfConstruct>() && eval.evaluationList->size() == 3) {
         const auto bodyEval = std::next(eval.evaluationList->begin());
         if (const auto *gotoStmt = bodyEval->getIf<parser::GotoStmt>()) {
-          ifCandidateStack.push_back({it, gotoStmt->v});
+          if (!bodyEval->lexicalSuccessor->label)
+            ifCandidateStack.push_back({it, gotoStmt->v});
         } else if (doStmt) {
           if (const auto *cycleStmt = bodyEval->getIf<parser::CycleStmt>()) {
             std::string cycleName = getConstructName(*cycleStmt);


        


More information about the flang-commits mailing list