[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