Skip to content

Commit d9d3dc4

Browse files
authored
Fix function alias support (#178)
1 parent 6c744f9 commit d9d3dc4

File tree

2 files changed

+56
-1
lines changed

2 files changed

+56
-1
lines changed

lib/Target/CBackend/CBackend.cpp

Lines changed: 20 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2460,6 +2460,13 @@ void CWriter::generateHeader(Module &M) {
24602460
continue;
24612461
printTypeName(NullOut, I->getValueType(), false);
24622462
}
2463+
for (Module::alias_iterator I = M.alias_begin(), E = M.alias_end(); I != E;
2464+
++I) {
2465+
if (!I->hasLocalLinkage() && I->getValueType()->isFunctionTy()) {
2466+
// Make sure that the aliasee function type name exists.
2467+
getFunctionName(cast<Function>(I->getAliaseeObject()));
2468+
}
2469+
}
24632470
printModuleTypes(Out);
24642471

24652472
// Global variable declarations...
@@ -2643,9 +2650,18 @@ void CWriter::generateHeader(Module &M) {
26432650
headerUseAligns();
26442651
Out << "__PREFIXALIGN__(" << Alignment << ") ";
26452652
}
2653+
std::optional<std::string> CastAs{};
2654+
if (ElTy->isFunctionTy()) {
2655+
std::string FunctionName =
2656+
getFunctionName(cast<Function>(I->getAliaseeObject()));
2657+
Out << FunctionName;
2658+
CastAs = FunctionName;
2659+
} else {
2660+
printTypeName(Out, ElTy, false);
2661+
}
26462662
// GetValueName would resolve the alias, which is not what we want,
26472663
// so use getName directly instead (assuming that the Alias has a name...)
2648-
printTypeName(Out, ElTy, false) << " *" << I->getName();
2664+
Out << " *" << I->getName();
26492665
if (IsOveraligned) {
26502666
headerUseAligns();
26512667
Out << " __POSTFIXALIGN__(" << Alignment << ")";
@@ -2656,6 +2672,9 @@ void CWriter::generateHeader(Module &M) {
26562672
Out << " __EXTERNAL_WEAK__";
26572673
}
26582674
Out << " = ";
2675+
if (CastAs.has_value()) {
2676+
Out << '(' << CastAs.value() << "*)";
2677+
}
26592678
writeOperand(I->getAliasee(), ContextStatic);
26602679
Out << ";\n";
26612680
}

test/ll_tests/test_function_alias.ll

Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
; Test function aliases
2+
; It is inspired by LLVM IR produced by rustc 1.69 for code like
3+
;
4+
; #[no_mangle]
5+
; unsafe extern "C" fn drop_vec_of_a(
6+
; data: *mut A,
7+
; len: usize,
8+
; capacity: usize,
9+
; ) {
10+
; drop(Vec::from_raw_parts(data, len, capacity))
11+
; }
12+
; #[no_mangle]
13+
; unsafe extern "C" fn drop_vec_of_b(
14+
; data: *mut B,
15+
; len: usize,
16+
; capacity: usize,
17+
; ) {
18+
; drop(Vec::from_raw_parts(data, len, capacity))
19+
; }
20+
;
21+
; but with some simplifications.
22+
23+
; Function Attrs: noinline nounwind optnone uwtable
24+
define i32 @drop_vec_of_a(i32 %retVal) #0 {
25+
ret i32 %retVal
26+
}
27+
28+
@drop_vec_of_b = unnamed_addr alias i32 (i32), ptr @drop_vec_of_a
29+
30+
; Function Attrs: noinline nounwind optnone uwtable
31+
define dso_local i32 @main() #1 {
32+
%a = call i32 @drop_vec_of_a(i32 2)
33+
%b = call i32 @drop_vec_of_b(i32 4)
34+
%sum = add i32 %a, %b
35+
ret i32 %sum
36+
}

0 commit comments

Comments
 (0)