-
Notifications
You must be signed in to change notification settings - Fork 14.3k
[flang][openacc] Make OpenACC block construct parse errors less verbose. #131042
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Conversation
@llvm/pr-subscribers-flang-parser @llvm/pr-subscribers-flang-driver Author: Andre Kuhlenschmidt (akuhlens) ChangesThis PR does reduces the verbosity of parser errors for OpenACC block constructs that do not parse correctly because they are missing their trailing end block directive by:
Prior to the changes:
Note there are still several bugs in the parsing that I would like to fix, but I am uploading this to talk with @klausler about where to look for those.
Full diff: https://github.com/llvm/llvm-project/pull/131042.diff 5 Files Affected:
diff --git a/flang/lib/Parser/message.cpp b/flang/lib/Parser/message.cpp
index 69e4814bf246c..0b8d300189a1b 100644
--- a/flang/lib/Parser/message.cpp
+++ b/flang/lib/Parser/message.cpp
@@ -272,6 +272,10 @@ static llvm::raw_ostream::Colors PrefixColor(Severity severity) {
return llvm::raw_ostream::SAVEDCOLOR;
}
+// FIXME: Make these configurable, based on verbosity level.
+const int MAX_CONTEXTS_EMITTED = 2;
+const bool OMIT_SHARED_CONTEXTS = true;
+
void Message::Emit(llvm::raw_ostream &o, const AllCookedSources &allCooked,
bool echoSourceLine) const {
std::optional<ProvenanceRange> provenanceRange{GetProvenanceRange(allCooked)};
@@ -279,12 +283,38 @@ void Message::Emit(llvm::raw_ostream &o, const AllCookedSources &allCooked,
sources.EmitMessage(o, provenanceRange, ToString(), Prefix(severity()),
PrefixColor(severity()), echoSourceLine);
bool isContext{attachmentIsContext_};
+ int contextsEmitted{isContext ? 1 : 0};
+ // Emit attachments.
for (const Message *attachment{attachment_.get()}; attachment;
- attachment = attachment->attachment_.get()) {
+ attachment = attachment->attachment_.get()) {
Severity severity = isContext ? Severity::Context : attachment->severity();
- sources.EmitMessage(o, attachment->GetProvenanceRange(allCooked),
- attachment->ToString(), Prefix(severity), PrefixColor(severity),
- echoSourceLine);
+ auto emitAttachment = [&]() {
+ sources.EmitMessage(o, attachment->GetProvenanceRange(allCooked),
+ attachment->ToString(), Prefix(severity), PrefixColor(severity),
+ echoSourceLine);
+ };
+ // TODO isContext is not used correctly here.
+ if (attachment->attachmentIsContext_) {
+ // Truncate the number of contexts emitted.
+ if (contextsEmitted <= MAX_CONTEXTS_EMITTED) {
+ emitAttachment();
+ contextsEmitted += 1;
+ }
+ if (OMIT_SHARED_CONTEXTS) {
+ // Skip less specific contexts at the same location.
+ for (const Message *next_attachment{attachment->attachment_.get()};
+ next_attachment && next_attachment->attachmentIsContext_ &&
+ next_attachment->AtSameLocation(*attachment);
+ next_attachment = next_attachment->attachment_.get()) {
+ attachment = next_attachment;
+ }
+ // NB, this loop increments `attachment` one more time after the
+ // previous loop is done advancing it to the last context at the same
+ // location.
+ }
+ } else {
+ emitAttachment();
+ }
}
}
@@ -298,7 +328,7 @@ bool Message::operator==(const Message &that) const {
}
const Message *thatAttachment{that.attachment_.get()};
for (const Message *attachment{attachment_.get()}; attachment;
- attachment = attachment->attachment_.get()) {
+ attachment = attachment->attachment_.get()) {
if (!thatAttachment || !attachment->AtSameLocation(*thatAttachment) ||
attachment->ToString() != thatAttachment->ToString() ||
attachment->severity() != thatAttachment->severity()) {
diff --git a/flang/lib/Parser/openacc-parsers.cpp b/flang/lib/Parser/openacc-parsers.cpp
index c78676664e0a3..6739bcc035fc2 100644
--- a/flang/lib/Parser/openacc-parsers.cpp
+++ b/flang/lib/Parser/openacc-parsers.cpp
@@ -19,8 +19,12 @@
// OpenACC Directives and Clauses
namespace Fortran::parser {
+// Only need to handle ! line comments because prescanning normalizes the
+// other types of line comments from fixed form.
constexpr auto startAccLine{skipStuffBeforeStatement >>
- ("!$ACC "_sptok || "C$ACC "_sptok || "*$ACC "_sptok)};
+ withMessage(
+ "expected OpenACC comment '!$ACC' (free-form), 'C$ACC', or '*$ACC' (fixed-form)"_err_en_US,
+ "!$ACC "_sptok)};
constexpr auto endAccLine{space >> endOfLine};
// Autogenerated clauses parser. Information is taken from ACC.td and the
@@ -225,7 +229,8 @@ TYPE_PARSER(startAccLine >> sourced(construct<AccEndBlockDirective>("END"_tok >>
TYPE_PARSER(construct<OpenACCBlockConstruct>(
Parser<AccBeginBlockDirective>{} / endAccLine, block,
- Parser<AccEndBlockDirective>{} / endAccLine))
+ withMessage("expected OpenACC end block directive"_err_en_US,
+ Parser<AccEndBlockDirective>{} / endAccLine)))
// Standalone constructs
TYPE_PARSER(construct<OpenACCStandaloneConstruct>(
diff --git a/flang/test/Driver/debug-parsing-log.f90 b/flang/test/Driver/debug-parsing-log.f90
index 7297163109450..4e56add386ef8 100644
--- a/flang/test/Driver/debug-parsing-log.f90
+++ b/flang/test/Driver/debug-parsing-log.f90
@@ -12,14 +12,14 @@
! CHECK-NEXT: {{.*[/\\]}}debug-parsing-log.f90:25:1: in the context: IMPLICIT statement
! CHECK-NEXT: END PROGRAM
! CHECK-NEXT: ^
-! CHECK-NEXT: {{.*[/\\]}}debug-parsing-log.f90:25:1: in the context: implicit part
-! CHECK-NEXT: END PROGRAM
-! CHECK-NEXT: ^
-! CHECK-NEXT: {{.*[/\\]}}debug-parsing-log.f90:25:1: in the context: specification part
-! CHECK-NEXT: END PROGRAM
-! CHECK-NEXT: ^
-! CHECK-NEXT: {{.*[/\\]}}debug-parsing-log.f90:25:1: in the context: main program
-! CHECK-NEXT: END PROGRAM
-! CHECK-NEXT: ^
+
+
+
+
+
+
+
+
+
END PROGRAM
diff --git a/flang/test/Parser/acc-data-statement.f90 b/flang/test/Parser/acc-data-statement.f90
new file mode 100644
index 0000000000000..1e369a0db3780
--- /dev/null
+++ b/flang/test/Parser/acc-data-statement.f90
@@ -0,0 +1,245 @@
+! RUN: not %flang_fc1 -fsyntax-only -fopenacc %s 2>&1 | FileCheck %s
+program acc_data_test
+ implicit none
+ integer :: a(100), b(100), c(100), d(100)
+ integer :: i, s ! FIXME: if s is named sum you get semantic errors.
+
+ ! Positive tests
+
+ ! Basic data construct in program body
+ !$acc data copy(a, b) create(c)
+ a = 1
+ b = 2
+ c = a + b
+ !$acc end data
+ print *, "After first data region"
+
+ ! Data construct within IF block
+ if (.true.) then
+ !$acc data copyout(a)
+ a = a + 1
+ !$acc end data
+ print *, "Inside if block"
+ end if
+
+ ! Data construct within DO loop
+ do i = 1, 10
+ !$acc data present(a)
+ a(i) = a(i) * 2
+ !$acc end data
+ print *, "Loop iteration", i
+ end do
+
+ ! Nested data constructs
+ !$acc data copyin(a)
+ s = 0
+ !$acc data copy(s)
+ s = s + 1
+ !$acc end data
+ print *, "After nested data"
+ !$acc end data
+
+ ! Negative tests
+ ! Basic data construct in program body
+ !$acc data copy(a, b) create(d)
+ a = 1
+ b = 2
+ d = a + b
+! !$acc end data
+ print *, "After first data region"
+
+ ! Data construct within IF block
+ if (.true.) then
+ !$acc data copyout(a)
+ a = a + 1
+! !$acc end data
+ print *, "Inside if block"
+ ! First error in the file.
+ !CHECK: acc-data-statement.f90:
+ !CHECK-SAME: [[ELINE1:[0-9]+]]:{{[0-9]+}}:
+ !CHECK-SAME: error: expected OpenACC end block directive
+ !CHECK-NEXT: end if
+ !CHECK-NEXT: ^
+ !CHECK-NEXT: in the context: OpenACC construct
+ !CHECK-NEXT: !$acc data copyout(a)
+ !CHECK-NEXT: ^
+ !CHECK-NEXT: in the context: IF construct
+ !CHECK-NEXT: if (.true.) then
+ !CHECK-NEXT: ^
+ !CHECK-NEXT: error: expected OpenACC end block directive
+ !CHECK-NEXT: end if
+ !CHECK-NEXT: ^
+ !CHECK-NEXT: in the context: OpenACC construct
+ !CHECK-NEXT: !$acc data copyout(a)
+ !CHECK-NEXT: ^
+ !CHECK-NEXT: in the context: IF construct
+ !CHECK-NEXT: if (.true.) then
+ !CHECK-NEXT: ^
+ end if
+
+ ! Data construct within DO loop
+ do i = 1, 10
+ !$acc data present(a)
+ a(i) = a(i) * 2
+! !$acc end data
+ print *, "Loop iteration", i
+ !CHECK: acc-data-statement.f90:
+ !CHECK-NOT: [[ELINE1]]
+ !CHECK-SAME: [[ELINE2:[0-9]+]]:{{[0-9]+}}:
+ !CHECK-SAME: error: expected OpenACC end block directive
+ !CHECK-NEXT: end do
+ !CHECK-NEXT: ^
+ !CHECK-NEXT: in the context: OpenACC construct
+ !CHECK-NEXT: !$acc data present(a)
+ !CHECK-NEXT: ^
+ !CHECK-NEXT: in the context: DO construct
+ !CHECK-NEXT: do i = 1, 10
+ !CHECK-NEXT: ^
+ !CHECK-NEXT: error: expected OpenACC end block directive
+ !CHECK-NEXT: end do
+ !CHECK-NEXT: ^
+ !CHECK-NEXT: in the context: OpenACC construct
+ !CHECK-NEXT: !$acc data present(a)
+ !CHECK-NEXT: ^
+ !CHECK-NEXT: in the context: DO construct
+ !CHECK-NEXT: do i = 1, 10
+ !CHECK-NEXT: ^
+ end do
+
+ ! Nested data constructs
+ !$acc data copyin(a)
+ s = 0
+ !$acc data copy(s)
+ s = s + 1
+! !$acc end data
+ print *, "After nested data"
+! !$acc end data
+
+ print *, "Program finished"
+ !CHECK: acc-data-statement.f90:
+ !CHECK-NOT: [[ELINE2]]
+ !CHECK-SAME: [[ELINE3:[0-9]+]]:{{[0-9]+}}:
+ !CHECK-SAME: error: expected OpenACC end block directive
+ !CHECK-NEXT: contains
+ !CHECK-NEXT: ^
+ !CHECK-NEXT: in the context: OpenACC construct
+ !CHECK-NEXT: !$acc data copy(s)
+ !CHECK-NEXT: ^
+ !CHECK-NEXT: in the context: execution part
+ !CHECK-NEXT: !$acc data copy(a, b) create(c)
+ !CHECK-NEXT: ^
+ !CHECK-NEXT: error: expected OpenACC end block directive
+ !CHECK-NEXT: contains
+ !CHECK-NEXT: ^
+ !CHECK-NEXT: in the context: OpenACC construct
+ !CHECK-NEXT: !$acc data copy(s)
+ !CHECK-NEXT: ^
+ !CHECK-NEXT: in the context: OpenACC construct
+ !CHECK-NEXT: !$acc data copyin(a)
+ !CHECK-NEXT: ^
+ !CHECK-NEXT: error: expected OpenACC end block directive
+ !CHECK-NEXT: contains
+ !CHECK-NEXT: ^
+ !CHECK-NEXT: in the context: OpenACC construct
+ !CHECK-NEXT: !$acc data copyin(a)
+ !CHECK-NEXT: ^
+ !CHECK-NEXT: in the context: execution part
+ !CHECK-NEXT: !$acc data copy(a, b) create(c)
+ !CHECK-NEXT: ^
+ !CHECK-NEXT: error: expected OpenACC end block directive
+ !CHECK-NEXT: contains
+ !CHECK-NEXT: ^
+ !CHECK-NEXT: in the context: OpenACC construct
+ !CHECK-NEXT: !$acc data copy(s)
+ !CHECK-NEXT: ^
+ !CHECK-NEXT: in the context: OpenACC construct
+ !CHECK-NEXT: !$acc data copy(a, b) create(d)
+ !CHECK-NEXT: ^
+ !CHECK-NEXT: error: expected OpenACC end block directive
+ !CHECK-NEXT: contains
+ !CHECK-NEXT: ^
+ !CHECK-NEXT: in the context: OpenACC construct
+ !CHECK-NEXT: !$acc data copy(s)
+ !CHECK-NEXT: ^
+ !CHECK-NEXT: in the context: OpenACC construct
+ !CHECK-NEXT: !$acc data copyin(a)
+ !CHECK-NEXT: ^
+ !CHECK-NEXT: error: expected OpenACC end block directive
+ !CHECK-NEXT: contains
+ !CHECK-NEXT: ^
+ !CHECK-NEXT: in the context: OpenACC construct
+ !CHECK-NEXT: !$acc data copyin(a)
+ !CHECK-NEXT: ^
+ !CHECK-NEXT: in the context: OpenACC construct
+ !CHECK-NEXT: !$acc data copy(a, b) create(d)
+ !CHECK-NEXT: ^
+ !CHECK-NEXT: error: expected OpenACC end block directive
+ !CHECK-NEXT: contains
+ !CHECK-NEXT: ^
+ !CHECK-NEXT: in the context: OpenACC construct
+ !CHECK-NEXT: !$acc data copy(a, b) create(d)
+ !CHECK-NEXT: ^
+ !CHECK-NEXT: in the context: execution part
+ !CHECK-NEXT: !$acc data copy(a, b) create(c)
+ !CHECK-NEXT: ^
+contains
+ subroutine positive_process_array(x)
+ integer, intent(inout) :: x(:)
+
+ ! Data construct in subroutine
+ !$acc data copy(x)
+ x = x + 1
+ !$acc end data
+ print *, "Subroutine finished"
+ end subroutine
+
+ function positive_compute_sum(x) result(total)
+ integer, intent(in) :: x(:)
+ integer :: total
+
+ ! Data construct in function
+ !$acc data copyin(x) copy(total)
+ total = sum(x)
+ !$acc end data
+ print *, "Function finished"
+ end function
+
+ subroutine negative_process_array(x)
+ integer, intent(inout) :: x(:)
+
+ ! Data construct in subroutine
+ !$acc data copy(x)
+ x = x + 1
+! !$acc end data
+ print *, "Subroutine finished"
+ !CHECK: error: expected OpenACC directive
+ !CHECK-NEXT: !$acc data copy(x)
+ !CHECK-NEXT: ^
+ !CHECK-NEXT: in the context: specification construct
+ !CHECK-NEXT: !$acc data copy(x)
+ !CHECK-NEXT: ^
+ !CHECK-NEXT: in the context: specification part
+ !CHECK-NEXT: integer, intent(inout) :: x(:)
+ !CHECK-NEXT: ^
+ end subroutine
+
+ function negative_compute_sum(x) result(total)
+ integer, intent(in) :: x(:)
+ integer :: total
+ total = sum(x)
+ ! Data construct in function
+ !$acc data copyin(x) copy(total)
+ total = total + x
+! !$acc end data
+ print *, "Function finished"
+ !CHECK: error: expected OpenACC end block directive
+ !CHECK-NEXT: end function
+ !CHECK-NEXT: ^
+ !CHECK-NEXT: in the context: OpenACC construct
+ !CHECK-NEXT: !$acc data copyin(x) copy(total)
+ !CHECK-NEXT: ^
+ !CHECK-NEXT: in the context: execution part
+ !CHECK-NEXT: total = sum(x)
+ !CHECK-NEXT: ^
+ end function
+end program acc_data_test
\ No newline at end of file
diff --git a/flang/test/Parser/acc.f b/flang/test/Parser/acc.f
new file mode 100644
index 0000000000000..b0c3927772568
--- /dev/null
+++ b/flang/test/Parser/acc.f
@@ -0,0 +1,96 @@
+! RUN: %flang_fc1 -fsyntax-only -fopenacc %s 2>&1
+C Test file for OpenACC directives in fixed-form Fortran
+ PROGRAM ACCTEST
+ IMPLICIT NONE
+ INTEGER :: N, I, J
+ PARAMETER (N=100)
+ REAL :: A(N), B(N), C(N), D(N)
+ REAL :: SUM
+
+C Initialize arrays
+ DO I = 1, N
+ A(I) = I * 1.0
+ B(I) = I * 2.0
+ C(I) = 0.0
+ D(I) = 1.0
+ END DO
+
+C Basic data construct using C$ACC
+C$ACC DATA COPYIN(A,B) COPYOUT(C)
+ DO I = 1, N
+ C(I) = A(I) + B(I)
+ END DO
+C$ACC END DATA
+
+* Parallel construct with loop using *$ACC
+*$ACC PARALLEL PRESENT(A,B,C)
+*$ACC LOOP
+ DO I = 1, N
+ C(I) = C(I) * 2.0
+ END DO
+*$ACC END PARALLEL
+
+C Nested loops with collapse - C$ACC style
+C$ACC PARALLEL LOOP COLLAPSE(2)
+ DO I = 1, N
+ DO J = 1, N
+ A(J) = A(J) + B(J)
+ END DO
+ END DO
+C$ACC END PARALLEL LOOP
+
+* Combined parallel loop with reduction - *$ACC style
+ SUM = 0.0
+*$ACC PARALLEL LOOP REDUCTION(+:SUM)
+ DO I = 1, N
+ SUM = SUM + C(I)
+ END DO
+*$ACC END PARALLEL LOOP
+
+C Kernels construct - C$ACC with continuation
+C$ACC KERNELS
+C$ACC+ COPYOUT(A)
+ DO I = 1, N
+ A(I) = A(I) * 2.0
+ END DO
+C$ACC END KERNELS
+
+* Data construct with update - *$ACC with continuation
+*$ACC DATA COPY(B)
+*$ACC+ PRESENT(D)
+ B(1) = 999.0
+*$ACC UPDATE HOST(B(1:1))
+ PRINT *, 'B(1) = ', B(1)
+*$ACC END DATA
+
+C Mixed style directives in nested constructs
+C$ACC DATA COPY(A,B,C)
+*$ACC PARALLEL LOOP
+ DO I = 1, N
+ A(I) = B(I) + C(I)
+ END DO
+*$ACC END PARALLEL LOOP
+C$ACC END DATA
+
+* Subroutine call within data region - *$ACC style
+*$ACC DATA COPY(A,B,C)
+ CALL SUB1(A, B, C, N)
+*$ACC END DATA
+
+ PRINT *, 'Sum = ', SUM
+ END PROGRAM
+
+C Subroutine with mixed ACC directive styles
+ SUBROUTINE SUB1(X, Y, Z, M)
+ INTEGER M, I
+ REAL X(M), Y(M), Z(M)
+
+*$ACC PARALLEL PRESENT(X,Y)
+C$ACC LOOP PRIVATE(I)
+ DO I = 1, M
+ Z(I) = X(I) + Y(I)
+ END DO
+C$ACC END LOOP
+*$ACC END PARALLEL
+ RETURN
+ END SUBROUTINE
\ No newline at end of file
|
@llvm/pr-subscribers-openacc Author: Andre Kuhlenschmidt (akuhlens) ChangesThis PR does reduces the verbosity of parser errors for OpenACC block constructs that do not parse correctly because they are missing their trailing end block directive by:
Prior to the changes:
Note there are still several bugs in the parsing that I would like to fix, but I am uploading this to talk with @klausler about where to look for those.
Full diff: https://github.com/llvm/llvm-project/pull/131042.diff 5 Files Affected:
diff --git a/flang/lib/Parser/message.cpp b/flang/lib/Parser/message.cpp
index 69e4814bf246c..0b8d300189a1b 100644
--- a/flang/lib/Parser/message.cpp
+++ b/flang/lib/Parser/message.cpp
@@ -272,6 +272,10 @@ static llvm::raw_ostream::Colors PrefixColor(Severity severity) {
return llvm::raw_ostream::SAVEDCOLOR;
}
+// FIXME: Make these configurable, based on verbosity level.
+const int MAX_CONTEXTS_EMITTED = 2;
+const bool OMIT_SHARED_CONTEXTS = true;
+
void Message::Emit(llvm::raw_ostream &o, const AllCookedSources &allCooked,
bool echoSourceLine) const {
std::optional<ProvenanceRange> provenanceRange{GetProvenanceRange(allCooked)};
@@ -279,12 +283,38 @@ void Message::Emit(llvm::raw_ostream &o, const AllCookedSources &allCooked,
sources.EmitMessage(o, provenanceRange, ToString(), Prefix(severity()),
PrefixColor(severity()), echoSourceLine);
bool isContext{attachmentIsContext_};
+ int contextsEmitted{isContext ? 1 : 0};
+ // Emit attachments.
for (const Message *attachment{attachment_.get()}; attachment;
- attachment = attachment->attachment_.get()) {
+ attachment = attachment->attachment_.get()) {
Severity severity = isContext ? Severity::Context : attachment->severity();
- sources.EmitMessage(o, attachment->GetProvenanceRange(allCooked),
- attachment->ToString(), Prefix(severity), PrefixColor(severity),
- echoSourceLine);
+ auto emitAttachment = [&]() {
+ sources.EmitMessage(o, attachment->GetProvenanceRange(allCooked),
+ attachment->ToString(), Prefix(severity), PrefixColor(severity),
+ echoSourceLine);
+ };
+ // TODO isContext is not used correctly here.
+ if (attachment->attachmentIsContext_) {
+ // Truncate the number of contexts emitted.
+ if (contextsEmitted <= MAX_CONTEXTS_EMITTED) {
+ emitAttachment();
+ contextsEmitted += 1;
+ }
+ if (OMIT_SHARED_CONTEXTS) {
+ // Skip less specific contexts at the same location.
+ for (const Message *next_attachment{attachment->attachment_.get()};
+ next_attachment && next_attachment->attachmentIsContext_ &&
+ next_attachment->AtSameLocation(*attachment);
+ next_attachment = next_attachment->attachment_.get()) {
+ attachment = next_attachment;
+ }
+ // NB, this loop increments `attachment` one more time after the
+ // previous loop is done advancing it to the last context at the same
+ // location.
+ }
+ } else {
+ emitAttachment();
+ }
}
}
@@ -298,7 +328,7 @@ bool Message::operator==(const Message &that) const {
}
const Message *thatAttachment{that.attachment_.get()};
for (const Message *attachment{attachment_.get()}; attachment;
- attachment = attachment->attachment_.get()) {
+ attachment = attachment->attachment_.get()) {
if (!thatAttachment || !attachment->AtSameLocation(*thatAttachment) ||
attachment->ToString() != thatAttachment->ToString() ||
attachment->severity() != thatAttachment->severity()) {
diff --git a/flang/lib/Parser/openacc-parsers.cpp b/flang/lib/Parser/openacc-parsers.cpp
index c78676664e0a3..6739bcc035fc2 100644
--- a/flang/lib/Parser/openacc-parsers.cpp
+++ b/flang/lib/Parser/openacc-parsers.cpp
@@ -19,8 +19,12 @@
// OpenACC Directives and Clauses
namespace Fortran::parser {
+// Only need to handle ! line comments because prescanning normalizes the
+// other types of line comments from fixed form.
constexpr auto startAccLine{skipStuffBeforeStatement >>
- ("!$ACC "_sptok || "C$ACC "_sptok || "*$ACC "_sptok)};
+ withMessage(
+ "expected OpenACC comment '!$ACC' (free-form), 'C$ACC', or '*$ACC' (fixed-form)"_err_en_US,
+ "!$ACC "_sptok)};
constexpr auto endAccLine{space >> endOfLine};
// Autogenerated clauses parser. Information is taken from ACC.td and the
@@ -225,7 +229,8 @@ TYPE_PARSER(startAccLine >> sourced(construct<AccEndBlockDirective>("END"_tok >>
TYPE_PARSER(construct<OpenACCBlockConstruct>(
Parser<AccBeginBlockDirective>{} / endAccLine, block,
- Parser<AccEndBlockDirective>{} / endAccLine))
+ withMessage("expected OpenACC end block directive"_err_en_US,
+ Parser<AccEndBlockDirective>{} / endAccLine)))
// Standalone constructs
TYPE_PARSER(construct<OpenACCStandaloneConstruct>(
diff --git a/flang/test/Driver/debug-parsing-log.f90 b/flang/test/Driver/debug-parsing-log.f90
index 7297163109450..4e56add386ef8 100644
--- a/flang/test/Driver/debug-parsing-log.f90
+++ b/flang/test/Driver/debug-parsing-log.f90
@@ -12,14 +12,14 @@
! CHECK-NEXT: {{.*[/\\]}}debug-parsing-log.f90:25:1: in the context: IMPLICIT statement
! CHECK-NEXT: END PROGRAM
! CHECK-NEXT: ^
-! CHECK-NEXT: {{.*[/\\]}}debug-parsing-log.f90:25:1: in the context: implicit part
-! CHECK-NEXT: END PROGRAM
-! CHECK-NEXT: ^
-! CHECK-NEXT: {{.*[/\\]}}debug-parsing-log.f90:25:1: in the context: specification part
-! CHECK-NEXT: END PROGRAM
-! CHECK-NEXT: ^
-! CHECK-NEXT: {{.*[/\\]}}debug-parsing-log.f90:25:1: in the context: main program
-! CHECK-NEXT: END PROGRAM
-! CHECK-NEXT: ^
+
+
+
+
+
+
+
+
+
END PROGRAM
diff --git a/flang/test/Parser/acc-data-statement.f90 b/flang/test/Parser/acc-data-statement.f90
new file mode 100644
index 0000000000000..1e369a0db3780
--- /dev/null
+++ b/flang/test/Parser/acc-data-statement.f90
@@ -0,0 +1,245 @@
+! RUN: not %flang_fc1 -fsyntax-only -fopenacc %s 2>&1 | FileCheck %s
+program acc_data_test
+ implicit none
+ integer :: a(100), b(100), c(100), d(100)
+ integer :: i, s ! FIXME: if s is named sum you get semantic errors.
+
+ ! Positive tests
+
+ ! Basic data construct in program body
+ !$acc data copy(a, b) create(c)
+ a = 1
+ b = 2
+ c = a + b
+ !$acc end data
+ print *, "After first data region"
+
+ ! Data construct within IF block
+ if (.true.) then
+ !$acc data copyout(a)
+ a = a + 1
+ !$acc end data
+ print *, "Inside if block"
+ end if
+
+ ! Data construct within DO loop
+ do i = 1, 10
+ !$acc data present(a)
+ a(i) = a(i) * 2
+ !$acc end data
+ print *, "Loop iteration", i
+ end do
+
+ ! Nested data constructs
+ !$acc data copyin(a)
+ s = 0
+ !$acc data copy(s)
+ s = s + 1
+ !$acc end data
+ print *, "After nested data"
+ !$acc end data
+
+ ! Negative tests
+ ! Basic data construct in program body
+ !$acc data copy(a, b) create(d)
+ a = 1
+ b = 2
+ d = a + b
+! !$acc end data
+ print *, "After first data region"
+
+ ! Data construct within IF block
+ if (.true.) then
+ !$acc data copyout(a)
+ a = a + 1
+! !$acc end data
+ print *, "Inside if block"
+ ! First error in the file.
+ !CHECK: acc-data-statement.f90:
+ !CHECK-SAME: [[ELINE1:[0-9]+]]:{{[0-9]+}}:
+ !CHECK-SAME: error: expected OpenACC end block directive
+ !CHECK-NEXT: end if
+ !CHECK-NEXT: ^
+ !CHECK-NEXT: in the context: OpenACC construct
+ !CHECK-NEXT: !$acc data copyout(a)
+ !CHECK-NEXT: ^
+ !CHECK-NEXT: in the context: IF construct
+ !CHECK-NEXT: if (.true.) then
+ !CHECK-NEXT: ^
+ !CHECK-NEXT: error: expected OpenACC end block directive
+ !CHECK-NEXT: end if
+ !CHECK-NEXT: ^
+ !CHECK-NEXT: in the context: OpenACC construct
+ !CHECK-NEXT: !$acc data copyout(a)
+ !CHECK-NEXT: ^
+ !CHECK-NEXT: in the context: IF construct
+ !CHECK-NEXT: if (.true.) then
+ !CHECK-NEXT: ^
+ end if
+
+ ! Data construct within DO loop
+ do i = 1, 10
+ !$acc data present(a)
+ a(i) = a(i) * 2
+! !$acc end data
+ print *, "Loop iteration", i
+ !CHECK: acc-data-statement.f90:
+ !CHECK-NOT: [[ELINE1]]
+ !CHECK-SAME: [[ELINE2:[0-9]+]]:{{[0-9]+}}:
+ !CHECK-SAME: error: expected OpenACC end block directive
+ !CHECK-NEXT: end do
+ !CHECK-NEXT: ^
+ !CHECK-NEXT: in the context: OpenACC construct
+ !CHECK-NEXT: !$acc data present(a)
+ !CHECK-NEXT: ^
+ !CHECK-NEXT: in the context: DO construct
+ !CHECK-NEXT: do i = 1, 10
+ !CHECK-NEXT: ^
+ !CHECK-NEXT: error: expected OpenACC end block directive
+ !CHECK-NEXT: end do
+ !CHECK-NEXT: ^
+ !CHECK-NEXT: in the context: OpenACC construct
+ !CHECK-NEXT: !$acc data present(a)
+ !CHECK-NEXT: ^
+ !CHECK-NEXT: in the context: DO construct
+ !CHECK-NEXT: do i = 1, 10
+ !CHECK-NEXT: ^
+ end do
+
+ ! Nested data constructs
+ !$acc data copyin(a)
+ s = 0
+ !$acc data copy(s)
+ s = s + 1
+! !$acc end data
+ print *, "After nested data"
+! !$acc end data
+
+ print *, "Program finished"
+ !CHECK: acc-data-statement.f90:
+ !CHECK-NOT: [[ELINE2]]
+ !CHECK-SAME: [[ELINE3:[0-9]+]]:{{[0-9]+}}:
+ !CHECK-SAME: error: expected OpenACC end block directive
+ !CHECK-NEXT: contains
+ !CHECK-NEXT: ^
+ !CHECK-NEXT: in the context: OpenACC construct
+ !CHECK-NEXT: !$acc data copy(s)
+ !CHECK-NEXT: ^
+ !CHECK-NEXT: in the context: execution part
+ !CHECK-NEXT: !$acc data copy(a, b) create(c)
+ !CHECK-NEXT: ^
+ !CHECK-NEXT: error: expected OpenACC end block directive
+ !CHECK-NEXT: contains
+ !CHECK-NEXT: ^
+ !CHECK-NEXT: in the context: OpenACC construct
+ !CHECK-NEXT: !$acc data copy(s)
+ !CHECK-NEXT: ^
+ !CHECK-NEXT: in the context: OpenACC construct
+ !CHECK-NEXT: !$acc data copyin(a)
+ !CHECK-NEXT: ^
+ !CHECK-NEXT: error: expected OpenACC end block directive
+ !CHECK-NEXT: contains
+ !CHECK-NEXT: ^
+ !CHECK-NEXT: in the context: OpenACC construct
+ !CHECK-NEXT: !$acc data copyin(a)
+ !CHECK-NEXT: ^
+ !CHECK-NEXT: in the context: execution part
+ !CHECK-NEXT: !$acc data copy(a, b) create(c)
+ !CHECK-NEXT: ^
+ !CHECK-NEXT: error: expected OpenACC end block directive
+ !CHECK-NEXT: contains
+ !CHECK-NEXT: ^
+ !CHECK-NEXT: in the context: OpenACC construct
+ !CHECK-NEXT: !$acc data copy(s)
+ !CHECK-NEXT: ^
+ !CHECK-NEXT: in the context: OpenACC construct
+ !CHECK-NEXT: !$acc data copy(a, b) create(d)
+ !CHECK-NEXT: ^
+ !CHECK-NEXT: error: expected OpenACC end block directive
+ !CHECK-NEXT: contains
+ !CHECK-NEXT: ^
+ !CHECK-NEXT: in the context: OpenACC construct
+ !CHECK-NEXT: !$acc data copy(s)
+ !CHECK-NEXT: ^
+ !CHECK-NEXT: in the context: OpenACC construct
+ !CHECK-NEXT: !$acc data copyin(a)
+ !CHECK-NEXT: ^
+ !CHECK-NEXT: error: expected OpenACC end block directive
+ !CHECK-NEXT: contains
+ !CHECK-NEXT: ^
+ !CHECK-NEXT: in the context: OpenACC construct
+ !CHECK-NEXT: !$acc data copyin(a)
+ !CHECK-NEXT: ^
+ !CHECK-NEXT: in the context: OpenACC construct
+ !CHECK-NEXT: !$acc data copy(a, b) create(d)
+ !CHECK-NEXT: ^
+ !CHECK-NEXT: error: expected OpenACC end block directive
+ !CHECK-NEXT: contains
+ !CHECK-NEXT: ^
+ !CHECK-NEXT: in the context: OpenACC construct
+ !CHECK-NEXT: !$acc data copy(a, b) create(d)
+ !CHECK-NEXT: ^
+ !CHECK-NEXT: in the context: execution part
+ !CHECK-NEXT: !$acc data copy(a, b) create(c)
+ !CHECK-NEXT: ^
+contains
+ subroutine positive_process_array(x)
+ integer, intent(inout) :: x(:)
+
+ ! Data construct in subroutine
+ !$acc data copy(x)
+ x = x + 1
+ !$acc end data
+ print *, "Subroutine finished"
+ end subroutine
+
+ function positive_compute_sum(x) result(total)
+ integer, intent(in) :: x(:)
+ integer :: total
+
+ ! Data construct in function
+ !$acc data copyin(x) copy(total)
+ total = sum(x)
+ !$acc end data
+ print *, "Function finished"
+ end function
+
+ subroutine negative_process_array(x)
+ integer, intent(inout) :: x(:)
+
+ ! Data construct in subroutine
+ !$acc data copy(x)
+ x = x + 1
+! !$acc end data
+ print *, "Subroutine finished"
+ !CHECK: error: expected OpenACC directive
+ !CHECK-NEXT: !$acc data copy(x)
+ !CHECK-NEXT: ^
+ !CHECK-NEXT: in the context: specification construct
+ !CHECK-NEXT: !$acc data copy(x)
+ !CHECK-NEXT: ^
+ !CHECK-NEXT: in the context: specification part
+ !CHECK-NEXT: integer, intent(inout) :: x(:)
+ !CHECK-NEXT: ^
+ end subroutine
+
+ function negative_compute_sum(x) result(total)
+ integer, intent(in) :: x(:)
+ integer :: total
+ total = sum(x)
+ ! Data construct in function
+ !$acc data copyin(x) copy(total)
+ total = total + x
+! !$acc end data
+ print *, "Function finished"
+ !CHECK: error: expected OpenACC end block directive
+ !CHECK-NEXT: end function
+ !CHECK-NEXT: ^
+ !CHECK-NEXT: in the context: OpenACC construct
+ !CHECK-NEXT: !$acc data copyin(x) copy(total)
+ !CHECK-NEXT: ^
+ !CHECK-NEXT: in the context: execution part
+ !CHECK-NEXT: total = sum(x)
+ !CHECK-NEXT: ^
+ end function
+end program acc_data_test
\ No newline at end of file
diff --git a/flang/test/Parser/acc.f b/flang/test/Parser/acc.f
new file mode 100644
index 0000000000000..b0c3927772568
--- /dev/null
+++ b/flang/test/Parser/acc.f
@@ -0,0 +1,96 @@
+! RUN: %flang_fc1 -fsyntax-only -fopenacc %s 2>&1
+C Test file for OpenACC directives in fixed-form Fortran
+ PROGRAM ACCTEST
+ IMPLICIT NONE
+ INTEGER :: N, I, J
+ PARAMETER (N=100)
+ REAL :: A(N), B(N), C(N), D(N)
+ REAL :: SUM
+
+C Initialize arrays
+ DO I = 1, N
+ A(I) = I * 1.0
+ B(I) = I * 2.0
+ C(I) = 0.0
+ D(I) = 1.0
+ END DO
+
+C Basic data construct using C$ACC
+C$ACC DATA COPYIN(A,B) COPYOUT(C)
+ DO I = 1, N
+ C(I) = A(I) + B(I)
+ END DO
+C$ACC END DATA
+
+* Parallel construct with loop using *$ACC
+*$ACC PARALLEL PRESENT(A,B,C)
+*$ACC LOOP
+ DO I = 1, N
+ C(I) = C(I) * 2.0
+ END DO
+*$ACC END PARALLEL
+
+C Nested loops with collapse - C$ACC style
+C$ACC PARALLEL LOOP COLLAPSE(2)
+ DO I = 1, N
+ DO J = 1, N
+ A(J) = A(J) + B(J)
+ END DO
+ END DO
+C$ACC END PARALLEL LOOP
+
+* Combined parallel loop with reduction - *$ACC style
+ SUM = 0.0
+*$ACC PARALLEL LOOP REDUCTION(+:SUM)
+ DO I = 1, N
+ SUM = SUM + C(I)
+ END DO
+*$ACC END PARALLEL LOOP
+
+C Kernels construct - C$ACC with continuation
+C$ACC KERNELS
+C$ACC+ COPYOUT(A)
+ DO I = 1, N
+ A(I) = A(I) * 2.0
+ END DO
+C$ACC END KERNELS
+
+* Data construct with update - *$ACC with continuation
+*$ACC DATA COPY(B)
+*$ACC+ PRESENT(D)
+ B(1) = 999.0
+*$ACC UPDATE HOST(B(1:1))
+ PRINT *, 'B(1) = ', B(1)
+*$ACC END DATA
+
+C Mixed style directives in nested constructs
+C$ACC DATA COPY(A,B,C)
+*$ACC PARALLEL LOOP
+ DO I = 1, N
+ A(I) = B(I) + C(I)
+ END DO
+*$ACC END PARALLEL LOOP
+C$ACC END DATA
+
+* Subroutine call within data region - *$ACC style
+*$ACC DATA COPY(A,B,C)
+ CALL SUB1(A, B, C, N)
+*$ACC END DATA
+
+ PRINT *, 'Sum = ', SUM
+ END PROGRAM
+
+C Subroutine with mixed ACC directive styles
+ SUBROUTINE SUB1(X, Y, Z, M)
+ INTEGER M, I
+ REAL X(M), Y(M), Z(M)
+
+*$ACC PARALLEL PRESENT(X,Y)
+C$ACC LOOP PRIVATE(I)
+ DO I = 1, M
+ Z(I) = X(I) + Y(I)
+ END DO
+C$ACC END LOOP
+*$ACC END PARALLEL
+ RETURN
+ END SUBROUTINE
\ No newline at end of file
|
This comment was marked as outdated.
This comment was marked as outdated.
e60c571
to
990e905
Compare
This PR does reduces the verbosity of parser errors for OpenACC block constructs that do not parse correctly because they are missing their trailing end block directive by:
Prior to the changes:
acc-data-statement.prior.log
acc-data-statement.post.log