diff options
| author | Dhruv Chawla <dhruv263.dc@gmail.com> | 2023-03-06 08:16:16 -0800 |
|---|---|---|
| committer | Erich Keane <erich.keane@intel.com> | 2023-03-06 08:59:02 -0800 |
| commit | 9306ef9750b7a319d59f6d3e4977e01e39b8f161 (patch) | |
| tree | 4603648f64fe81f2b6715be0cad7523c5b010b70 /clang/lib/CodeGen/CodeGenModule.cpp | |
| parent | 38c85a419605417b818bc017aff734ab2f2007f5 (diff) | |
[clang][alias|ifunc]: Add a diagnostic for mangled names
When an alias or ifunc attribute refers to a function name that is
mangled, a diagnostic is emitted to suggest the mangled name as a
replacement for the given function name for every matching name in the
current TU.
Fixes #59164
Differential Revision: https://reviews.llvm.org/D143803
Diffstat (limited to 'clang/lib/CodeGen/CodeGenModule.cpp')
| -rw-r--r-- | clang/lib/CodeGen/CodeGenModule.cpp | 34 |
1 files changed, 27 insertions, 7 deletions
diff --git a/clang/lib/CodeGen/CodeGenModule.cpp b/clang/lib/CodeGen/CodeGenModule.cpp index 90c9df4ea442..b512fb576a2c 100644 --- a/clang/lib/CodeGen/CodeGenModule.cpp +++ b/clang/lib/CodeGen/CodeGenModule.cpp @@ -338,10 +338,11 @@ static const llvm::GlobalValue *getAliasedGlobal(const llvm::GlobalValue *GV) { return FinalGV; } -static bool checkAliasedGlobal(DiagnosticsEngine &Diags, - SourceLocation Location, bool IsIFunc, - const llvm::GlobalValue *Alias, - const llvm::GlobalValue *&GV) { +static bool checkAliasedGlobal( + DiagnosticsEngine &Diags, SourceLocation Location, bool IsIFunc, + const llvm::GlobalValue *Alias, const llvm::GlobalValue *&GV, + const llvm::MapVector<GlobalDecl, StringRef> &MangledDeclNames, + SourceRange AliasRange) { GV = getAliasedGlobal(Alias); if (!GV) { Diags.Report(Location, diag::err_cyclic_alias) << IsIFunc; @@ -350,6 +351,22 @@ static bool checkAliasedGlobal(DiagnosticsEngine &Diags, if (GV->isDeclaration()) { Diags.Report(Location, diag::err_alias_to_undefined) << IsIFunc << IsIFunc; + Diags.Report(Location, diag::note_alias_requires_mangled_name) + << IsIFunc << IsIFunc; + // Provide a note if the given function is not found and exists as a + // mangled name. + for (const auto &[Decl, Name] : MangledDeclNames) { + if (const auto *ND = dyn_cast<NamedDecl>(Decl.getDecl())) { + if (ND->getName() == GV->getName()) { + Diags.Report(Location, diag::note_alias_mangled_name_alternative) + << Name + << FixItHint::CreateReplacement( + AliasRange, + (Twine(IsIFunc ? "ifunc" : "alias") + "(\"" + Name + "\")") + .str()); + } + } + } return false; } @@ -381,16 +398,19 @@ void CodeGenModule::checkAliases() { for (const GlobalDecl &GD : Aliases) { const auto *D = cast<ValueDecl>(GD.getDecl()); SourceLocation Location; + SourceRange Range; bool IsIFunc = D->hasAttr<IFuncAttr>(); - if (const Attr *A = D->getDefiningAttr()) + if (const Attr *A = D->getDefiningAttr()) { Location = A->getLocation(); - else + Range = A->getRange(); + } else llvm_unreachable("Not an alias or ifunc?"); StringRef MangledName = getMangledName(GD); llvm::GlobalValue *Alias = GetGlobalValue(MangledName); const llvm::GlobalValue *GV = nullptr; - if (!checkAliasedGlobal(Diags, Location, IsIFunc, Alias, GV)) { + if (!checkAliasedGlobal(Diags, Location, IsIFunc, Alias, GV, + MangledDeclNames, Range)) { Error = true; continue; } |
