authorgravatar for thatlemon@gmail.comLemonBoy <thatlemon@gmail.com> 2019-09-05 10:17:47+02:00
committergravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2019-09-05 13:09:43-04:00
log0107b19124255179a48cd605f31ed57d5ade28e7
tree4384d9d8973a0c58e79a74c7950912493657213c
parent9a358d2d33b0ecdec38ba3698acf8b239c43b667

Resolve lazy values when checking for definedness

Fixes #3154

2 files changed, 23 insertions(+), 9 deletions(-)

src/codegen.cpp+14-9
...@@ -183,7 +183,7 @@ static void render_const_val(CodeGen *g, ConstExprValue *const_val, const char *...@@ -183,7 +183,7 @@ static void render_const_val(CodeGen *g, ConstExprValue *const_val, const char *
183static void render_const_val_global(CodeGen *g, ConstExprValue *const_val, const char *name);183static void render_const_val_global(CodeGen *g, ConstExprValue *const_val, const char *name);
184static LLVMValueRef gen_const_val(CodeGen *g, ConstExprValue *const_val, const char *name);184static LLVMValueRef gen_const_val(CodeGen *g, ConstExprValue *const_val, const char *name);
185static void generate_error_name_table(CodeGen *g);185static void generate_error_name_table(CodeGen *g);
186static bool value_is_all_undef(ConstExprValue *const_val);186static bool value_is_all_undef(CodeGen *g, ConstExprValue *const_val);
187static void gen_undef_init(CodeGen *g, uint32_t ptr_align_bytes, ZigType *value_type, LLVMValueRef ptr);187static void gen_undef_init(CodeGen *g, uint32_t ptr_align_bytes, ZigType *value_type, LLVMValueRef ptr);
188static LLVMValueRef build_alloca(CodeGen *g, ZigType *type_entry, const char *name, uint32_t alignment);188static LLVMValueRef build_alloca(CodeGen *g, ZigType *type_entry, const char *name, uint32_t alignment);
189189
...@@ -3377,7 +3377,7 @@ static LLVMValueRef ir_render_load_ptr(CodeGen *g, IrExecutable *executable, IrI...@@ -3377,7 +3377,7 @@ static LLVMValueRef ir_render_load_ptr(CodeGen *g, IrExecutable *executable, IrI
3377 return LLVMBuildTrunc(g->builder, shifted_value, get_llvm_type(g, child_type), "");3377 return LLVMBuildTrunc(g->builder, shifted_value, get_llvm_type(g, child_type), "");
3378}3378}
33793379
3380static bool value_is_all_undef_array(ConstExprValue *const_val, size_t len) {3380static bool value_is_all_undef_array(CodeGen *g, ConstExprValue *const_val, size_t len) {
3381 switch (const_val->data.x_array.special) {3381 switch (const_val->data.x_array.special) {
3382 case ConstArraySpecialUndef:3382 case ConstArraySpecialUndef:
3383 return true;3383 return true;
...@@ -3385,7 +3385,7 @@ static bool value_is_all_undef_array(ConstExprValue *const_val, size_t len) {...@@ -3385,7 +3385,7 @@ static bool value_is_all_undef_array(ConstExprValue *const_val, size_t len) {
3385 return false;3385 return false;
3386 case ConstArraySpecialNone:3386 case ConstArraySpecialNone:
3387 for (size_t i = 0; i < len; i += 1) {3387 for (size_t i = 0; i < len; i += 1) {
3388 if (!value_is_all_undef(&const_val->data.x_array.data.s_none.elements[i]))3388 if (!value_is_all_undef(g, &const_val->data.x_array.data.s_none.elements[i]))
3389 return false;3389 return false;
3390 }3390 }
3391 return true;3391 return true;
...@@ -3393,7 +3393,12 @@ static bool value_is_all_undef_array(ConstExprValue *const_val, size_t len) {...@@ -3393,7 +3393,12 @@ static bool value_is_all_undef_array(ConstExprValue *const_val, size_t len) {
3393 zig_unreachable();3393 zig_unreachable();
3394}3394}
33953395
3396static bool value_is_all_undef(ConstExprValue *const_val) {3396static bool value_is_all_undef(CodeGen *g, ConstExprValue *const_val) {
3397 Error err;
3398 if (const_val->special == ConstValSpecialLazy &&
3399 (err = ir_resolve_lazy(g, nullptr, const_val)))
3400 report_errors_and_exit(g);
3401
3397 switch (const_val->special) {3402 switch (const_val->special) {
3398 case ConstValSpecialLazy:3403 case ConstValSpecialLazy:
3399 zig_unreachable();3404 zig_unreachable();
...@@ -3404,14 +3409,14 @@ static bool value_is_all_undef(ConstExprValue *const_val) {...@@ -3404,14 +3409,14 @@ static bool value_is_all_undef(ConstExprValue *const_val) {
3404 case ConstValSpecialStatic:3409 case ConstValSpecialStatic:
3405 if (const_val->type->id == ZigTypeIdStruct) {3410 if (const_val->type->id == ZigTypeIdStruct) {
3406 for (size_t i = 0; i < const_val->type->data.structure.src_field_count; i += 1) {3411 for (size_t i = 0; i < const_val->type->data.structure.src_field_count; i += 1) {
3407 if (!value_is_all_undef(&const_val->data.x_struct.fields[i]))3412 if (!value_is_all_undef(g, &const_val->data.x_struct.fields[i]))
3408 return false;3413 return false;
3409 }3414 }
3410 return true;3415 return true;
3411 } else if (const_val->type->id == ZigTypeIdArray) {3416 } else if (const_val->type->id == ZigTypeIdArray) {
3412 return value_is_all_undef_array(const_val, const_val->type->data.array.len);3417 return value_is_all_undef_array(g, const_val, const_val->type->data.array.len);
3413 } else if (const_val->type->id == ZigTypeIdVector) {3418 } else if (const_val->type->id == ZigTypeIdVector) {
3414 return value_is_all_undef_array(const_val, const_val->type->data.vector.len);3419 return value_is_all_undef_array(g, const_val, const_val->type->data.vector.len);
3415 } else {3420 } else {
3416 return false;3421 return false;
3417 }3422 }
...@@ -3532,7 +3537,7 @@ static LLVMValueRef ir_render_store_ptr(CodeGen *g, IrExecutable *executable, Ir...@@ -3532,7 +3537,7 @@ static LLVMValueRef ir_render_store_ptr(CodeGen *g, IrExecutable *executable, Ir
3532 return nullptr;3537 return nullptr;
3533 }3538 }
35343539
3535 bool have_init_expr = !value_is_all_undef(&instruction->value->value);3540 bool have_init_expr = !value_is_all_undef(g, &instruction->value->value);
3536 if (have_init_expr) {3541 if (have_init_expr) {
3537 LLVMValueRef ptr = ir_llvm_value(g, instruction->ptr);3542 LLVMValueRef ptr = ir_llvm_value(g, instruction->ptr);
3538 LLVMValueRef value = ir_llvm_value(g, instruction->value);3543 LLVMValueRef value = ir_llvm_value(g, instruction->value);
...@@ -4887,7 +4892,7 @@ static LLVMValueRef ir_render_memset(CodeGen *g, IrExecutable *executable, IrIns...@@ -4887,7 +4892,7 @@ static LLVMValueRef ir_render_memset(CodeGen *g, IrExecutable *executable, IrIns
4887 ZigType *ptr_type = instruction->dest_ptr->value.type;4892 ZigType *ptr_type = instruction->dest_ptr->value.type;
4888 assert(ptr_type->id == ZigTypeIdPointer);4893 assert(ptr_type->id == ZigTypeIdPointer);
48894894
4890 bool val_is_undef = value_is_all_undef(&instruction->byte->value);4895 bool val_is_undef = value_is_all_undef(g, &instruction->byte->value);
4891 LLVMValueRef fill_char;4896 LLVMValueRef fill_char;
4892 if (val_is_undef) {4897 if (val_is_undef) {
4893 fill_char = LLVMConstInt(LLVMInt8Type(), 0xaa, false);4898 fill_char = LLVMConstInt(LLVMInt8Type(), 0xaa, false);
test/stage1/behavior/sizeof_and_typeof.zig+9
...@@ -115,3 +115,12 @@ test "branching logic inside @typeOf" {...@@ -115,3 +115,12 @@ test "branching logic inside @typeOf" {
115 comptime expect(T == i32);115 comptime expect(T == i32);
116 expect(S.data == 0);116 expect(S.data == 0);
117}117}
118
119fn fn1(alpha: bool) void {
120 const n: usize = 7;
121 const v = if (alpha) n else @sizeOf(usize);
122}
123
124test "lazy @sizeOf result is checked for definedness" {
125 const f = fn1;
126}