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
signature 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
593593 }
594594
595595 if (inferred_struct_field != nullptr) {
596 entry->abi_size = g->builtin_types.entry_usize->abi_size;
597 entry->size_in_bits = g->builtin_types.entry_usize->size_in_bits;
598 entry->abi_align = g->builtin_types.entry_usize->abi_align;
596 entry->abi_size = SIZE_MAX;
597 entry->size_in_bits = SIZE_MAX;
598 entry->abi_align = UINT32_MAX;
599599 } else if (type_is_resolved(child_type, ResolveStatusZeroBitsKnown)) {
600600 if (type_has_bits(child_type)) {
601601 entry->abi_size = g->builtin_types.entry_usize->abi_size;
......@@ -6474,7 +6474,21 @@ static Error resolve_pointer_zero_bits(CodeGen *g, ZigType *ty) {
64746474 }
64756475 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
64796493 bool has_bits;
64806494 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
31203120static LLVMValueRef ir_render_cast(CodeGen *g, IrExecutableGen *executable,
31213121 IrInstGenCast *cast_instruction)
31223122{
3123 Error err;
31233124 ZigType *actual_type = cast_instruction->value->value->type;
31243125 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;
31253131 LLVMValueRef expr_val = ir_llvm_value(g, cast_instruction->value);
31263132 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
880880 case ZigTypeIdComptimeFloat:
881881 case ZigTypeIdComptimeInt:
882882 case ZigTypeIdEnumLiteral:
883 case ZigTypeIdPointer:
884883 case ZigTypeIdUndefined:
885884 case ZigTypeIdNull:
886885 case ZigTypeIdBoundFn:
......@@ -889,6 +888,8 @@ static bool types_have_same_zig_comptime_repr(CodeGen *codegen, ZigType *expecte
889888 case ZigTypeIdAnyFrame:
890889 case ZigTypeIdFn:
891890 return true;
891 case ZigTypeIdPointer:
892 return expected->data.pointer.inferred_struct_field == actual->data.pointer.inferred_struct_field;
892893 case ZigTypeIdFloat:
893894 return expected->data.floating.bit_count == actual->data.floating.bit_count;
894895 case ZigTypeIdInt:
......@@ -7014,6 +7015,7 @@ static IrInstSrc *ir_gen_builtin_fn_call(IrBuilderSrc *irb, Scope *scope, AstNod
70147015 ResultLocBitCast *result_loc_bit_cast = allocate<ResultLocBitCast>(1);
70157016 result_loc_bit_cast->base.id = ResultLocIdBitCast;
70167017 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;
70177019 ir_ref_instruction(dest_type, irb->current_basic_block);
70187020 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
1359713599 return result;
1359813600}
1359913601
13600static IrInstGen *ir_get_ref(IrAnalyze *ira, IrInst* source_instruction, IrInstGen *value,
13601 bool is_const, bool is_volatile)
13602static IrInstGen *ir_get_ref2(IrAnalyze *ira, IrInst* source_instruction, IrInstGen *value,
13603 ZigType *elem_type, bool is_const, bool is_volatile)
1360213604{
1360313605 Error err;
1360413606
13605 if (type_is_invalid(value->value->type))
13607 if (type_is_invalid(elem_type))
1360613608 return ira->codegen->invalid_inst_gen;
1360713609
1360813610 if (instr_is_comptime(value)) {
1360913611 ZigValue *val = ir_resolve_const(ira, value, LazyOk);
1361013612 if (!val)
1361113613 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,
1361313615 ConstPtrMutComptimeConst, is_const, is_volatile, 0);
1361413616 }
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,
1361713619 is_const, is_volatile, PtrLenSingle, 0, 0, 0, false);
1361813620
1361913621 if ((err = type_resolve(ira->codegen, ptr_type, ResolveStatusZeroBitsKnown)))
1362013622 return ira->codegen->invalid_inst_gen;
1362113623
1362213624 IrInstGen *result_loc;
13623 if (type_has_bits(ptr_type) && !handle_is_ptr(value->value->type)) {
13624 result_loc = ir_resolve_result(ira, source_instruction, no_result_loc(), value->value->type,
13625 nullptr, true, true);
13625 if (type_has_bits(ptr_type) && !handle_is_ptr(elem_type)) {
13626 result_loc = ir_resolve_result(ira, source_instruction, no_result_loc(), elem_type, nullptr, true, true);
1362613627 } else {
1362713628 result_loc = nullptr;
1362813629 }
......@@ -13632,6 +13633,12 @@ static IrInstGen *ir_get_ref(IrAnalyze *ira, IrInst* source_instruction, IrInstG
1363213633 return new_instruction;
1363313634}
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
1363513642static ZigType *ir_resolve_union_tag_type(IrAnalyze *ira, AstNode *source_node, ZigType *union_type) {
1363613643 assert(union_type->id == ZigTypeIdUnion);
1363713644
......@@ -18204,6 +18211,21 @@ static IrInstGen *ir_resolve_no_result_loc(IrAnalyze *ira, IrInst *suspend_sourc
1820418211 return result_loc->resolved_loc;
1820518212}
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
1820718229// when calling this function, at the callsite must check for result type noreturn and propagate it up
1820818230static IrInstGen *ir_resolve_result_raw(IrAnalyze *ira, IrInst *suspend_source_instr,
1820918231 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
1849418516 assert(parent_ptr_type->id == ZigTypeIdPointer);
1849518517 ZigType *child_type = parent_ptr_type->data.pointer.child_type;
1849618518
18497 bool has_bits;
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) {
18519 if (result_loc_is_discard(result_bit_cast->parent)) {
1850418520 assert(allow_discard);
1850518521 return parent_result_loc;
1850618522 }
......@@ -18531,16 +18547,8 @@ static IrInstGen *ir_resolve_result(IrAnalyze *ira, IrInst *suspend_source_instr
1853118547 bool allow_discard)
1853218548{
1853318549 Error err;
18534 if (!allow_discard && result_loc_pass1->id == ResultLocIdInstruction &&
18535 result_loc_pass1->source_instruction->id == IrInstSrcIdConst)
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 }
18550 if (!allow_discard && result_loc_is_discard(result_loc_pass1)) {
18551 result_loc_pass1 = no_result_loc();
1854418552 }
1854518553 bool was_written = result_loc_pass1->written;
1854618554 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
2106221070 IrInstGen *elem = ir_const(ira, source_instr, field_type);
2106321071 memoize_field_init_val(ira->codegen, struct_type, field);
2106421072 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);
2106621074 }
2106721075 switch (type_has_one_possible_value(ira->codegen, field_type)) {
2106821076 case OnePossibleValueInvalid:
......@@ -27708,7 +27716,7 @@ static IrInstGen *ir_analyze_ptr_cast(IrAnalyze *ira, IrInst* source_instr, IrIn
2770827716 if ((err = type_resolve(ira->codegen, src_type, ResolveStatusZeroBitsKnown)))
2770927717 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) {
2771227720 ErrorMsg *msg = ir_add_error(ira, source_instr,
2771327721 buf_sprintf("'%s' and '%s' do not have the same in-memory representation",
2771427722 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
2772327731 bool dest_allows_addr_zero = ptr_allows_addr_zero(dest_type);
2772427732 UndefAllowed is_undef_allowed = dest_allows_addr_zero ? UndefOk : UndefBad;
2772527733 ZigValue *val = ir_resolve_const(ira, ptr, is_undef_allowed);
27726 if (!val)
27734 if (val == nullptr)
2772727735 return ira->codegen->invalid_inst_gen;
2772827736
2772927737 if (value_is_comptime(val) && val->special != ConstValSpecialUndef) {
......@@ -27738,15 +27746,31 @@ static IrInstGen *ir_analyze_ptr_cast(IrAnalyze *ira, IrInst* source_instr, IrIn
2773827746 }
2773927747
2774027748 IrInstGen *result;
27741 if (ptr->value->data.x_ptr.mut == ConstPtrMutInfer) {
27749 if (val->data.x_ptr.mut == ConstPtrMutInfer) {
2774227750 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;
2774627751 } else {
2774727752 result = ir_const(ira, source_instr, dest_type);
2774827753 }
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 }
2775027774 result->value->type = dest_type;
2775127775
2775227776 // Keep the bigger alignment, it can only help-
test/stage1/behavior/bitcast.zig+9-8
......@@ -168,11 +168,12 @@ test "nested bitcast" {
168168 comptime S.foo(42);
169169}
170170
171//test "bitcast passed as tuple element" {
172// const S = struct {
173// fn foo(args: var) void {
174// expect(args[0] == 1.00000e-09);
175// }
176// };
177// S.foo(.{@bitCast(f32, @as(u32, 814313563))});
178//}
171test "bitcast passed as tuple element" {
172 const S = struct {
173 fn foo(args: var) void {
174 comptime expect(@TypeOf(args[0]) == f32);
175 expect(args[0] == 12.34);
176 }
177 };
178 S.foo(.{@bitCast(f32, @as(u32, 0x414570A4))});
179}