[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:02:05 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/6] [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/6] 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/6] 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/6] 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/6] [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/6] 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.



More information about the cfe-commits mailing list