-
Notifications
You must be signed in to change notification settings - Fork 15.1k
[flang] Line continuation for !@acc and !@cuf conditional lines #164475
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
Some Fortran source-level features that work for OpenMP !$ conditional lines, such as free form line continuation, don't work for OpenACC !@acc or CUDA !@Cuf conditional lines. Make them less particular. Fixes llvm#164470.
|
@llvm/pr-subscribers-flang-parser Author: Peter Klausler (klausler) ChangesSome Fortran source-level features that work for OpenMP !$ conditional lines, such as free form line continuation, don't work for OpenACC !@acc or CUDA !@cuf conditional lines. Make them less particular. Fixes #164470. Full diff: https://github.com/llvm/llvm-project/pull/164475.diff 3 Files Affected:
diff --git a/flang/lib/Parser/prescan.cpp b/flang/lib/Parser/prescan.cpp
index 66e5b2cbd5c7f..df0372bbe554a 100644
--- a/flang/lib/Parser/prescan.cpp
+++ b/flang/lib/Parser/prescan.cpp
@@ -140,17 +140,9 @@ void Prescanner::Statement() {
CHECK(*at_ == '!');
}
std::optional<int> condOffset;
- if (InOpenMPConditionalLine()) {
+ if (InOpenMPConditionalLine()) { // !$
condOffset = 2;
- } else if (directiveSentinel_[0] == '@' && directiveSentinel_[1] == 'c' &&
- directiveSentinel_[2] == 'u' && directiveSentinel_[3] == 'f' &&
- directiveSentinel_[4] == '\0') {
- // CUDA conditional compilation line.
- condOffset = 5;
- } else if (directiveSentinel_[0] == '@' && directiveSentinel_[1] == 'a' &&
- directiveSentinel_[2] == 'c' && directiveSentinel_[3] == 'c' &&
- directiveSentinel_[4] == '\0') {
- // OpenACC conditional compilation line.
+ } else if (InOpenACCOrCUDAConditionalLine()) { // !@acc or !@cuf
condOffset = 5;
}
if (condOffset && !preprocessingOnly_) {
@@ -166,7 +158,8 @@ void Prescanner::Statement() {
} else {
// Compiler directive. Emit normalized sentinel, squash following spaces.
// Conditional compilation lines (!$) take this path in -E mode too
- // so that -fopenmp only has to appear on the later compilation.
+ // so that -fopenmp only has to appear on the later compilation
+ // (ditto for !@cuf and !@acc).
EmitChar(tokens, '!');
++at_, ++column_;
for (const char *sp{directiveSentinel_}; *sp != '\0';
@@ -202,7 +195,7 @@ void Prescanner::Statement() {
}
tokens.CloseToken();
SkipSpaces();
- if (InOpenMPConditionalLine() && inFixedForm_ && !tabInCurrentLine_ &&
+ if (InConditionalLine() && inFixedForm_ && !tabInCurrentLine_ &&
column_ == 6 && *at_ != '\n') {
// !$ 0 - turn '0' into a space
// !$ 1 - turn '1' into '&'
@@ -347,7 +340,7 @@ void Prescanner::Statement() {
while (CompilerDirectiveContinuation(tokens, line.sentinel)) {
newlineProvenance = GetCurrentProvenance();
}
- if (preprocessingOnly_ && inFixedForm_ && InOpenMPConditionalLine() &&
+ if (preprocessingOnly_ && inFixedForm_ && InConditionalLine() &&
nextLine_ < limit_) {
// In -E mode, when the line after !$ conditional compilation is a
// regular fixed form continuation line, append a '&' to the line.
@@ -1360,11 +1353,10 @@ const char *Prescanner::FixedFormContinuationLine(bool atNewline) {
features_.IsEnabled(LanguageFeature::OldDebugLines))) &&
nextLine_[1] == ' ' && nextLine_[2] == ' ' && nextLine_[3] == ' ' &&
nextLine_[4] == ' '};
- if (InCompilerDirective() &&
- !(InOpenMPConditionalLine() && !preprocessingOnly_)) {
+ if (InCompilerDirective() && !(InConditionalLine() && !preprocessingOnly_)) {
// !$ under -E is not continued, but deferred to later compilation
if (IsFixedFormCommentChar(col1) &&
- !(InOpenMPConditionalLine() && preprocessingOnly_)) {
+ !(InConditionalLine() && preprocessingOnly_)) {
int j{1};
for (; j < 5; ++j) {
char ch{directiveSentinel_[j - 1]};
@@ -1443,7 +1435,7 @@ const char *Prescanner::FreeFormContinuationLine(bool ampersand) {
}
p = SkipWhiteSpaceIncludingEmptyMacros(p);
if (InCompilerDirective()) {
- if (InOpenMPConditionalLine()) {
+ if (InConditionalLine()) {
if (preprocessingOnly_) {
// in -E mode, don't treat !$ as a continuation
return nullptr;
diff --git a/flang/lib/Parser/prescan.h b/flang/lib/Parser/prescan.h
index fc38adb926530..5e7481781d944 100644
--- a/flang/lib/Parser/prescan.h
+++ b/flang/lib/Parser/prescan.h
@@ -171,7 +171,17 @@ class Prescanner {
bool InOpenMPConditionalLine() const {
return directiveSentinel_ && directiveSentinel_[0] == '$' &&
!directiveSentinel_[1];
- ;
+ }
+ bool InOpenACCOrCUDAConditionalLine() const {
+ return directiveSentinel_ && directiveSentinel_[0] == '@' &&
+ ((directiveSentinel_[1] == 'a' && directiveSentinel_[2] == 'c' &&
+ directiveSentinel_[3] == 'c') ||
+ (directiveSentinel_[1] == 'c' && directiveSentinel_[2] == 'u' &&
+ directiveSentinel_[3] == 'f')) &&
+ directiveSentinel_[4] == '\0';
+ }
+ bool InConditionalLine() const {
+ return InOpenMPConditionalLine() || InOpenACCOrCUDAConditionalLine();
}
bool InFixedFormSource() const {
return inFixedForm_ && !inPreprocessorDirective_ && !InCompilerDirective();
diff --git a/flang/test/Preprocessing/bug164470.cuf b/flang/test/Preprocessing/bug164470.cuf
new file mode 100644
index 0000000000000..3e959f40d2e3f
--- /dev/null
+++ b/flang/test/Preprocessing/bug164470.cuf
@@ -0,0 +1,6 @@
+!RUN: %flang_fc1 -x cuda -fdebug-unparse %s 2>&1 | FileCheck %s
+!CHECK: ATTRIBUTES(DEVICE) FUNCTION foo()
+!@cuf attributes(device) &
+function foo()
+ foo = 1.
+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.
LGTM! Thanks
…#164475) Some Fortran source-level features that work for OpenMP !$ conditional lines, such as free form line continuation, don't work for OpenACC !@acc or CUDA !@Cuf conditional lines. Make them less particular. Fixes llvm#164470.
…#164475) Some Fortran source-level features that work for OpenMP !$ conditional lines, such as free form line continuation, don't work for OpenACC !@acc or CUDA !@Cuf conditional lines. Make them less particular. Fixes llvm#164470.
Some Fortran source-level features that work for OpenMP !$ conditional lines, such as free form line continuation, don't work for OpenACC !@acc or CUDA !@Cuf conditional lines. Make them less particular.
Fixes #164470.