0xdc03 created this revision. Herald added a subscriber: jeroen.dobbelaere. Herald added a project: All. 0xdc03 requested review of this revision. Herald added a project: clang. Herald added a subscriber: cfe-commits.
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. Repository: rG LLVM Github Monorepo https://reviews.llvm.org/D143803 Files: clang/include/clang/Basic/DiagnosticFrontendKinds.td clang/lib/CodeGen/CodeGenModule.cpp clang/test/CodeGen/alias.cpp clang/test/CodeGen/attr-ifunc.cpp Index: clang/test/CodeGen/attr-ifunc.cpp =================================================================== --- /dev/null +++ clang/test/CodeGen/attr-ifunc.cpp @@ -0,0 +1,14 @@ +// RUN: %clang_cc1 -triple x86_64-linux -fsyntax-only -verify -emit-llvm-only %s + +void *f1_ifunc(void) { return nullptr; } +void f1(void) __attribute__((ifunc("f1_ifunc"))); +// expected-error@-1 {{ifunc must point to a defined function}} +// expected-note@-2 {{exists as a mangled name}} + +void *f6_resolver_resolver(void) { return 0; } +void *f6_resolver(void) __attribute__((ifunc("f6_resolver_resolver"))); +// expected-error@-1 {{ifunc must point to a defined function}} +// expected-note@-2 {{exists as a mangled name}} +void f6(void) __attribute__((ifunc("f6_resolver"))); +// expected-error@-1 {{ifunc must point to a defined function}} +// expected-note@-2 {{exists as a mangled name}} Index: clang/test/CodeGen/alias.cpp =================================================================== --- /dev/null +++ clang/test/CodeGen/alias.cpp @@ -0,0 +1,14 @@ +// RUN: %clang_cc1 -triple x86_64-linux -fsyntax-only -verify -emit-llvm-only %s + +void *f1_ifunc(void) { return nullptr; } +void f1(void) __attribute__((alias("f1_ifunc"))); +// expected-error@-1 {{alias must point to a defined variable or function}} +// expected-note@-2 {{exists as a mangled name}} + +void *f6_resolver_resolver(void) { return 0; } +void *f6_resolver(void) __attribute__((alias("f6_resolver_resolver"))); +// expected-error@-1 {{alias must point to a defined variable or function}} +// expected-note@-2 {{exists as a mangled name}} +void f6(void) __attribute__((alias("f6_resolver"))); +// expected-error@-1 {{alias must point to a defined variable or function}} +// expected-note@-2 {{exists as a mangled name}} Index: clang/lib/CodeGen/CodeGenModule.cpp =================================================================== --- clang/lib/CodeGen/CodeGenModule.cpp +++ clang/lib/CodeGen/CodeGenModule.cpp @@ -341,7 +341,8 @@ static bool checkAliasedGlobal(DiagnosticsEngine &Diags, SourceLocation Location, bool IsIFunc, const llvm::GlobalValue *Alias, - const llvm::GlobalValue *&GV) { + const llvm::GlobalValue *&GV, + const llvm::MapVector<GlobalDecl, StringRef> &MangledDeclNames) { GV = getAliasedGlobal(Alias); if (!GV) { Diags.Report(Location, diag::err_cyclic_alias) << IsIFunc; @@ -350,6 +351,16 @@ if (GV->isDeclaration()) { Diags.Report(Location, diag::err_alias_to_undefined) << 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_requires_mangled_name) + << GV->getName() << Name; + } + } + } return false; } @@ -390,7 +401,8 @@ 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)) { Error = true; continue; } Index: clang/include/clang/Basic/DiagnosticFrontendKinds.td =================================================================== --- clang/include/clang/Basic/DiagnosticFrontendKinds.td +++ clang/include/clang/Basic/DiagnosticFrontendKinds.td @@ -278,6 +278,8 @@ def err_alias_to_undefined : Error< "%select{alias|ifunc}0 must point to a defined " "%select{variable or |}1function">; +def note_alias_requires_mangled_name : Note< + "'%0' exists as a mangled name, did you mean to use '%1'?">; def warn_alias_to_weak_alias : Warning< "%select{alias|ifunc}2 will always resolve to %0 even if weak definition of " "%1 is overridden">,
Index: clang/test/CodeGen/attr-ifunc.cpp =================================================================== --- /dev/null +++ clang/test/CodeGen/attr-ifunc.cpp @@ -0,0 +1,14 @@ +// RUN: %clang_cc1 -triple x86_64-linux -fsyntax-only -verify -emit-llvm-only %s + +void *f1_ifunc(void) { return nullptr; } +void f1(void) __attribute__((ifunc("f1_ifunc"))); +// expected-error@-1 {{ifunc must point to a defined function}} +// expected-note@-2 {{exists as a mangled name}} + +void *f6_resolver_resolver(void) { return 0; } +void *f6_resolver(void) __attribute__((ifunc("f6_resolver_resolver"))); +// expected-error@-1 {{ifunc must point to a defined function}} +// expected-note@-2 {{exists as a mangled name}} +void f6(void) __attribute__((ifunc("f6_resolver"))); +// expected-error@-1 {{ifunc must point to a defined function}} +// expected-note@-2 {{exists as a mangled name}} Index: clang/test/CodeGen/alias.cpp =================================================================== --- /dev/null +++ clang/test/CodeGen/alias.cpp @@ -0,0 +1,14 @@ +// RUN: %clang_cc1 -triple x86_64-linux -fsyntax-only -verify -emit-llvm-only %s + +void *f1_ifunc(void) { return nullptr; } +void f1(void) __attribute__((alias("f1_ifunc"))); +// expected-error@-1 {{alias must point to a defined variable or function}} +// expected-note@-2 {{exists as a mangled name}} + +void *f6_resolver_resolver(void) { return 0; } +void *f6_resolver(void) __attribute__((alias("f6_resolver_resolver"))); +// expected-error@-1 {{alias must point to a defined variable or function}} +// expected-note@-2 {{exists as a mangled name}} +void f6(void) __attribute__((alias("f6_resolver"))); +// expected-error@-1 {{alias must point to a defined variable or function}} +// expected-note@-2 {{exists as a mangled name}} Index: clang/lib/CodeGen/CodeGenModule.cpp =================================================================== --- clang/lib/CodeGen/CodeGenModule.cpp +++ clang/lib/CodeGen/CodeGenModule.cpp @@ -341,7 +341,8 @@ static bool checkAliasedGlobal(DiagnosticsEngine &Diags, SourceLocation Location, bool IsIFunc, const llvm::GlobalValue *Alias, - const llvm::GlobalValue *&GV) { + const llvm::GlobalValue *&GV, + const llvm::MapVector<GlobalDecl, StringRef> &MangledDeclNames) { GV = getAliasedGlobal(Alias); if (!GV) { Diags.Report(Location, diag::err_cyclic_alias) << IsIFunc; @@ -350,6 +351,16 @@ if (GV->isDeclaration()) { Diags.Report(Location, diag::err_alias_to_undefined) << 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_requires_mangled_name) + << GV->getName() << Name; + } + } + } return false; } @@ -390,7 +401,8 @@ 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)) { Error = true; continue; } Index: clang/include/clang/Basic/DiagnosticFrontendKinds.td =================================================================== --- clang/include/clang/Basic/DiagnosticFrontendKinds.td +++ clang/include/clang/Basic/DiagnosticFrontendKinds.td @@ -278,6 +278,8 @@ def err_alias_to_undefined : Error< "%select{alias|ifunc}0 must point to a defined " "%select{variable or |}1function">; +def note_alias_requires_mangled_name : Note< + "'%0' exists as a mangled name, did you mean to use '%1'?">; def warn_alias_to_weak_alias : Warning< "%select{alias|ifunc}2 will always resolve to %0 even if weak definition of " "%1 is overridden">,
_______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits