Skip to content

Commit 8643f5e

Browse files
committed
[flang] Handle more use cases reported for issues/78797
I implemented legacy "token pasting" via line continuation for call prefix& &MACRO& &suffix(1) in a recent patch; this patch addresses the related cases call prefix& &MACRO& &(1) and call & &MACRO& &suffix(1) and call prefix& &MACRO Fixes the latest #79590.
1 parent e6fdbd1 commit 8643f5e

File tree

6 files changed

+43
-19
lines changed

6 files changed

+43
-19
lines changed

flang/lib/Parser/prescan.cpp

+15-5
Original file line numberDiff line numberDiff line change
@@ -630,22 +630,32 @@ bool Prescanner::NextToken(TokenSequence &tokens) {
630630
preventHollerith_ = false;
631631
} else if (IsLegalInIdentifier(*at_)) {
632632
int parts{1};
633+
const char *afterLast{nullptr};
633634
do {
634635
EmitChar(tokens, *at_);
635636
++at_, ++column_;
637+
afterLast = at_;
636638
if (SkipToNextSignificantCharacter() && IsLegalIdentifierStart(*at_)) {
637639
tokens.CloseToken();
638640
++parts;
639641
}
640642
} while (IsLegalInIdentifier(*at_));
641643
if (parts >= 3) {
642644
// Subtlety: When an identifier is split across three or more continuation
643-
// lines, its parts are kept as distinct pp-tokens so that macro
644-
// operates on them independently. This trick accommodates the historic
645-
// practice of using line continuation for token pasting after
646-
// replacement.
645+
// lines (or two continuation lines, immediately preceded or followed
646+
// by '&' free form continuation line markers, its parts are kept as
647+
// distinct pp-tokens so that macro operates on them independently.
648+
// This trick accommodates the historic practice of using line
649+
// continuation for token pasting after replacement.
647650
} else if (parts == 2) {
648-
tokens.ReopenLastToken();
651+
if ((start > start_ && start[-1] == '&') ||
652+
(afterLast < limit_ && (*afterLast == '&' || *afterLast == '\n'))) {
653+
// call & call foo& call foo&
654+
// &MACRO& OR &MACRO& OR &MACRO
655+
// &foo(...) &(...)
656+
} else {
657+
tokens.ReopenLastToken();
658+
}
649659
}
650660
if (InFixedFormSource()) {
651661
SkipSpaces();

flang/test/Preprocessing/pp005.F

+3-3
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,11 @@
11
! RUN: %flang -E %s 2>&1 | FileCheck %s
2-
! CHECK: res = 777
2+
! CHECK: res = (777)
33
* KWM split across continuation, implicit padding
44
integer, parameter :: KWM = 666
55
#define KWM 777
66
integer :: res
7-
res = KW
8-
+M
7+
res = (KW
8+
+M)
99
if (res .eq. 777) then
1010
print *, 'pp005.F yes'
1111
else

flang/test/Preprocessing/pp006.F

+3-3
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,12 @@
11
! RUN: %flang -E %s 2>&1 | FileCheck %s
2-
! CHECK: res = 777
2+
! CHECK: res = (777)
33
* ditto, but with intervening *comment line
44
integer, parameter :: KWM = 666
55
#define KWM 777
66
integer :: res
7-
res = KW
7+
res = (KW
88
*comment
9-
+M
9+
+M)
1010
if (res .eq. 777) then
1111
print *, 'pp006.F yes'
1212
else

flang/test/Preprocessing/pp105.F90

+3-3
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,11 @@
11
! RUN: %flang -E %s 2>&1 | FileCheck %s
2-
! CHECK: res = 777
2+
! CHECK: res = (777)
33
! KWM call name split across continuation, with leading &
44
integer, parameter :: KWM = 666
55
#define KWM 777
66
integer :: res
7-
res = KW&
8-
&M
7+
res = (KW&
8+
&M)
99
if (res .eq. 777) then
1010
print *, 'pp105.F90 yes'
1111
else

flang/test/Preprocessing/pp106.F90

+3-3
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,11 @@
11
! RUN: %flang -E %s 2>&1 | FileCheck %s
2-
! CHECK: res = 777
2+
! CHECK: res = (777)
33
! ditto, with & ! comment
44
integer, parameter :: KWM = 666
55
#define KWM 777
66
integer :: res
7-
res = KW& ! comment
8-
&M
7+
res = (KW& ! comment
8+
&M)
99
if (res .eq. 777) then
1010
print *, 'pp106.F90 yes'
1111
else

flang/test/Preprocessing/pp134.F90

+16-2
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,23 @@
11
! RUN: %flang -E %s 2>&1 | FileCheck %s
2-
! CHECK: print *, ADC
2+
! CHECK: print *, ADC, 1
3+
! CHECK: print *, AD, 1
4+
! CHECK: print *, DC, 1
5+
! CHECK: print *, AD
6+
! CHECK: print *, AB
37
#define B D
48
implicit none
59
real ADC
610
print *, A&
711
&B&
8-
&C
12+
&C, 1
13+
print *, A&
14+
&B&
15+
&, 1
16+
print *, &
17+
&B&
18+
&C, 1
19+
print *, A&
20+
&B
21+
print *, A&
22+
&B ! but not this
923
end

0 commit comments

Comments
 (0)