authorgravatar for jacobly@ziglang.orgJacob Young <jacobly@ziglang.org> 2022-10-03 20:14:24-04:00
committergravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2022-10-15 11:12:04-04:00
log400319872ba2fd1707a90db232e9c790450f37eb
tree2bd8298f2630393968a90aed0f5252d8a6f0e3ac
parentae39e7867db8053cd0538da10e144bf86bce4eba

llvm: fix bug lowering aggregate_init with a byref sentinel

Closes #12972

3 files changed, 33 insertions(+), 13 deletions(-)

src/codegen/llvm.zig+15-13
......@@ -4355,13 +4355,17 @@ pub const FuncGen = struct {
43554355 const gop = try self.func_inst_table.getOrPut(self.dg.gpa, inst);
43564356 if (gop.found_existing) return gop.value_ptr.*;
43574357
4358 const val = self.air.value(inst).?;
4359 const ty = self.air.typeOf(inst);
4360 const llvm_val = try self.dg.lowerValue(.{ .ty = ty, .val = val });
4361 if (!isByRef(ty)) {
4362 gop.value_ptr.* = llvm_val;
4363 return llvm_val;
4364 }
4358 const llvm_val = try self.resolveValue(.{
4359 .ty = self.air.typeOf(inst),
4360 .val = self.air.value(inst).?,
4361 });
4362 gop.value_ptr.* = llvm_val;
4363 return llvm_val;
4364 }
4365
4366 fn resolveValue(self: *FuncGen, tv: TypedValue) !*llvm.Value {
4367 const llvm_val = try self.dg.lowerValue(tv);
4368 if (!isByRef(tv.ty)) return llvm_val;
43654369
43664370 // We have an LLVM value but we need to create a global constant and
43674371 // set the value as its initializer, and then return a pointer to the global.
......@@ -4371,15 +4375,13 @@ pub const FuncGen = struct {
43714375 global.setLinkage(.Private);
43724376 global.setGlobalConstant(.True);
43734377 global.setUnnamedAddr(.True);
4374 global.setAlignment(ty.abiAlignment(target));
4378 global.setAlignment(tv.ty.abiAlignment(target));
43754379 // Because of LLVM limitations for lowering certain types such as unions,
43764380 // the type of global constants might not match the type it is supposed to
43774381 // be, and so we must bitcast the pointer at the usage sites.
4378 const wanted_llvm_ty = try self.dg.lowerType(ty);
4382 const wanted_llvm_ty = try self.dg.lowerType(tv.ty);
43794383 const wanted_llvm_ptr_ty = wanted_llvm_ty.pointerType(0);
4380 const casted_ptr = global.constBitCast(wanted_llvm_ptr_ty);
4381 gop.value_ptr.* = casted_ptr;
4382 return casted_ptr;
4384 return global.constBitCast(wanted_llvm_ptr_ty);
43834385 }
43844386
43854387 fn genBody(self: *FuncGen, body: []const Air.Inst.Index) Error!void {
......@@ -9032,7 +9034,7 @@ pub const FuncGen = struct {
90329034 llvm_usize.constInt(@intCast(c_uint, array_info.len), .False),
90339035 };
90349036 const elem_ptr = self.builder.buildInBoundsGEP(llvm_result_ty, alloca_inst, &indices, indices.len, "");
9035 const llvm_elem = try self.dg.lowerValue(.{
9037 const llvm_elem = try self.resolveValue(.{
90369038 .ty = array_info.elem_type,
90379039 .val = sent_val,
90389040 });
test/behavior.zig+1
......@@ -99,6 +99,7 @@ test {
9999 _ = @import("behavior/bugs/12911.zig");
100100 _ = @import("behavior/bugs/12928.zig");
101101 _ = @import("behavior/bugs/12945.zig");
102 _ = @import("behavior/bugs/12972.zig");
102103 _ = @import("behavior/bugs/12984.zig");
103104 _ = @import("behavior/bugs/13068.zig");
104105 _ = @import("behavior/bugs/13128.zig");
test/behavior/bugs/12972.zig created+17
......@@ -0,0 +1,17 @@
1const builtin = @import("builtin");
2
3pub fn f(_: [:null]const ?u8) void {}
4
5test {
6 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
7 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
8 if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; // TODO
9
10 const c: u8 = 42;
11 f(&[_:null]?u8{c});
12 f(&.{c});
13
14 var v: u8 = 42;
15 f(&[_:null]?u8{v});
16 f(&.{v});
17}