Skip to content
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

[flang][preprocessor] Change handling of macros in text from Fortran … #108113

Merged
merged 1 commit into from
Sep 12, 2024

Conversation

klausler
Copy link
Contributor

…INCLUDE lines

The compiler current treats an INCLUDE line as essentially a synonym for a preprocessing #include directive. The causes macros that have been defined at the point where the INCLUDE line is processed to be replaced within the text of the included file.

This behavior is surprising to users who expect an INCLUDE line to be expanded into its contents after preprocessing has been applied to the original source file, with no further macro expansion.

Change INCLUDE line processing to use a fresh instance of Preprocessor containing no macro definitions except _CUDA in CUDA Fortran compilations and, if the original file was being preprocessed, the standard definitions of FILE, LINE, and so forth.

…INCLUDE lines

The compiler current treats an INCLUDE line as essentially a synonym
for a preprocessing #include directive.  The causes macros that have
been defined at the point where the INCLUDE line is processed to be
replaced within the text of the included file.

This behavior is surprising to users who expect an INCLUDE line
to be expanded into its contents *after* preprocessing has been
applied to the original source file, with no further macro
expansion.

Change INCLUDE line processing to use a fresh instance of Preprocessor
containing no macro definitions except _CUDA in CUDA Fortran compilations
and, if the original file was being preprocessed, the standard definitions
of __FILE__, __LINE__, and so forth.
@llvmbot llvmbot added flang:driver flang Flang issues not falling into any other category flang:parser labels Sep 10, 2024
@llvmbot
Copy link
Collaborator

llvmbot commented Sep 10, 2024

@llvm/pr-subscribers-flang-parser

@llvm/pr-subscribers-flang-driver

Author: Peter Klausler (klausler)

Changes

…INCLUDE lines

The compiler current treats an INCLUDE line as essentially a synonym for a preprocessing #include directive. The causes macros that have been defined at the point where the INCLUDE line is processed to be replaced within the text of the included file.

This behavior is surprising to users who expect an INCLUDE line to be expanded into its contents after preprocessing has been applied to the original source file, with no further macro expansion.

Change INCLUDE line processing to use a fresh instance of Preprocessor containing no macro definitions except _CUDA in CUDA Fortran compilations and, if the original file was being preprocessed, the standard definitions of FILE, LINE, and so forth.


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

10 Files Affected:

  • (modified) flang/lib/Parser/preprocessor.cpp (+1-1)
  • (modified) flang/lib/Parser/prescan.cpp (+12-5)
  • (modified) flang/lib/Parser/prescan.h (+2-1)
  • (modified) flang/module/__fortran_builtins.f90 (+1-1)
  • (modified) flang/module/__fortran_ieee_exceptions.f90 (+1-1)
  • (modified) flang/module/ieee_arithmetic.f90 (+1-1)
  • (modified) flang/module/iso_fortran_env.f90 (+1-1)
  • (modified) flang/test/Driver/include-header.f90 (+1-1)
  • (added) flang/test/Preprocessing/include-file.h (+1)
  • (added) flang/test/Preprocessing/include-line.F90 (+6)
