Skip to content

Commit 9a29dd6

Browse files
committed
[Clang] Allow vanilla C function symbol name to be used in __attribute__((alias)) when -funique-internal-linkage-names is specified
1 parent 836ff36 commit 9a29dd6

File tree

2 files changed

+54
-4
lines changed

2 files changed

+54
-4
lines changed

clang/lib/CodeGen/CodeGenModule.cpp

Lines changed: 44 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -588,8 +588,9 @@ static const llvm::GlobalValue *getAliasedGlobal(const llvm::GlobalValue *GV) {
588588
}
589589

590590
static bool checkAliasedGlobal(
591-
const ASTContext &Context, DiagnosticsEngine &Diags, SourceLocation Location,
592-
bool IsIFunc, const llvm::GlobalValue *Alias, const llvm::GlobalValue *&GV,
591+
const CodeGenModule *CGM, const ASTContext &Context,
592+
DiagnosticsEngine &Diags, SourceLocation Location, bool IsIFunc,
593+
const llvm::GlobalValue *Alias, const llvm::GlobalValue *&GV,
593594
const llvm::MapVector<GlobalDecl, StringRef> &MangledDeclNames,
594595
SourceRange AliasRange) {
595596
GV = getAliasedGlobal(Alias);
@@ -598,6 +599,23 @@ static bool checkAliasedGlobal(
598599
return false;
599600
}
600601

602+
// Only resolve unique internal linkage symbols for C code
603+
if (!CGM->getLangOpts().CPlusPlus) {
604+
for (const auto &[Decl, Name] : MangledDeclNames) {
605+
if (const auto *ND = dyn_cast<NamedDecl>(Decl.getDecl())) {
606+
IdentifierInfo *II = ND->getIdentifier();
607+
if (II && II->getName() == GV->getName() &&
608+
Name.contains(llvm::FunctionSamples::UniqSuffix)) {
609+
GlobalDecl GD;
610+
if (CGM->lookupRepresentativeDecl(Name, GD)) {
611+
GV = CGM->getModule().getNamedValue(Name);
612+
break;
613+
}
614+
}
615+
}
616+
}
617+
}
618+
601619
if (GV->hasCommonLinkage()) {
602620
const llvm::Triple &Triple = Context.getTargetInfo().getTriple();
603621
if (Triple.getObjectFormat() == llvm::Triple::XCOFF) {
@@ -687,8 +705,8 @@ void CodeGenModule::checkAliases() {
687705
StringRef MangledName = getMangledName(GD);
688706
llvm::GlobalValue *Alias = GetGlobalValue(MangledName);
689707
const llvm::GlobalValue *GV = nullptr;
690-
if (!checkAliasedGlobal(getContext(), Diags, Location, IsIFunc, Alias, GV,
691-
MangledDeclNames, Range)) {
708+
if (!checkAliasedGlobal(this, getContext(), Diags, Location, IsIFunc, Alias,
709+
GV, MangledDeclNames, Range)) {
692710
Error = true;
693711
continue;
694712
}
@@ -4038,6 +4056,7 @@ void CodeGenModule::EmitGlobal(GlobalDecl GD) {
40384056
CXXGlobalInits.push_back(nullptr);
40394057
}
40404058

4059+
const auto *ND = dyn_cast<NamedDecl>(GD.getDecl());
40414060
StringRef MangledName = getMangledName(GD);
40424061
if (GetGlobalValue(MangledName) != nullptr) {
40434062
// The value has already been used and should therefore be emitted.
@@ -4046,6 +4065,12 @@ void CodeGenModule::EmitGlobal(GlobalDecl GD) {
40464065
// The value must be emitted, but cannot be emitted eagerly.
40474066
assert(!MayBeEmittedEagerly(Global));
40484067
addDeferredDeclToEmit(GD);
4068+
} else if (!getLangOpts().CPlusPlus && ND &&
4069+
GetGlobalValue(ND->getName()) != nullptr &&
4070+
MangledName.contains(llvm::FunctionSamples::UniqSuffix)) {
4071+
// Emit static C function that is mangled with
4072+
// -funique-internal-linkage-names.
4073+
addDeferredDeclToEmit(GD);
40494074
} else {
40504075
// Otherwise, remember that we saw a deferred decl with this name. The
40514076
// first use of the mangled name will cause it to move into
@@ -6189,6 +6214,21 @@ void CodeGenModule::EmitGlobalFunctionDefinition(GlobalDecl GD,
61896214
/*DontDefer=*/true,
61906215
ForDefinition));
61916216

6217+
if (!getLangOpts().CPlusPlus &&
6218+
getCXXABI().getMangleContext().shouldMangleDeclName(D)) {
6219+
// -funique-internal-linkage-names may change the symbol name of C function.
6220+
// Replace all uses of old symbol with the emitted global value.
6221+
if (IdentifierInfo *II = D->getIdentifier()) {
6222+
if (II->getName() != GV->getName() &&
6223+
GV->getName().contains(llvm::FunctionSamples::UniqSuffix)) {
6224+
if (llvm::GlobalValue *GVDef =
6225+
getModule().getNamedValue(D->getName())) {
6226+
GVDef->replaceAllUsesWith(GV);
6227+
}
6228+
}
6229+
}
6230+
}
6231+
61926232
// Already emitted.
61936233
if (!GV->isDeclaration())
61946234
return;
Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
// RUN: %clang_cc1 %s -emit-llvm -funique-internal-linkage-names -o - | FileCheck %s
2+
3+
struct A;
4+
static long foo(const struct A*p);
5+
6+
long bar(const struct A*p);
7+
long bar(const struct A*p) __attribute__((__alias__("foo")));
8+
9+
// CHECK: define internal i64 @_ZL3fooPK1A.__uniq.[[ATTR:[0-9]+]](ptr noundef %p) #1 {
10+
static long foo(const struct A*p) {return 1;}

0 commit comments

Comments
 (0)