Skip to content

Commit 54ee2e5

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

File tree

7 files changed

+54
-0
lines changed

7 files changed

+54
-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 issue a diagnostic if a produced mangled name can not be demangled with the LLVM demangler.
466+
CODEGENOPT(DemanglingFailures, 1, 0)
467+
465468
/// FIXME: Make DebugOptions its own top-level .def file.
466469
#include "DebugOptions.def"
467470

clang/include/clang/Basic/DiagnosticFrontendKinds.td

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -384,4 +384,8 @@ def warn_hlsl_langstd_minimal :
384384
Warning<"support for HLSL language version %0 is incomplete, "
385385
"recommend using %1 instead">,
386386
InGroup<HLSLDXCCompat>;
387+
388+
def warn_name_cannot_be_demangled : Warning<
389+
"cannot demangle the name '%0'">,
390+
InGroup<CXX20Compat>;
387391
}

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 fdemangling_failures: Flag<["-"], "fdemangling-failures">, Group<f_clang_Group>,
1971+
Visibility<[ClangOption, CC1Option]>,
1972+
HelpText<"Produce a diagnostic if clang cannot demangle all the mangled names it generates">,
1973+
MarshallingInfoFlag<CodeGenOpts<"DemanglingFailures">>;
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: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -41,7 +41,9 @@
4141
#include "clang/Basic/CharInfo.h"
4242
#include "clang/Basic/CodeGenOptions.h"
4343
#include "clang/Basic/Diagnostic.h"
44+
#include "clang/Basic/DiagnosticFrontend.h"
4445
#include "clang/Basic/FileManager.h"
46+
#include "clang/Basic/LangOptions.h"
4547
#include "clang/Basic/Module.h"
4648
#include "clang/Basic/SourceManager.h"
4749
#include "clang/Basic/TargetInfo.h"
@@ -54,6 +56,7 @@
5456
#include "llvm/ADT/StringSwitch.h"
5557
#include "llvm/Analysis/TargetLibraryInfo.h"
5658
#include "llvm/BinaryFormat/ELF.h"
59+
#include "llvm/Demangle/Demangle.h"
5760
#include "llvm/Frontend/OpenMP/OMPIRBuilder.h"
5861
#include "llvm/IR/AttributeMask.h"
5962
#include "llvm/IR/CallingConv.h"
@@ -75,6 +78,7 @@
7578
#include "llvm/TargetParser/Triple.h"
7679
#include "llvm/TargetParser/X86TargetParser.h"
7780
#include "llvm/Transforms/Utils/BuildLibCalls.h"
81+
#include <cassert>
7882
#include <optional>
7983

8084
using namespace clang;
@@ -2044,6 +2048,15 @@ StringRef CodeGenModule::getMangledName(GlobalDecl GD) {
20442048
GD.getWithKernelReferenceKind(KernelReferenceKind::Kernel),
20452049
ND));
20462050

2051+
if (getCodeGenOpts().DemanglingFailures &&
2052+
getContext().getLangOpts().getClangABICompat() >
2053+
LangOptions::ClangABI::Ver19) {
2054+
if (llvm::isMangledName(MangledName) &&
2055+
llvm::demangle(MangledName) == MangledName)
2056+
Diags.Report(ND->getLocation(), diag::warn_name_cannot_be_demangled)
2057+
<< MangledName;
2058+
}
2059+
20472060
auto Result = Manglings.insert(std::make_pair(MangledName, GD));
20482061
return MangledDeclNames[CanonicalGD] = Result.first->first();
20492062
}
Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
// RUN: %clang_cc1 -emit-llvm -fdemangling-failures -triple %itanium_abi_triple -o - %s | FileCheck %s
2+
template <class F> void parallel_loop(F &&f) { f(0); }
3+
4+
//CHECK-LABEL: @main
5+
int main() {
6+
int x;
7+
parallel_loop([&](auto y) { // expected-warning {{cannot demangle the name '_ZZ4mainENK3$_0clIiEEDaT_'}}
8+
#pragma clang __debug captured
9+
{
10+
x = y;
11+
};
12+
});
13+
}

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)