llvmbot wrote:
<!--LLVM PR SUMMARY COMMENT--> @llvm/pr-subscribers-clang @llvm/pr-subscribers-clang-codegen Author: None (HighW4y2H3ll) <details> <summary>Changes</summary> `-funique-internal-linkage-names` mangles function symbols even for C functions. When using `__attribute__((alias()))`, it's a bit counter-intuitive to specify a C++ mangled symbol name in the attribute. Besides, `EmitGlobal` won't be able to emit the *aliasee* function because its name has been changed which no longer matches any GlobalValue name in the emitted LLVM Module. This patch fixes the `EmitGlobal` function which emits a function with the mangled name, and resolves the C symbol inside `__attribute__((alias))` to its uniquely mangled name to keep the behavior consistent. --- Full diff: https://github.com/llvm/llvm-project/pull/145652.diff 2 Files Affected: - (modified) clang/lib/CodeGen/CodeGenModule.cpp (+44-4) - (added) clang/test/CodeGen/unique-internal-linkage-names-alias.c (+10) ``````````diff diff --git a/clang/lib/CodeGen/CodeGenModule.cpp b/clang/lib/CodeGen/CodeGenModule.cpp index 16688810d0685..90f02220ec306 100644 --- a/clang/lib/CodeGen/CodeGenModule.cpp +++ b/clang/lib/CodeGen/CodeGenModule.cpp @@ -588,8 +588,9 @@ static const llvm::GlobalValue *getAliasedGlobal(const llvm::GlobalValue *GV) { } static bool checkAliasedGlobal( - const ASTContext &Context, DiagnosticsEngine &Diags, SourceLocation Location, - bool IsIFunc, const llvm::GlobalValue *Alias, const llvm::GlobalValue *&GV, + const CodeGenModule *CGM, const ASTContext &Context, + 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); @@ -598,6 +599,23 @@ static bool checkAliasedGlobal( return false; } + // Only resolve unique internal linkage symbols for C code + if (!CGM->getLangOpts().CPlusPlus) { + for (const auto &[Decl, Name] : MangledDeclNames) { + if (const auto *ND = dyn_cast<NamedDecl>(Decl.getDecl())) { + IdentifierInfo *II = ND->getIdentifier(); + if (II && II->getName() == GV->getName() && + Name.contains(llvm::FunctionSamples::UniqSuffix)) { + GlobalDecl GD; + if (CGM->lookupRepresentativeDecl(Name, GD)) { + GV = CGM->getModule().getNamedValue(Name); + break; + } + } + } + } + } + if (GV->hasCommonLinkage()) { const llvm::Triple &Triple = Context.getTargetInfo().getTriple(); if (Triple.getObjectFormat() == llvm::Triple::XCOFF) { @@ -687,8 +705,8 @@ void CodeGenModule::checkAliases() { StringRef MangledName = getMangledName(GD); llvm::GlobalValue *Alias = GetGlobalValue(MangledName); const llvm::GlobalValue *GV = nullptr; - if (!checkAliasedGlobal(getContext(), Diags, Location, IsIFunc, Alias, GV, - MangledDeclNames, Range)) { + if (!checkAliasedGlobal(this, getContext(), Diags, Location, IsIFunc, Alias, + GV, MangledDeclNames, Range)) { Error = true; continue; } @@ -4038,6 +4056,7 @@ void CodeGenModule::EmitGlobal(GlobalDecl GD) { CXXGlobalInits.push_back(nullptr); } + const auto *ND = dyn_cast<NamedDecl>(GD.getDecl()); StringRef MangledName = getMangledName(GD); if (GetGlobalValue(MangledName) != nullptr) { // The value has already been used and should therefore be emitted. @@ -4046,6 +4065,12 @@ void CodeGenModule::EmitGlobal(GlobalDecl GD) { // The value must be emitted, but cannot be emitted eagerly. assert(!MayBeEmittedEagerly(Global)); addDeferredDeclToEmit(GD); + } else if (!getLangOpts().CPlusPlus && ND && + GetGlobalValue(ND->getName()) != nullptr && + MangledName.contains(llvm::FunctionSamples::UniqSuffix)) { + // Emit static C function that is mangled with + // -funique-internal-linkage-names. + addDeferredDeclToEmit(GD); } else { // Otherwise, remember that we saw a deferred decl with this name. The // first use of the mangled name will cause it to move into @@ -6189,6 +6214,21 @@ void CodeGenModule::EmitGlobalFunctionDefinition(GlobalDecl GD, /*DontDefer=*/true, ForDefinition)); + if (!getLangOpts().CPlusPlus && + getCXXABI().getMangleContext().shouldMangleDeclName(D)) { + // -funique-internal-linkage-names may change the symbol name of C function. + // Replace all uses of old symbol with the emitted global value. + if (IdentifierInfo *II = D->getIdentifier()) { + if (II->getName() != GV->getName() && + GV->getName().contains(llvm::FunctionSamples::UniqSuffix)) { + if (llvm::GlobalValue *GVDef = + getModule().getNamedValue(D->getName())) { + GVDef->replaceAllUsesWith(GV); + } + } + } + } + // Already emitted. if (!GV->isDeclaration()) return; diff --git a/clang/test/CodeGen/unique-internal-linkage-names-alias.c b/clang/test/CodeGen/unique-internal-linkage-names-alias.c new file mode 100644 index 0000000000000..14bfea08367d3 --- /dev/null +++ b/clang/test/CodeGen/unique-internal-linkage-names-alias.c @@ -0,0 +1,10 @@ +// RUN: %clang_cc1 %s -emit-llvm -funique-internal-linkage-names -o - | FileCheck %s + +struct A; +static long foo(const struct A*p); + +long bar(const struct A*p); +long bar(const struct A*p) __attribute__((__alias__("foo"))); + +// CHECK: define internal i64 @_ZL3fooPK1A.__uniq.[[ATTR:[0-9]+]](ptr noundef %p) #1 { +static long foo(const struct A*p) {return 1;} `````````` </details> https://github.com/llvm/llvm-project/pull/145652 _______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits