Skip to content
Open
Show file tree
Hide file tree
Changes from 2 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions clang/include/clang/Basic/CodeGenOptions.def
Original file line number Diff line number Diff line change
Expand Up @@ -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)
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
CODEGENOPT(DemanglingFailures, 1, 0)
CODEGENOPT(DiagDemanglerFailures, 1, 0)

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks, mentioning diagnostics makes sense.


/// FIXME: Make DebugOptions its own top-level .def file.
#include "DebugOptions.def"

Expand Down
4 changes: 4 additions & 0 deletions clang/include/clang/Basic/DiagnosticFrontendKinds.td
Original file line number Diff line number Diff line change
Expand Up @@ -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>;
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Group is wrong here, we likely want to give it its own group for the diagnostic.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Added a new Demangler group.

}
4 changes: 4 additions & 0 deletions clang/include/clang/Driver/Options.td
Original file line number Diff line number Diff line change
Expand Up @@ -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>,
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
def fdemangling_failures: Flag<["-"], "fdemangling-failures">, Group<f_clang_Group>,
def fdiag-demangler_failures: Flag<["-"], "fdiag-demangler-failures">, Group<f_clang_Group>,

Same as above... I'm not attached to the demangling vs demangler, but mentioning explicitly that this is for 'diag' everywhere is necessary for readability.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thank you, good point. I've looked through the existing flags, there are multiple ones that start with fdiagnostics_XXX, so I have renamed the flag to fdiagnostics_demangler_failures.
Let me know if this works.

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>,

Expand Down
13 changes: 13 additions & 0 deletions clang/lib/CodeGen/CodeGenModule.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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"
Expand All @@ -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"
Expand All @@ -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;
Expand Down Expand Up @@ -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();
}
Expand Down
3 changes: 3 additions & 0 deletions clang/lib/Driver/ToolChains/Clang.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -4444,6 +4444,9 @@ static void RenderDiagnosticsOptions(const Driver &D, const ArgList &Args,

Args.addOptOutFlag(CmdArgs, options::OPT_fspell_checking,
options::OPT_fno_spell_checking);

if (Args.hasArg(options::OPT_fdemangling_failures))
CmdArgs.push_back("-fdemangling-failures");
}

DwarfFissionKind tools::getDebugFissionKind(const Driver &D,
Expand Down
13 changes: 13 additions & 0 deletions clang/test/CodeGenCXX/warn-demangling-failure.cpp
Original file line number Diff line number Diff line change
@@ -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;
};
});
}
7 changes: 7 additions & 0 deletions llvm/include/llvm/Demangle/Demangle.h
Original file line number Diff line number Diff line change
Expand Up @@ -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);
Expand Down
10 changes: 10 additions & 0 deletions llvm/lib/Demangle/Demangle.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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) {
Expand Down
Loading