diff --git a/flang/docs/Extensions.md b/flang/docs/Extensions.md --- a/flang/docs/Extensions.md +++ b/flang/docs/Extensions.md @@ -240,6 +240,8 @@ * 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 diff --git a/flang/lib/Parser/prescan.h b/flang/lib/Parser/prescan.h --- a/flang/lib/Parser/prescan.h +++ b/flang/lib/Parser/prescan.h @@ -109,6 +109,7 @@ slashInCurrentStatement_ = false; preventHollerith_ = false; delimiterNesting_ = 0; + continuationLines_ = 0; } Provenance GetProvenance(const char *sourceChar) const { @@ -195,6 +196,7 @@ 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/lib/Parser/prescan.cpp b/flang/lib/Parser/prescan.cpp --- a/flang/lib/Parser/prescan.cpp +++ b/flang/lib/Parser/prescan.cpp @@ -89,7 +89,8 @@ 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 @@ 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 preprocessed{ @@ -299,7 +305,7 @@ 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 @@ mightNeedSpace = *at_ == '\n'; } for (; Continuation(mightNeedSpace); mightNeedSpace = false) { + ++continuationLines_; if (MustSkipToEndOfLine()) { SkipToEndOfLine(); } @@ -493,7 +500,7 @@ // 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(); diff --git a/flang/test/Parser/excessive-continuations.f90 b/flang/test/Parser/excessive-continuations.f90 new file mode 100644 --- /dev/null +++ b/flang/test/Parser/excessive-continuations.f90 @@ -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