authorgravatar for wxsychi@163.comriChar <wxsychi@163.com> 2022-09-04 23:44:45+08:00
committergravatar for noreply@github.comGitHub <noreply@github.com> 2022-09-04 18:44:45+03:00
log349cf54b3293bc4177253e96a4f84fea0251fa08
tree5d10e1ca26ee49a5121a18aa5dffc269bd729277
parentb7d5582dede8f4cae341365ac9c47c840bd80eff
signaturebadge-question-mark Signed by PGP key 4AEE18F83AFDEB23

llvm: fix the `type` parameter of `GlobalAlias`

Closes 12680

4 files changed, 38 insertions(+), 12 deletions(-)

src/codegen/llvm.zig+12-12
...@@ -287,6 +287,15 @@ pub fn supportsTailCall(target: std.Target) bool {...@@ -287,6 +287,15 @@ pub fn supportsTailCall(target: std.Target) bool {
287 }287 }
288}288}
289289
290/// TODO can this be done with simpler logic / different API binding?
291fn deleteLlvmGlobal(llvm_global: *const llvm.Value) void {
292 if (llvm_global.globalGetValueType().getTypeKind() == .Function) {
293 llvm_global.deleteFunction();
294 return;
295 }
296 return llvm_global.deleteGlobal();
297}
298
290pub const Object = struct {299pub const Object = struct {
291 gpa: Allocator,300 gpa: Allocator,
292 module: *Module,301 module: *Module,
...@@ -640,7 +649,7 @@ pub const Object = struct {...@@ -640,7 +649,7 @@ pub const Object = struct {
640649
641 const new_global_ptr = other_global.constBitCast(llvm_global.typeOf());650 const new_global_ptr = other_global.constBitCast(llvm_global.typeOf());
642 llvm_global.replaceAllUsesWith(new_global_ptr);651 llvm_global.replaceAllUsesWith(new_global_ptr);
643 object.deleteLlvmGlobal(llvm_global);652 deleteLlvmGlobal(llvm_global);
644 entry.value_ptr.* = new_global_ptr;653 entry.value_ptr.* = new_global_ptr;
645 }654 }
646 object.extern_collisions.clearRetainingCapacity();655 object.extern_collisions.clearRetainingCapacity();
...@@ -666,7 +675,7 @@ pub const Object = struct {...@@ -666,7 +675,7 @@ pub const Object = struct {
666 const new_global_ptr = llvm_global.constBitCast(other_global.typeOf());675 const new_global_ptr = llvm_global.constBitCast(other_global.typeOf());
667 other_global.replaceAllUsesWith(new_global_ptr);676 other_global.replaceAllUsesWith(new_global_ptr);
668 llvm_global.takeName(other_global);677 llvm_global.takeName(other_global);
669 other_global.deleteGlobal();678 deleteLlvmGlobal(other_global);
670 // Problem: now we need to replace in the decl_map that679 // Problem: now we need to replace in the decl_map that
671 // the extern decl index points to this new global. However we don't680 // the extern decl index points to this new global. However we don't
672 // know the decl index.681 // know the decl index.
...@@ -1184,15 +1193,6 @@ pub const Object = struct {...@@ -1184,15 +1193,6 @@ pub const Object = struct {
1184 return null;1193 return null;
1185 }1194 }
11861195
1187 /// TODO can this be done with simpler logic / different API binding?
1188 fn deleteLlvmGlobal(o: Object, llvm_global: *const llvm.Value) void {
1189 if (o.llvm_module.getNamedFunction(llvm_global.getValueName()) != null) {
1190 llvm_global.deleteFunction();
1191 return;
1192 }
1193 return llvm_global.deleteGlobal();
1194 }
1195
1196 pub fn updateDeclExports(1196 pub fn updateDeclExports(
1197 self: *Object,1197 self: *Object,
1198 module: *Module,1198 module: *Module,
...@@ -1287,7 +1287,7 @@ pub const Object = struct {...@@ -1287,7 +1287,7 @@ pub const Object = struct {
1287 alias.setAliasee(llvm_global);1287 alias.setAliasee(llvm_global);
1288 } else {1288 } else {
1289 _ = self.llvm_module.addAlias(1289 _ = self.llvm_module.addAlias(
1290 llvm_global.typeOf(),1290 llvm_global.globalGetValueType(),
1291 0,1291 0,
1292 llvm_global,1292 llvm_global,
1293 exp_name_z,1293 exp_name_z,
test/behavior.zig+1
...@@ -85,6 +85,7 @@ test {...@@ -85,6 +85,7 @@ test {
85 _ = @import("behavior/bugs/12033.zig");85 _ = @import("behavior/bugs/12033.zig");
86 _ = @import("behavior/bugs/12430.zig");86 _ = @import("behavior/bugs/12430.zig");
87 _ = @import("behavior/bugs/12486.zig");87 _ = @import("behavior/bugs/12486.zig");
88 _ = @import("behavior/bugs/12680.zig");
88 _ = @import("behavior/byteswap.zig");89 _ = @import("behavior/byteswap.zig");
89 _ = @import("behavior/byval_arg_var.zig");90 _ = @import("behavior/byval_arg_var.zig");
90 _ = @import("behavior/call.zig");91 _ = @import("behavior/call.zig");
test/behavior/bugs/12680.zig created+17
...@@ -0,0 +1,17 @@
1const std = @import("std");
2const expectEqual = std.testing.expectEqual;
3const other_file = @import("12680_other_file.zig");
4const builtin = @import("builtin");
5
6extern fn test_func() callconv(.C) usize;
7
8test "export a function twice" {
9 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest;
10 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest;
11 if (builtin.zig_backend == .stage2_c) return error.SkipZigTest;
12 if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest;
13 if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest;
14
15 // If it exports the function correctly, `test_func` and `testFunc` will points to the same address.
16 try expectEqual(test_func(), other_file.testFunc());
17}
test/behavior/bugs/12680_other_file.zig created+8
...@@ -0,0 +1,8 @@
1// export this function twice
2pub export fn testFunc() callconv(.C) usize {
3 return @ptrToInt(&testFunc);
4}
5
6comptime {
7 @export(testFunc, .{ .name = "test_func", .linkage = .Strong });
8}