diff --git a/flang/lib/Parser/prescan.cpp b/flang/lib/Parser/prescan.cpp index f7f22177a7d0b..e9b23172ed2e2 100644 --- a/flang/lib/Parser/prescan.cpp +++ b/flang/lib/Parser/prescan.cpp @@ -630,9 +630,11 @@ bool Prescanner::NextToken(TokenSequence &tokens) { preventHollerith_ = false; } else if (IsLegalInIdentifier(*at_)) { int parts{1}; + const char *afterLast{nullptr}; do { EmitChar(tokens, *at_); ++at_, ++column_; + afterLast = at_; if (SkipToNextSignificantCharacter() && IsLegalIdentifierStart(*at_)) { tokens.CloseToken(); ++parts; @@ -640,12 +642,20 @@ bool Prescanner::NextToken(TokenSequence &tokens) { } while (IsLegalInIdentifier(*at_)); if (parts >= 3) { // Subtlety: When an identifier is split across three or more continuation - // lines, its parts are kept as distinct pp-tokens so that macro - // operates on them independently. This trick accommodates the historic - // practice of using line continuation for token pasting after - // replacement. + // lines (or two continuation lines, immediately preceded or followed + // by '&' free form continuation line markers, its parts are kept as + // distinct pp-tokens so that macro operates on them independently. + // This trick accommodates the historic practice of using line + // continuation for token pasting after replacement. } else if (parts == 2) { - tokens.ReopenLastToken(); + if ((start > start_ && start[-1] == '&') || + (afterLast < limit_ && (*afterLast == '&' || *afterLast == '\n'))) { + // call & call foo& call foo& + // &MACRO& OR &MACRO& OR &MACRO + // &foo(...) &(...) + } else { + tokens.ReopenLastToken(); + } } if (InFixedFormSource()) { SkipSpaces(); diff --git a/flang/test/Preprocessing/pp005.F b/flang/test/Preprocessing/pp005.F index e4483b404c367..a8d7394cb12d3 100644 --- a/flang/test/Preprocessing/pp005.F +++ b/flang/test/Preprocessing/pp005.F @@ -1,11 +1,11 @@ ! RUN: %flang -E %s 2>&1 | FileCheck %s -! CHECK: res = 777 +! CHECK: res = (777) * KWM split across continuation, implicit padding integer, parameter :: KWM = 666 #define KWM 777 integer :: res - res = KW - +M + res = (KW + +M) if (res .eq. 777) then print *, 'pp005.F yes' else diff --git a/flang/test/Preprocessing/pp006.F b/flang/test/Preprocessing/pp006.F index f526ad31733ef..e45dcf9c18e19 100644 --- a/flang/test/Preprocessing/pp006.F +++ b/flang/test/Preprocessing/pp006.F @@ -1,12 +1,12 @@ ! RUN: %flang -E %s 2>&1 | FileCheck %s -! CHECK: res = 777 +! CHECK: res = (777) * ditto, but with intervening *comment line integer, parameter :: KWM = 666 #define KWM 777 integer :: res - res = KW + res = (KW *comment - +M + +M) if (res .eq. 777) then print *, 'pp006.F yes' else diff --git a/flang/test/Preprocessing/pp105.F90 b/flang/test/Preprocessing/pp105.F90 index b4f73da6fa24c..e861e9688d2c5 100644 --- a/flang/test/Preprocessing/pp105.F90 +++ b/flang/test/Preprocessing/pp105.F90 @@ -1,11 +1,11 @@ ! RUN: %flang -E %s 2>&1 | FileCheck %s -! CHECK: res = 777 +! CHECK: res = (777) ! KWM call name split across continuation, with leading & integer, parameter :: KWM = 666 #define KWM 777 integer :: res - res = KW& -&M + res = (KW& +&M) if (res .eq. 777) then print *, 'pp105.F90 yes' else diff --git a/flang/test/Preprocessing/pp106.F90 b/flang/test/Preprocessing/pp106.F90 index 556d779048f6c..a450807f0bd21 100644 --- a/flang/test/Preprocessing/pp106.F90 +++ b/flang/test/Preprocessing/pp106.F90 @@ -1,11 +1,11 @@ ! RUN: %flang -E %s 2>&1 | FileCheck %s -! CHECK: res = 777 +! CHECK: res = (777) ! ditto, with & ! comment integer, parameter :: KWM = 666 #define KWM 777 integer :: res - res = KW& ! comment -&M + res = (KW& ! comment +&M) if (res .eq. 777) then print *, 'pp106.F90 yes' else diff --git a/flang/test/Preprocessing/pp134.F90 b/flang/test/Preprocessing/pp134.F90 index 01e7b010d426e..bc34767224fa0 100644 --- a/flang/test/Preprocessing/pp134.F90 +++ b/flang/test/Preprocessing/pp134.F90 @@ -1,9 +1,23 @@ ! RUN: %flang -E %s 2>&1 | FileCheck %s -! CHECK: print *, ADC +! CHECK: print *, ADC, 1 +! CHECK: print *, AD, 1 +! CHECK: print *, DC, 1 +! CHECK: print *, AD +! CHECK: print *, AB #define B D implicit none real ADC print *, A& &B& - &C + &C, 1 +print *, A& + &B& + &, 1 +print *, & + &B& + &C, 1 +print *, A& + &B +print *, A& + &B ! but not this end