diff --git a/flang/lib/Parser/preprocessor.cpp b/flang/lib/Parser/preprocessor.cpp
index 7d3130cd66ed99..cb3725bc4ea67e 100644
--- a/flang/lib/Parser/preprocessor.cpp
+++ b/flang/lib/Parser/preprocessor.cpp
@@ -769,7 +769,7 @@ void Preprocessor::Directive(const TokenSequence &dir, Prescanner &prescanner) {
       if (included->bytes() > 0) {
         ProvenanceRange fileRange{
             allSources_.AddIncludedFile(*included, dir.GetProvenanceRange())};
-        Prescanner{prescanner, /*isNestedInIncludeDirective=*/true}
+        Prescanner{prescanner, *this, /*isNestedInIncludeDirective=*/true}
             .set_encoding(included->encoding())
             .Prescan(fileRange);
       }
diff --git a/flang/lib/Parser/prescan.cpp b/flang/lib/Parser/prescan.cpp
index 7dcb61ac79109f..b594df8ecb6858 100644
--- a/flang/lib/Parser/prescan.cpp
+++ b/flang/lib/Parser/prescan.cpp
@@ -32,10 +32,10 @@ Prescanner::Prescanner(Messages &messages, CookedSource &cooked,
       backslashFreeFormContinuation_{preprocessor.AnyDefinitions()},
       encoding_{allSources_.encoding()} {}
 
-Prescanner::Prescanner(const Prescanner &that, bool isNestedInIncludeDirective)
-    : messages_{that.messages_}, cooked_{that.cooked_},
-      preprocessor_{that.preprocessor_}, allSources_{that.allSources_},
-      features_{that.features_},
+Prescanner::Prescanner(const Prescanner &that, Preprocessor &prepro,
+    bool isNestedInIncludeDirective)
+    : messages_{that.messages_}, cooked_{that.cooked_}, preprocessor_{prepro},
+      allSources_{that.allSources_}, features_{that.features_},
       isNestedInIncludeDirective_{isNestedInIncludeDirective},
       backslashFreeFormContinuation_{that.backslashFreeFormContinuation_},
       inFixedForm_{that.inFixedForm_},
@@ -1104,7 +1104,14 @@ void Prescanner::FortranInclude(const char *firstQuote) {
         provenance, static_cast<std::size_t>(p - nextLine_)};
     ProvenanceRange fileRange{
         allSources_.AddIncludedFile(*included, includeLineRange)};
-    Prescanner{*this, /*isNestedInIncludeDirective=*/false}
+    Preprocessor cleanPrepro{allSources_};
+    if (preprocessor_.IsNameDefined("__FILE__"s)) {
+      cleanPrepro.DefineStandardMacros(); // __FILE__, __LINE__, &c.
+    }
+    if (preprocessor_.IsNameDefined("_CUDA"s)) {
+      cleanPrepro.Define("_CUDA"s, "1");
+    }
+    Prescanner{*this, cleanPrepro, /*isNestedInIncludeDirective=*/false}
         .set_encoding(included->encoding())
         .Prescan(fileRange);
   }
diff --git a/flang/lib/Parser/prescan.h b/flang/lib/Parser/prescan.h
index a64df5377e7e03..9d4f7c0c302a1a 100644
--- a/flang/lib/Parser/prescan.h
+++ b/flang/lib/Parser/prescan.h
@@ -35,7 +35,8 @@ class Prescanner {
 public:
   Prescanner(Messages &, CookedSource &, Preprocessor &,
       common::LanguageFeatureControl);
-  Prescanner(const Prescanner &, bool isNestedInIncludeDirective);
+  Prescanner(
+      const Prescanner &, Preprocessor &, bool isNestedInIncludeDirective);
   Prescanner(const Prescanner &) = delete;
   Prescanner(Prescanner &&) = delete;
 
diff --git a/flang/module/__fortran_builtins.f90 b/flang/module/__fortran_builtins.f90
index a9d3ac897eb583..d1d4a639e70d72 100644
--- a/flang/module/__fortran_builtins.f90
+++ b/flang/module/__fortran_builtins.f90
@@ -6,7 +6,7 @@
 !
 !===------------------------------------------------------------------------===!
 
-include '../include/flang/Runtime/magic-numbers.h'
+#include '../include/flang/Runtime/magic-numbers.h'
 
 ! These naming shenanigans prevent names from Fortran intrinsic modules
 ! from being usable on INTRINSIC statements, and force the program
diff --git a/flang/module/__fortran_ieee_exceptions.f90 b/flang/module/__fortran_ieee_exceptions.f90
index cebd6045201812..6691012eda238a 100644
--- a/flang/module/__fortran_ieee_exceptions.f90
+++ b/flang/module/__fortran_ieee_exceptions.f90
@@ -11,7 +11,7 @@
 ! here under another name so that IEEE_ARITHMETIC can USE it and export its
 ! declarations without clashing with a non-intrinsic module in a program.
 
-include '../include/flang/Runtime/magic-numbers.h'
+#include '../include/flang/Runtime/magic-numbers.h'
 
 module __fortran_ieee_exceptions
   use __fortran_builtins, only: &
diff --git a/flang/module/ieee_arithmetic.f90 b/flang/module/ieee_arithmetic.f90
index 32e640b9e24574..7eaa7db55af9f8 100644
--- a/flang/module/ieee_arithmetic.f90
+++ b/flang/module/ieee_arithmetic.f90
@@ -8,7 +8,7 @@
 
 ! Fortran 2018 Clause 17
 
-include '../include/flang/Runtime/magic-numbers.h'
+#include '../include/flang/Runtime/magic-numbers.h'
 
 module ieee_arithmetic
   ! F18 Clause 17.1p1:
diff --git a/flang/module/iso_fortran_env.f90 b/flang/module/iso_fortran_env.f90
index cc1f58e7feccb5..4e575b422c2a04 100644
--- a/flang/module/iso_fortran_env.f90
+++ b/flang/module/iso_fortran_env.f90
@@ -8,7 +8,7 @@
 
 ! See Fortran 2023, subclause 16.10.2
 
-include '../include/flang/Runtime/magic-numbers.h'
+#include '../include/flang/Runtime/magic-numbers.h'
 
 module iso_fortran_env
 
diff --git a/flang/test/Driver/include-header.f90 b/flang/test/Driver/include-header.f90
index 789d99526d3620..28b75e072544e4 100644
--- a/flang/test/Driver/include-header.f90
+++ b/flang/test/Driver/include-header.f90
@@ -51,7 +51,7 @@ program B
 end
 
 ! include-test-two.f90
-INCLUDE "basic-header-two.h"
+#include "basic-header-two.h"
 #ifdef Y
 program Y
 #else
diff --git a/flang/test/Preprocessing/include-file.h b/flang/test/Preprocessing/include-file.h
new file mode 100644
index 00000000000000..4d4404e75e0e3b
--- /dev/null
+++ b/flang/test/Preprocessing/include-file.h
@@ -0,0 +1 @@
+print *, sin(0.), j
diff --git a/flang/test/Preprocessing/include-line.F90 b/flang/test/Preprocessing/include-line.F90
new file mode 100644
index 00000000000000..63ff9d33b07b40
--- /dev/null
+++ b/flang/test/Preprocessing/include-line.F90
@@ -0,0 +1,6 @@
+! RUN: %flang_fc1 -fdebug-unparse %s -Dj=1 2>&1 | FileCheck %s
+! Ensure that macro definitions don't affect INCLUDE lines (unlike #include)
+#define sin cos
+!CHECK: PRINT *, 0._4, j
+include "include-file.h"
+end

Copy link
Contributor

@jeanPerier jeanPerier 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 fc1c481 into llvm:main Sep 12, 2024
12 checks passed
@klausler klausler deleted the fs36358 branch September 12, 2024 16:08
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
flang:driver flang:parser flang Flang issues not falling into any other category
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants