[clang] [llvm] [clang][LLVM Demangler] Add a diagnostic that validates that all mang… (PR #111391)

Viktoriia Bakalova via cfe-commits cfe-commits at lists.llvm.org
Mon Oct 28 07:05:30 PDT 2024


https://github.com/VitaNuo updated https://github.com/llvm/llvm-project/pull/111391

>From 54ee2e5d83a940b113f0fc326c511322605bfb78 Mon Sep 17 00:00:00 2001
From: Viktoriia Bakalova <bakalova at google.com>
Date: Tue, 15 Oct 2024 09:48:09 +0000
Subject: [PATCH 1/3] [clang][LLVM Demangler] Add a diagnostic that validates
 that all mangled names produced by `clang` can be demangled by LLVM
 demangler.

Introduce the above warning behind the `-fdemangling-failures` flag, since:

a. the diagnostic cannot be fixed by an application developer.
b. the diagnostic is expected to be quite chatty.
---
 clang/include/clang/Basic/CodeGenOptions.def        |  3 +++
 .../include/clang/Basic/DiagnosticFrontendKinds.td  |  4 ++++
 clang/include/clang/Driver/Options.td               |  4 ++++
 clang/lib/CodeGen/CodeGenModule.cpp                 | 13 +++++++++++++
 clang/test/CodeGenCXX/warn-demangling-failure.cpp   | 13 +++++++++++++
 llvm/include/llvm/Demangle/Demangle.h               |  7 +++++++
 llvm/lib/Demangle/Demangle.cpp                      | 10 ++++++++++
 7 files changed, 54 insertions(+)
 create mode 100644 clang/test/CodeGenCXX/warn-demangling-failure.cpp

diff --git a/clang/include/clang/Basic/CodeGenOptions.def b/clang/include/clang/Basic/CodeGenOptions.def
index eac831278ee20d..d0e2393cbb5616 100644
--- a/clang/include/clang/Basic/CodeGenOptions.def
+++ b/clang/include/clang/Basic/CodeGenOptions.def
@@ -462,6 +462,9 @@ ENUM_CODEGENOPT(ZeroCallUsedRegs, llvm::ZeroCallUsedRegs::ZeroCallUsedRegsKind,
 /// non-deleting destructors. (No effect on Microsoft ABI.)
 CODEGENOPT(CtorDtorReturnThis, 1, 0)
 
+/// Whether to issue a diagnostic if a produced mangled name can not be demangled with the LLVM demangler.
+CODEGENOPT(DemanglingFailures, 1, 0)
+
 /// FIXME: Make DebugOptions its own top-level .def file.
 #include "DebugOptions.def"
 
diff --git a/clang/include/clang/Basic/DiagnosticFrontendKinds.td b/clang/include/clang/Basic/DiagnosticFrontendKinds.td
index a6b17ccb6799d2..4cad78d5120d6d 100644
--- a/clang/include/clang/Basic/DiagnosticFrontendKinds.td
+++ b/clang/include/clang/Basic/DiagnosticFrontendKinds.td
@@ -384,4 +384,8 @@ def warn_hlsl_langstd_minimal :
   Warning<"support for HLSL language version %0 is incomplete, "
           "recommend using %1 instead">,
   InGroup<HLSLDXCCompat>;
+
+def warn_name_cannot_be_demangled : Warning<
+  "cannot demangle the name '%0'">,
+  InGroup<CXX20Compat>;
 }
diff --git a/clang/include/clang/Driver/Options.td b/clang/include/clang/Driver/Options.td
index 607ff47a857b8f..40d142555c85e1 100644
--- a/clang/include/clang/Driver/Options.td
+++ b/clang/include/clang/Driver/Options.td
@@ -1967,6 +1967,10 @@ def fclang_abi_compat_EQ : Joined<["-"], "fclang-abi-compat=">, Group<f_clang_Gr
   Visibility<[ClangOption, CC1Option]>,
   MetaVarName<"<version>">, Values<"<major>.<minor>,latest">,
   HelpText<"Attempt to match the ABI of Clang <version>">;
+def fdemangling_failures: Flag<["-"], "fdemangling-failures">, Group<f_clang_Group>,
+  Visibility<[ClangOption, CC1Option]>,
+  HelpText<"Produce a diagnostic if clang cannot demangle all the mangled names it generates">,
+  MarshallingInfoFlag<CodeGenOpts<"DemanglingFailures">>;
 def fclasspath_EQ : Joined<["-"], "fclasspath=">, Group<f_Group>;
 def fcolor_diagnostics : Flag<["-"], "fcolor-diagnostics">, Group<f_Group>,
 
diff --git a/clang/lib/CodeGen/CodeGenModule.cpp b/clang/lib/CodeGen/CodeGenModule.cpp
index 25c1c496a4f27f..420b39ff2c301d 100644
--- a/clang/lib/CodeGen/CodeGenModule.cpp
+++ b/clang/lib/CodeGen/CodeGenModule.cpp
@@ -41,7 +41,9 @@
 #include "clang/Basic/CharInfo.h"
 #include "clang/Basic/CodeGenOptions.h"
 #include "clang/Basic/Diagnostic.h"
+#include "clang/Basic/DiagnosticFrontend.h"
 #include "clang/Basic/FileManager.h"
+#include "clang/Basic/LangOptions.h"
 #include "clang/Basic/Module.h"
 #include "clang/Basic/SourceManager.h"
 #include "clang/Basic/TargetInfo.h"
@@ -54,6 +56,7 @@
 #include "llvm/ADT/StringSwitch.h"
 #include "llvm/Analysis/TargetLibraryInfo.h"
 #include "llvm/BinaryFormat/ELF.h"
+#include "llvm/Demangle/Demangle.h"
 #include "llvm/Frontend/OpenMP/OMPIRBuilder.h"
 #include "llvm/IR/AttributeMask.h"
 #include "llvm/IR/CallingConv.h"
@@ -75,6 +78,7 @@
 #include "llvm/TargetParser/Triple.h"
 #include "llvm/TargetParser/X86TargetParser.h"
 #include "llvm/Transforms/Utils/BuildLibCalls.h"
+#include <cassert>
 #include <optional>
 
 using namespace clang;
@@ -2044,6 +2048,15 @@ StringRef CodeGenModule::getMangledName(GlobalDecl GD) {
                  GD.getWithKernelReferenceKind(KernelReferenceKind::Kernel),
                  ND));
 
+  if (getCodeGenOpts().DemanglingFailures &&
+      getContext().getLangOpts().getClangABICompat() >
+          LangOptions::ClangABI::Ver19) {
+    if (llvm::isMangledName(MangledName) &&
+        llvm::demangle(MangledName) == MangledName)
+      Diags.Report(ND->getLocation(), diag::warn_name_cannot_be_demangled)
+          << MangledName;
+  }
+
   auto Result = Manglings.insert(std::make_pair(MangledName, GD));
   return MangledDeclNames[CanonicalGD] = Result.first->first();
 }
diff --git a/clang/test/CodeGenCXX/warn-demangling-failure.cpp b/clang/test/CodeGenCXX/warn-demangling-failure.cpp
new file mode 100644
index 00000000000000..8f75d93a0a440b
--- /dev/null
+++ b/clang/test/CodeGenCXX/warn-demangling-failure.cpp
@@ -0,0 +1,13 @@
+// RUN: %clang_cc1 -emit-llvm -fdemangling-failures -triple %itanium_abi_triple -o - %s | FileCheck %s
+template <class F> void parallel_loop(F &&f) { f(0); }
+
+//CHECK-LABEL: @main
+int main() {
+  int x;
+  parallel_loop([&](auto y) { // expected-warning {{cannot demangle the name '_ZZ4mainENK3$_0clIiEEDaT_'}}
+#pragma clang __debug captured
+    {
+      x = y;
+    };
+  });
+}
diff --git a/llvm/include/llvm/Demangle/Demangle.h b/llvm/include/llvm/Demangle/Demangle.h
index fe129603c0785d..910f0410d62db3 100644
--- a/llvm/include/llvm/Demangle/Demangle.h
+++ b/llvm/include/llvm/Demangle/Demangle.h
@@ -67,6 +67,13 @@ char *dlangDemangle(std::string_view MangledName);
 /// demangling occurred.
 std::string demangle(std::string_view MangledName);
 
