Skip to content

Conversation

klausler
Copy link
Contributor

@klausler klausler commented Apr 9, 2025

See test case. When Fortran line continuation has been used, don't insert spaces in -E formatted output to put things into the right column, as this can break up a token.

Fixes #134986.

See test case.  When Fortran line continuation has been used,
don't insert spaces in -E formatted output to put things into
the right column, as this can break up a token.

Fixes llvm#134986.
@llvmbot llvmbot added flang Flang issues not falling into any other category flang:parser labels Apr 9, 2025
@llvmbot
Copy link
Member

llvmbot commented Apr 9, 2025

@llvm/pr-subscribers-flang-parser

Author: Peter Klausler (klausler)

Changes

See test case. When Fortran line continuation has been used, don't insert spaces in -E formatted output to put things into the right column, as this can break up a token.

Fixes #134986.


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

2 Files Affected:

  • (modified) flang/lib/Parser/parsing.cpp (+18-16)
  • (added) flang/test/Preprocessing/bug134986.F90 (+5)
diff --git a/flang/lib/Parser/parsing.cpp b/flang/lib/Parser/parsing.cpp
index 5f486cbf8e4c8..17f544194de02 100644
--- a/flang/lib/Parser/parsing.cpp
+++ b/flang/lib/Parser/parsing.cpp
@@ -155,7 +155,7 @@ void Parsing::EmitPreprocessedSource(
       const auto getOriginalChar{[&](char ch) {
         if (IsLetter(ch) && provenance && provenance->size() == 1) {
           if (const char *orig{allSources.GetSource(*provenance)}) {
-            const char upper{ToUpperCaseLetter(ch)};
+            char upper{ToUpperCaseLetter(ch)};
             if (*orig == upper) {
               return upper;
             }
@@ -184,21 +184,23 @@ void Parsing::EmitPreprocessedSource(
       std::optional<SourcePosition> position{provenance
               ? allSources.GetSourcePosition(provenance->start())
               : std::nullopt};
-      if (lineDirectives && column == 1 && position) {
-        if (&*position->path != sourcePath) {
-          out << "#line \"" << *position->path << "\" " << position->line
-              << '\n';
-        } else if (position->line != sourceLine) {
-          if (sourceLine < position->line &&
-              sourceLine + 10 >= position->line) {
-            // Emit a few newlines to catch up when they'll likely
-            // require fewer bytes than a #line directive would have
-            // occupied.
-            while (sourceLine++ < position->line) {
-              out << '\n';
+      if (column == 1 && position) {
+        if (lineDirectives) {
+          if (&*position->path != sourcePath) {
+            out << "#line \"" << *position->path << "\" " << position->line
+                << '\n';
+          } else if (position->line != sourceLine) {
+            if (sourceLine < position->line &&
+                sourceLine + 10 >= position->line) {
+              // Emit a few newlines to catch up when they'll likely
+              // require fewer bytes than a #line directive would have
+              // occupied.
+              while (sourceLine++ < position->line) {
+                out << '\n';
+              }
+            } else {
+              out << "#line " << position->line << '\n';
             }
-          } else {
-            out << "#line " << position->line << '\n';
           }
         }
         sourcePath = &*position->path;
@@ -244,7 +246,7 @@ void Parsing::EmitPreprocessedSource(
             }
           }
         } else if (!inContinuation && !inDirectiveSentinel && position &&
-            position->column <= 72) {
+            position->line == sourceLine && position->column < 72) {
           // Preserve original indentation
           for (; column < position->column; ++column) {
             out << ' ';
diff --git a/flang/test/Preprocessing/bug134986.F90 b/flang/test/Preprocessing/bug134986.F90
new file mode 100644
index 0000000000000..c97353e95b240
--- /dev/null
+++ b/flang/test/Preprocessing/bug134986.F90
@@ -0,0 +1,5 @@
+! RUN: %flang -E %s 2>&1 | FileCheck %s
+! CHECK: print *, "HELLO "//" WORLD"
+print *, "HELLO "/&
+                       &/" WORLD"
+end

Copy link
Contributor

@clementval clementval 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 cf8c02f into llvm:main Apr 10, 2025
14 checks passed
@klausler klausler deleted the bug134986 branch April 10, 2025 16:57
var-const pushed a commit to ldionne/llvm-project that referenced this pull request Apr 17, 2025
…m#135063)

See test case. When Fortran line continuation has been used, don't
insert spaces in -E formatted output to put things into the right
column, as this can break up a token.

Fixes llvm#134986.
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][preprocessor] Preprocessor splits a token while preserving column
4 participants