[flang] Implement -Wno-<warning> flags for driver diagnostics (#196354)
Utilize clang::ProcessWarningOptions function to process -Wno-... options. This has the side effect that without additional changes it would cause driver warnings to become errors with -Werror. That would be a change from the existing behavior, so make sure that these warnings remain unaffected. Modify the diagnostic emitter to add the disabling option at the end of the emitted diagnostic. Fixes https://github.com/llvm/llvm-project/issues/195921 --------- Co-authored-by: Tarun Prabhu <tarun@lanl.gov>
This commit is contained in:
parent
b9bc518ac5
commit
42b4cb6aeb
17 changed files with 81 additions and 47 deletions
|
|
@ -167,10 +167,13 @@ def warn_drv_unsupported_option_for_runtime : Warning<
|
|||
def warn_drv_unsupported_openmp_library : Warning<
|
||||
"the library '%0=%1' is not supported, OpenMP will not be enabled">,
|
||||
InGroup<OptionIgnored>;
|
||||
def warn_openmp_incomplete : Warning<
|
||||
def warn_openmp_impl_incomplete : Warning<
|
||||
"OpenMP support for version %0 in flang is still incomplete">,
|
||||
InGroup<ExperimentalOption>;
|
||||
|
||||
def warn_openmp_spec_incomplete : Warning<
|
||||
"the specification for OpenMP version %0 is still under development; "
|
||||
"the syntax and semantics of new features may be subject to change">,
|
||||
InGroup<ExperimentalOption>;
|
||||
def err_drv_invalid_thread_model_for_target : Error<
|
||||
"invalid thread model '%0' in '%1' for this target">;
|
||||
def err_drv_invalid_linker_name : Error<
|
||||
|
|
|
|||
|
|
@ -36,7 +36,7 @@ page](https://llvm.org/releases/).
|
|||
## New Compiler Flags
|
||||
|
||||
- The warning flags with prefixes -Wopen-mp and -Wopen-acc have been deprecated in favor of corrected spellings with the respective prefixes -Wopenmp and -Wopenacc. Removal of the deprecated options is planned for LLVM 25 (July 2027).
|
||||
|
||||
- The `-Werror` flag will cause all warnings to become errors. This includes warnings about support for OpenMP versions, which will now prevent the compilation from happening with the `-Werror` flag. These OpenMP warnings can be disabled with `-Wno-experimental-option`.
|
||||
|
||||
## Windows Support
|
||||
|
||||
|
|
|
|||
|
|
@ -85,7 +85,7 @@ ENUM_CLASS(UsageWarning, Portability, PointerToUndefinable,
|
|||
RealConstantWidening, VolatileOrAsynchronousTemporary, UnusedVariable,
|
||||
UsedUndefinedVariable, BadValueInDeadCode, AssumedTypeSizeDummy,
|
||||
MisplacedIgnoreTKR, NamelistParameter, ImpureFinalInPure,
|
||||
IgnoredNoReallocateLHS, CLoc)
|
||||
IgnoredNoReallocateLHS, CLoc, ExperimentalOption)
|
||||
|
||||
using LanguageFeatures = EnumSet<LanguageFeature, LanguageFeature_enumSize>;
|
||||
using UsageWarnings = EnumSet<UsageWarning, UsageWarning_enumSize>;
|
||||
|
|
|
|||
|
|
@ -40,6 +40,7 @@
|
|||
#include "llvm/Support/FileSystem.h"
|
||||
#include "llvm/Support/Path.h"
|
||||
#include "llvm/Support/Process.h"
|
||||
#include "llvm/Support/VirtualFileSystem.h"
|
||||
#include "llvm/Support/raw_ostream.h"
|
||||
#include "llvm/TargetParser/Host.h"
|
||||
#include "llvm/TargetParser/Triple.h"
|
||||
|
|
@ -601,8 +602,6 @@ static std::optional<const char *> parseConvertArg(const char *s) {
|
|||
|
||||
static bool parseFrontendArgs(FrontendOptions &opts, llvm::opt::ArgList &args,
|
||||
clang::DiagnosticsEngine &diags) {
|
||||
unsigned numErrorsBefore = diags.getNumErrors();
|
||||
|
||||
// By default the frontend driver creates a ParseSyntaxOnly action.
|
||||
opts.programAction = ParseSyntaxOnly;
|
||||
|
||||
|
|
@ -910,7 +909,7 @@ static bool parseFrontendArgs(FrontendOptions &opts, llvm::opt::ArgList &args,
|
|||
setUpFrontendBasedOnAction(opts);
|
||||
opts.dashX = dashX;
|
||||
|
||||
return diags.getNumErrors() == numErrorsBefore;
|
||||
return !diags.hasUncompilableErrorOccurred();
|
||||
}
|
||||
|
||||
// Generate the path to look for intrinsic modules
|
||||
|
|
@ -983,8 +982,6 @@ static void parsePreprocessorArgs(Fortran::frontend::PreprocessorOptions &opts,
|
|||
/// options accordingly. Returns false if new errors are generated.
|
||||
static bool parseSemaArgs(CompilerInvocation &res, llvm::opt::ArgList &args,
|
||||
clang::DiagnosticsEngine &diags) {
|
||||
unsigned numErrorsBefore = diags.getNumErrors();
|
||||
|
||||
// -J/module-dir option
|
||||
std::vector<std::string> moduleDirList =
|
||||
args.getAllArgValues(clang::options::OPT_module_dir);
|
||||
|
|
@ -1026,7 +1023,7 @@ static bool parseSemaArgs(CompilerInvocation &res, llvm::opt::ArgList &args,
|
|||
args.hasFlag(clang::options::OPT_fanalyzed_objects_for_unparse,
|
||||
clang::options::OPT_fno_analyzed_objects_for_unparse, true));
|
||||
|
||||
return diags.getNumErrors() == numErrorsBefore;
|
||||
return !diags.hasUncompilableErrorOccurred();
|
||||
}
|
||||
|
||||
/// Parses all diagnostics related arguments and populates the variables
|
||||
|
|
@ -1034,8 +1031,6 @@ static bool parseSemaArgs(CompilerInvocation &res, llvm::opt::ArgList &args,
|
|||
/// FC1 driver entry point for parsing diagnostic arguments.
|
||||
static bool parseDiagArgs(CompilerInvocation &res, llvm::opt::ArgList &args,
|
||||
clang::DiagnosticsEngine &diags) {
|
||||
unsigned numErrorsBefore = diags.getNumErrors();
|
||||
|
||||
auto &features{res.getFrontendOpts().features};
|
||||
// The order of these flags (-pedantic -W<feature> -w) is important and is
|
||||
// chosen to match clang's behavior.
|
||||
|
|
@ -1092,15 +1087,13 @@ static bool parseDiagArgs(CompilerInvocation &res, llvm::opt::ArgList &args,
|
|||
diags.getDiagnosticOptions().ShowColors = showColors;
|
||||
res.getDiagnosticOpts().ShowColors = showColors;
|
||||
res.getFrontendOpts().showColors = showColors;
|
||||
return diags.getNumErrors() == numErrorsBefore;
|
||||
return !diags.hasUncompilableErrorOccurred();
|
||||
}
|
||||
|
||||
/// Parses all Dialect related arguments and populates the variables
|
||||
/// options accordingly. Returns false if new errors are generated.
|
||||
static bool parseDialectArgs(CompilerInvocation &res, llvm::opt::ArgList &args,
|
||||
clang::DiagnosticsEngine &diags) {
|
||||
unsigned numErrorsBefore = diags.getNumErrors();
|
||||
|
||||
// -fd-lines-as-code
|
||||
if (args.hasArg(clang::options::OPT_fd_lines_as_code)) {
|
||||
if (res.getFrontendOpts().fortranForm == FortranForm::FreeForm) {
|
||||
|
|
@ -1213,7 +1206,7 @@ static bool parseDialectArgs(CompilerInvocation &res, llvm::opt::ArgList &args,
|
|||
diags.Report(diagID);
|
||||
}
|
||||
|
||||
return diags.getNumErrors() == numErrorsBefore;
|
||||
return !diags.hasUncompilableErrorOccurred();
|
||||
}
|
||||
|
||||
/// Parses all OpenMP related arguments if the -fopenmp option is present,
|
||||
|
|
@ -1232,7 +1225,6 @@ static bool parseOpenMPArgs(CompilerInvocation &res, llvm::opt::ArgList &args,
|
|||
res.getLangOpts().OpenMPSimd = 1;
|
||||
}
|
||||
|
||||
unsigned numErrorsBefore = diags.getNumErrors();
|
||||
llvm::Triple t(res.getTargetOpts().triple);
|
||||
|
||||
constexpr unsigned newestFullySupported = 31;
|
||||
|
|
@ -1258,27 +1250,15 @@ static bool parseOpenMPArgs(CompilerInvocation &res, llvm::opt::ArgList &args,
|
|||
diags.Report(diagID) << value << arg->getAsString(args) << versions.str();
|
||||
};
|
||||
|
||||
auto reportFutureVersion = [&](llvm::StringRef value) {
|
||||
const unsigned diagID = diags.getCustomDiagID(
|
||||
clang::DiagnosticsEngine::Warning,
|
||||
"The specification for OpenMP version %0 is still under development; "
|
||||
"the syntax and semantics of new features may be subject to change");
|
||||
std::string buffer;
|
||||
llvm::raw_string_ostream versions(buffer);
|
||||
llvm::interleaveComma(ompVersions, versions);
|
||||
|
||||
diags.Report(diagID) << value;
|
||||
};
|
||||
|
||||
llvm::StringRef value = arg->getValue();
|
||||
if (!value.getAsInteger(/*radix=*/10, version)) {
|
||||
if (llvm::is_contained(ompVersions, version)) {
|
||||
res.getLangOpts().OpenMPVersion = version;
|
||||
|
||||
if (version > latestFinalized)
|
||||
reportFutureVersion(value);
|
||||
diags.Report(clang::diag::warn_openmp_spec_incomplete) << version;
|
||||
else if (version > newestFullySupported)
|
||||
diags.Report(clang::diag::warn_openmp_incomplete) << version;
|
||||
diags.Report(clang::diag::warn_openmp_impl_incomplete) << version;
|
||||
} else if (llvm::is_contained(oldVersions, version)) {
|
||||
const unsigned diagID =
|
||||
diags.getCustomDiagID(clang::DiagnosticsEngine::Warning,
|
||||
|
|
@ -1382,7 +1362,7 @@ static bool parseOpenMPArgs(CompilerInvocation &res, llvm::opt::ArgList &args,
|
|||
res.getLangOpts().OMPTargetTriples.push_back(tt);
|
||||
}
|
||||
}
|
||||
return diags.getNumErrors() == numErrorsBefore;
|
||||
return !diags.hasUncompilableErrorOccurred();
|
||||
}
|
||||
|
||||
/// Parses signed integer overflow options and populates the
|
||||
|
|
@ -1588,11 +1568,35 @@ static bool parseLangOptionsArgs(CompilerInvocation &invoc,
|
|||
return success;
|
||||
}
|
||||
|
||||
// Copied from clang/lib/Frontend/CompilerInvocation.cpp.
|
||||
static void addDiagnosticArgs(llvm::opt::ArgList &args,
|
||||
llvm::opt::OptSpecifier group,
|
||||
llvm::opt::OptSpecifier groupWithValue,
|
||||
std::vector<std::string> &diagnostics) {
|
||||
for (auto *a : args.filtered(group)) {
|
||||
if (a->getOption().getKind() == llvm::opt::Option::FlagClass) {
|
||||
// The argument is a pure flag (such as OPT_Wall or OPT_Wdeprecated). Add
|
||||
// its name (minus the "W" or "R" at the beginning) to the diagnostics.
|
||||
diagnostics.push_back(
|
||||
std::string(a->getOption().getName().drop_front(1)));
|
||||
} else if (a->getOption().matches(groupWithValue)) {
|
||||
// This is -Wfoo= or -Rfoo=, where foo is the name of the diagnostic
|
||||
// group. Add only the group name to the diagnostics.
|
||||
diagnostics.push_back(
|
||||
std::string(a->getOption().getName().drop_front(1).rtrim("=-")));
|
||||
} else {
|
||||
// Otherwise, add its value (for OPT_W_Joined and similar).
|
||||
diagnostics.push_back(a->getValue());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
bool CompilerInvocation::createFromArgs(
|
||||
CompilerInvocation &invoc, llvm::ArrayRef<const char *> commandLineArgs,
|
||||
clang::DiagnosticsEngine &diags, const char *argv0) {
|
||||
|
||||
bool success = true;
|
||||
clang::DiagnosticOptions &diagOpts = diags.getDiagnosticOptions();
|
||||
|
||||
// Set the default triple for this CompilerInvocation. This might be
|
||||
// overridden by users with `-triple` (see the call to `ParseTargetArgs`
|
||||
|
|
@ -1629,6 +1633,12 @@ bool CompilerInvocation::createFromArgs(
|
|||
success = false;
|
||||
}
|
||||
|
||||
// Handle -Wno-<warning> flags.
|
||||
addDiagnosticArgs(args, clang::options::OPT_W_Group,
|
||||
clang::options::OPT_W_value_Group, diagOpts.Warnings);
|
||||
auto vfs = llvm::vfs::getRealFileSystem();
|
||||
clang::ProcessWarningOptions(diags, diagOpts, *vfs, /*ReportDiags=*/false);
|
||||
|
||||
// -fno-ppc-native-vector-element-order
|
||||
if (args.hasArg(clang::options::OPT_fno_ppc_native_vec_elem_order)) {
|
||||
invoc.loweringOpts.setNoPPCNativeVecElemOrder(true);
|
||||
|
|
|
|||
|
|
@ -18,18 +18,39 @@
|
|||
#include "clang/Basic/Diagnostic.h"
|
||||
#include "llvm/ADT/SmallString.h"
|
||||
#include "llvm/Support/ErrorHandling.h"
|
||||
#include "llvm/Support/raw_ostream.h"
|
||||
|
||||
using namespace Fortran::frontend;
|
||||
|
||||
static void printWarningOption(llvm::raw_ostream &os,
|
||||
clang::DiagnosticsEngine::Level level,
|
||||
const clang::Diagnostic &info) {
|
||||
auto &diagIDs = *info.getDiags()->getDiagnosticIDs();
|
||||
|
||||
if (level == clang::DiagnosticsEngine::Warning) {
|
||||
llvm::StringRef opt = diagIDs.getWarningOptionForDiag(info.getID());
|
||||
if (!opt.empty()) {
|
||||
os << " [-W" << opt;
|
||||
llvm::StringRef optValue = info.getFlagValue();
|
||||
if (!optValue.empty())
|
||||
os << "=" << optValue;
|
||||
os << "]";
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// HandleDiagnostic - Store the errors, warnings, and notes that are
|
||||
/// reported.
|
||||
void TextDiagnosticBuffer::HandleDiagnostic(
|
||||
clang::DiagnosticsEngine::Level level, const clang::Diagnostic &info) {
|
||||
// Default implementation (warnings_/errors count).
|
||||
// Default implementation (warnings/errors count).
|
||||
DiagnosticConsumer::HandleDiagnostic(level, info);
|
||||
|
||||
llvm::SmallString<100> buf;
|
||||
info.FormatDiagnostic(buf);
|
||||
llvm::raw_svector_ostream os(buf);
|
||||
printWarningOption(os, level, info);
|
||||
|
||||
switch (level) {
|
||||
default:
|
||||
llvm_unreachable("Diagnostic not handled during diagnostic buffering!");
|
||||
|
|
|
|||
|
|
@ -16,14 +16,14 @@
|
|||
|
||||
|
||||
!RUN: %flang -c -fopenmp -fopenmp-version=25 %s 2>&1 | FileCheck --check-prefix=WARN-ASSUMED %s
|
||||
|
||||
!WARN-ASSUMED: warning: OpenMP version 25 is no longer supported, assuming version 31
|
||||
|
||||
|
||||
!RUN: not %flang -c -fopenmp -fopenmp-version=29 %s 2>&1 | FileCheck --check-prefix=ERR-BAD %s
|
||||
|
||||
!ERR-BAD: error: '29' is not a valid OpenMP version in '-fopenmp-version=29', valid versions are 31, 40, 45, 50, 51, 52, 60, 61
|
||||
|
||||
!RUN: %flang -c -fopenmp -fopenmp-version=61 %s 2>&1 | FileCheck --check-prefix=FUTURE %s
|
||||
!FUTURE: the specification for OpenMP version 61 is still under development; the syntax and semantics of new features may be subject to change [-Wexperimental-option]
|
||||
|
||||
!FUTURE: The specification for OpenMP version 61 is still under development; the syntax and semantics of new features may be subject to change
|
||||
!RUN: %flang -c -fopenmp -fopenmp-version=60 %s 2>&1 | FileCheck --check-prefix=IMPL %s
|
||||
!IMPL: OpenMP support for version 60 in flang is still incomplete [-Wexperimental-option]
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
!RUN: %python %S/../test_errors.py %s %flang -fopenmp -fopenmp-version=45 -Werror
|
||||
!RUN: %python %S/../test_errors.py %s %flang -fopenmp -fopenmp-version=45 -Werror -Wno-experimental-option
|
||||
|
||||
subroutine f00
|
||||
!WARNING: 'variable-category' modifier is required
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
!RUN: %python %S/../test_errors.py %s %flang -fopenmp -fopenmp-version=50 -Werror
|
||||
!RUN: %python %S/../test_errors.py %s %flang -fopenmp -fopenmp-version=50 -Werror -Wno-experimental-option
|
||||
|
||||
subroutine f00
|
||||
!$omp target defaultmap(tofrom)
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
!RUN: %python %S/../test_errors.py %s %flang -fopenmp -fopenmp-version=45 -Werror
|
||||
!RUN: %python %S/../test_errors.py %s %flang -fopenmp -fopenmp-version=45 -Werror -Wno-experimental-option
|
||||
|
||||
subroutine f00(x)
|
||||
integer :: x(10)
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
!RUN: %python %S/../test_errors.py %s %flang -fopenmp -fopenmp-version=45 -Werror
|
||||
!RUN: %python %S/../test_errors.py %s %flang -fopenmp -fopenmp-version=45 -Werror -Wno-experimental-option
|
||||
|
||||
subroutine f00(x)
|
||||
integer :: x
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
! RUN: %python %S/../test_errors.py %s %flang_fc1 -fopenmp -Werror -fopenmp-version=52
|
||||
! RUN: %python %S/../test_errors.py %s %flang_fc1 -fopenmp -Werror -fopenmp-version=52 -Wno-experimental-option
|
||||
|
||||
! Check for deprecation of master directive and its combined/composite variants
|
||||
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
! RUN: %python %S/../test_errors.py %s %flang_fc1 -fopenmp -fopenmp-version=52 -Werror
|
||||
! RUN: %python %S/../test_errors.py %s %flang_fc1 -fopenmp -fopenmp-version=52 -Werror -Wno-experimental-option
|
||||
|
||||
subroutine f00(x)
|
||||
integer :: x
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
!RUN: %python %S/../test_errors.py %s %flang -fopenmp -fopenmp-version=52 -Werror
|
||||
!RUN: %python %S/../test_errors.py %s %flang -fopenmp -fopenmp-version=52 -Werror -Wno-experimental-option
|
||||
|
||||
! The directives to check:
|
||||
! cancellation_point
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
!RUN: %python %S/../test_errors.py %s %flang -fopenmp -fopenmp-version=52 -Werror
|
||||
!RUN: %python %S/../test_errors.py %s %flang -fopenmp -fopenmp-version=52 -Werror -Wno-experimental-option
|
||||
|
||||
subroutine f00(x)
|
||||
integer :: x
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
!RUN: %python %S/../test_errors.py %s %flang -fopenmp -fopenmp-version=61 -Werror
|
||||
!RUN: %python %S/../test_errors.py %s %flang -fopenmp -fopenmp-version=61 -Werror -Wno-experimental-option
|
||||
|
||||
subroutine f00(x)
|
||||
integer, pointer :: x
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
!RUN: %python %S/../test_errors.py %s %flang -fopenmp -fopenmp-version=52 -Werror
|
||||
!RUN: %python %S/../test_errors.py %s %flang -fopenmp -fopenmp-version=52 -Werror -Wno-experimental-option
|
||||
|
||||
subroutine f10(x)
|
||||
integer :: x
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
!RUN: %flang_fc1 -fsyntax-only -fopenmp -fopenmp-version=60 -Werror %s | FileCheck --allow-empty %s
|
||||
!RUN: %flang_fc1 -fsyntax-only -fopenmp -fopenmp-version=60 -Werror -Wno-experimental-option %s | FileCheck --allow-empty %s
|
||||
|
||||
!CHECK-NOT: deprecated
|
||||
subroutine f00
|
||||
|
|
|
|||
Loading…
Reference in a new issue