[flang] Warn about more continuation lines than the standard permits
authorPeter Klausler <pklausler@nvidia.com>
Fri, 4 Nov 2022 23:39:52 +0000 (16:39 -0700)
committerPeter Klausler <pklausler@nvidia.com>
Sat, 3 Dec 2022 01:07:11 +0000 (17:07 -0800)
f18 doesn't have any limit on continuation lines in fixed or free form
source (other than available memory), but the standard does.  Emit
a portability warning when it is exceeded.

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

flang/docs/Extensions.md
flang/lib/Parser/prescan.cpp
flang/lib/Parser/prescan.h
flang/test/Parser/excessive-continuations.f90 [new file with mode: 0644]

index ed0229d..039b1f9 100644 (file)
@@ -240,6 +240,8 @@ end
 * The legacy extension intrinsic functions `IZEXT` and `JZEXT`
   are supported; `ZEXT` has different behavior with various older
   compilers, so it is not supported.
+* f18 doesn't impose a limit on the number of continuation lines
+  allowed for a single statement.
 
 ### Extensions supported when enabled by options
 
index 17fc090..ae8decf 100644 (file)
@@ -89,7 +89,8 @@ void Prescanner::Prescan(ProvenanceRange range) {
 
 void Prescanner::Statement() {
   TokenSequence tokens;
-  LineClassification line{ClassifyLine(nextLine_)};
+  const char *statementStart{nextLine_};
+  LineClassification line{ClassifyLine(statementStart)};
   switch (line.kind) {
   case LineClassification::Kind::Comment:
     nextLine_ += line.payloadOffset; // advance to '!' or newline
@@ -164,6 +165,11 @@ void Prescanner::Statement() {
 
   while (NextToken(tokens)) {
   }
+  if (continuationLines_ > 255) {
+    Say(GetProvenance(statementStart),
+        "%d continuation lines is more than the Fortran standard allows"_port_en_US,
+        continuationLines_);
+  }
 
   Provenance newlineProvenance{GetCurrentProvenance()};
   if (std::optional<TokenSequence> preprocessed{
@@ -299,7 +305,7 @@ void Prescanner::LabelField(TokenSequence &token) {
   token.CloseToken();
   SkipToNextSignificantCharacter();
   if (IsDecimalDigit(*at_)) {
-    Say(GetProvenance(at_),
+    Say(GetCurrentProvenance(),
         "Label digit is not in fixed-form label field"_port_en_US);
   }
 }
@@ -406,6 +412,7 @@ void Prescanner::SkipToNextSignificantCharacter() {
       mightNeedSpace = *at_ == '\n';
     }
     for (; Continuation(mightNeedSpace); mightNeedSpace = false) {
+      ++continuationLines_;
       if (MustSkipToEndOfLine()) {
         SkipToEndOfLine();
       }
@@ -493,7 +500,7 @@ bool Prescanner::NextToken(TokenSequence &tokens) {
       // Recognize and skip over classic C style /*comments*/ when
       // outside a character literal.
       if (features_.ShouldWarn(LanguageFeature::ClassicCComments)) {
-        Say(GetProvenance(at_),
+        Say(GetCurrentProvenance(),
             "nonstandard usage: C-style comment"_port_en_US);
       }
       SkipCComments();
index 4d002ad..ad8b90b 100644 (file)
@@ -109,6 +109,7 @@ private:
     slashInCurrentStatement_ = false;
     preventHollerith_ = false;
     delimiterNesting_ = 0;
+    continuationLines_ = 0;
   }
 
   Provenance GetProvenance(const char *sourceChar) const {
@@ -195,6 +196,7 @@ private:
   Encoding encoding_{Encoding::UTF_8};
   int delimiterNesting_{0};
   int prescannerNesting_{0};
+  int continuationLines_{0};
 
   Provenance startProvenance_;
   const char *start_{nullptr}; // beginning of current source file content
diff --git a/flang/test/Parser/excessive-continuations.f90 b/flang/test/Parser/excessive-continuations.f90
new file mode 100644 (file)
index 0000000..e5855cf
--- /dev/null
@@ -0,0 +1,262 @@
+! RUN: %flang_fc1 -fdebug-unparse %s 2>&1 | FileCheck %s
+! CHECK: portability: 256 continuation lines is more than the Fortran standard allows
+! CHECK: LOGICAL, PARAMETER :: c255 = .true._4
+program test
+  logical, parameter :: c255 = 255 == len("&
+ &a&
+ &a&
+ &a&
+ &a&
+ &a&
+ &a&
+ &a&
+ &a&
+ &a&
+ &a&
+ &a&
+ &a&
+ &a&
+ &a&
+ &a&
+ &a&
+ &a&
+ &a&
+ &a&
+ &a&
+ &a&
+ &a&
+ &a&
+ &a&
+ &a&
+ &a&
+ &a&
+ &a&
+ &a&
+ &a&
+ &a&
+ &a&
+ &a&
+ &a&
+ &a&
+ &a&
+ &a&
+ &a&
+ &a&
+ &a&
+ &a&
+ &a&
+ &a&
+ &a&
+ &a&
+ &a&
+ &a&
+ &a&
+ &a&
+ &a&
+ &a&
+ &a&
+ &a&
+ &a&
+ &a&
+ &a&
+ &a&
+ &a&
+ &a&
+ &a&
+ &a&
+ &a&
+ &a&
+ &a&
+ &a&
+ &a&
+ &a&
+ &a&
+ &a&
+ &a&
+ &a&
+ &a&
+ &a&
+ &a&
+ &a&
+ &a&
+ &a&
+ &a&
+ &a&
+ &a&
+ &a&
+ &a&
+ &a&
+ &a&
+ &a&
+ &a&
+ &a&
+ &a&
+ &a&
+ &a&
+ &a&
+ &a&
+ &a&
+ &a&
+ &a&
+ &a&
+ &a&
+ &a&
+ &a&
+ &a&
+ &a&
+ &a&
+ &a&
+ &a&
+ &a&
+ &a&
+ &a&
+ &a&
+ &a&
+ &a&
+ &a&
+ &a&
+ &a&
+ &a&
+ &a&
+ &a&
+ &a&
+ &a&
+ &a&
+ &a&
+ &a&
+ &a&
+ &a&
+ &a&
+ &a&
+ &a&
+ &a&
+ &a&
+ &a&
+ &a&
+ &a&
+ &a&
+ &a&
+ &a&
+ &a&
+ &a&
+ &a&
+ &a&
+ &a&
+ &a&
+ &a&
+ &a&
+ &a&
+ &a&
+ &a&
+ &a&
+ &a&
+ &a&
+ &a&
+ &a&
+ &a&
+ &a&
+ &a&
+ &a&
+ &a&
+ &a&
+ &a&
+ &a&
+ &a&
+ &a&
+ &a&
+ &a&
+ &a&
+ &a&
+ &a&
+ &a&
+ &a&
+ &a&
+ &a&
+ &a&
+ &a&
+ &a&
+ &a&
+ &a&
+ &a&
+ &a&
+ &a&
+ &a&
+ &a&
+ &a&
+ &a&
+ &a&
+ &a&
+ &a&
+ &a&
+ &a&
+ &a&
+ &a&
+ &a&
+ &a&
+ &a&
+ &a&
+ &a&
+ &a&
+ &a&
+ &a&
+ &a&
+ &a&
+ &a&
+ &a&
+ &a&
+ &a&
+ &a&
+ &a&
+ &a&
+ &a&
+ &a&
+ &a&
+ &a&
+ &a&
+ &a&
+ &a&
+ &a&
+ &a&
+ &a&
+ &a&
+ &a&
+ &a&
+ &a&
+ &a&
+ &a&
+ &a&
+ &a&
+ &a&
+ &a&
+ &a&
+ &a&
+ &a&
+ &a&
+ &a&
+ &a&
+ &a&
+ &a&
+ &a&
+ &a&
+ &a&
+ &a&
+ &a&
+ &a&
+ &a&
+ &a&
+ &a&
+ &a&
+ &a&
+ &a&
+ &a&
+ &a&
+ &a&
+ &a&
+ &a&
+ &a&
+ &a&
+ &a&
+ &a&
+ &a&
+ &")
+end