[clang] [llvm] [driver] Make --version show if assertions, etc. are enabled (PR #87585)
Cassie Jones via cfe-commits
cfe-commits at lists.llvm.org
Thu Apr 4 14:57:21 PDT 2024
https://github.com/porglezomp updated https://github.com/llvm/llvm-project/pull/87585
>From a104ff0a445dfe5c6e6cfcf3734f6c0942eca082 Mon Sep 17 00:00:00 2001
From: Cassie Jones <cassie_jones at apple.com>
Date: Thu, 28 Mar 2024 13:58:19 -0700
Subject: [PATCH 1/7] [driver] Make --version show if assertions, etc. are
enabled
It's useful to have some significant build options visible in the
version when investigating problems with a specific compiler artifact.
This makes it easy to see if assertions, expensive checks, sanitizers,
etc. are enabled when checking a compiler version.
---
clang/lib/Driver/Driver.cpp | 38 +++++++++++++++++++++
clang/test/Driver/version-build-config.test | 6 ++++
2 files changed, 44 insertions(+)
create mode 100644 clang/test/Driver/version-build-config.test
diff --git a/clang/lib/Driver/Driver.cpp b/clang/lib/Driver/Driver.cpp
index 7a53764364ce4d..37180efb7ea67b 100644
--- a/clang/lib/Driver/Driver.cpp
+++ b/clang/lib/Driver/Driver.cpp
@@ -2002,6 +2002,44 @@ void Driver::PrintVersion(const Compilation &C, raw_ostream &OS) const {
// Print out the install directory.
OS << "InstalledDir: " << Dir << '\n';
+ // Print out build configuration options that impact the compiler's runtime
+ // behavior. Intended for identifying the source of issues when reproducing
+ // changes.
+ std::vector<std::string> BuildOptions = {
+#if !__OPTIMIZE__
+ "+unoptimized",
+#endif
+#ifndef NDEBUG
+ "+assertions",
+#endif
+#ifdef EXPENSIVE_CHECKS
+ "+expensive-checks",
+#endif
+#if __has_feature(address_sanitizer)
+ "+asan",
+#endif
+#if __has_feature(undefined_behavior_sanitizer)
+ "+ubsan",
+#endif
+#if __has_feature(memory_sanitizer)
+ "+msan",
+#endif
+#if __has_feature(dataflow_sanitizer)
+ "+dfsan",
+#endif
+ };
+ if (!BuildOptions.empty()) {
+ OS << "Build configuration: ";
+ bool FirstOption = true;
+ for (const auto &Option : BuildOptions) {
+ if (!FirstOption)
+ OS << ", ";
+ OS << Option;
+ FirstOption = false;
+ }
+ OS << '\n';
+ }
+
// If configuration files were used, print their paths.
for (auto ConfigFile : ConfigFiles)
OS << "Configuration file: " << ConfigFile << '\n';
diff --git a/clang/test/Driver/version-build-config.test b/clang/test/Driver/version-build-config.test
new file mode 100644
index 00000000000000..3d183f372908ea
--- /dev/null
+++ b/clang/test/Driver/version-build-config.test
@@ -0,0 +1,6 @@
+# REQUIRES: asserts
+# RUN: %clang --version 2>&1 | FileCheck %s
+
+# CHECK: clang version
+# When assertions are enabled, we should have a build configuration line that reflects that
+# CHECK: Build configuration: {{.*}}+assertions
>From efc90ba92c29f1cd14f508f56a82a1f03f960401 Mon Sep 17 00:00:00 2001
From: Cassie Jones <cassie_jones at apple.com>
Date: Wed, 3 Apr 2024 22:01:39 -0700
Subject: [PATCH 2/7] Address review feedback
---
clang/lib/Driver/Driver.cpp | 31 ++++++++++++++-----------------
1 file changed, 14 insertions(+), 17 deletions(-)
diff --git a/clang/lib/Driver/Driver.cpp b/clang/lib/Driver/Driver.cpp
index 37180efb7ea67b..680c58e4ea43d8 100644
--- a/clang/lib/Driver/Driver.cpp
+++ b/clang/lib/Driver/Driver.cpp
@@ -2005,38 +2005,35 @@ void Driver::PrintVersion(const Compilation &C, raw_ostream &OS) const {
// Print out build configuration options that impact the compiler's runtime
// behavior. Intended for identifying the source of issues when reproducing
// changes.
- std::vector<std::string> BuildOptions = {
-#if !__OPTIMIZE__
- "+unoptimized",
+ SmallVector<StringRef> BuildOptions = {
+#if __GNUC__ && !__OPTIMIZE__
+ // FIXME: __OPTIMIZE__ is not available on MSVC, this will never show there
+ "+unoptimized",
#endif
#ifndef NDEBUG
- "+assertions",
+ "+assertions",
#endif
#ifdef EXPENSIVE_CHECKS
- "+expensive-checks",
+ "+expensive-checks",
#endif
#if __has_feature(address_sanitizer)
- "+asan",
+ "+asan",
#endif
#if __has_feature(undefined_behavior_sanitizer)
- "+ubsan",
+ "+ubsan",
#endif
#if __has_feature(memory_sanitizer)
- "+msan",
+ "+msan",
#endif
#if __has_feature(dataflow_sanitizer)
- "+dfsan",
+ "+dfsan",
#endif
};
if (!BuildOptions.empty()) {
- OS << "Build configuration: ";
- bool FirstOption = true;
- for (const auto &Option : BuildOptions) {
- if (!FirstOption)
- OS << ", ";
- OS << Option;
- FirstOption = false;
- }
+ OS << "Build config: ";
+ llvm::interleaveComma(BuildOptions, OS, [&OS](const StringRef &Option) {
+ OS << Option;
+ });
OS << '\n';
}
>From 1213ba2f965a0577fc6504e967ae17346da4ef4f Mon Sep 17 00:00:00 2001
From: Cassie Jones <cassie_jones at apple.com>
Date: Wed, 3 Apr 2024 22:02:19 -0700
Subject: [PATCH 3/7] Move LLVM_IS_DEBUG_BUILD into Support/CommandLine.h
Allow us to reuse this logic in the feature printing.
---
clang/lib/Driver/Driver.cpp | 3 +--
llvm/include/llvm/Support/CommandLine.h | 22 ++++++++++++++++++++++
llvm/lib/Support/CommandLine.cpp | 22 ----------------------
3 files changed, 23 insertions(+), 24 deletions(-)
diff --git a/clang/lib/Driver/Driver.cpp b/clang/lib/Driver/Driver.cpp
index 680c58e4ea43d8..c094f387f87a52 100644
--- a/clang/lib/Driver/Driver.cpp
+++ b/clang/lib/Driver/Driver.cpp
@@ -2006,8 +2006,7 @@ void Driver::PrintVersion(const Compilation &C, raw_ostream &OS) const {
// behavior. Intended for identifying the source of issues when reproducing
// changes.
SmallVector<StringRef> BuildOptions = {
-#if __GNUC__ && !__OPTIMIZE__
- // FIXME: __OPTIMIZE__ is not available on MSVC, this will never show there
+#if !LLVM_IS_DEBUG_BUILD
"+unoptimized",
#endif
#ifndef NDEBUG
diff --git a/llvm/include/llvm/Support/CommandLine.h b/llvm/include/llvm/Support/CommandLine.h
index 99dc9aefbd7d63..b205f7f1002845 100644
--- a/llvm/include/llvm/Support/CommandLine.h
+++ b/llvm/include/llvm/Support/CommandLine.h
@@ -40,6 +40,28 @@
#include <type_traits>
#include <vector>
+#if defined(__GNUC__)
+// GCC and GCC-compatible compilers define __OPTIMIZE__ when optimizations are
+// enabled.
+# if defined(__OPTIMIZE__)
+# define LLVM_IS_DEBUG_BUILD 0
+# else
+# define LLVM_IS_DEBUG_BUILD 1
+# endif
+#elif defined(_MSC_VER)
+// MSVC doesn't have a predefined macro indicating if optimizations are enabled.
+// Use _DEBUG instead. This macro actually corresponds to the choice between
+// debug and release CRTs, but it is a reasonable proxy.
+# if defined(_DEBUG)
+# define LLVM_IS_DEBUG_BUILD 1
+# else
+# define LLVM_IS_DEBUG_BUILD 0
+# endif
+#else
+// Otherwise, for an unknown compiler, assume this is an optimized build.
+# define LLVM_IS_DEBUG_BUILD 0
+#endif
+
namespace llvm {
namespace vfs {
diff --git a/llvm/lib/Support/CommandLine.cpp b/llvm/lib/Support/CommandLine.cpp
index c076ae8b843179..91e25486a738c1 100644
--- a/llvm/lib/Support/CommandLine.cpp
+++ b/llvm/lib/Support/CommandLine.cpp
@@ -2506,28 +2506,6 @@ class HelpPrinterWrapper {
} // End anonymous namespace
-#if defined(__GNUC__)
-// GCC and GCC-compatible compilers define __OPTIMIZE__ when optimizations are
-// enabled.
-# if defined(__OPTIMIZE__)
-# define LLVM_IS_DEBUG_BUILD 0
-# else
-# define LLVM_IS_DEBUG_BUILD 1
-# endif
-#elif defined(_MSC_VER)
-// MSVC doesn't have a predefined macro indicating if optimizations are enabled.
-// Use _DEBUG instead. This macro actually corresponds to the choice between
-// debug and release CRTs, but it is a reasonable proxy.
-# if defined(_DEBUG)
-# define LLVM_IS_DEBUG_BUILD 1
-# else
-# define LLVM_IS_DEBUG_BUILD 0
-# endif
-#else
-// Otherwise, for an unknown compiler, assume this is an optimized build.
-# define LLVM_IS_DEBUG_BUILD 0
-#endif
-
namespace {
class VersionPrinter {
public:
>From 82fa43a20adfff2435f934a23f84b84557fc12f9 Mon Sep 17 00:00:00 2001
From: Cassie Jones <cassie_jones at apple.com>
Date: Wed, 3 Apr 2024 22:51:13 -0700
Subject: [PATCH 4/7] Revert "Move LLVM_IS_DEBUG_BUILD into
Support/CommandLine.h"
This reverts commit 1213ba2f965a0577fc6504e967ae17346da4ef4f.
---
clang/lib/Driver/Driver.cpp | 3 ++-
llvm/include/llvm/Support/CommandLine.h | 22 ----------------------
llvm/lib/Support/CommandLine.cpp | 22 ++++++++++++++++++++++
3 files changed, 24 insertions(+), 23 deletions(-)
diff --git a/clang/lib/Driver/Driver.cpp b/clang/lib/Driver/Driver.cpp
index c094f387f87a52..680c58e4ea43d8 100644
--- a/clang/lib/Driver/Driver.cpp
+++ b/clang/lib/Driver/Driver.cpp
@@ -2006,7 +2006,8 @@ void Driver::PrintVersion(const Compilation &C, raw_ostream &OS) const {
// behavior. Intended for identifying the source of issues when reproducing
// changes.
SmallVector<StringRef> BuildOptions = {
-#if !LLVM_IS_DEBUG_BUILD
+#if __GNUC__ && !__OPTIMIZE__
+ // FIXME: __OPTIMIZE__ is not available on MSVC, this will never show there
"+unoptimized",
#endif
#ifndef NDEBUG
diff --git a/llvm/include/llvm/Support/CommandLine.h b/llvm/include/llvm/Support/CommandLine.h
index b205f7f1002845..99dc9aefbd7d63 100644
--- a/llvm/include/llvm/Support/CommandLine.h
+++ b/llvm/include/llvm/Support/CommandLine.h
@@ -40,28 +40,6 @@
#include <type_traits>
#include <vector>
-#if defined(__GNUC__)
-// GCC and GCC-compatible compilers define __OPTIMIZE__ when optimizations are
-// enabled.
-# if defined(__OPTIMIZE__)
-# define LLVM_IS_DEBUG_BUILD 0
-# else
-# define LLVM_IS_DEBUG_BUILD 1
-# endif
-#elif defined(_MSC_VER)
-// MSVC doesn't have a predefined macro indicating if optimizations are enabled.
-// Use _DEBUG instead. This macro actually corresponds to the choice between
-// debug and release CRTs, but it is a reasonable proxy.
-# if defined(_DEBUG)
-# define LLVM_IS_DEBUG_BUILD 1
-# else
-# define LLVM_IS_DEBUG_BUILD 0
-# endif
-#else
-// Otherwise, for an unknown compiler, assume this is an optimized build.
-# define LLVM_IS_DEBUG_BUILD 0
-#endif
-
namespace llvm {
namespace vfs {
diff --git a/llvm/lib/Support/CommandLine.cpp b/llvm/lib/Support/CommandLine.cpp
index 91e25486a738c1..c076ae8b843179 100644
--- a/llvm/lib/Support/CommandLine.cpp
+++ b/llvm/lib/Support/CommandLine.cpp
@@ -2506,6 +2506,28 @@ class HelpPrinterWrapper {
} // End anonymous namespace
+#if defined(__GNUC__)
+// GCC and GCC-compatible compilers define __OPTIMIZE__ when optimizations are
+// enabled.
+# if defined(__OPTIMIZE__)
+# define LLVM_IS_DEBUG_BUILD 0
+# else
+# define LLVM_IS_DEBUG_BUILD 1
+# endif
+#elif defined(_MSC_VER)
+// MSVC doesn't have a predefined macro indicating if optimizations are enabled.
+// Use _DEBUG instead. This macro actually corresponds to the choice between
+// debug and release CRTs, but it is a reasonable proxy.
+# if defined(_DEBUG)
+# define LLVM_IS_DEBUG_BUILD 1
+# else
+# define LLVM_IS_DEBUG_BUILD 0
+# endif
+#else
+// Otherwise, for an unknown compiler, assume this is an optimized build.
+# define LLVM_IS_DEBUG_BUILD 0
+#endif
+
namespace {
class VersionPrinter {
public:
>From 732388b97b96c83b75a8753cb605ef98bca4780b Mon Sep 17 00:00:00 2001
From: Cassie Jones <cassie_jones at apple.com>
Date: Thu, 4 Apr 2024 13:38:47 -0700
Subject: [PATCH 5/7] [Support] Expose config printing as
llvm::cl::printBuildConfig
---
clang/lib/Driver/Driver.cpp | 39 ++++---------------------
llvm/include/llvm/Support/CommandLine.h | 10 +++++++
llvm/lib/Support/CommandLine.cpp | 32 ++++++++++++++++++++
3 files changed, 47 insertions(+), 34 deletions(-)
diff --git a/clang/lib/Driver/Driver.cpp b/clang/lib/Driver/Driver.cpp
index 680c58e4ea43d8..d856685b5a38cb 100644
--- a/clang/lib/Driver/Driver.cpp
+++ b/clang/lib/Driver/Driver.cpp
@@ -2002,40 +2002,11 @@ void Driver::PrintVersion(const Compilation &C, raw_ostream &OS) const {
// Print out the install directory.
OS << "InstalledDir: " << Dir << '\n';
- // Print out build configuration options that impact the compiler's runtime
- // behavior. Intended for identifying the source of issues when reproducing
- // changes.
- SmallVector<StringRef> BuildOptions = {
-#if __GNUC__ && !__OPTIMIZE__
- // FIXME: __OPTIMIZE__ is not available on MSVC, this will never show there
- "+unoptimized",
-#endif
-#ifndef NDEBUG
- "+assertions",
-#endif
-#ifdef EXPENSIVE_CHECKS
- "+expensive-checks",
-#endif
-#if __has_feature(address_sanitizer)
- "+asan",
-#endif
-#if __has_feature(undefined_behavior_sanitizer)
- "+ubsan",
-#endif
-#if __has_feature(memory_sanitizer)
- "+msan",
-#endif
-#if __has_feature(dataflow_sanitizer)
- "+dfsan",
-#endif
- };
- if (!BuildOptions.empty()) {
- OS << "Build config: ";
- llvm::interleaveComma(BuildOptions, OS, [&OS](const StringRef &Option) {
- OS << Option;
- });
- OS << '\n';
- }
+ // Print the build config if it's non-default.
+ // Intended to help LLVM developers understand the configs of compilers
+ // they're investigating.
+ if (!llvm::cl::CompilerBuildConfig.empty())
+ llvm::cl::printBuildConfig(OS);
// If configuration files were used, print their paths.
for (auto ConfigFile : ConfigFiles)
diff --git a/llvm/include/llvm/Support/CommandLine.h b/llvm/include/llvm/Support/CommandLine.h
index 99dc9aefbd7d63..f13a1cbc9710ee 100644
--- a/llvm/include/llvm/Support/CommandLine.h
+++ b/llvm/include/llvm/Support/CommandLine.h
@@ -2002,6 +2002,16 @@ void PrintVersionMessage();
/// \param Categorized if true print options in categories
void PrintHelpMessage(bool Hidden = false, bool Categorized = false);
+/// An array of optional enabled settings in the LLVM build configuration,
+/// which may be of interest to compiler developers. For example, includes
+/// "+assertions" if assertions are enabled. Used by printBuildConfig.
+extern ArrayRef<StringRef> CompilerBuildConfig;
+
+/// Prints the compiler build configuration.
+/// Designed for compiler developers, not compiler end-users.
+/// Intended to be used in --version output when enabled.
+void printBuildConfig(raw_ostream &OS);
+
//===----------------------------------------------------------------------===//
// Public interface for accessing registered options.
//
diff --git a/llvm/lib/Support/CommandLine.cpp b/llvm/lib/Support/CommandLine.cpp
index c076ae8b843179..ab77fdc4b4a3f4 100644
--- a/llvm/lib/Support/CommandLine.cpp
+++ b/llvm/lib/Support/CommandLine.cpp
@@ -2734,6 +2734,38 @@ void cl::PrintHelpMessage(bool Hidden, bool Categorized) {
CommonOptions->CategorizedHiddenPrinter.printHelp();
}
+ArrayRef<StringRef> cl::CompilerBuildConfig = {
+#if LLVM_IS_DEBUG_BUILD
+ "+unoptimized",
+#endif
+#ifndef NDEBUG
+ "+assertions",
+#endif
+#ifdef EXPENSIVE_CHECKS
+ "+expensive-checks",
+#endif
+#if __has_feature(address_sanitizer)
+ "+asan",
+#endif
+#if __has_feature(undefined_behavior_sanitizer)
+ "+ubsan",
+#endif
+#if __has_feature(memory_sanitizer)
+ "+msan",
+#endif
+#if __has_feature(dataflow_sanitizer)
+ "+dfsan",
+#endif
+};
+
+// Utility function for printing the build config.
+void cl::printBuildConfig(raw_ostream &OS) {
+ OS << "Build config: ";
+ llvm::interleaveComma(cl::CompilerBuildConfig, OS,
+ [&OS](const StringRef &Option) { OS << Option; });
+ OS << '\n';
+}
+
/// Utility function for printing version number.
void cl::PrintVersionMessage() {
CommonOptions->VersionPrinterInstance.print(CommonOptions->ExtraVersionPrinters);
>From 5fba05b8c73019a8dd33dc4a3c95e189de5b45b6 Mon Sep 17 00:00:00 2001
From: Cassie Jones <cassie_jones at apple.com>
Date: Thu, 4 Apr 2024 14:00:05 -0700
Subject: [PATCH 6/7] Add a config flag to disable build config printing for
vendors
Some compilers released to end-users will want to force-disable printing
the build config, since that's intended for compiler developers and not
really end-users. Add that flag, defaulting to on, so compiler
developers get the most benefit but release engineers can hide it.
---
llvm/CMakeLists.txt | 3 +++
llvm/include/llvm/Config/config.h.cmake | 3 +++
llvm/lib/Support/CommandLine.cpp | 2 ++
3 files changed, 8 insertions(+)
diff --git a/llvm/CMakeLists.txt b/llvm/CMakeLists.txt
index 6f5647d70d8bc1..88cf2d7ff099c9 100644
--- a/llvm/CMakeLists.txt
+++ b/llvm/CMakeLists.txt
@@ -799,6 +799,9 @@ option (LLVM_BUILD_EXTERNAL_COMPILER_RT
option (LLVM_VERSION_PRINTER_SHOW_HOST_TARGET_INFO
"Show target and host info when tools are invoked with --version." ON)
+option(LLVM_VERSION_PRINTER_SHOW_BUILD_CONFIG
+ "Show the optional build config flags when tools are invoked with --version." ON)
+
# You can configure which libraries from LLVM you want to include in the
# shared library by setting LLVM_DYLIB_COMPONENTS to a semi-colon delimited
# list of LLVM components. All component names handled by llvm-config are valid.
diff --git a/llvm/include/llvm/Config/config.h.cmake b/llvm/include/llvm/Config/config.h.cmake
index fc1f9bf342f8d5..977c182e9d2b0d 100644
--- a/llvm/include/llvm/Config/config.h.cmake
+++ b/llvm/include/llvm/Config/config.h.cmake
@@ -290,6 +290,9 @@
/* Whether tools show host and target info when invoked with --version */
#cmakedefine01 LLVM_VERSION_PRINTER_SHOW_HOST_TARGET_INFO
+/* Whether tools show optional build config flags when invoked with --version */
+#cmakedefine01 LLVM_VERSION_PRINTER_SHOW_BUILD_CONFIG
+
/* Define if libxml2 is supported on this platform. */
#cmakedefine LLVM_ENABLE_LIBXML2 ${LLVM_ENABLE_LIBXML2}
diff --git a/llvm/lib/Support/CommandLine.cpp b/llvm/lib/Support/CommandLine.cpp
index ab77fdc4b4a3f4..2a1c98a702c32c 100644
--- a/llvm/lib/Support/CommandLine.cpp
+++ b/llvm/lib/Support/CommandLine.cpp
@@ -2760,10 +2760,12 @@ ArrayRef<StringRef> cl::CompilerBuildConfig = {
// Utility function for printing the build config.
void cl::printBuildConfig(raw_ostream &OS) {
+#if LLVM_VERSION_PRINTER_SHOW_BUILD_CONFIG
OS << "Build config: ";
llvm::interleaveComma(cl::CompilerBuildConfig, OS,
[&OS](const StringRef &Option) { OS << Option; });
OS << '\n';
+#endif
}
/// Utility function for printing version number.
>From 14bc6ff6bd9ce6eba4f7dfbcbfee4dafa9ddb7bb Mon Sep 17 00:00:00 2001
From: Cassie Jones <code at witchoflight.com>
Date: Thu, 4 Apr 2024 14:57:12 -0700
Subject: [PATCH 7/7] Apply suggestions from code review
Co-authored-by: Jon Roelofs <jroelofs at gmail.com>
---
clang/test/Driver/version-build-config.test | 2 +-
llvm/lib/Support/CommandLine.cpp | 3 +--
2 files changed, 2 insertions(+), 3 deletions(-)
diff --git a/clang/test/Driver/version-build-config.test b/clang/test/Driver/version-build-config.test
index 3d183f372908ea..4cedf1e63181fd 100644
--- a/clang/test/Driver/version-build-config.test
+++ b/clang/test/Driver/version-build-config.test
@@ -3,4 +3,4 @@
# CHECK: clang version
# When assertions are enabled, we should have a build configuration line that reflects that
-# CHECK: Build configuration: {{.*}}+assertions
+# CHECK: Build config: {{.*}}+assertions
diff --git a/llvm/lib/Support/CommandLine.cpp b/llvm/lib/Support/CommandLine.cpp
index 2a1c98a702c32c..f261c694b12f08 100644
--- a/llvm/lib/Support/CommandLine.cpp
+++ b/llvm/lib/Support/CommandLine.cpp
@@ -2762,8 +2762,7 @@ ArrayRef<StringRef> cl::CompilerBuildConfig = {
void cl::printBuildConfig(raw_ostream &OS) {
#if LLVM_VERSION_PRINTER_SHOW_BUILD_CONFIG
OS << "Build config: ";
- llvm::interleaveComma(cl::CompilerBuildConfig, OS,
- [&OS](const StringRef &Option) { OS << Option; });
+ llvm::interleaveComma(cl::CompilerBuildConfig, OS);
OS << '\n';
#endif
}
More information about the cfe-commits
mailing list