authorgravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2020-01-27 17:30:39-05:00
committergravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2020-01-27 17:30:39-05:00
logc0fee9dfc7be5ab2c232a4787223a8e56a56745b
tree86983d21004c4dcd0ed10aa72f517ad7521309cd
parente2778c03e07c23d60861b90474859b9d8a62bce8
signaturelock-open Commit is signed but in an unrecognized format.

fix nested bitcast passed as tuple element


4 files changed, 91 insertions(+), 46 deletions(-)

src/analyze.cpp+18-4
...@@ -593,9 +593,9 @@ ZigType *get_pointer_to_type_extra2(CodeGen *g, ZigType *child_type, bool is_con...@@ -593,9 +593,9 @@ ZigType *get_pointer_to_type_extra2(CodeGen *g, ZigType *child_type, bool is_con
593 }593 }
594594
595 if (inferred_struct_field != nullptr) {595 if (inferred_struct_field != nullptr) {
596 entry->abi_size = g->builtin_types.entry_usize->abi_size;596 entry->abi_size = SIZE_MAX;
597 entry->size_in_bits = g->builtin_types.entry_usize->size_in_bits;597 entry->size_in_bits = SIZE_MAX;
598 entry->abi_align = g->builtin_types.entry_usize->abi_align;598 entry->abi_align = UINT32_MAX;
599 } else if (type_is_resolved(child_type, ResolveStatusZeroBitsKnown)) {599 } else if (type_is_resolved(child_type, ResolveStatusZeroBitsKnown)) {
600 if (type_has_bits(child_type)) {600 if (type_has_bits(child_type)) {
601 entry->abi_size = g->builtin_types.entry_usize->abi_size;601 entry->abi_size = g->builtin_types.entry_usize->abi_size;
...@@ -6474,7 +6474,21 @@ static Error resolve_pointer_zero_bits(CodeGen *g, ZigType *ty) {...@@ -6474,7 +6474,21 @@ static Error resolve_pointer_zero_bits(CodeGen *g, ZigType *ty) {
6474 }6474 }
6475 ty->data.pointer.resolve_loop_flag_zero_bits = true;6475 ty->data.pointer.resolve_loop_flag_zero_bits = true;
64766476
6477 ZigType *elem_type = ty->data.pointer.child_type;6477 ZigType *elem_type;
6478 InferredStructField *isf = ty->data.pointer.inferred_struct_field;
6479 if (isf != nullptr) {
6480 TypeStructField *field = find_struct_type_field(isf->inferred_struct_type, isf->field_name);
6481 assert(field != nullptr);
6482 if (field->is_comptime) {
6483 ty->abi_size = 0;
6484 ty->size_in_bits = 0;
6485 ty->abi_align = 0;
6486 return ErrorNone;
6487 }
6488 elem_type = field->type_entry;
6489 } else {
6490 elem_type = ty->data.pointer.child_type;
6491 }
64786492
6479 bool has_bits;6493 bool has_bits;
6480 if ((err = type_has_bits2(g, elem_type, &has_bits)))6494 if ((err = type_has_bits2(g, elem_type, &has_bits)))
src/codegen.cpp+6
...@@ -3120,8 +3120,14 @@ static LLVMValueRef ir_render_resize_slice(CodeGen *g, IrExecutableGen *executab...@@ -3120,8 +3120,14 @@ static LLVMValueRef ir_render_resize_slice(CodeGen *g, IrExecutableGen *executab
3120static LLVMValueRef ir_render_cast(CodeGen *g, IrExecutableGen *executable,3120static LLVMValueRef ir_render_cast(CodeGen *g, IrExecutableGen *executable,
3121 IrInstGenCast *cast_instruction)3121 IrInstGenCast *cast_instruction)
3122{3122{
3123 Error err;
3123 ZigType *actual_type = cast_instruction->value->value->type;3124 ZigType *actual_type = cast_instruction->value->value->type;
3124 ZigType *wanted_type = cast_instruction->base.value->type;3125 ZigType *wanted_type = cast_instruction->base.value->type;
3126 bool wanted_type_has_bits;
3127 if ((err = type_has_bits2(g, wanted_type, &wanted_type_has_bits)))
3128 codegen_report_errors_and_exit(g);
3129 if (!wanted_type_has_bits)
3130 return nullptr;
3125 LLVMValueRef expr_val = ir_llvm_value(g, cast_instruction->value);3131 LLVMValueRef expr_val = ir_llvm_value(g, cast_instruction->value);
3126 ir_assert(expr_val, &cast_instruction->base);3132 ir_assert(expr_val, &cast_instruction->base);
31273133
src/ir.cpp+58-34
...@@ -880,7 +880,6 @@ static bool types_have_same_zig_comptime_repr(CodeGen *codegen, ZigType *expecte...@@ -880,7 +880,6 @@ static bool types_have_same_zig_comptime_repr(CodeGen *codegen, ZigType *expecte
880 case ZigTypeIdComptimeFloat:880 case ZigTypeIdComptimeFloat:
881 case ZigTypeIdComptimeInt:881 case ZigTypeIdComptimeInt:
882 case ZigTypeIdEnumLiteral:882 case ZigTypeIdEnumLiteral:
883 case ZigTypeIdPointer:
884 case ZigTypeIdUndefined:883 case ZigTypeIdUndefined:
885 case ZigTypeIdNull:884 case ZigTypeIdNull:
886 case ZigTypeIdBoundFn:885 case ZigTypeIdBoundFn:
...@@ -889,6 +888,8 @@ static bool types_have_same_zig_comptime_repr(CodeGen *codegen, ZigType *expecte...@@ -889,6 +888,8 @@ static bool types_have_same_zig_comptime_repr(CodeGen *codegen, ZigType *expecte
889 case ZigTypeIdAnyFrame:888 case ZigTypeIdAnyFrame:
890 case ZigTypeIdFn:889 case ZigTypeIdFn:
891 return true;890 return true;
891 case ZigTypeIdPointer:
892 return expected->data.pointer.inferred_struct_field == actual->data.pointer.inferred_struct_field;
892 case ZigTypeIdFloat:893 case ZigTypeIdFloat:
893 return expected->data.floating.bit_count == actual->data.floating.bit_count;894 return expected->data.floating.bit_count == actual->data.floating.bit_count;
894 case ZigTypeIdInt:895 case ZigTypeIdInt:
...@@ -7014,6 +7015,7 @@ static IrInstSrc *ir_gen_builtin_fn_call(IrBuilderSrc *irb, Scope *scope, AstNod...@@ -7014,6 +7015,7 @@ static IrInstSrc *ir_gen_builtin_fn_call(IrBuilderSrc *irb, Scope *scope, AstNod
7014 ResultLocBitCast *result_loc_bit_cast = allocate<ResultLocBitCast>(1);7015 ResultLocBitCast *result_loc_bit_cast = allocate<ResultLocBitCast>(1);
7015 result_loc_bit_cast->base.id = ResultLocIdBitCast;7016 result_loc_bit_cast->base.id = ResultLocIdBitCast;
7016 result_loc_bit_cast->base.source_instruction = dest_type;7017 result_loc_bit_cast->base.source_instruction = dest_type;
7018 result_loc_bit_cast->base.allow_write_through_const = result_loc->allow_write_through_const;
7017 ir_ref_instruction(dest_type, irb->current_basic_block);7019 ir_ref_instruction(dest_type, irb->current_basic_block);
7018 result_loc_bit_cast->parent = result_loc;7020 result_loc_bit_cast->parent = result_loc;
70197021
...@@ -13597,32 +13599,31 @@ static IrInstGen *ir_analyze_null_to_c_pointer(IrAnalyze *ira, IrInst *source_in...@@ -13597,32 +13599,31 @@ static IrInstGen *ir_analyze_null_to_c_pointer(IrAnalyze *ira, IrInst *source_in
13597 return result;13599 return result;
13598}13600}
1359913601
13600static IrInstGen *ir_get_ref(IrAnalyze *ira, IrInst* source_instruction, IrInstGen *value,13602static IrInstGen *ir_get_ref2(IrAnalyze *ira, IrInst* source_instruction, IrInstGen *value,
13601 bool is_const, bool is_volatile)13603 ZigType *elem_type, bool is_const, bool is_volatile)
13602{13604{
13603 Error err;13605 Error err;
1360413606
13605 if (type_is_invalid(value->value->type))13607 if (type_is_invalid(elem_type))
13606 return ira->codegen->invalid_inst_gen;13608 return ira->codegen->invalid_inst_gen;
1360713609
13608 if (instr_is_comptime(value)) {13610 if (instr_is_comptime(value)) {
13609 ZigValue *val = ir_resolve_const(ira, value, LazyOk);13611 ZigValue *val = ir_resolve_const(ira, value, LazyOk);
13610 if (!val)13612 if (!val)
13611 return ira->codegen->invalid_inst_gen;13613 return ira->codegen->invalid_inst_gen;
13612 return ir_get_const_ptr(ira, source_instruction, val, value->value->type,13614 return ir_get_const_ptr(ira, source_instruction, val, elem_type,
13613 ConstPtrMutComptimeConst, is_const, is_volatile, 0);13615 ConstPtrMutComptimeConst, is_const, is_volatile, 0);
13614 }13616 }
1361513617
13616 ZigType *ptr_type = get_pointer_to_type_extra(ira->codegen, value->value->type,13618 ZigType *ptr_type = get_pointer_to_type_extra(ira->codegen, elem_type,
13617 is_const, is_volatile, PtrLenSingle, 0, 0, 0, false);13619 is_const, is_volatile, PtrLenSingle, 0, 0, 0, false);
1361813620
13619 if ((err = type_resolve(ira->codegen, ptr_type, ResolveStatusZeroBitsKnown)))13621 if ((err = type_resolve(ira->codegen, ptr_type, ResolveStatusZeroBitsKnown)))
13620 return ira->codegen->invalid_inst_gen;13622 return ira->codegen->invalid_inst_gen;
1362113623
13622 IrInstGen *result_loc;13624 IrInstGen *result_loc;
13623 if (type_has_bits(ptr_type) && !handle_is_ptr(value->value->type)) {13625 if (type_has_bits(ptr_type) && !handle_is_ptr(elem_type)) {
13624 result_loc = ir_resolve_result(ira, source_instruction, no_result_loc(), value->value->type,13626 result_loc = ir_resolve_result(ira, source_instruction, no_result_loc(), elem_type, nullptr, true, true);
13625 nullptr, true, true);
13626 } else {13627 } else {
13627 result_loc = nullptr;13628 result_loc = nullptr;
13628 }13629 }
...@@ -13632,6 +13633,12 @@ static IrInstGen *ir_get_ref(IrAnalyze *ira, IrInst* source_instruction, IrInstG...@@ -13632,6 +13633,12 @@ static IrInstGen *ir_get_ref(IrAnalyze *ira, IrInst* source_instruction, IrInstG
13632 return new_instruction;13633 return new_instruction;
13633}13634}
1363413635
13636static IrInstGen *ir_get_ref(IrAnalyze *ira, IrInst* source_instruction, IrInstGen *value,
13637 bool is_const, bool is_volatile)
13638{
13639 return ir_get_ref2(ira, source_instruction, value, value->value->type, is_const, is_volatile);
13640}
13641
13635static ZigType *ir_resolve_union_tag_type(IrAnalyze *ira, AstNode *source_node, ZigType *union_type) {13642static ZigType *ir_resolve_union_tag_type(IrAnalyze *ira, AstNode *source_node, ZigType *union_type) {
13636 assert(union_type->id == ZigTypeIdUnion);13643 assert(union_type->id == ZigTypeIdUnion);
1363713644
...@@ -18204,6 +18211,21 @@ static IrInstGen *ir_resolve_no_result_loc(IrAnalyze *ira, IrInst *suspend_sourc...@@ -18204,6 +18211,21 @@ static IrInstGen *ir_resolve_no_result_loc(IrAnalyze *ira, IrInst *suspend_sourc
18204 return result_loc->resolved_loc;18211 return result_loc->resolved_loc;
18205}18212}
1820618213
18214static bool result_loc_is_discard(ResultLoc *result_loc_pass1) {
18215 if (result_loc_pass1->id == ResultLocIdInstruction &&
18216 result_loc_pass1->source_instruction->id == IrInstSrcIdConst)
18217 {
18218 IrInstSrcConst *const_inst = reinterpret_cast<IrInstSrcConst *>(result_loc_pass1->source_instruction);
18219 if (value_is_comptime(const_inst->value) &&
18220 const_inst->value->type->id == ZigTypeIdPointer &&
18221 const_inst->value->data.x_ptr.special == ConstPtrSpecialDiscard)
18222 {
18223 return true;
18224 }
18225 }
18226 return false;
18227}
18228
18207// when calling this function, at the callsite must check for result type noreturn and propagate it up18229// when calling this function, at the callsite must check for result type noreturn and propagate it up
18208static IrInstGen *ir_resolve_result_raw(IrAnalyze *ira, IrInst *suspend_source_instr,18230static IrInstGen *ir_resolve_result_raw(IrAnalyze *ira, IrInst *suspend_source_instr,
18209 ResultLoc *result_loc, ZigType *value_type, IrInstGen *value, bool force_runtime,18231 ResultLoc *result_loc, ZigType *value_type, IrInstGen *value, bool force_runtime,
...@@ -18494,13 +18516,7 @@ static IrInstGen *ir_resolve_result_raw(IrAnalyze *ira, IrInst *suspend_source_i...@@ -18494,13 +18516,7 @@ static IrInstGen *ir_resolve_result_raw(IrAnalyze *ira, IrInst *suspend_source_i
18494 assert(parent_ptr_type->id == ZigTypeIdPointer);18516 assert(parent_ptr_type->id == ZigTypeIdPointer);
18495 ZigType *child_type = parent_ptr_type->data.pointer.child_type;18517 ZigType *child_type = parent_ptr_type->data.pointer.child_type;
1849618518
18497 bool has_bits;18519 if (result_loc_is_discard(result_bit_cast->parent)) {
18498 if ((err = type_has_bits2(ira->codegen, child_type, &has_bits))) {
18499 return ira->codegen->invalid_inst_gen;
18500 }
18501
18502 // This happens when the bitCast result is assigned to _
18503 if (!has_bits) {
18504 assert(allow_discard);18520 assert(allow_discard);
18505 return parent_result_loc;18521 return parent_result_loc;
18506 }18522 }
...@@ -18531,16 +18547,8 @@ static IrInstGen *ir_resolve_result(IrAnalyze *ira, IrInst *suspend_source_instr...@@ -18531,16 +18547,8 @@ static IrInstGen *ir_resolve_result(IrAnalyze *ira, IrInst *suspend_source_instr
18531 bool allow_discard)18547 bool allow_discard)
18532{18548{
18533 Error err;18549 Error err;
18534 if (!allow_discard && result_loc_pass1->id == ResultLocIdInstruction &&18550 if (!allow_discard && result_loc_is_discard(result_loc_pass1)) {
18535 result_loc_pass1->source_instruction->id == IrInstSrcIdConst)18551 result_loc_pass1 = no_result_loc();
18536 {
18537 IrInstSrcConst *const_inst = reinterpret_cast<IrInstSrcConst *>(result_loc_pass1->source_instruction);
18538 if (value_is_comptime(const_inst->value) &&
18539 const_inst->value->type->id == ZigTypeIdPointer &&
18540 const_inst->value->data.x_ptr.special == ConstPtrSpecialDiscard)
18541 {
18542 result_loc_pass1 = no_result_loc();
18543 }
18544 }18552 }
18545 bool was_written = result_loc_pass1->written;18553 bool was_written = result_loc_pass1->written;
18546 IrInstGen *result_loc = ir_resolve_result_raw(ira, suspend_source_instr, result_loc_pass1, value_type,18554 IrInstGen *result_loc = ir_resolve_result_raw(ira, suspend_source_instr, result_loc_pass1, value_type,
...@@ -21062,7 +21070,7 @@ static IrInstGen *ir_analyze_struct_field_ptr(IrAnalyze *ira, IrInst* source_ins...@@ -21062,7 +21070,7 @@ static IrInstGen *ir_analyze_struct_field_ptr(IrAnalyze *ira, IrInst* source_ins
21062 IrInstGen *elem = ir_const(ira, source_instr, field_type);21070 IrInstGen *elem = ir_const(ira, source_instr, field_type);
21063 memoize_field_init_val(ira->codegen, struct_type, field);21071 memoize_field_init_val(ira->codegen, struct_type, field);
21064 copy_const_val(elem->value, field->init_val);21072 copy_const_val(elem->value, field->init_val);
21065 return ir_get_ref(ira, source_instr, elem, true, false);21073 return ir_get_ref2(ira, source_instr, elem, field_type, true, false);
21066 }21074 }
21067 switch (type_has_one_possible_value(ira->codegen, field_type)) {21075 switch (type_has_one_possible_value(ira->codegen, field_type)) {
21068 case OnePossibleValueInvalid:21076 case OnePossibleValueInvalid:
...@@ -27708,7 +27716,7 @@ static IrInstGen *ir_analyze_ptr_cast(IrAnalyze *ira, IrInst* source_instr, IrIn...@@ -27708,7 +27716,7 @@ static IrInstGen *ir_analyze_ptr_cast(IrAnalyze *ira, IrInst* source_instr, IrIn
27708 if ((err = type_resolve(ira->codegen, src_type, ResolveStatusZeroBitsKnown)))27716 if ((err = type_resolve(ira->codegen, src_type, ResolveStatusZeroBitsKnown)))
27709 return ira->codegen->invalid_inst_gen;27717 return ira->codegen->invalid_inst_gen;
2771027718
27711 if (type_has_bits(dest_type) && !type_has_bits(src_type)) {27719 if (type_has_bits(dest_type) && !type_has_bits(src_type) && safety_check_on) {
27712 ErrorMsg *msg = ir_add_error(ira, source_instr,27720 ErrorMsg *msg = ir_add_error(ira, source_instr,
27713 buf_sprintf("'%s' and '%s' do not have the same in-memory representation",27721 buf_sprintf("'%s' and '%s' do not have the same in-memory representation",
27714 buf_ptr(&src_type->name), buf_ptr(&dest_type->name)));27722 buf_ptr(&src_type->name), buf_ptr(&dest_type->name)));
...@@ -27723,7 +27731,7 @@ static IrInstGen *ir_analyze_ptr_cast(IrAnalyze *ira, IrInst* source_instr, IrIn...@@ -27723,7 +27731,7 @@ static IrInstGen *ir_analyze_ptr_cast(IrAnalyze *ira, IrInst* source_instr, IrIn
27723 bool dest_allows_addr_zero = ptr_allows_addr_zero(dest_type);27731 bool dest_allows_addr_zero = ptr_allows_addr_zero(dest_type);
27724 UndefAllowed is_undef_allowed = dest_allows_addr_zero ? UndefOk : UndefBad;27732 UndefAllowed is_undef_allowed = dest_allows_addr_zero ? UndefOk : UndefBad;
27725 ZigValue *val = ir_resolve_const(ira, ptr, is_undef_allowed);27733 ZigValue *val = ir_resolve_const(ira, ptr, is_undef_allowed);
27726 if (!val)27734 if (val == nullptr)
27727 return ira->codegen->invalid_inst_gen;27735 return ira->codegen->invalid_inst_gen;
2772827736
27729 if (value_is_comptime(val) && val->special != ConstValSpecialUndef) {27737 if (value_is_comptime(val) && val->special != ConstValSpecialUndef) {
...@@ -27738,15 +27746,31 @@ static IrInstGen *ir_analyze_ptr_cast(IrAnalyze *ira, IrInst* source_instr, IrIn...@@ -27738,15 +27746,31 @@ static IrInstGen *ir_analyze_ptr_cast(IrAnalyze *ira, IrInst* source_instr, IrIn
27738 }27746 }
2773927747
27740 IrInstGen *result;27748 IrInstGen *result;
27741 if (ptr->value->data.x_ptr.mut == ConstPtrMutInfer) {27749 if (val->data.x_ptr.mut == ConstPtrMutInfer) {
27742 result = ir_build_ptr_cast_gen(ira, source_instr, dest_type, ptr, safety_check_on);27750 result = ir_build_ptr_cast_gen(ira, source_instr, dest_type, ptr, safety_check_on);
27743
27744 if ((err = type_resolve(ira->codegen, dest_type, ResolveStatusZeroBitsKnown)))
27745 return ira->codegen->invalid_inst_gen;
27746 } else {27751 } else {
27747 result = ir_const(ira, source_instr, dest_type);27752 result = ir_const(ira, source_instr, dest_type);
27748 }27753 }
27749 copy_const_val(result->value, val);27754 InferredStructField *isf = (val->type->id == ZigTypeIdPointer) ?
27755 val->type->data.pointer.inferred_struct_field : nullptr;
27756 if (isf == nullptr) {
27757 copy_const_val(result->value, val);
27758 } else {
27759 // The destination value should have x_ptr struct pointing to underlying struct value
27760 result->value->data.x_ptr.mut = val->data.x_ptr.mut;
27761 TypeStructField *field = find_struct_type_field(isf->inferred_struct_type, isf->field_name);
27762 assert(field != nullptr);
27763 if (field->is_comptime) {
27764 result->value->data.x_ptr.special = ConstPtrSpecialRef;
27765 result->value->data.x_ptr.data.ref.pointee = field->init_val;
27766 } else {
27767 assert(val->data.x_ptr.special == ConstPtrSpecialRef);
27768 result->value->data.x_ptr.special = ConstPtrSpecialBaseStruct;
27769 result->value->data.x_ptr.data.base_struct.struct_val = val->data.x_ptr.data.ref.pointee;
27770 result->value->data.x_ptr.data.base_struct.field_index = field->src_index;
27771 }
27772 result->value->special = ConstValSpecialStatic;
27773 }
27750 result->value->type = dest_type;27774 result->value->type = dest_type;
2775127775
27752 // Keep the bigger alignment, it can only help-27776 // Keep the bigger alignment, it can only help-
test/stage1/behavior/bitcast.zig+9-8
...@@ -168,11 +168,12 @@ test "nested bitcast" {...@@ -168,11 +168,12 @@ test "nested bitcast" {
168 comptime S.foo(42);168 comptime S.foo(42);
169}169}
170170
171//test "bitcast passed as tuple element" {171test "bitcast passed as tuple element" {
172// const S = struct {172 const S = struct {
173// fn foo(args: var) void {173 fn foo(args: var) void {
174// expect(args[0] == 1.00000e-09);174 comptime expect(@TypeOf(args[0]) == f32);
175// }175 expect(args[0] == 12.34);
176// };176 }
177// S.foo(.{@bitCast(f32, @as(u32, 814313563))});177 };
178//}178 S.foo(.{@bitCast(f32, @as(u32, 0x414570A4))});
179}