[clang] [AIX] Detect `#pragma mc_func` (PR #99888)

Qiongsi Wu via cfe-commits cfe-commits at lists.llvm.org
Mon Jul 22 08:09:49 PDT 2024


https://github.com/qiongsiwu created https://github.com/llvm/llvm-project/pull/99888

`#pragma mc_func` is an IBM XL feature that should be replaced by inline assembly. This PR adds an option `-ferr-pragma-mc-func-aix` to detect uses of `#pragma mc_func` and reports an error if the option is in effect. If `-fno-err-pragma-mc-func-aix` is in effect, `#pragma mc_func` is ignored even if `-Werror=unknown-pragmas` is in effect. 

>From 11f3983bf8eae0d2cc47f342b3a7ac59fff43988 Mon Sep 17 00:00:00 2001
From: Qiongsi Wu <qwu at ibm.com>
Date: Mon, 22 Jul 2024 11:14:22 -0400
Subject: [PATCH] pragma mc_func check

---
 .../clang/Basic/DiagnosticParseKinds.td       |  3 +++
 clang/include/clang/Driver/Options.td         |  7 ++++++
 clang/include/clang/Lex/PreprocessorOptions.h |  5 ++++
 clang/include/clang/Parse/Parser.h            |  1 +
 clang/lib/Driver/ToolChains/AIX.cpp           |  6 +++++
 clang/lib/Parse/ParsePragma.cpp               | 25 +++++++++++++++++++
 clang/test/Preprocessor/pragma_mc_func.c      | 23 +++++++++++++++++
 7 files changed, 70 insertions(+)
 create mode 100644 clang/test/Preprocessor/pragma_mc_func.c

diff --git a/clang/include/clang/Basic/DiagnosticParseKinds.td b/clang/include/clang/Basic/DiagnosticParseKinds.td
index 12aab09f28556..f8d50d12bb935 100644
--- a/clang/include/clang/Basic/DiagnosticParseKinds.td
+++ b/clang/include/clang/Basic/DiagnosticParseKinds.td
@@ -1260,6 +1260,9 @@ def warn_pragma_intrinsic_builtin : Warning<
 def warn_pragma_unused_expected_var : Warning<
   "expected '#pragma unused' argument to be a variable name">,
   InGroup<IgnoredPragmas>;
+// - #pragma mc_func
+def err_pragma_mc_func_not_supported :
+   Error<"#pragma mc_func is not supported">;
 // - #pragma init_seg
 def warn_pragma_init_seg_unsupported_target : Warning<
   "'#pragma init_seg' is only supported when targeting a "
diff --git a/clang/include/clang/Driver/Options.td b/clang/include/clang/Driver/Options.td
index 9c6cebd77ff0a..020032de31c46 100644
--- a/clang/include/clang/Driver/Options.td
+++ b/clang/include/clang/Driver/Options.td
@@ -8082,6 +8082,13 @@ def source_date_epoch : Separate<["-"], "source-date-epoch">,
 
 } // let Visibility = [CC1Option]
 
+defm err_pragma_mc_func_aix : BoolFOption<"err-pragma-mc-func-aix",
+  PreprocessorOpts<"ErrorOnPragmaMcfuncOnAIX">, DefaultFalse,
+  PosFlag<SetTrue, [], [ClangOption, CC1Option],
+          "Treat uses of #pragma mc_func as errors">,
+  NegFlag<SetFalse,[], [ClangOption, CC1Option],
+          "Ignore uses of #pragma mc_func">>;
+
 //===----------------------------------------------------------------------===//
 // CUDA Options
 //===----------------------------------------------------------------------===//
diff --git a/clang/include/clang/Lex/PreprocessorOptions.h b/clang/include/clang/Lex/PreprocessorOptions.h
index c2e3d68333024..3f7dd9db18ba7 100644
--- a/clang/include/clang/Lex/PreprocessorOptions.h
+++ b/clang/include/clang/Lex/PreprocessorOptions.h
@@ -211,6 +211,10 @@ class PreprocessorOptions {
   /// If set, the UNIX timestamp specified by SOURCE_DATE_EPOCH.
   std::optional<uint64_t> SourceDateEpoch;
 
+  /// If set, the preprocessor reports an error when processing #pragma mc_func
+  /// on AIX.
+  bool ErrorOnPragmaMcfuncOnAIX = false;
+
 public:
   PreprocessorOptions() : PrecompiledPreambleBytes(0, false) {}
 
@@ -248,6 +252,7 @@ class PreprocessorOptions {
     PrecompiledPreambleBytes.first = 0;
     PrecompiledPreambleBytes.second = false;
     RetainExcludedConditionalBlocks = false;
+    ErrorOnPragmaMcfuncOnAIX = false;
   }
 };
 
