Skip to content

Commit 0d69f83

Browse files
committed
ACC token and context duplication fixed
1 parent 6dbe82f commit 0d69f83

File tree

5 files changed

+392
-16
lines changed

5 files changed

+392
-16
lines changed

flang/lib/Parser/message.cpp

Lines changed: 35 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -272,19 +272,49 @@ static llvm::raw_ostream::Colors PrefixColor(Severity severity) {
272272
return llvm::raw_ostream::SAVEDCOLOR;
273273
}
274274

275+
// FIXME: Make these configurable, based on verbosity level.
276+
const int MAX_CONTEXTS_EMITTED = 2;
277+
const bool OMIT_SHARED_CONTEXTS = true;
278+
275279
void Message::Emit(llvm::raw_ostream &o, const AllCookedSources &allCooked,
276280
bool echoSourceLine) const {
277281
std::optional<ProvenanceRange> provenanceRange{GetProvenanceRange(allCooked)};
278282
const AllSources &sources{allCooked.allSources()};
279283
sources.EmitMessage(o, provenanceRange, ToString(), Prefix(severity()),
280284
PrefixColor(severity()), echoSourceLine);
281285
bool isContext{attachmentIsContext_};
286+
int contextsEmitted{isContext ? 1 : 0};
287+
// Emit attachments.
282288
for (const Message *attachment{attachment_.get()}; attachment;
283-
attachment = attachment->attachment_.get()) {
289+
attachment = attachment->attachment_.get()) {
284290
Severity severity = isContext ? Severity::Context : attachment->severity();
285-
sources.EmitMessage(o, attachment->GetProvenanceRange(allCooked),
286-
attachment->ToString(), Prefix(severity), PrefixColor(severity),
287-
echoSourceLine);
291+
auto emitAttachment = [&]() {
292+
sources.EmitMessage(o, attachment->GetProvenanceRange(allCooked),
293+
attachment->ToString(), Prefix(severity), PrefixColor(severity),
294+
echoSourceLine);
295+
};
296+
// TODO isContext is not used correctly here.
297+
if (attachment->attachmentIsContext_) {
298+
// Truncate the number of contexts emitted.
299+
if (contextsEmitted <= MAX_CONTEXTS_EMITTED) {
300+
emitAttachment();
301+
contextsEmitted += 1;
302+
}
303+
if (OMIT_SHARED_CONTEXTS) {
304+
// Skip less specific contexts at the same location.
305+
for (const Message *next_attachment{attachment->attachment_.get()};
306+
next_attachment && next_attachment->attachmentIsContext_ &&
307+
next_attachment->AtSameLocation(*attachment);
308+
next_attachment = next_attachment->attachment_.get()) {
309+
attachment = next_attachment;
310+
}
311+
// NB, this loop increments `attachment` one more time after the
312+
// previous loop is done advancing it to the last context at the same
313+
// location.
314+
}
315+
} else {
316+
emitAttachment();
317+
}
288318
}
289319
}
290320

