-
Notifications
You must be signed in to change notification settings - Fork 15k
[flang] Let !@acc and !@cuf conditional lines be continuations #164892
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
OpenMP conditional compilation lines (!$) work as continuation lines, but OpenACC and CUDA conditional lines do not. Fixes llvm#164727 and llvm#164708.
|
@llvm/pr-subscribers-flang-parser Author: Peter Klausler (klausler) ChangesOpenMP conditional compilation lines (!$) work as continuation lines, but OpenACC and CUDA conditional lines do not. Full diff: https://github.com/llvm/llvm-project/pull/164892.diff 2 Files Affected:
diff --git a/flang/lib/Parser/prescan.cpp b/flang/lib/Parser/prescan.cpp
index df0372bbe554a..4739da0676fa9 100644
--- a/flang/lib/Parser/prescan.cpp
+++ b/flang/lib/Parser/prescan.cpp
@@ -1380,19 +1380,23 @@ const char *Prescanner::FixedFormContinuationLine(bool atNewline) {
}
}
} else { // Normal case: not in a compiler directive.
- // !$ conditional compilation lines may be continuations when not
+ // Conditional compilation lines may be continuations when not
// just preprocessing.
- if (!preprocessingOnly_ && IsFixedFormCommentChar(col1) &&
- nextLine_[1] == '$' && nextLine_[2] == ' ' && nextLine_[3] == ' ' &&
- nextLine_[4] == ' ' && IsCompilerDirectiveSentinel(&nextLine_[1], 1)) {
- if (const char *col6{nextLine_ + 5};
- *col6 != '\n' && *col6 != '0' && !IsSpaceOrTab(col6)) {
- if (atNewline && !IsSpace(nextLine_ + 6)) {
- brokenToken_ = true;
+ if (!preprocessingOnly_ && IsFixedFormCommentChar(col1)) {
+ if ((nextLine_[1] == '$' && nextLine_[2] == ' ' && nextLine_[3] == ' ' &&
+ nextLine_[4] == ' ' &&
+ IsCompilerDirectiveSentinel(&nextLine_[1], 1)) ||
+ (nextLine_[1] == '@' &&
+ IsCompilerDirectiveSentinel(&nextLine_[1], 4))) {
+ if (const char *col6{nextLine_ + 5};
+ *col6 != '\n' && *col6 != '0' && !IsSpaceOrTab(col6)) {
+ if (atNewline && !IsSpace(nextLine_ + 6)) {
+ brokenToken_ = true;
+ }
+ return nextLine_ + 6;
+ } else {
+ return nullptr;
}
- return nextLine_ + 6;
- } else {
- return nullptr;
}
}
if (col1 == '&' &&
@@ -1427,6 +1431,15 @@ const char *Prescanner::FixedFormContinuationLine(bool atNewline) {
return nullptr; // not a continuation line
}
+constexpr bool IsDirective(const char *match, const char *dir) {
+ for (; *match; ++match) {
+ if (*match != ToLowerCaseLetter(*dir++)) {
+ return false;
+ }
+ }
+ return true;
+}
+
const char *Prescanner::FreeFormContinuationLine(bool ampersand) {
const char *lineStart{nextLine_};
const char *p{lineStart};
@@ -1439,12 +1452,18 @@ const char *Prescanner::FreeFormContinuationLine(bool ampersand) {
if (preprocessingOnly_) {
// in -E mode, don't treat !$ as a continuation
return nullptr;
- } else if (p[0] == '!' && p[1] == '$') {
- // accept but do not require a matching sentinel
- if (p[2] != '&' && !IsSpaceOrTab(&p[2])) {
- return nullptr; // not !$
- }
+ } else if (p[0] == '!' && (p[1] == '$' || p[1] == '@')) {
p += 2;
+ if (InOpenACCOrCUDAConditionalLine()) {
+ if (IsDirective("acc", p) || IsDirective("cuf", p)) {
+ p += 3;
+ } else {
+ return nullptr;
+ }
+ }
+ if (*p != '&' && !IsSpaceOrTab(p)) {
+ return nullptr;
+ }
}
} else if (*p++ == '!') {
for (const char *s{directiveSentinel_}; *s != '\0'; ++p, ++s) {
@@ -1467,10 +1486,17 @@ const char *Prescanner::FreeFormContinuationLine(bool ampersand) {
return nullptr;
}
}
- if (p[0] == '!' && p[1] == '$' && !preprocessingOnly_ &&
- features_.IsEnabled(LanguageFeature::OpenMP)) {
- // !$ conditional line can be a continuation
- p = lineStart = SkipWhiteSpace(p + 2);
+ if (p[0] == '!' && !preprocessingOnly_) {
+ // Conditional lines can be continuations
+ if (p[1] == '$' && features_.IsEnabled(LanguageFeature::OpenMP)) {
+ p = lineStart = SkipWhiteSpace(p + 2);
+ } else if (IsDirective("@acc", p + 1) &&
+ features_.IsEnabled(LanguageFeature::OpenACC)) {
+ p = lineStart = SkipWhiteSpace(p + 5);
+ } else if (IsDirective("@cuf", p + 1) &&
+ features_.IsEnabled(LanguageFeature::CUDA)) {
+ p = lineStart = SkipWhiteSpace(p + 5);
+ }
}
if (*p == '&') {
return p + 1;
@@ -1706,15 +1732,6 @@ Prescanner::IsCompilerDirectiveSentinel(const char *p) const {
return std::nullopt;
}
-constexpr bool IsDirective(const char *match, const char *dir) {
- for (; *match; ++match) {
- if (*match != ToLowerCaseLetter(*dir++)) {
- return false;
- }
- }
- return true;
-}
-
Prescanner::LineClassification Prescanner::ClassifyLine(
const char *start) const {
if (inFixedForm_) {
diff --git a/flang/test/Preprocessing/bug164727.cuf b/flang/test/Preprocessing/bug164727.cuf
new file mode 100644
index 0000000000000..89c846d25bb22
--- /dev/null
+++ b/flang/test/Preprocessing/bug164727.cuf
@@ -0,0 +1,6 @@
+!RUN: %flang_fc1 -fdebug-unparse -x cuda %s 2>&1 | FileCheck %s
+!CHECK: REAL, MANAGED, ALLOCATABLE :: x
+real, &
+ !@cuf managed, &
+ allocatable :: x
+end
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks for the quick fix! LGTM
OpenMP conditional compilation lines (!$) work as continuation lines, but OpenACC and CUDA conditional lines do not.
Fixes #164727 and #164708.