Skip to content

[flang] Handle pp-directives better in line continuation #105572

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

Merged
merged 1 commit into from
Aug 26, 2024

Conversation

klausler
Copy link
Contributor

The code for detecting and processing some preprocessing directives (conditional compilation and #line) while skipping comments between one source or compiler directive line and its continuations wasn't correctly handling the case of such a directive following an explicit ampersand.

Fixes #100730 and #100345.

The code for detecting and processing some preprocessing directives
(conditional compilation and #line) while skipping comments between
one source or compiler directive line and its continuations wasn't
correctly handling the case of such a directive following an explicit
ampersand.

Fixes llvm#100730 and
llvm#100345.
@klausler klausler requested a review from psteinfeld August 21, 2024 19:18
@llvmbot llvmbot added flang Flang issues not falling into any other category flang:parser labels Aug 21, 2024
@llvmbot
Copy link
Member

llvmbot commented Aug 21, 2024

@llvm/pr-subscribers-flang-parser

Author: Peter Klausler (klausler)

Changes

The code for detecting and processing some preprocessing directives (conditional compilation and #line) while skipping comments between one source or compiler directive line and its continuations wasn't correctly handling the case of such a directive following an explicit ampersand.

Fixes #100730 and #100345.


Full diff: https://github.com/llvm/llvm-project/pull/105572.diff

2 Files Affected:

  • (modified) flang/lib/Parser/prescan.cpp (+28-32)
  • (modified) flang/test/Preprocessing/line-in-contin.F90 (+19-5)
diff --git a/flang/lib/Parser/prescan.cpp b/flang/lib/Parser/prescan.cpp
index c01d512b4653de..804ada7d11e020 100644
--- a/flang/lib/Parser/prescan.cpp
+++ b/flang/lib/Parser/prescan.cpp
@@ -207,11 +207,13 @@ void Prescanner::Statement() {
           toks.Put(id, GetProvenance(at_));
           if (auto replaced{preprocessor_.MacroReplacement(toks, *this)}) {
             auto newLineClass{ClassifyLine(*replaced, GetCurrentProvenance())};
-            disableSourceContinuation_ =
-                newLineClass.kind != LineClassification::Kind::Source;
             if (newLineClass.kind ==
                 LineClassification::Kind::CompilerDirective) {
               directiveSentinel_ = newLineClass.sentinel;
+              disableSourceContinuation_ = false;
+            } else {
+              disableSourceContinuation_ =
+                  newLineClass.kind != LineClassification::Kind::Source;
             }
           }
         }
@@ -1114,39 +1116,33 @@ bool Prescanner::SkipCommentLine(bool afterAmpersand) {
       SkipToEndOfLine();
       omitNewline_ = true;
     }
-    return false;
-  }
-  auto lineClass{ClassifyLine(nextLine_)};
-  if (lineClass.kind == LineClassification::Kind::Comment) {
-    NextLine();
-    return true;
   } else if (inPreprocessorDirective_) {
-    return false;
-  } else if (afterAmpersand &&
-      (lineClass.kind ==
-              LineClassification::Kind::ConditionalCompilationDirective ||
-          lineClass.kind == LineClassification::Kind::DefinitionDirective ||
-          lineClass.kind == LineClassification::Kind::PreprocessorDirective ||
-          lineClass.kind == LineClassification::Kind::IncludeDirective ||
-          lineClass.kind == LineClassification::Kind::IncludeLine)) {
-    SkipToEndOfLine();
-    omitNewline_ = true;
-    skipLeadingAmpersand_ = true;
-    return false;
-  } else if (lineClass.kind ==
-          LineClassification::Kind::ConditionalCompilationDirective ||
-      lineClass.kind == LineClassification::Kind::PreprocessorDirective) {
-    // Allow conditional compilation directives (e.g., #ifdef) to affect
-    // continuation lines.
-    // Allow other preprocessor directives, too, except #include
-    // (when it does not follow '&'), #define, and #undef (because
-    // they cannot be allowed to affect preceding text on a
-    // continued line).
-    preprocessor_.Directive(TokenizePreprocessorDirective(), *this);
-    return true;
   } else {
-    return false;
+    auto lineClass{ClassifyLine(nextLine_)};
+    if (lineClass.kind == LineClassification::Kind::Comment) {
+      NextLine();
+      return true;
+    } else if (lineClass.kind ==
+            LineClassification::Kind::ConditionalCompilationDirective ||
+        lineClass.kind == LineClassification::Kind::PreprocessorDirective) {
+      // Allow conditional compilation directives (e.g., #ifdef) to affect
+      // continuation lines.
+      // Allow other preprocessor directives, too, except #include
+      // (when it does not follow '&'), #define, and #undef (because
+      // they cannot be allowed to affect preceding text on a
+      // continued line).
+      preprocessor_.Directive(TokenizePreprocessorDirective(), *this);
+      return true;
+    } else if (afterAmpersand &&
+        (lineClass.kind == LineClassification::Kind::DefinitionDirective ||
+            lineClass.kind == LineClassification::Kind::IncludeDirective ||
+            lineClass.kind == LineClassification::Kind::IncludeLine)) {
+      SkipToEndOfLine();
+      omitNewline_ = true;
+      skipLeadingAmpersand_ = true;
+    }
   }
+  return false;
 }
 
 const char *Prescanner::FixedFormContinuationLine(bool mightNeedSpace) {
diff --git a/flang/test/Preprocessing/line-in-contin.F90 b/flang/test/Preprocessing/line-in-contin.F90
index 138e579bffaa28..28efbd02d3ae89 100644
--- a/flang/test/Preprocessing/line-in-contin.F90
+++ b/flang/test/Preprocessing/line-in-contin.F90
@@ -1,8 +1,10 @@
-! RUN: %flang_fc1 -E %s 2>&1 | FileCheck %s
-! CHECK: call foo( 0.)
-! CHECK: call foo( 1.)
-! CHECK: call foo( 2.)
-! CHECK: call foo( 3.)
+! RUN: %flang_fc1 -fopenmp -E %s 2>&1 | FileCheck %s
+! CHECK: call foo(0.)
+! CHECK: call foo(1.)
+! CHECK: call foo(2.)
+! CHECK: call foo(3.)
+! CHECK: !$omp parallel do default(none) private(j)
+! CHECK: !$omp end parallel do
 call foo( &
 # 100 "bar.h"
          & 0.)
@@ -17,4 +19,16 @@
 # 103 "bar.h"
          & 3. &
     )
+!$omp parallel do &
+#ifdef undef
+!$omp garbage &
+#else
+!$omp default(none) &
+#endif
+!$omp private(j)
+  do j=1,100
+  end do
+!$omp end &
+# 104 "bar.h"
+!$omp parallel do
 end

Copy link
Contributor

@psteinfeld psteinfeld left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

All builds and tests correctly and looks good.

Copy link
Contributor

@Leporacanthicus Leporacanthicus left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM

@klausler klausler merged commit f099f76 into llvm:main Aug 26, 2024
11 checks passed
@klausler klausler deleted the bug100730 branch August 26, 2024 17:51
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
flang:parser flang Flang issues not falling into any other category
Projects
None yet
Development

Successfully merging this pull request may close these issues.

[Flang,OpenMP] preprocessor inside of OpenMP statements break parse
4 participants