Skip to content

Commit b70a41c

Browse files
qiongsiwuyuxuanchen1997
authored andcommitted
[AIX] Detect #pragma mc_func (#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.
1 parent 641a7de commit b70a41c

File tree

7 files changed

+70
-0
lines changed

7 files changed

+70
-0
lines changed

clang/include/clang/Basic/DiagnosticParseKinds.td

+3
Original file line numberDiff line numberDiff line change
@@ -1260,6 +1260,9 @@ def warn_pragma_intrinsic_builtin : Warning<
12601260
def warn_pragma_unused_expected_var : Warning<
12611261
"expected '#pragma unused' argument to be a variable name">,
12621262
InGroup<IgnoredPragmas>;
1263+
// - #pragma mc_func
1264+
def err_pragma_mc_func_not_supported :
1265+
Error<"#pragma mc_func is not supported">;
12631266
// - #pragma init_seg
12641267
def warn_pragma_init_seg_unsupported_target : Warning<
12651268
"'#pragma init_seg' is only supported when targeting a "

clang/include/clang/Driver/Options.td

+7
Original file line numberDiff line numberDiff line change
@@ -8084,6 +8084,13 @@ def source_date_epoch : Separate<["-"], "source-date-epoch">,
80848084

80858085
} // let Visibility = [CC1Option]
80868086

8087+
defm err_pragma_mc_func_aix : BoolFOption<"err-pragma-mc-func-aix",
8088+
PreprocessorOpts<"ErrorOnPragmaMcfuncOnAIX">, DefaultFalse,
8089+
PosFlag<SetTrue, [], [ClangOption, CC1Option],
8090+
"Treat uses of #pragma mc_func as errors">,
8091+
NegFlag<SetFalse,[], [ClangOption, CC1Option],
8092+
"Ignore uses of #pragma mc_func">>;
8093+
80878094
//===----------------------------------------------------------------------===//
80888095
// CUDA Options
80898096
//===----------------------------------------------------------------------===//

clang/include/clang/Lex/PreprocessorOptions.h

+5
Original file line numberDiff line numberDiff line change
@@ -211,6 +211,10 @@ class PreprocessorOptions {
211211
/// If set, the UNIX timestamp specified by SOURCE_DATE_EPOCH.
212212
std::optional<uint64_t> SourceDateEpoch;
213213

214+
/// If set, the preprocessor reports an error when processing #pragma mc_func
215+
/// on AIX.
216+
bool ErrorOnPragmaMcfuncOnAIX = false;
217+
214218
public:
215219
PreprocessorOptions() : PrecompiledPreambleBytes(0, false) {}
216220

@@ -248,6 +252,7 @@ class PreprocessorOptions {
248252
PrecompiledPreambleBytes.first = 0;
249253
PrecompiledPreambleBytes.second = false;
250254
RetainExcludedConditionalBlocks = false;
255+
ErrorOnPragmaMcfuncOnAIX = false;
251256
}
252257
};
253258

clang/include/clang/Parse/Parser.h