@@ -298,7 +328,7 @@ bool Message::operator==(const Message &that) const {
298328
}
299329
const Message *thatAttachment{that.attachment_.get()};
300330
for (const Message *attachment{attachment_.get()}; attachment;
301-
attachment = attachment->attachment_.get()) {
331+
attachment = attachment->attachment_.get()) {
302332
if (!thatAttachment || !attachment->AtSameLocation(*thatAttachment) ||
303333
attachment->ToString() != thatAttachment->ToString() ||
304334
attachment->severity() != thatAttachment->severity()) {

flang/lib/Parser/openacc-parsers.cpp

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -19,8 +19,12 @@
1919
// OpenACC Directives and Clauses
2020
namespace Fortran::parser {
2121

22+
// Only need to handle ! line comments because prescanning normalizes the
23+
// other types of line comments from fixed form.
2224
constexpr auto startAccLine{skipStuffBeforeStatement >>
23-
("!$ACC "_sptok || "C$ACC "_sptok || "*$ACC "_sptok)};
25+
withMessage(
26+
"expected OpenACC comment '!$ACC' (free-form), 'C$ACC', or '*$ACC' (fixed-form)"_err_en_US,
27+
"!$ACC "_sptok)};
2428
constexpr auto endAccLine{space >> endOfLine};
2529

2630
// Autogenerated clauses parser. Information is taken from ACC.td and the
@@ -225,7 +229,8 @@ TYPE_PARSER(startAccLine >> sourced(construct<AccEndBlockDirective>("END"_tok >>
225229

226230
TYPE_PARSER(construct<OpenACCBlockConstruct>(
227231
Parser<AccBeginBlockDirective>{} / endAccLine, block,
228-
Parser<AccEndBlockDirective>{} / endAccLine))
232+
withMessage("expected OpenACC end block directive"_err_en_US,
233+
Parser<AccEndBlockDirective>{} / endAccLine)))
229234

230235
// Standalone constructs
231236
TYPE_PARSER(construct<OpenACCStandaloneConstruct>(

flang/test/Driver/debug-parsing-log.f90

Lines changed: 9 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -12,14 +12,14 @@
1212
! CHECK-NEXT: {{.*[/\\]}}debug-parsing-log.f90:25:1: in the context: IMPLICIT statement
1313
! CHECK-NEXT: END PROGRAM
1414
! CHECK-NEXT: ^
15-
! CHECK-NEXT: {{.*[/\\]}}debug-parsing-log.f90:25:1: in the context: implicit part
16-
! CHECK-NEXT: END PROGRAM
17-
! CHECK-NEXT: ^
18-
! CHECK-NEXT: {{.*[/\\]}}debug-parsing-log.f90:25:1: in the context: specification part
19-
! CHECK-NEXT: END PROGRAM
20-
! CHECK-NEXT: ^
21-
! CHECK-NEXT: {{.*[/\\]}}debug-parsing-log.f90:25:1: in the context: main program
22-
! CHECK-NEXT: END PROGRAM
23-
! CHECK-NEXT: ^
15+
16+
17+
18+
19+
20+
21+
22+
23+
2424

2525
END PROGRAM
Lines changed: 245 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,245 @@
1+
! RUN: not %flang_fc1 -fsyntax-only -fopenacc %s 2>&1 | FileCheck %s
2+
program acc_data_test
3+
implicit none
4+
integer :: a(100), b(100), c(100), d(100)
5+
integer :: i, s ! FIXME: if s is named sum you get semantic errors.
6+
7+
! Positive tests
8+
9+
! Basic data construct in program body
10+
!$acc data copy(a, b) create(c)
11+
a = 1
12+
b = 2
13+
c = a + b
14+
!$acc end data
15+
print *, "After first data region"
16+
17+
! Data construct within IF block
18+
if (.true.) then
19+
!$acc data copyout(a)
20+
a = a + 1
21+
!$acc end data
22+
print *, "Inside if block"
23+
end if
24+
25+
! Data construct within DO loop
26+
do i = 1, 10
27+
!$acc data present(a)
28+
a(i) = a(i) * 2
29+
!$acc end data
30+
print *, "Loop iteration", i
31+
end do
32+
33+
! Nested data constructs
34+
!$acc data copyin(a)
35+
s = 0
36+
!$acc data copy(s)
37+
s = s + 1
38+
!$acc end data
39+
print *, "After nested data"
40+
!$acc end data
41+
42+
! Negative tests
43+
! Basic data construct in program body
44+
!$acc data copy(a, b) create(d)
45+
a = 1
46+
b = 2
47+
d = a + b
48+
! !$acc end data
49+
print *, "After first data region"
50+
51+
! Data construct within IF block
52+
if (.true.) then
53+
!$acc data copyout(a)
54+
a = a + 1
55+
! !$acc end data
56+
print *, "Inside if block"
57+
! First error in the file.
58+
!CHECK: acc-data-statement.f90:
59+
!CHECK-SAME: [[ELINE1:[0-9]+]]:{{[0-9]+}}:
60+
!CHECK-SAME: error: expected OpenACC end block directive
61+
!CHECK-NEXT: end if
62+
!CHECK-NEXT: ^
63+
!CHECK-NEXT: in the context: OpenACC construct
64+
!CHECK-NEXT: !$acc data copyout(a)
65+
!CHECK-NEXT: ^
66+
!CHECK-NEXT: in the context: IF construct
67+
!CHECK-NEXT: if (.true.) then
68+
!CHECK-NEXT: ^
69+
!CHECK-NEXT: error: expected OpenACC end block directive
70+
!CHECK-NEXT: end if
71+
!CHECK-NEXT: ^
72+
!CHECK-NEXT: in the context: OpenACC construct
73+
!CHECK-NEXT: !$acc data copyout(a)
74+
!CHECK-NEXT: ^
75+
!CHECK-NEXT: in the context: IF construct
76+
!CHECK-NEXT: if (.true.) then
77+
!CHECK-NEXT: ^
78+
end if
79+
80+
! Data construct within DO loop
81+
do i = 1, 10
82+
!$acc data present(a)
83+
a(i) = a(i) * 2
84+
! !$acc end data
85+
print *, "Loop iteration", i
86+
!CHECK: acc-data-statement.f90:
87+
!CHECK-NOT: [[ELINE1]]
88+
!CHECK-SAME: [[ELINE2:[0-9]+]]:{{[0-9]+}}:
89+
!CHECK-SAME: error: expected OpenACC end block directive
90+
!CHECK-NEXT: end do
91+
!CHECK-NEXT: ^
92+
!CHECK-NEXT: in the context: OpenACC construct
93+
!CHECK-NEXT: !$acc data present(a)
94+
!CHECK-NEXT: ^
95+
!CHECK-NEXT: in the context: DO construct
96+
!CHECK-NEXT: do i = 1, 10
97+
!CHECK-NEXT: ^
98+
!CHECK-NEXT: error: expected OpenACC end block directive
99+
!CHECK-NEXT: end do
100+
!CHECK-NEXT: ^
101+
!CHECK-NEXT: in the context: OpenACC construct
102+
!CHECK-NEXT: !$acc data present(a)
103+
!CHECK-NEXT: ^
104+
!CHECK-NEXT: in the context: DO construct
105+
!CHECK-NEXT: do i = 1, 10
106+
!CHECK-NEXT: ^
107+
end do
108+
109+
! Nested data constructs
110+
!$acc data copyin(a)
111+
s = 0
112+
!$acc data copy(s)
113+
s = s + 1
114+
! !$acc end data
115+
print *, "After nested data"
116+
! !$acc end data
117+
118+
print *, "Program finished"
119+
!CHECK: acc-data-statement.f90:
120+
!CHECK-NOT: [[ELINE2]]
121+
!CHECK-SAME: [[ELINE3:[0-9]+]]:{{[0-9]+}}:
122+
!CHECK-SAME: error: expected OpenACC end block directive
123+
!CHECK-NEXT: contains
124+
!CHECK-NEXT: ^
125+
!CHECK-NEXT: in the context: OpenACC construct
126+
!CHECK-NEXT: !$acc data copy(s)
127+
!CHECK-NEXT: ^
128+
!CHECK-NEXT: in the context: execution part
129+
!CHECK-NEXT: !$acc data copy(a, b) create(c)
130+
!CHECK-NEXT: ^
131+
!CHECK-NEXT: error: expected OpenACC end block directive
132+
!CHECK-NEXT: contains
133+
!CHECK-NEXT: ^
134+
!CHECK-NEXT: in the context: OpenACC construct
135+
!CHECK-NEXT: !$acc data copy(s)
136+
!CHECK-NEXT: ^
137+
!CHECK-NEXT: in the context: OpenACC construct
138+
!CHECK-NEXT: !$acc data copyin(a)
139+
!CHECK-NEXT: ^
140+
!CHECK-NEXT: error: expected OpenACC end block directive
141+
!CHECK-NEXT: contains
142+
!CHECK-NEXT: ^
143+
!CHECK-NEXT: in the context: OpenACC construct
144+
!CHECK-NEXT: !$acc data copyin(a)
145+
!CHECK-NEXT: ^
146+
!CHECK-NEXT: in the context: execution part
147+
!CHECK-NEXT: !$acc data copy(a, b) create(c)
148+
!CHECK-NEXT: ^
149+
!CHECK-NEXT: error: expected OpenACC end block directive
150+
!CHECK-NEXT: contains
151+
!CHECK-NEXT: ^
152+
!CHECK-NEXT: in the context: OpenACC construct
153+
!CHECK-NEXT: !$acc data copy(s)
154+
!CHECK-NEXT: ^
155+
!CHECK-NEXT: in the context: OpenACC construct
156+
!CHECK-NEXT: !$acc data copy(a, b) create(d)
157+
!CHECK-NEXT: ^
158+
!CHECK-NEXT: error: expected OpenACC end block directive
159+
!CHECK-NEXT: contains
160+
!CHECK-NEXT: ^
161+
!CHECK-NEXT: in the context: OpenACC construct
162+
!CHECK-NEXT: !$acc data copy(s)
163+
!CHECK-NEXT: ^
164+
!CHECK-NEXT: in the context: OpenACC construct
165+
!CHECK-NEXT: !$acc data copyin(a)
166+
!CHECK-NEXT: ^
167+
!CHECK-NEXT: error: expected OpenACC end block directive
168+
!CHECK-NEXT: contains
169+
!CHECK-NEXT: ^
170+
!CHECK-NEXT: in the context: OpenACC construct
171+
!CHECK-NEXT: !$acc data copyin(a)
172+
!CHECK-NEXT: ^
173+
!CHECK-NEXT: in the context: OpenACC construct
174+
!CHECK-NEXT: !$acc data copy(a, b) create(d)
175+
!CHECK-NEXT: ^
176+
!CHECK-NEXT: error: expected OpenACC end block directive
177+
!CHECK-NEXT: contains
178+
!CHECK-NEXT: ^
179+
!CHECK-NEXT: in the context: OpenACC construct
180+
!CHECK-NEXT: !$acc data copy(a, b) create(d)
181+
!CHECK-NEXT: ^
182+
!CHECK-NEXT: in the context: execution part
183+
!CHECK-NEXT: !$acc data copy(a, b) create(c)
184+
!CHECK-NEXT: ^
185+
contains
186+
subroutine positive_process_array(x)
187+
integer, intent(inout) :: x(:)
188+
189+
! Data construct in subroutine
190+
!$acc data copy(x)
191+
x = x + 1
192+
!$acc end data
193+
print *, "Subroutine finished"
194+
end subroutine
195+
196+
function positive_compute_sum(x) result(total)
197+
integer, intent(in) :: x(:)
198+
integer :: total
199+
200+
! Data construct in function
201+
!$acc data copyin(x) copy(total)
202+
total = sum(x)
203+
!$acc end data
204+
print *, "Function finished"
205+
end function
206+
207+
subroutine negative_process_array(x)
208+
integer, intent(inout) :: x(:)
209+
210+
! Data construct in subroutine
211+
!$acc data copy(x)
212+
x = x + 1
213+
! !$acc end data
214+
print *, "Subroutine finished"
215+
!CHECK: error: expected OpenACC directive
216+
!CHECK-NEXT: !$acc data copy(x)
217+
!CHECK-NEXT: ^
218+
!CHECK-NEXT: in the context: specification construct
219+
!CHECK-NEXT: !$acc data copy(x)
220+
!CHECK-NEXT: ^
221+
!CHECK-NEXT: in the context: specification part
222+
!CHECK-NEXT: integer, intent(inout) :: x(:)
223+
!CHECK-NEXT: ^
224+
end subroutine
225+
226+
function negative_compute_sum(x) result(total)
227+
integer, intent(in) :: x(:)
228+
integer :: total
229+
total = sum(x)
230+
! Data construct in function
231+
!$acc data copyin(x) copy(total)
232+
total = total + x
233+
! !$acc end data
234+
print *, "Function finished"
235+
!CHECK: error: expected OpenACC end block directive
236+
!CHECK-NEXT: end function
237+
!CHECK-NEXT: ^
238+
!CHECK-NEXT: in the context: OpenACC construct
239+
!CHECK-NEXT: !$acc data copyin(x) copy(total)
240+
!CHECK-NEXT: ^
241+
!CHECK-NEXT: in the context: execution part
242+
!CHECK-NEXT: total = sum(x)
243+
!CHECK-NEXT: ^
244+
end function
245+
end program acc_data_test

0 commit comments

Comments
 (0)