[clang] [Clang] Allow vanilla C function symbol name to be used in __attribute__((alias)) when -funique-internal-linkage-names is specified (PR #145652)
via cfe-commits
cfe-commits at lists.llvm.org
Thu Jul 3 13:34:28 PDT 2025
https://github.com/HighW4y2H3ll updated https://github.com/llvm/llvm-project/pull/145652
>From 9a29dd6fa3f28bf507f047a22597f8510bd096b3 Mon Sep 17 00:00:00 2001
From: h2h <h2h at meta.com>
Date: Tue, 24 Jun 2025 23:24:32 -0700
Subject: [PATCH 1/3] [Clang] Allow vanilla C function symbol name to be used
in __attribute__((alias)) when -funique-internal-linkage-names is specified
---
clang/lib/CodeGen/CodeGenModule.cpp | 48 +++++++++++++++++--
.../unique-internal-linkage-names-alias.c | 10 ++++
2 files changed, 54 insertions(+), 4 deletions(-)
create mode 100644 clang/test/CodeGen/unique-internal-linkage-names-alias.c
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;}
>From aedff8d00362405ad73880eccf4bd7006f6facb2 Mon Sep 17 00:00:00 2001
From: h2h <h2h at meta.com>
Date: Wed, 25 Jun 2025 16:22:49 -0700
Subject: [PATCH 2/3] Check Itanium mangling only
---
clang/test/CodeGen/unique-internal-linkage-names-alias.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/clang/test/CodeGen/unique-internal-linkage-names-alias.c b/clang/test/CodeGen/unique-internal-linkage-names-alias.c
index 14bfea08367d3..85345233ad507 100644
--- a/clang/test/CodeGen/unique-internal-linkage-names-alias.c
+++ b/clang/test/CodeGen/unique-internal-linkage-names-alias.c
@@ -1,4 +1,4 @@
-// RUN: %clang_cc1 %s -emit-llvm -funique-internal-linkage-names -o - | FileCheck %s
+// RUN: %clang_cc1 -triple x86_64-unknown-linux %s -emit-llvm -funique-internal-linkage-names -o - | FileCheck %s
struct A;
static long foo(const struct A*p);
>From 80e7bda91ae783ce02e8c3491a88e65779a1e01c Mon Sep 17 00:00:00 2001
From: h2h <h2h at meta.com>
Date: Thu, 3 Jul 2025 13:33:44 -0700
Subject: [PATCH 3/3] Fix frontend crash with extern_weak when using
__attribute__((weak, alias()))
---
clang/lib/CodeGen/CodeGenModule.cpp | 1 -
1 file changed, 1 deletion(-)
diff --git a/clang/lib/CodeGen/CodeGenModule.cpp b/clang/lib/CodeGen/CodeGenModule.cpp
index 90f02220ec306..83515a4488256 100644
--- a/clang/lib/CodeGen/CodeGenModule.cpp
+++ b/clang/lib/CodeGen/CodeGenModule.cpp
@@ -4066,7 +4066,6 @@ void CodeGenModule::EmitGlobal(GlobalDecl GD) {
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.
More information about the cfe-commits
mailing list