[flang-commits] [flang] ea3a3b2 - [flang] Handle continuation line edge case (#74751)

via flang-commits flang-commits at lists.llvm.org
Mon Dec 11 13:09:17 PST 2023


Author: Peter Klausler
Date: 2023-12-11T13:09:12-08:00
New Revision: ea3a3b25b93664c8be750ac3cd550855dcd1848b

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

LOG: [flang] Handle continuation line edge case (#74751)

For a character literal that is split over more than one source line
with free form line continuation using '&'
at the end of one line but missing the standard-required '&' on the
continuation line, also handle the case of spaces at the beginning of
the continuation line.
    
For example,
    
PRINT *, 'don'&
   't poke the bear'
    
now prints "don't poke the bear", like nearly all other Fortran
compilers do.
    
This is not strictly standard conforming behavior, and the compiler
emits a portability warning with -pedantic.
    
Fixes llvm-test-suite/Fortran/gfortran/regression/continuation_1.f90,
.../continuation_12.f90, and .../continuation_13.f90.

Added: 
    flang/test/Parser/continuation-without-ampersand.f90

Modified: 
    flang/lib/Parser/prescan.cpp
    flang/lib/Parser/prescan.h

Removed: 
    flang/test/Parser/continuation-before-quote.f90


################################################################################
diff  --git a/flang/lib/Parser/prescan.cpp b/flang/lib/Parser/prescan.cpp
index 449ea60144424a..79cdaccf1fbfec 100644
--- a/flang/lib/Parser/prescan.cpp
+++ b/flang/lib/Parser/prescan.cpp
@@ -706,6 +706,7 @@ void Prescanner::QuotedCharacterLiteral(
   char quote{*at_};
   const char *end{at_ + 1};
   inCharLiteral_ = true;
+  continuationInCharLiteral_ = true;
   const auto emit{[&](char ch) { EmitChar(tokens, ch); }};
   const auto insert{[&](char ch) { EmitInsertedChar(tokens, ch); }};
   bool isEscaped{false};
@@ -749,16 +750,9 @@ void Prescanner::QuotedCharacterLiteral(
         break;
       }
       inCharLiteral_ = true;
-      if (insertASpace_) {
-        if (features_.ShouldWarn(
-                common::LanguageFeature::MiscSourceExtensions)) {
-          Say(GetProvenanceRange(at_, end),
-              "Repeated quote mark in character literal continuation line should have been preceded by '&'"_port_en_US);
-        }
-        insertASpace_ = false;
-      }
     }
   }
+  continuationInCharLiteral_ = false;
   inCharLiteral_ = false;
 }
 
@@ -1122,7 +1116,15 @@ const char *Prescanner::FreeFormContinuationLine(bool ampersand) {
     } else if (*p == '!' || *p == '\n' || *p == '#') {
       return nullptr;
     } else if (ampersand || IsImplicitContinuation()) {
-      if (p > nextLine_) {
+      if (continuationInCharLiteral_) {
+        // 'a'&            -> 'a''b' == "a'b"
+        //   'b'
+        if (features_.ShouldWarn(
+                common::LanguageFeature::MiscSourceExtensions)) {
+          Say(GetProvenanceRange(p, p + 1),
+              "Character literal continuation line should have been preceded by '&'"_port_en_US);
+        }
+      } else if (p > nextLine_) {
         --p;
       } else {
         insertASpace_ = true;

diff  --git a/flang/lib/Parser/prescan.h b/flang/lib/Parser/prescan.h
index 16b2c6165f611c..84e046c1b102f0 100644
--- a/flang/lib/Parser/prescan.h
+++ b/flang/lib/Parser/prescan.h
@@ -218,6 +218,7 @@ class Prescanner {
   bool slashInCurrentStatement_{false};
   bool preventHollerith_{false}; // CHARACTER*4HIMOM not Hollerith
   bool inCharLiteral_{false};
+  bool continuationInCharLiteral_{false};
   bool inPreprocessorDirective_{false};
 
   // In some edge cases of compiler directive continuation lines, it

diff  --git a/flang/test/Parser/continuation-before-quote.f90 b/flang/test/Parser/continuation-before-quote.f90
deleted file mode 100644
index 66252010d89c46..00000000000000
--- a/flang/test/Parser/continuation-before-quote.f90
+++ /dev/null
@@ -1,10 +0,0 @@
-! RUN: %flang_fc1 -fsyntax-only -pedantic %s 2>&1 | FileCheck %s
-! Continuation between repeated quotation marks
-subroutine test
-!CHECK: portability: Repeated quote mark in character literal continuation line should have been preceded by '&'
-  print *, 'needs an '&
-'ampersand'''
-!CHECK-NOT: portability: Repeated quote mark in character literal continuation line should have been preceded by '&'
-  print *, 'has an '&
-&'ampersand'''
-end

diff  --git a/flang/test/Parser/continuation-without-ampersand.f90 b/flang/test/Parser/continuation-without-ampersand.f90
new file mode 100644
index 00000000000000..5c3f23235edccb
--- /dev/null
+++ b/flang/test/Parser/continuation-without-ampersand.f90
@@ -0,0 +1,13 @@
+! RUN: %flang_fc1 -fsyntax-only -pedantic %s 2>&1 | FileCheck %s
+! Continuation between repeated quotation marks
+subroutine test
+!CHECK: portability: Character literal continuation line should have been preceded by '&'
+  print *, 'needs an '&
+'ampersand'''
+!CHECK: portability: Character literal continuation line should have been preceded by '&'
+  print *, 'also needs an '&
+ 'ampersand'''
+!CHECK-NOT: portability: Character literal continuation line should have been preceded by '&'
+  print *, 'has an '&
+&'ampersand'''
+end


        


More information about the flang-commits mailing list