+/// Determines if the argument string is a valid mangled name known to the
+/// demangler.
+/// \param Name - reference to a string that is potentially a mangled name.
+/// \returns - true if the argument represents a valid mangled name, false
+/// otherwise.
+bool isMangledName(std::string_view Name);
+
 bool nonMicrosoftDemangle(std::string_view MangledName, std::string &Result,
                           bool CanHaveLeadingDot = true,
                           bool ParseParams = true);
diff --git a/llvm/lib/Demangle/Demangle.cpp b/llvm/lib/Demangle/Demangle.cpp
index f0f7eacac98e64..6b40cbb56cf28d 100644
--- a/llvm/lib/Demangle/Demangle.cpp
+++ b/llvm/lib/Demangle/Demangle.cpp
@@ -47,6 +47,16 @@ static bool isRustEncoding(std::string_view S) { return starts_with(S, "_R"); }
 
 static bool isDLangEncoding(std::string_view S) { return starts_with(S, "_D"); }
 
+static bool isMicrosoftEncoding(std::string_view S) {
+  return starts_with(S, '?');
+}
+
+bool llvm::isMangledName(std::string_view Name) {
+  return starts_with(Name, '.') || isItaniumEncoding(Name) ||
+         isRustEncoding(Name) || isDLangEncoding(Name) ||
+         isMicrosoftEncoding(Name);
+}
+
 bool llvm::nonMicrosoftDemangle(std::string_view MangledName,
                                 std::string &Result, bool CanHaveLeadingDot,
                                 bool ParseParams) {

>From 303a062e6823ebf7d123278e184c566f66f41a74 Mon Sep 17 00:00:00 2001
From: Viktoriia Bakalova <bakalova at google.com>
Date: Thu, 24 Oct 2024 10:17:43 +0000
Subject: [PATCH 2/3] [clang][LLVM Demangler] Introduce support for the
 `-fdemangling-failures` flag to `clang` driver.

---
 clang/lib/Driver/ToolChains/Clang.cpp | 3 +++
 1 file changed, 3 insertions(+)

diff --git a/clang/lib/Driver/ToolChains/Clang.cpp b/clang/lib/Driver/ToolChains/Clang.cpp
index b9987288d82d10..617de4afd33529 100644
--- a/clang/lib/Driver/ToolChains/Clang.cpp
+++ b/clang/lib/Driver/ToolChains/Clang.cpp
@@ -4444,6 +4444,9 @@ static void RenderDiagnosticsOptions(const Driver &D, const ArgList &Args,
 
   Args.addOptOutFlag(CmdArgs, options::OPT_fspell_checking,
                      options::OPT_fno_spell_checking);
+
+  if (Args.hasArg(options::OPT_fdemangling_failures))
+    CmdArgs.push_back("-fdemangling-failures");
 }
 
 DwarfFissionKind tools::getDebugFissionKind(const Driver &D,

>From 5f65b71f6db5d8986988ecd19fa436e707894938 Mon Sep 17 00:00:00 2001
From: Viktoriia Bakalova <bakalova at google.com>
Date: Mon, 28 Oct 2024 14:01:14 +0000
Subject: [PATCH 3/3] [clang][LLVM Demangler] Address review comments. Rename
 the flag that controls the demangler diagnostic. Reduce the new include count
 in CodeGenModule.cpp. Add a new diagnostic group for demangler failures.

---
 clang/include/clang/Basic/CodeGenOptions.def         | 2 +-
 clang/include/clang/Basic/DiagnosticFrontendKinds.td | 2 +-
 clang/include/clang/Basic/DiagnosticGroups.td        | 3 +++
 clang/include/clang/Driver/Options.td                | 6 +++---
 clang/lib/CodeGen/CodeGenModule.cpp                  | 8 ++------
 clang/lib/Driver/ToolChains/Clang.cpp                | 4 ++--
 llvm/lib/Demangle/Demangle.cpp                       | 5 ++---
 7 files changed, 14 insertions(+), 16 deletions(-)

diff --git a/clang/include/clang/Basic/CodeGenOptions.def b/clang/include/clang/Basic/CodeGenOptions.def
index d0e2393cbb5616..ad5e125c5b8bbc 100644
--- a/clang/include/clang/Basic/CodeGenOptions.def
+++ b/clang/include/clang/Basic/CodeGenOptions.def
@@ -463,7 +463,7 @@ ENUM_CODEGENOPT(ZeroCallUsedRegs, llvm::ZeroCallUsedRegs::ZeroCallUsedRegsKind,
 CODEGENOPT(CtorDtorReturnThis, 1, 0)
 
 /// Whether to issue a diagnostic if a produced mangled name can not be demangled with the LLVM demangler.
-CODEGENOPT(DemanglingFailures, 1, 0)
+CODEGENOPT(DiagnosticsDemanglerFailures, 1, 0)
 
 /// FIXME: Make DebugOptions its own top-level .def file.
 #include "DebugOptions.def"
diff --git a/clang/include/clang/Basic/DiagnosticFrontendKinds.td b/clang/include/clang/Basic/DiagnosticFrontendKinds.td
index 4cad78d5120d6d..b785aa0ee0b5a6 100644
--- a/clang/include/clang/Basic/DiagnosticFrontendKinds.td
+++ b/clang/include/clang/Basic/DiagnosticFrontendKinds.td
@@ -387,5 +387,5 @@ def warn_hlsl_langstd_minimal :
 
 def warn_name_cannot_be_demangled : Warning<
   "cannot demangle the name '%0'">,
-  InGroup<CXX20Compat>;
+  InGroup<Demangler>;
 }
diff --git a/clang/include/clang/Basic/DiagnosticGroups.td b/clang/include/clang/Basic/DiagnosticGroups.td
index 7d81bdf827ea0c..993ec111605441 100644
--- a/clang/include/clang/Basic/DiagnosticGroups.td
+++ b/clang/include/clang/Basic/DiagnosticGroups.td
@@ -1582,3 +1582,6 @@ def ExtractAPIMisuse : DiagGroup<"extractapi-misuse">;
 // Warnings about using the non-standard extension having an explicit specialization
 // with a storage class specifier.
 def ExplicitSpecializationStorageClass : DiagGroup<"explicit-specialization-storage-class">;
+
+// Diagnostics related to the LLVM demangler.
+def Demangler: DiagGroup<"demangler">;
diff --git a/clang/include/clang/Driver/Options.td b/clang/include/clang/Driver/Options.td
index 40d142555c85e1..d6320d82d94cdd 100644
--- a/clang/include/clang/Driver/Options.td
+++ b/clang/include/clang/Driver/Options.td
@@ -1967,10 +1967,10 @@ def fclang_abi_compat_EQ : Joined<["-"], "fclang-abi-compat=">, Group<f_clang_Gr
   Visibility<[ClangOption, CC1Option]>,
   MetaVarName<"<version>">, Values<"<major>.<minor>,latest">,
   HelpText<"Attempt to match the ABI of Clang <version>">;
-def fdemangling_failures: Flag<["-"], "fdemangling-failures">, Group<f_clang_Group>,
+def fdiagnostics_demangler_failures: Flag<["-"], "fdiagnostics-demangler-failures">, Group<f_clang_Group>,
   Visibility<[ClangOption, CC1Option]>,
-  HelpText<"Produce a diagnostic if clang cannot demangle all the mangled names it generates">,
-  MarshallingInfoFlag<CodeGenOpts<"DemanglingFailures">>;
+  HelpText<"Produce a diagnostic if clang cannot demangle a mangled name it generates">,
+  MarshallingInfoFlag<CodeGenOpts<"DiagnosticsDemanglerFailures">>;
 def fclasspath_EQ : Joined<["-"], "fclasspath=">, Group<f_Group>;
 def fcolor_diagnostics : Flag<["-"], "fcolor-diagnostics">, Group<f_Group>,
 
diff --git a/clang/lib/CodeGen/CodeGenModule.cpp b/clang/lib/CodeGen/CodeGenModule.cpp
index 420b39ff2c301d..3d63564c7e8cc2 100644
--- a/clang/lib/CodeGen/CodeGenModule.cpp
+++ b/clang/lib/CodeGen/CodeGenModule.cpp
@@ -41,9 +41,7 @@
 #include "clang/Basic/CharInfo.h"
 #include "clang/Basic/CodeGenOptions.h"
 #include "clang/Basic/Diagnostic.h"
-#include "clang/Basic/DiagnosticFrontend.h"
 #include "clang/Basic/FileManager.h"
-#include "clang/Basic/LangOptions.h"
 #include "clang/Basic/Module.h"
 #include "clang/Basic/SourceManager.h"
 #include "clang/Basic/TargetInfo.h"
@@ -78,7 +76,6 @@
 #include "llvm/TargetParser/Triple.h"
 #include "llvm/TargetParser/X86TargetParser.h"
 #include "llvm/Transforms/Utils/BuildLibCalls.h"
-#include <cassert>
 #include <optional>
 
 using namespace clang;
@@ -2048,9 +2045,8 @@ StringRef CodeGenModule::getMangledName(GlobalDecl GD) {
                  GD.getWithKernelReferenceKind(KernelReferenceKind::Kernel),
                  ND));
 
-  if (getCodeGenOpts().DemanglingFailures &&
-      getContext().getLangOpts().getClangABICompat() >
-          LangOptions::ClangABI::Ver19) {
+  if (getContext().getLangOpts().getClangABICompat() >
+      LangOptions::ClangABI::Ver19) {
     if (llvm::isMangledName(MangledName) &&
         llvm::demangle(MangledName) == MangledName)
       Diags.Report(ND->getLocation(), diag::warn_name_cannot_be_demangled)
diff --git a/clang/lib/Driver/ToolChains/Clang.cpp b/clang/lib/Driver/ToolChains/Clang.cpp
index 617de4afd33529..cb648a2baa29f2 100644
--- a/clang/lib/Driver/ToolChains/Clang.cpp
+++ b/clang/lib/Driver/ToolChains/Clang.cpp
@@ -4445,8 +4445,8 @@ static void RenderDiagnosticsOptions(const Driver &D, const ArgList &Args,
   Args.addOptOutFlag(CmdArgs, options::OPT_fspell_checking,
                      options::OPT_fno_spell_checking);
 
-  if (Args.hasArg(options::OPT_fdemangling_failures))
-    CmdArgs.push_back("-fdemangling-failures");
+  if (Args.hasArg(options::OPT_fdiagnostics_demangler_failures))
+    CmdArgs.push_back("-fdiagnostics-demangler-failures");
 }
 
 DwarfFissionKind tools::getDebugFissionKind(const Driver &D,
diff --git a/llvm/lib/Demangle/Demangle.cpp b/llvm/lib/Demangle/Demangle.cpp
index 6b40cbb56cf28d..a2b97b72b3fc18 100644
--- a/llvm/lib/Demangle/Demangle.cpp
+++ b/llvm/lib/Demangle/Demangle.cpp
@@ -52,9 +52,8 @@ static bool isMicrosoftEncoding(std::string_view S) {
 }
 
 bool llvm::isMangledName(std::string_view Name) {
-  return starts_with(Name, '.') || isItaniumEncoding(Name) ||
-         isRustEncoding(Name) || isDLangEncoding(Name) ||
-         isMicrosoftEncoding(Name);
+  return isItaniumEncoding(Name) || isRustEncoding(Name) ||
+         isDLangEncoding(Name) || isMicrosoftEncoding(Name);
 }
 
 bool llvm::nonMicrosoftDemangle(std::string_view MangledName,



More information about the cfe-commits mailing list