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 <bakal...@google.com> Date: Tue, 15 Oct 2024 09:48:09 +0000 Subject: [PATCH] [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) { _______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits