authorgravatar for raulgrell@gmail.comraulgrell <raulgrell@gmail.com> 2018-08-27 16:37:37+01:00
committergravatar for raulgrell@gmail.comraulgrell <raulgrell@gmail.com> 2018-08-27 23:13:57+01:00
loge2a9f2ef988e6ff4ec9f943ead9285c67c56ffd7
treeb61d37c78a9281d55959af5bf6de6d6a5412087a
parentc48be3a742cd82a8007512bfe145374e4b3750be

Allow implicit cast from *T and [*]T to ?*c_void


2 files changed, 40 insertions(+), 4 deletions(-)

src/ir.cpp+16-4
...@@ -60,7 +60,7 @@ enum ConstCastResultId {...@@ -60,7 +60,7 @@ enum ConstCastResultId {
60 ConstCastResultIdType,60 ConstCastResultIdType,
61 ConstCastResultIdUnresolvedInferredErrSet,61 ConstCastResultIdUnresolvedInferredErrSet,
62 ConstCastResultIdAsyncAllocatorType,62 ConstCastResultIdAsyncAllocatorType,
63 ConstCastResultIdNullWrapPtr,63 ConstCastResultIdNullWrapPtr
64};64};
6565
66struct ConstCastOnly;66struct ConstCastOnly;
...@@ -8471,9 +8471,9 @@ static ConstCastOnly types_match_const_cast_only(IrAnalyze *ira, TypeTableEntry...@@ -8471,9 +8471,9 @@ static ConstCastOnly types_match_const_cast_only(IrAnalyze *ira, TypeTableEntry
8471 if (wanted_type == actual_type)8471 if (wanted_type == actual_type)
8472 return result;8472 return result;
84738473
8474 // * and [*] can do a const-cast-only to ?* and ?[*], respectively8474 // *T and [*]T may const-cast-only to ?*U and ?[*]U, respectively
8475 // but not if there is a mutable parent pointer8475 // but not if we want a mutable pointer
8476 // and not if the pointer is zero bits8476 // and not if the actual pointer has zero bits
8477 if (!wanted_is_mutable && wanted_type->id == TypeTableEntryIdOptional &&8477 if (!wanted_is_mutable && wanted_type->id == TypeTableEntryIdOptional &&
8478 wanted_type->data.maybe.child_type->id == TypeTableEntryIdPointer &&8478 wanted_type->data.maybe.child_type->id == TypeTableEntryIdPointer &&
8479 actual_type->id == TypeTableEntryIdPointer && type_has_bits(actual_type))8479 actual_type->id == TypeTableEntryIdPointer && type_has_bits(actual_type))
...@@ -8488,6 +8488,18 @@ static ConstCastOnly types_match_const_cast_only(IrAnalyze *ira, TypeTableEntry...@@ -8488,6 +8488,18 @@ static ConstCastOnly types_match_const_cast_only(IrAnalyze *ira, TypeTableEntry
8488 return result;8488 return result;
8489 }8489 }
84908490
8491 // *T and [*]T can always cast to ?*c_void
8492 if (wanted_type->id == TypeTableEntryIdPointer &&
8493 wanted_type->data.pointer.ptr_len == PtrLenSingle &&
8494 wanted_type->data.pointer.child_type == g->builtin_types.entry_c_void &&
8495 actual_type->id == TypeTableEntryIdPointer &&
8496 (!actual_type->data.pointer.is_const || wanted_type->data.pointer.is_const) &&
8497 (!actual_type->data.pointer.is_volatile || wanted_type->data.pointer.is_volatile))
8498 {
8499 assert(actual_type->data.pointer.alignment >= wanted_type->data.pointer.alignment);
8500 return result;
8501 }
8502
8491 // pointer const8503 // pointer const
8492 if (wanted_type->id == TypeTableEntryIdPointer && actual_type->id == TypeTableEntryIdPointer) {8504 if (wanted_type->id == TypeTableEntryIdPointer && actual_type->id == TypeTableEntryIdPointer) {
8493 ConstCastOnly child = types_match_const_cast_only(ira, wanted_type->data.pointer.child_type,8505 ConstCastOnly child = types_match_const_cast_only(ira, wanted_type->data.pointer.child_type,
test/cases/cast.zig+24
...@@ -495,4 +495,28 @@ test "implicit cast from *[N]T to ?[*]T" {...@@ -495,4 +495,28 @@ test "implicit cast from *[N]T to ?[*]T" {
495 x.?[0] = 8;495 x.?[0] = 8;
496 y[3] = 6;496 y[3] = 6;
497 assert(std.mem.eql(u16, x.?[0..4], y[0..4]));497 assert(std.mem.eql(u16, x.?[0..4], y[0..4]));
498}
499
500test "implicit cast from *T to ?*c_void" {
501 var a: u8 = 1;
502 incrementVoidPtrValue(&a);
503 std.debug.assert(a == 2);
504}
505
506fn incrementVoidPtrValue(value: ?*c_void) void {
507 @ptrCast(*u8, value.?).* += 1;
508}
509
510test "implicit cast from [*]T to ?*c_void" {
511 var a = []u8{3, 2, 1};
512 incrementVoidPtrArray(a[0..].ptr, 3);
513 std.debug.assert(std.mem.eql(u8, a, []u8{4, 3, 2}));
514}
515
516fn incrementVoidPtrArray(array: ?*c_void, len: usize) void {
517 var n: usize = 0;
518 while(n < len) : (n += 1) {
519 std.debug.warn("{}", n);
520 @ptrCast([*]u8, array.?)[n] += 1;
521 }
498}522}
\ No newline at end of file