authorgravatar for thatlemon@gmail.comLemonBoy <thatlemon@gmail.com> 2020-11-29 11:53:08+01:00
committergravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2020-11-29 11:37:44-07:00
log0a4a99ec8760b10b209fe886dbea6f15413d52d2
treee31e3a53912b49bbba192021c7a7f2b5f8019582
parentbe2adff087d4fb3ce6f559bf3563bf4ff7dd6df3

stage1: Add missing bitcast when rendering var ptr

Some types require this extra bitcast, eg. structs or unions with extra padding fields inserted by the compiler. Fixes #7250

3 files changed, 38 insertions(+), 7 deletions(-)

src/stage1/codegen.cpp+22-7
......@@ -3893,15 +3893,30 @@ static LLVMValueRef ir_render_vector_store_elem(CodeGen *g, IrExecutableGen *exe
38933893}
38943894
38953895static LLVMValueRef ir_render_var_ptr(CodeGen *g, IrExecutableGen *executable, IrInstGenVarPtr *instruction) {
3896 if (instruction->base.value->special != ConstValSpecialRuntime)
3897 return ir_llvm_value(g, &instruction->base);
3898 ZigVar *var = instruction->var;
3899 if (type_has_bits(g, var->var_type)) {
3900 assert(var->value_ref);
3901 return var->value_ref;
3902 } else {
3896 Error err;
3897
3898 ZigType *ptr_type = instruction->base.value->type;
3899 assert(ptr_type->id == ZigTypeIdPointer);
3900 bool ptr_type_has_bits;
3901 if ((err = type_has_bits2(g, ptr_type, &ptr_type_has_bits)))
3902 codegen_report_errors_and_exit(g);
3903
3904 if (!ptr_type_has_bits) {
39033905 return nullptr;
39043906 }
3907
3908 // The extra bitcasts are needed in case the LLVM value is an unnamed
3909 // struct, as it happens when rendering container types with extra alignment
3910 // fields.
3911 if (instruction->base.value->special != ConstValSpecialRuntime) {
3912 return LLVMBuildBitCast(g->builder, ir_llvm_value(g, &instruction->base),
3913 get_llvm_type(g, ptr_type), "");
3914 }
3915
3916 ZigVar *var = instruction->var;
3917 assert(var->value_ref);
3918 return LLVMBuildBitCast(g->builder, var->value_ref,
3919 get_llvm_type(g, ptr_type), "");
39053920}
39063921
39073922static LLVMValueRef ir_render_return_ptr(CodeGen *g, IrExecutableGen *executable,
test/stage1/behavior.zig+1
......@@ -60,6 +60,7 @@ comptime {
6060 _ = @import("behavior/bugs/7027.zig");
6161 _ = @import("behavior/bugs/7047.zig");
6262 _ = @import("behavior/bugs/7003.zig");
63 _ = @import("behavior/bugs/7250.zig");
6364 _ = @import("behavior/bugs/394.zig");
6465 _ = @import("behavior/bugs/421.zig");
6566 _ = @import("behavior/bugs/529.zig");
test/stage1/behavior/bugs/7250.zig created+15
......@@ -0,0 +1,15 @@
1const nrfx_uart_t = extern struct {
2 p_reg: [*c]u32,
3 drv_inst_idx: u8,
4};
5
6pub fn nrfx_uart_rx(p_instance: [*c]const nrfx_uart_t) void {}
7
8threadlocal var g_uart0 = nrfx_uart_t{
9 .p_reg = 0,
10 .drv_inst_idx = 0,
11};
12
13test "reference a global threadlocal variable" {
14 _ = nrfx_uart_rx(&g_uart0);
15}