authorgravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2020-03-26 12:34:16-04:00
committergravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2020-03-26 12:34:16-04:00
logddd98a7f10767e2bea43fb35405a9414a02ecbdf
tree51f769dadbca2a6736fb0f8ce42cfc68039bba3f
parentf7f563ea53cf58c772003a46624b87dad9c4311d
signaturelock-open Commit is signed but in an unrecognized format.

prevent ptr cast from forcing alignment resolution unnecessarily


3 files changed, 42 insertions(+), 22 deletions(-)

src/ir.cpp+24-20
......@@ -237,7 +237,8 @@ static void buf_write_value_bytes(CodeGen *codegen, uint8_t *buf, ZigValue *val)
237237static Error ir_read_const_ptr(IrAnalyze *ira, CodeGen *codegen, AstNode *source_node,
238238 ZigValue *out_val, ZigValue *ptr_val);
239239static IrInstGen *ir_analyze_ptr_cast(IrAnalyze *ira, IrInst* source_instr, IrInstGen *ptr,
240 IrInst *ptr_src, ZigType *dest_type, IrInst *dest_type_src, bool safety_check_on);
240 IrInst *ptr_src, ZigType *dest_type, IrInst *dest_type_src, bool safety_check_on,
241 bool keep_bigger_alignment);
241242static ZigValue *ir_resolve_const(IrAnalyze *ira, IrInstGen *value, UndefAllowed undef_allowed);
242243static Error resolve_ptr_align(IrAnalyze *ira, ZigType *ty, uint32_t *result_align);
243244static IrInstGen *ir_analyze_int_to_ptr(IrAnalyze *ira, IrInst* source_instr, IrInstGen *target,
......@@ -15066,7 +15067,8 @@ static IrInstGen *ir_analyze_cast(IrAnalyze *ira, IrInst *source_instr,
1506615067 dest_ptr_type = wanted_type->data.maybe.child_type;
1506715068 }
1506815069 if (dest_ptr_type != nullptr) {
15069 return ir_analyze_ptr_cast(ira, source_instr, value, source_instr, wanted_type, source_instr, true);
15070 return ir_analyze_ptr_cast(ira, source_instr, value, source_instr, wanted_type, source_instr, true,
15071 false);
1507015072 }
1507115073 }
1507215074
......@@ -15108,7 +15110,7 @@ static IrInstGen *ir_analyze_cast(IrAnalyze *ira, IrInst *source_instr,
1510815110 actual_type->data.pointer.child_type, source_node,
1510915111 !wanted_type->data.pointer.is_const).id == ConstCastResultIdOk)
1511015112 {
15111 return ir_analyze_ptr_cast(ira, source_instr, value, source_instr, wanted_type, source_instr, true);
15113 return ir_analyze_ptr_cast(ira, source_instr, value, source_instr, wanted_type, source_instr, true, false);
1511215114 }
1511315115
1511415116 // cast from integer to C pointer
......@@ -18576,7 +18578,7 @@ static IrInstGen *ir_resolve_result_raw(IrAnalyze *ira, IrInst *suspend_source_i
1857618578
1857718579 result_loc->written = true;
1857818580 result_loc->resolved_loc = ir_analyze_ptr_cast(ira, suspend_source_instr, parent_result_loc,
18579 &parent_result_loc->base, ptr_type, &result_cast->base.source_instruction->base, false);
18581 &parent_result_loc->base, ptr_type, &result_cast->base.source_instruction->base, false, false);
1858018582 return result_loc->resolved_loc;
1858118583 }
1858218584 case ResultLocIdBitCast: {
......@@ -18670,7 +18672,7 @@ static IrInstGen *ir_resolve_result_raw(IrAnalyze *ira, IrInst *suspend_source_i
1867018672
1867118673 result_loc->written = true;
1867218674 result_loc->resolved_loc = ir_analyze_ptr_cast(ira, suspend_source_instr, parent_result_loc,
18673 &parent_result_loc->base, ptr_type, &result_bit_cast->base.source_instruction->base, false);
18675 &parent_result_loc->base, ptr_type, &result_bit_cast->base.source_instruction->base, false, false);
1867418676 return result_loc->resolved_loc;
1867518677 }
1867618678 }
......@@ -22947,7 +22949,7 @@ static IrInstGen *ir_analyze_instruction_switch_var(IrAnalyze *ira, IrInstSrcSwi
2294722949 ref_type->data.pointer.bit_offset_in_host, ref_type->data.pointer.host_int_bytes,
2294822950 ref_type->data.pointer.allow_zero);
2294922951 return ir_analyze_ptr_cast(ira, &instruction->base.base, target_value_ptr,
22950 &instruction->target_value_ptr->base, new_target_value_ptr_type, &instruction->base.base, false);
22952 &instruction->target_value_ptr->base, new_target_value_ptr_type, &instruction->base.base, false, false);
2295122953 } else {
2295222954 ir_add_error(ira, &instruction->base.base,
2295322955 buf_sprintf("switch on type '%s' provides no expression parameter", buf_ptr(&target_type->name)));
......@@ -23030,7 +23032,7 @@ static IrInstGen *ir_analyze_instruction_switch_else_var(IrAnalyze *ira,
2303023032 ref_type->data.pointer.bit_offset_in_host, ref_type->data.pointer.host_int_bytes,
2303123033 ref_type->data.pointer.allow_zero);
2303223034 return ir_analyze_ptr_cast(ira, &instruction->base.base, target_value_ptr,
23033 &instruction->target_value_ptr->base, new_target_value_ptr_type, &instruction->base.base, false);
23035 &instruction->target_value_ptr->base, new_target_value_ptr_type, &instruction->base.base, false, false);
2303423036 }
2303523037
2303623038 return target_value_ptr;
......@@ -27814,7 +27816,8 @@ static IrInstGen *ir_align_cast(IrAnalyze *ira, IrInstGen *target, uint32_t alig
2781427816}
2781527817
2781627818static IrInstGen *ir_analyze_ptr_cast(IrAnalyze *ira, IrInst* source_instr, IrInstGen *ptr,
27817 IrInst *ptr_src, ZigType *dest_type, IrInst *dest_type_src, bool safety_check_on)
27819 IrInst *ptr_src, ZigType *dest_type, IrInst *dest_type_src, bool safety_check_on,
27820 bool keep_bigger_alignment)
2781827821{
2781927822 Error err;
2782027823
......@@ -27853,14 +27856,16 @@ static IrInstGen *ir_analyze_ptr_cast(IrAnalyze *ira, IrInst* source_instr, IrIn
2785327856 ir_add_error(ira, source_instr, buf_sprintf("cast discards const qualifier"));
2785427857 return ira->codegen->invalid_inst_gen;
2785527858 }
27856 uint32_t src_align_bytes;
27857 if ((err = resolve_ptr_align(ira, src_type, &src_align_bytes)))
27858 return ira->codegen->invalid_inst_gen;
27859
2786027859 uint32_t dest_align_bytes;
2786127860 if ((err = resolve_ptr_align(ira, dest_type, &dest_align_bytes)))
2786227861 return ira->codegen->invalid_inst_gen;
2786327862
27863 uint32_t src_align_bytes = 0;
27864 if (keep_bigger_alignment || dest_align_bytes != 1) {
27865 if ((err = resolve_ptr_align(ira, src_type, &src_align_bytes)))
27866 return ira->codegen->invalid_inst_gen;
27867 }
27868
2786427869 if ((err = type_resolve(ira->codegen, dest_type, ResolveStatusZeroBitsKnown)))
2786527870 return ira->codegen->invalid_inst_gen;
2786627871
......@@ -27935,16 +27940,15 @@ static IrInstGen *ir_analyze_ptr_cast(IrAnalyze *ira, IrInst* source_instr, IrIn
2793527940 }
2793627941 result->value->type = dest_type;
2793727942
27938 // Keep the bigger alignment, it can only help-
27939 // unless the target is zero bits.
27940 if (src_align_bytes > dest_align_bytes && type_has_bits(ira->codegen, dest_type)) {
27943 // Keep the bigger alignment, it can only help- unless the target is zero bits.
27944 if (keep_bigger_alignment && src_align_bytes > dest_align_bytes && type_has_bits(ira->codegen, dest_type)) {
2794127945 result = ir_align_cast(ira, result, src_align_bytes, false);
2794227946 }
2794327947
2794427948 return result;
2794527949 }
2794627950
27947 if (dest_align_bytes > src_align_bytes) {
27951 if (src_align_bytes != 0 && dest_align_bytes > src_align_bytes) {
2794827952 ErrorMsg *msg = ir_add_error(ira, source_instr, buf_sprintf("cast increases pointer alignment"));
2794927953 add_error_note(ira->codegen, msg, ptr_src->source_node,
2795027954 buf_sprintf("'%s' has alignment %" PRIu32, buf_ptr(&src_type->name), src_align_bytes));
......@@ -27955,10 +27959,9 @@ static IrInstGen *ir_analyze_ptr_cast(IrAnalyze *ira, IrInst* source_instr, IrIn
2795527959
2795627960 IrInstGen *casted_ptr = ir_build_ptr_cast_gen(ira, source_instr, dest_type, ptr, safety_check_on);
2795727961
27958 // Keep the bigger alignment, it can only help-
27959 // unless the target is zero bits.
27962 // Keep the bigger alignment, it can only help- unless the target is zero bits.
2796027963 IrInstGen *result;
27961 if (src_align_bytes > dest_align_bytes && type_has_bits(ira->codegen, dest_type)) {
27964 if (keep_bigger_alignment && src_align_bytes > dest_align_bytes && type_has_bits(ira->codegen, dest_type)) {
2796227965 result = ir_align_cast(ira, casted_ptr, src_align_bytes, false);
2796327966 if (type_is_invalid(result->value->type))
2796427967 return ira->codegen->invalid_inst_gen;
......@@ -27979,8 +27982,9 @@ static IrInstGen *ir_analyze_instruction_ptr_cast(IrAnalyze *ira, IrInstSrcPtrCa
2797927982 if (type_is_invalid(src_type))
2798027983 return ira->codegen->invalid_inst_gen;
2798127984
27985 bool keep_bigger_alignment = true;
2798227986 return ir_analyze_ptr_cast(ira, &instruction->base.base, ptr, &instruction->ptr->base,
27983 dest_type, &dest_type_value->base, instruction->safety_check_on);
27987 dest_type, &dest_type_value->base, instruction->safety_check_on, keep_bigger_alignment);
2798427988}
2798527989
2798627990static void buf_write_value_bytes_array(CodeGen *codegen, uint8_t *buf, ZigValue *val, size_t len) {
test/stage1/behavior/async_fn.zig+16
......@@ -1547,3 +1547,19 @@ test "noasync on function calls" {
15471547 expectEqual(@as(i32, 42), noasync S1.c().b);
15481548 expectEqual(@as(i32, 42), (try noasync S1.d()).b);
15491549}
1550
1551test "avoid forcing frame alignment resolution implicit cast to *c_void" {
1552 const S = struct {
1553 var x: ?*c_void = null;
1554
1555 fn foo() bool {
1556 suspend {
1557 x = @frame();
1558 }
1559 return true;
1560 }
1561 };
1562 var frame = async S.foo();
1563 resume @ptrCast(anyframe->bool, @alignCast(@alignOf(@Frame(S.foo)), S.x));
1564 expect(noasync await frame);
1565}
test/stage1/behavior/cast.zig+2-2
......@@ -462,10 +462,10 @@ fn foobar(func: PFN_void) void {
462462
463463test "implicit ptr to *c_void" {
464464 var a: u32 = 1;
465 var ptr: *c_void = &a;
465 var ptr: *align(@alignOf(u32)) c_void = &a;
466466 var b: *u32 = @ptrCast(*u32, ptr);
467467 expect(b.* == 1);
468 var ptr2: ?*c_void = &a;
468 var ptr2: ?*align(@alignOf(u32)) c_void = &a;
469469 var c: *u32 = @ptrCast(*u32, ptr2.?);
470470 expect(c.* == 1);
471471}