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 10:37:06-08:00
logc80d196094de3e0258b4a1146cff56576ec8e95d
tree1f42f229449123b6adb3624ec793962674e17b39
parent48660371a2f66b3859831abb276180c557a12f93

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
......@@ -3887,15 +3887,30 @@ static LLVMValueRef ir_render_vector_store_elem(CodeGen *g, IrExecutableGen *exe
38873887}
38883888
38893889static LLVMValueRef ir_render_var_ptr(CodeGen *g, IrExecutableGen *executable, IrInstGenVarPtr *instruction) {
3890 if (instruction->base.value->special != ConstValSpecialRuntime)
3891 return ir_llvm_value(g, &instruction->base);
3892 ZigVar *var = instruction->var;
3893 if (type_has_bits(g, var->var_type)) {
3894 assert(var->value_ref);
3895 return var->value_ref;
3896 } else {
3890 Error err;
3891
3892 ZigType *ptr_type = instruction->base.value->type;
3893 assert(ptr_type->id == ZigTypeIdPointer);
3894 bool ptr_type_has_bits;
3895 if ((err = type_has_bits2(g, ptr_type, &ptr_type_has_bits)))
3896 codegen_report_errors_and_exit(g);
3897
3898 if (!ptr_type_has_bits) {
38973899 return nullptr;
38983900 }
3901
3902 // The extra bitcasts are needed in case the LLVM value is an unnamed
3903 // struct, as it happens when rendering container types with extra alignment
3904 // fields.
3905 if (instruction->base.value->special != ConstValSpecialRuntime) {
3906 return LLVMBuildBitCast(g->builder, ir_llvm_value(g, &instruction->base),
3907 get_llvm_type(g, ptr_type), "");
3908 }
3909
3910 ZigVar *var = instruction->var;
3911 assert(var->value_ref);
3912 return LLVMBuildBitCast(g->builder, var->value_ref,
3913 get_llvm_type(g, ptr_type), "");
38993914}
39003915
39013916static 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}