summaryrefslogtreecommitdiff
path: root/clang/lib/CodeGen/CodeGenModule.cpp
diff options
context:
space:
mode:
authorDhruv Chawla <dhruv263.dc@gmail.com>2023-03-06 08:16:16 -0800
committerErich Keane <erich.keane@intel.com>2023-03-06 08:59:02 -0800
commit9306ef9750b7a319d59f6d3e4977e01e39b8f161 (patch)
tree4603648f64fe81f2b6715be0cad7523c5b010b70 /clang/lib/CodeGen/CodeGenModule.cpp
parent38c85a419605417b818bc017aff734ab2f2007f5 (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.cpp34
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;
}