llvmbot wrote:
<!--LLVM PR SUMMARY COMMENT--> @llvm/pr-subscribers-clang Author: Viktoriia Bakalova (VitaNuo) <details> <summary>Changes</summary> …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. --- Full diff: https://github.com/llvm/llvm-project/pull/111391.diff 6 Files Affected: - (modified) clang/include/clang/Basic/CodeGenOptions.def (+3) - (modified) clang/include/clang/Driver/Options.td (+4) - (modified) clang/lib/CodeGen/CodeGenModule.cpp (+7) - (added) clang/test/CodeGenCXX/assert-demangle.cpp (+14) - (modified) llvm/include/llvm/Demangle/Demangle.h (+7) - (modified) llvm/lib/Demangle/Demangle.cpp (+10) ``````````diff 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) { `````````` </details> https://github.com/llvm/llvm-project/pull/111391 _______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits