Skip to content

Commit 542558c

Browse files
committed
[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.
1 parent 4b3ba64 commit 542558c

File tree

6 files changed

+46
-0
lines changed

6 files changed

+46
-0
lines changed

clang/include/clang/Basic/CodeGenOptions.def

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -462,6 +462,9 @@ ENUM_CODEGENOPT(ZeroCallUsedRegs, llvm::ZeroCallUsedRegs::ZeroCallUsedRegsKind,
462462
/// non-deleting destructors. (No effect on Microsoft ABI.)
463463
CODEGENOPT(CtorDtorReturnThis, 1, 0)
464464

465+
/// Whether to validate if a produced mangled name can be demangled with LLVM demangler.
466+
CODEGENOPT(NoDemanglingFailures, 1, 0)
467+
465468
/// FIXME: Make DebugOptions its own top-level .def file.
466469
#include "DebugOptions.def"
467470

clang/include/clang/Driver/Options.td

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1967,6 +1967,10 @@ def fclang_abi_compat_EQ : Joined<["-"], "fclang-abi-compat=">, Group<f_clang_Gr
19671967
Visibility<[ClangOption, CC1Option]>,
19681968
MetaVarName<"<version>">, Values<"<major>.<minor>,latest">,
19691969
HelpText<"Attempt to match the ABI of Clang <version>">;
1970+
def fno_demangling_failures: Flag<["-"], "fno-demangling-failures">, Group<f_clang_Group>,
1971+
Visibility<[ClangOption, CC1Option]>,
1972+
HelpText<"Assert that clang can demangle all the mangled names it generates">,
1973+
MarshallingInfoFlag<CodeGenOpts<"NoDemanglingFailures">>;
19701974
def fclasspath_EQ : Joined<["-"], "fclasspath=">, Group<f_Group>;
19711975
def fcolor_diagnostics : Flag<["-"], "fcolor-diagnostics">, Group<f_Group>,
19721976

clang/lib/CodeGen/CodeGenModule.cpp

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -48,12 +48,14 @@
4848
#include "clang/Basic/Version.h"
4949
#include "clang/CodeGen/BackendUtil.h"
5050
#include "clang/CodeGen/ConstantInitBuilder.h"
51+
#include "clang/Driver/Driver.h"
5152
#include "clang/Frontend/FrontendDiagnostic.h"
5253
#include "llvm/ADT/STLExtras.h"
5354
#include "llvm/ADT/StringExtras.h"
5455
#include "llvm/ADT/StringSwitch.h"
5556
#include "llvm/Analysis/TargetLibraryInfo.h"
5657
#include "llvm/BinaryFormat/ELF.h"
58+
#include "llvm/Demangle/Demangle.h"
5759
#include "llvm/Frontend/OpenMP/OMPIRBuilder.h"
5860
#include "llvm/IR/AttributeMask.h"
5961
#include "llvm/IR/CallingConv.h"
@@ -75,6 +77,7 @@
7577
#include "llvm/TargetParser/Triple.h"
7678
#include "llvm/TargetParser/X86TargetParser.h"
7779
#include "llvm/Transforms/Utils/BuildLibCalls.h"
80+
#include <cassert>
7881
#include <optional>
7982

8083
using namespace clang;
@@ -2044,6 +2047,11 @@ StringRef CodeGenModule::getMangledName(GlobalDecl GD) {
20442047
GD.getWithKernelReferenceKind(KernelReferenceKind::Kernel),
20452048
ND));
20462049

2050+
if (getCodeGenOpts().NoDemanglingFailures)
2051+
assert((!llvm::isMangledName(MangledName) ||
2052+
llvm::demangle(MangledName) != MangledName) &&
2053+
"clang must demangle a mangled name it generates!");
2054+
20472055
auto Result = Manglings.insert(std::make_pair(MangledName, GD));
20482056
return MangledDeclNames[CanonicalGD] = Result.first->first();
20492057
}
Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
// RUN: %clang_cc1 -emit-llvm -fno-demangling-failures -triple %itanium_abi_triple -o - %s | FileCheck %s
2+
3+
// CHECK: @_ZN6foobar3barEv
4+
// CHECK: @_ZN6foobar1A3fooEi
5+
namespace foobar {
6+
struct A {
7+
void foo (int) {
8+
}
9+
};
10+
11+
void bar() {
12+
A().foo(0);
13+
}
14+
} // namespace foobar

llvm/include/llvm/Demangle/Demangle.h

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -67,6 +67,13 @@ char *dlangDemangle(std::string_view MangledName);
6767
/// demangling occurred.
6868
std::string demangle(std::string_view MangledName);
6969

70+
/// Determines if the argument string is a valid mangled name known to the
71+
/// demangler.
72+
/// \param Name - reference to a string that is potentially a mangled name.
73+
/// \returns - true if the argument represents a valid mangled name, false
74+
/// otherwise.
75+
bool isMangledName(std::string_view Name);
76+
7077
bool nonMicrosoftDemangle(std::string_view MangledName, std::string &Result,
7178
bool CanHaveLeadingDot = true,
7279
bool ParseParams = true);

llvm/lib/Demangle/Demangle.cpp

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -47,6 +47,16 @@ static bool isRustEncoding(std::string_view S) { return starts_with(S, "_R"); }
4747

4848
static bool isDLangEncoding(std::string_view S) { return starts_with(S, "_D"); }
4949

50+
static bool isMicrosoftEncoding(std::string_view S) {
51+
return starts_with(S, '?');
52+
}
53+
54+
bool llvm::isMangledName(std::string_view Name) {
55+
return starts_with(Name, '.') || isItaniumEncoding(Name) ||
56+
isRustEncoding(Name) || isDLangEncoding(Name) ||
57+
isMicrosoftEncoding(Name);
58+
}
59+
5060
bool llvm::nonMicrosoftDemangle(std::string_view MangledName,
5161
std::string &Result, bool CanHaveLeadingDot,
5262
bool ParseParams) {

0 commit comments

Comments
 (0)