Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Commit 35efbc0

Browse files
authored
[flang] Warn if conditional compilation statements begin with a continuation line (llvm#179802)
In fixed source form, allow conditional compilation statements to begin with a continuation line and emit a warning. This behavior is similar to that of regular statements and -E mode. Fixes llvm#129457
1 parent 7fcc12c commit 35efbc0

4 files changed

Lines changed: 35 additions & 23 deletions

File tree

flang/lib/Parser/prescan.cpp

Lines changed: 21 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -423,7 +423,8 @@ void Prescanner::NextLine() {
423423
}
424424

425425
void Prescanner::LabelField(TokenSequence &token) {
426-
int outCol{1};
426+
int outChars{0};
427+
int colOffset{column_ - 1};
427428
const char *start{at_};
428429
std::optional<int> badColumn;
429430
for (; *at_ != '\n' && column_ <= 6; ++at_) {
@@ -435,14 +436,15 @@ void Prescanner::LabelField(TokenSequence &token) {
435436
if (int n{IsSpace(at_)}; n == 0 &&
436437
!(*at_ == '0' && column_ == 6)) { // '0' in column 6 becomes space
437438
EmitChar(token, *at_);
438-
++outCol;
439+
++outChars;
439440
if (!badColumn && (column_ == 6 || !IsDecimalDigit(*at_))) {
440441
badColumn = column_;
441442
}
442443
}
443444
++column_;
444445
}
445446
if (badColumn && !preprocessor_.IsNameDefined(token.CurrentOpenToken())) {
447+
int badOffset{*badColumn - colOffset - 1};
446448
if (*badColumn == 6) {
447449
if ((prescannerNesting_ > 0 &&
448450
cooked_.BufferedBytes() == firstCookedCharacterOffset_) ||
@@ -455,34 +457,32 @@ void Prescanner::LabelField(TokenSequence &token) {
455457
// CookedSource::Marshal().
456458
cooked_.MarkPossibleFixedFormContinuation();
457459
} else if (features_.ShouldWarn(common::UsageWarning::Scanning)) {
458-
Say(common::UsageWarning::Scanning,
459-
GetProvenance(start + *badColumn - 1),
460+
Say(common::UsageWarning::Scanning, GetProvenance(start + badOffset),
460461
"Statement should not begin with a continuation line"_warn_en_US);
461462
}
462463
} else if (preprocessingOnly_) {
463464
if (features_.ShouldWarn(common::UsageWarning::Scanning)) {
464-
Say(common::UsageWarning::Scanning,
465-
GetProvenance(start + *badColumn - 1),
465+
Say(common::UsageWarning::Scanning, GetProvenance(start + badOffset),
466466
"Character in fixed-form label field should be a digit"_warn_en_US);
467467
}
468468
} else {
469-
Say(GetProvenance(start + *badColumn - 1),
469+
Say(GetProvenance(start + badOffset),
470470
"Character in fixed-form label field must be a digit"_err_en_US);
471471
}
472472
token.clear();
473473
if (*badColumn < 6) {
474474
at_ = start;
475-
column_ = 1;
475+
column_ = 1 + colOffset;
476476
return;
477477
}
478-
outCol = 1;
478+
outChars = 0;
479479
}
480-
if (outCol == 1) { // empty or ignored label field
480+
if (outChars == 0) { // empty or ignored label field
481481
// Emit a space so that, if the line is rescanned after preprocessing,
482482
// a leading 'C' or 'D' won't be left-justified and then accidentally
483483
// misinterpreted as a comment card.
484484
EmitChar(token, ' ');
485-
++outCol;
485+
++outChars;
486486
}
487487
token.CloseToken();
488488
SkipToNextSignificantCharacter();
@@ -1633,12 +1633,9 @@ Prescanner::IsFixedFormCompilerDirectiveLine(const char *start) const {
16331633
// - Columns 3 through 5 must have only white space or numbers.
16341634
// - Column 6 must be space or zero.
16351635
bool isOpenMPConditional{sp == &sentinel[1] && sentinel[0] == '$'};
1636-
bool hadDigit{false};
16371636
if (isOpenMPConditional) {
16381637
for (; column < 6; ++column, ++p) {
1639-
if (IsDecimalDigit(*p)) {
1640-
hadDigit = true;
1641-
} else if (!IsSpaceOrTab(p)) {
1638+
if (!IsDecimalDigit(*p) && !IsSpaceOrTab(p)) {
16421639
return std::nullopt;
16431640
}
16441641
}
@@ -1648,14 +1645,17 @@ Prescanner::IsFixedFormCompilerDirectiveLine(const char *start) const {
16481645
++p;
16491646
} else if (int n{IsSpaceOrTab(p)}) {
16501647
p += n;
1651-
} else if (isOpenMPConditional && preprocessingOnly_ && !hadDigit &&
1652-
*p != '\n') {
1653-
// In -E mode, "!$ &" is treated as a directive
16541648
} else {
1655-
// This is a Continuation line, not an initial directive line.
1656-
return std::nullopt;
1649+
// This is a continuation line.
1650+
// Directives are not allowed to begin with a continuation line, but
1651+
// this is allowed for OpenMP conditional compilation, which will result
1652+
// in a warning.
1653+
++p;
1654+
if (!isOpenMPConditional) {
1655+
return std::nullopt;
1656+
}
16571657
}
1658-
++column, ++p;
1658+
++column;
16591659
}
16601660
if (isOpenMPConditional) {
16611661
for (; column <= fixedFormColumnLimit_; ++column, ++p) {
Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
! RUN: not %flang_fc1 -fopenmp -fsyntax-only %s 2>&1 | FileCheck %s
2+
! CHECK: warning: Statement should not begin with a continuation line [-Wscanning]
3+
c$ ! 0 !
4+
5+
print *,'pass'
6+
end

flang/test/Parser/OpenMP/sentinels.f

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -50,12 +50,12 @@ subroutine sub(a, b)
5050
! CHECK: "msg1"
5151
! CHECK-NOT: "comment"
5252
c$ x PRINT *, "comment"
53-
c$1 & , "comment"
53+
c$* & , "comment"
5454
c$ x & , "comment"
5555
c$ +& , "comment"
5656

5757
c$ PRINT *, "msg1"
58-
c$1 & , "comment"
58+
c$* & , "comment"
5959
c$ x & , "comment"
6060
c$ +& , "comment"
6161

flang/test/Parser/continuation-in-conditional-compilation.f

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,4 +21,10 @@ program main
2121
!$omp parallel
2222
!$acc+comment
2323
!$omp end parallel
24+
25+
! Conditional compilation statements beginning with a continuation line
26+
! are allowed with a warning.
27+
! CHECK: !$ &i=5
28+
c comment
29+
c$ !i=5
2430
end

0 commit comments

Comments
 (0)