+1
Original file line numberDiff line numberDiff line change
@@ -221,6 +221,7 @@ class Parser : public CodeCompletionHandler {
221221
std::unique_ptr<PragmaHandler> MaxTokensHerePragmaHandler;
222222
std::unique_ptr<PragmaHandler> MaxTokensTotalPragmaHandler;
223223
std::unique_ptr<PragmaHandler> RISCVPragmaHandler;
224+
std::unique_ptr<PragmaHandler> MCFuncPragmaHandler;
224225

225226
std::unique_ptr<CommentHandler> CommentSemaHandler;
226227

clang/lib/Driver/ToolChains/AIX.cpp

+6
Original file line numberDiff line numberDiff line change
@@ -557,6 +557,12 @@ void AIX::addClangTargetOptions(
557557
if (!Args.getLastArgNoClaim(options::OPT_fsized_deallocation,
558558
options::OPT_fno_sized_deallocation))
559559
CC1Args.push_back("-fno-sized-deallocation");
560+
561+
if (Args.hasFlag(options::OPT_ferr_pragma_mc_func_aix,
562+
options::OPT_fno_err_pragma_mc_func_aix, false))
563+
CC1Args.push_back("-ferr-pragma-mc-func-aix");
564+
else
565+
CC1Args.push_back("-fno-err-pragma-mc-func-aix");
560566
}
561567

562568
void AIX::addProfileRTLibs(const llvm::opt::ArgList &Args,

clang/lib/Parse/ParsePragma.cpp

+25
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@
1414
#include "clang/Basic/PragmaKinds.h"
1515
#include "clang/Basic/TargetInfo.h"
1616
#include "clang/Lex/Preprocessor.h"
17+
#include "clang/Lex/PreprocessorOptions.h"
1718
#include "clang/Lex/Token.h"
1819
#include "clang/Parse/LoopHint.h"
1920
#include "clang/Parse/ParseDiagnostic.h"
@@ -411,6 +412,19 @@ struct PragmaRISCVHandler : public PragmaHandler {
411412
Sema &Actions;
412413
};
413414

415+
struct PragmaMCFuncHandler : public PragmaHandler {
416+
PragmaMCFuncHandler(bool ReportError)
417+
: PragmaHandler("mc_func"), ReportError(ReportError) {}
418+
void HandlePragma(Preprocessor &PP, PragmaIntroducer Introducer,
419+
Token &Tok) override {
420+
if (ReportError)
421+
PP.Diag(Tok, diag::err_pragma_mc_func_not_supported);
422+
}
423+
424+
private:
425+
bool ReportError = false;
426+
};
427+
414428
void markAsReinjectedForRelexing(llvm::MutableArrayRef<clang::Token> Toks) {
415429
for (auto &T : Toks)
416430
T.setFlag(clang::Token::IsReinjected);
@@ -568,6 +582,12 @@ void Parser::initializePragmaHandlers() {
568582
RISCVPragmaHandler = std::make_unique<PragmaRISCVHandler>(Actions);
569583
PP.AddPragmaHandler("clang", RISCVPragmaHandler.get());
570584
}
585+
586+
if (getTargetInfo().getTriple().isOSAIX()) {
587+
MCFuncPragmaHandler = std::make_unique<PragmaMCFuncHandler>(
588+
PP.getPreprocessorOpts().ErrorOnPragmaMcfuncOnAIX);
589+
PP.AddPragmaHandler(MCFuncPragmaHandler.get());
590+
}
571591
}
572592

573593
void Parser::resetPragmaHandlers() {
@@ -702,6 +722,11 @@ void Parser::resetPragmaHandlers() {
702722
PP.RemovePragmaHandler("clang", RISCVPragmaHandler.get());
703723
RISCVPragmaHandler.reset();
704724
}
725+
726+
if (getTargetInfo().getTriple().isOSAIX()) {
727+
PP.RemovePragmaHandler(MCFuncPragmaHandler.get());
728+
MCFuncPragmaHandler.reset();
729+
}
705730
}
706731

707732
/// Handle the annotation token produced for #pragma unused(...)
+23
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
// RUN: not %clang --target=powerpc64-ibm-aix -ferr-pragma-mc-func-aix -c -S \
2+
// RUN: %s 2>&1 | FileCheck %s
3+
#pragma mc_func asm_barrier {"60000000"}
4+
5+
// CHECK: error: #pragma mc_func is not supported
6+
7+
// Cases where no errors occur.
8+
// RUN: %clang --target=powerpc64-ibm-aix -fno-err-pragma-mc-func-aix -c -S %s
9+
// RUN: %clang --target=powerpc64-ibm-aix -ferr-pragma-mc-func-aix -c -S \
10+
// RUN: -fno-err-pragma-mc-func-aix %s
11+
// RUN: %clang --target=powerpc64-ibm-aix -c -S %s
12+
// RUN: %clang --target=powerpc64-ibm-aix -Werror=unknown-pragmas \
13+
// RUN: -fno-err-pragma-mc-func-aix -c -S %s
14+
15+
// Cases where we have errors or warnings.
16+
// RUN: not %clang --target=powerpc64le-unknown-linux-gnu \
17+
// RUN: -Werror=unknown-pragmas -fno-err-pragma-mc-func-aix -c -S %s 2>&1 | \
18+
// RUN: FileCheck --check-prefix=UNUSED %s
19+
// RUN: %clang --target=powerpc64le-unknown-linux-gnu \
20+
// RUN: -fno-err-pragma-mc-func-aix -c -S %s 2>&1 | \
21+
// RUN: FileCheck --check-prefix=UNUSED %s
22+
23+
// UNUSED: clang: warning: argument unused during compilation: '-fno-err-pragma-mc-func-aix' [-Wunused-command-line-argument]

0 commit comments

Comments
 (0)