[clang] [llvm] [clang][LLVM Demangler] Add an assertion that validates that all mang… (PR #111391)
Viktoriia Bakalova via cfe-commits
cfe-commits at lists.llvm.org
Mon Oct 7 08:11:26 PDT 2024
https://github.com/VitaNuo created https://github.com/llvm/llvm-project/pull/111391
…led names produced by `clang` can be demangled by LLVM demangler.
Introduce the above assertion behind the `-fno-demangling-failures` flag to prevent unintended breakages.
>From 9c16570650e487e63ec887d61be478ecad5402c2 Mon Sep 17 00:00:00 2001
From: Viktoriia Bakalova <bakalova at google.com>
Date: Mon, 7 Oct 2024 15:10:28 +0000
Subject: [PATCH] [clang][LLVM Demangler] Add an assertion that validates that
all mangled names produced by `clang` can be demangled by LLVM demangler.
Introduce the above assertion behind the `-fno-demangling-failures` flag to prevent unintended breakages.
---
clang/include/clang/Basic/CodeGenOptions.def | 3 +++
clang/include/clang/Driver/Options.td | 4 ++++
clang/lib/CodeGen/CodeGenModule.cpp | 7 +++++++
clang/test/CodeGenCXX/assert-demangle.cpp | 14 ++++++++++++++
llvm/include/llvm/Demangle/Demangle.h | 7 +++++++
llvm/lib/Demangle/Demangle.cpp | 10 ++++++++++
6 files changed, 45 insertions(+)
create mode 100644 clang/test/CodeGenCXX/assert-demangle.cpp
diff --git a/clang/include/clang/Basic/CodeGenOptions.def b/clang/include/clang/Basic/CodeGenOptions.def
index eac831278ee20d..d3e150fe53f804 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 validate if a produced mangled name can be demangled with LLVM demangler.
+CODEGENOPT(NoDemanglingFailures, 1, 0)
+
/// FIXME: Make DebugOptions its own top-level .def file.
#include "DebugOptions.def"
diff --git a/clang/include/clang/Driver/Options.td b/clang/include/clang/Driver/Options.td
index 607ff47a857b8f..a6a8cfe21676c0 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 fno_demangling_failures: Flag<["-"], "fno-demangling-failures">, Group<f_clang_Group>,
+ Visibility<[ClangOption, CC1Option]>,
+ HelpText<"Assert that clang can demangle all the mangled names it generates">,
+ MarshallingInfoFlag<CodeGenOpts<"NoDemanglingFailures">>;
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..6afbfa9ae45ed9 100644
--- a/clang/lib/CodeGen/CodeGenModule.cpp
+++ b/clang/lib/CodeGen/CodeGenModule.cpp
@@ -48,12 +48,14 @@
#include "clang/Basic/Version.h"
#include "clang/CodeGen/BackendUtil.h"
#include "clang/CodeGen/ConstantInitBuilder.h"
+#include "clang/Driver/Driver.h"
#include "clang/Frontend/FrontendDiagnostic.h"
#include "llvm/ADT/STLExtras.h"
#include "llvm/ADT/StringExtras.h"
#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 +77,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 +2047,10 @@ StringRef CodeGenModule::getMangledName(GlobalDecl GD) {
GD.getWithKernelReferenceKind(KernelReferenceKind::Kernel),
ND));
+ if (getCodeGenOpts().NoDemanglingFailures)
+ assert((!llvm::isMangledName(MangledName) || llvm::demangle(MangledName) !=
+ MangledName) && "clang must demangle a mangled name it generates!");
+
auto Result = Manglings.insert(std::make_pair(MangledName, GD));
return MangledDeclNames[CanonicalGD] = Result.first->first();
}
diff --git a/clang/test/CodeGenCXX/assert-demangle.cpp b/clang/test/CodeGenCXX/assert-demangle.cpp
new file mode 100644
index 00000000000000..86a7686f72d929
--- /dev/null
+++ b/clang/test/CodeGenCXX/assert-demangle.cpp
@@ -0,0 +1,14 @@
+// RUN: %clang_cc1 -emit-llvm -fno-demangling-failures -triple %itanium_abi_triple -o - %s | FileCheck %s
+
+// CHECK: @_ZN6foobar3barEv
+// CHECK: @_ZN6foobar1A3fooEi
+namespace foobar {
+struct A {
+ void foo (int) {
+ }
+};
+
+void bar() {
+ A().foo(0);
+}
+} // namespace foobar
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) {
More information about the cfe-commits
mailing list