diff --git a/clang/include/clang/Parse/Parser.h b/clang/include/clang/Parse/Parser.h
index 93e60be512aae..613bab9120dfc 100644
--- a/clang/include/clang/Parse/Parser.h
+++ b/clang/include/clang/Parse/Parser.h
@@ -221,6 +221,7 @@ class Parser : public CodeCompletionHandler {
   std::unique_ptr<PragmaHandler> MaxTokensHerePragmaHandler;
   std::unique_ptr<PragmaHandler> MaxTokensTotalPragmaHandler;
   std::unique_ptr<PragmaHandler> RISCVPragmaHandler;
+  std::unique_ptr<PragmaHandler> MCFuncPragmaHandler;
 
   std::unique_ptr<CommentHandler> CommentSemaHandler;
 
diff --git a/clang/lib/Driver/ToolChains/AIX.cpp b/clang/lib/Driver/ToolChains/AIX.cpp
index b04502a57a9f7..fb780fb75651d 100644
--- a/clang/lib/Driver/ToolChains/AIX.cpp
+++ b/clang/lib/Driver/ToolChains/AIX.cpp
@@ -557,6 +557,12 @@ void AIX::addClangTargetOptions(
   if (!Args.getLastArgNoClaim(options::OPT_fsized_deallocation,
                               options::OPT_fno_sized_deallocation))
     CC1Args.push_back("-fno-sized-deallocation");
+
+  if (Args.hasFlag(options::OPT_ferr_pragma_mc_func_aix,
+                   options::OPT_fno_err_pragma_mc_func_aix, false))
+    CC1Args.push_back("-ferr-pragma-mc-func-aix");
+  else
+    CC1Args.push_back("-fno-err-pragma-mc-func-aix");
 }
 
 void AIX::addProfileRTLibs(const llvm::opt::ArgList &Args,
diff --git a/clang/lib/Parse/ParsePragma.cpp b/clang/lib/Parse/ParsePragma.cpp
index cc6f18b5b319f..aef4ddb758816 100644
--- a/clang/lib/Parse/ParsePragma.cpp
+++ b/clang/lib/Parse/ParsePragma.cpp
@@ -14,6 +14,7 @@
 #include "clang/Basic/PragmaKinds.h"
 #include "clang/Basic/TargetInfo.h"
 #include "clang/Lex/Preprocessor.h"
+#include "clang/Lex/PreprocessorOptions.h"
 #include "clang/Lex/Token.h"
 #include "clang/Parse/LoopHint.h"
 #include "clang/Parse/ParseDiagnostic.h"
@@ -411,6 +412,19 @@ struct PragmaRISCVHandler : public PragmaHandler {
   Sema &Actions;
 };
 
+struct PragmaMCFuncHandler : public PragmaHandler {
+  PragmaMCFuncHandler(bool ReportError)
+      : PragmaHandler("mc_func"), ReportError(ReportError) {}
+  void HandlePragma(Preprocessor &PP, PragmaIntroducer Introducer,
+                    Token &Tok) override {
+    if (ReportError)
+      PP.Diag(Tok, diag::err_pragma_mc_func_not_supported);
+  }
+
+private:
+  bool ReportError = false;
+};
+
 void markAsReinjectedForRelexing(llvm::MutableArrayRef<clang::Token> Toks) {
   for (auto &T : Toks)
     T.setFlag(clang::Token::IsReinjected);
@@ -568,6 +582,12 @@ void Parser::initializePragmaHandlers() {
     RISCVPragmaHandler = std::make_unique<PragmaRISCVHandler>(Actions);
     PP.AddPragmaHandler("clang", RISCVPragmaHandler.get());
   }
+
+  if (getTargetInfo().getTriple().isOSAIX()) {
+    MCFuncPragmaHandler = std::make_unique<PragmaMCFuncHandler>(
+        PP.getPreprocessorOpts().ErrorOnPragmaMcfuncOnAIX);
+    PP.AddPragmaHandler(MCFuncPragmaHandler.get());
+  }
 }
 
 void Parser::resetPragmaHandlers() {
@@ -702,6 +722,11 @@ void Parser::resetPragmaHandlers() {
     PP.RemovePragmaHandler("clang", RISCVPragmaHandler.get());
     RISCVPragmaHandler.reset();
   }
+
+  if (getTargetInfo().getTriple().isOSAIX()) {
+    PP.RemovePragmaHandler(MCFuncPragmaHandler.get());
+    MCFuncPragmaHandler.reset();
+  }
 }
 
 /// Handle the annotation token produced for #pragma unused(...)
diff --git a/clang/test/Preprocessor/pragma_mc_func.c b/clang/test/Preprocessor/pragma_mc_func.c
new file mode 100644
index 0000000000000..e5f362f10e41a
--- /dev/null
+++ b/clang/test/Preprocessor/pragma_mc_func.c
@@ -0,0 +1,23 @@
+// RUN: not %clang --target=powerpc64-ibm-aix -ferr-pragma-mc-func-aix -c -S \
+// RUN:   %s 2>&1 | FileCheck %s
+#pragma mc_func asm_barrier {"60000000"}
+
+// CHECK:  error: #pragma mc_func is not supported
+
+// Cases where no errors occur.
+// RUN: %clang --target=powerpc64-ibm-aix -fno-err-pragma-mc-func-aix -c -S %s
+// RUN: %clang --target=powerpc64-ibm-aix -ferr-pragma-mc-func-aix -c -S \
+// RUN:    -fno-err-pragma-mc-func-aix %s
+// RUN: %clang --target=powerpc64-ibm-aix -c -S %s
+// RUN: %clang --target=powerpc64-ibm-aix -Werror=unknown-pragmas \
+// RUN:   -fno-err-pragma-mc-func-aix -c -S %s
+
+// Cases where we have errors or warnings.
+// RUN: not %clang --target=powerpc64le-unknown-linux-gnu \
+// RUN:   -Werror=unknown-pragmas -fno-err-pragma-mc-func-aix -c -S %s 2>&1 | \
+// RUN:   FileCheck --check-prefix=UNUSED %s
+// RUN: %clang --target=powerpc64le-unknown-linux-gnu \
+// RUN:   -fno-err-pragma-mc-func-aix -c -S %s 2>&1 | \
+// RUN:   FileCheck --check-prefix=UNUSED %s
+
+// UNUSED: clang: warning: argument unused during compilation: '-fno-err-pragma-mc-func-aix' [-Wunused-command-line-argument]



More information about the cfe-commits mailing list