mirror of
https://github.com/ziglang/zig.git
synced 2024-11-15 00:26:57 +00:00
parent
fb91483e48
commit
541b3e3a31
@ -1560,7 +1560,7 @@ fn parseInternal(
|
||||
}
|
||||
}
|
||||
if (field.is_comptime) {
|
||||
if (!try parsesTo(field.field_type, @ptrCast(*const field.field_type, field.default_value.?).*, tokens, child_options)) {
|
||||
if (!try parsesTo(field.field_type, @ptrCast(*align(1) const field.field_type, field.default_value.?).*, tokens, child_options)) {
|
||||
return error.UnexpectedValue;
|
||||
}
|
||||
} else {
|
||||
@ -1587,7 +1587,7 @@ fn parseInternal(
|
||||
if (!fields_seen[i]) {
|
||||
if (field.default_value) |default_ptr| {
|
||||
if (!field.is_comptime) {
|
||||
const default = @ptrCast(*const field.field_type, default_ptr).*;
|
||||
const default = @ptrCast(*align(1) const field.field_type, default_ptr).*;
|
||||
@field(r, field.name) = default;
|
||||
}
|
||||
} else {
|
||||
@ -1667,7 +1667,7 @@ fn parseInternal(
|
||||
}
|
||||
|
||||
if (ptrInfo.sentinel) |some| {
|
||||
const sentinel_value = @ptrCast(*const ptrInfo.child, some).*;
|
||||
const sentinel_value = @ptrCast(*align(1) const ptrInfo.child, some).*;
|
||||
try arraylist.append(sentinel_value);
|
||||
const output = arraylist.toOwnedSlice();
|
||||
return output[0 .. output.len - 1 :sentinel_value];
|
||||
|
@ -297,7 +297,7 @@ pub fn zeroes(comptime T: type) T {
|
||||
},
|
||||
.Array => |info| {
|
||||
if (info.sentinel) |sentinel_ptr| {
|
||||
const sentinel = @ptrCast(*const info.child, sentinel_ptr).*;
|
||||
const sentinel = @ptrCast(*align(1) const info.child, sentinel_ptr).*;
|
||||
return [_:sentinel]info.child{zeroes(info.child)} ** info.len;
|
||||
}
|
||||
return [_]info.child{zeroes(info.child)} ** info.len;
|
||||
@ -443,7 +443,7 @@ pub fn zeroInit(comptime T: type, init: anytype) T {
|
||||
|
||||
inline for (struct_info.fields) |field| {
|
||||
if (field.default_value) |default_value_ptr| {
|
||||
const default_value = @ptrCast(*const field.field_type, default_value_ptr).*;
|
||||
const default_value = @ptrCast(*align(1) const field.field_type, default_value_ptr).*;
|
||||
@field(value, field.name) = default_value;
|
||||
}
|
||||
}
|
||||
@ -687,7 +687,7 @@ pub fn span(ptr: anytype) Span(@TypeOf(ptr)) {
|
||||
const l = len(ptr);
|
||||
const ptr_info = @typeInfo(Result).Pointer;
|
||||
if (ptr_info.sentinel) |s_ptr| {
|
||||
const s = @ptrCast(*const ptr_info.child, s_ptr).*;
|
||||
const s = @ptrCast(*align(1) const ptr_info.child, s_ptr).*;
|
||||
return ptr[0..l :s];
|
||||
} else {
|
||||
return ptr[0..l];
|
||||
@ -719,7 +719,7 @@ fn SliceTo(comptime T: type, comptime end: meta.Elem(T)) type {
|
||||
// to find the value searched for, which is only the case if it matches
|
||||
// the sentinel of the type passed.
|
||||
if (array_info.sentinel) |sentinel_ptr| {
|
||||
const sentinel = @ptrCast(*const array_info.child, sentinel_ptr).*;
|
||||
const sentinel = @ptrCast(*align(1) const array_info.child, sentinel_ptr).*;
|
||||
if (end == sentinel) {
|
||||
new_ptr_info.sentinel = &end;
|
||||
} else {
|
||||
@ -734,7 +734,7 @@ fn SliceTo(comptime T: type, comptime end: meta.Elem(T)) type {
|
||||
// to find the value searched for, which is only the case if it matches
|
||||
// the sentinel of the type passed.
|
||||
if (ptr_info.sentinel) |sentinel_ptr| {
|
||||
const sentinel = @ptrCast(*const ptr_info.child, sentinel_ptr).*;
|
||||
const sentinel = @ptrCast(*align(1) const ptr_info.child, sentinel_ptr).*;
|
||||
if (end == sentinel) {
|
||||
new_ptr_info.sentinel = &end;
|
||||
} else {
|
||||
@ -772,7 +772,7 @@ pub fn sliceTo(ptr: anytype, comptime end: meta.Elem(@TypeOf(ptr))) SliceTo(@Typ
|
||||
const length = lenSliceTo(ptr, end);
|
||||
const ptr_info = @typeInfo(Result).Pointer;
|
||||
if (ptr_info.sentinel) |s_ptr| {
|
||||
const s = @ptrCast(*const ptr_info.child, s_ptr).*;
|
||||
const s = @ptrCast(*align(1) const ptr_info.child, s_ptr).*;
|
||||
return ptr[0..length :s];
|
||||
} else {
|
||||
return ptr[0..length];
|
||||
@ -825,7 +825,7 @@ fn lenSliceTo(ptr: anytype, comptime end: meta.Elem(@TypeOf(ptr))) usize {
|
||||
.One => switch (@typeInfo(ptr_info.child)) {
|
||||
.Array => |array_info| {
|
||||
if (array_info.sentinel) |sentinel_ptr| {
|
||||
const sentinel = @ptrCast(*const array_info.child, sentinel_ptr).*;
|
||||
const sentinel = @ptrCast(*align(1) const array_info.child, sentinel_ptr).*;
|
||||
if (sentinel == end) {
|
||||
return indexOfSentinel(array_info.child, end, ptr);
|
||||
}
|
||||
@ -835,7 +835,7 @@ fn lenSliceTo(ptr: anytype, comptime end: meta.Elem(@TypeOf(ptr))) usize {
|
||||
else => {},
|
||||
},
|
||||
.Many => if (ptr_info.sentinel) |sentinel_ptr| {
|
||||
const sentinel = @ptrCast(*const ptr_info.child, sentinel_ptr).*;
|
||||
const sentinel = @ptrCast(*align(1) const ptr_info.child, sentinel_ptr).*;
|
||||
// We may be looking for something other than the sentinel,
|
||||
// but iterating past the sentinel would be a bug so we need
|
||||
// to check for both.
|
||||
@ -849,7 +849,7 @@ fn lenSliceTo(ptr: anytype, comptime end: meta.Elem(@TypeOf(ptr))) usize {
|
||||
},
|
||||
.Slice => {
|
||||
if (ptr_info.sentinel) |sentinel_ptr| {
|
||||
const sentinel = @ptrCast(*const ptr_info.child, sentinel_ptr).*;
|
||||
const sentinel = @ptrCast(*align(1) const ptr_info.child, sentinel_ptr).*;
|
||||
if (sentinel == end) {
|
||||
return indexOfSentinel(ptr_info.child, sentinel, ptr);
|
||||
}
|
||||
@ -911,7 +911,7 @@ pub fn len(value: anytype) usize {
|
||||
.Many => {
|
||||
const sentinel_ptr = info.sentinel orelse
|
||||
@compileError("length of pointer with no sentinel");
|
||||
const sentinel = @ptrCast(*const info.child, sentinel_ptr).*;
|
||||
const sentinel = @ptrCast(*align(1) const info.child, sentinel_ptr).*;
|
||||
return indexOfSentinel(info.child, sentinel, value);
|
||||
},
|
||||
.C => {
|
||||
@ -2882,7 +2882,8 @@ fn AsBytesReturnType(comptime P: type) type {
|
||||
/// Given a pointer to a single item, returns a slice of the underlying bytes, preserving pointer attributes.
|
||||
pub fn asBytes(ptr: anytype) AsBytesReturnType(@TypeOf(ptr)) {
|
||||
const P = @TypeOf(ptr);
|
||||
return @ptrCast(AsBytesReturnType(P), ptr);
|
||||
const T = AsBytesReturnType(P);
|
||||
return @ptrCast(T, @alignCast(meta.alignment(T), ptr));
|
||||
}
|
||||
|
||||
test "asBytes" {
|
||||
|
@ -204,12 +204,12 @@ pub fn sentinel(comptime T: type) ?Elem(T) {
|
||||
switch (info.size) {
|
||||
.Many, .Slice => {
|
||||
const sentinel_ptr = info.sentinel orelse return null;
|
||||
return @ptrCast(*const info.child, sentinel_ptr).*;
|
||||
return @ptrCast(*align(1) const info.child, sentinel_ptr).*;
|
||||
},
|
||||
.One => switch (@typeInfo(info.child)) {
|
||||
.Array => |array_info| {
|
||||
const sentinel_ptr = array_info.sentinel orelse return null;
|
||||
return @ptrCast(*const array_info.child, sentinel_ptr).*;
|
||||
return @ptrCast(*align(1) const array_info.child, sentinel_ptr).*;
|
||||
},
|
||||
else => {},
|
||||
},
|
||||
|
@ -888,7 +888,7 @@ else
|
||||
const vdso_clock_gettime_ty = if (builtin.zig_backend == .stage1)
|
||||
fn (i32, *timespec) callconv(.C) usize
|
||||
else
|
||||
*const fn (i32, *timespec) callconv(.C) usize;
|
||||
*align(1) const fn (i32, *timespec) callconv(.C) usize;
|
||||
|
||||
pub fn clock_gettime(clk_id: i32, tp: *timespec) usize {
|
||||
if (@hasDecl(VDSO, "CGT_SYM")) {
|
||||
|
@ -193,7 +193,7 @@ pub fn sizeof(target: anytype) usize {
|
||||
const array_info = @typeInfo(ptr.child).Array;
|
||||
if ((array_info.child == u8 or array_info.child == u16) and
|
||||
array_info.sentinel != null and
|
||||
@ptrCast(*const array_info.child, array_info.sentinel.?).* == 0)
|
||||
@ptrCast(*align(1) const array_info.child, array_info.sentinel.?).* == 0)
|
||||
{
|
||||
// length of the string plus one for the null terminator.
|
||||
return (array_info.len + 1) * @sizeOf(array_info.child);
|
||||
|
81
src/Sema.zig
81
src/Sema.zig
@ -22811,6 +22811,7 @@ fn coerceExtra(
|
||||
if (dest_ty.isPtrLikeOptional() and dest_ty.elemType2().tag() == .anyopaque and
|
||||
inst_ty.isPtrLikeOptional() and inst_ty.elemType2().zigTypeTag() != .Pointer)
|
||||
{
|
||||
if (!sema.checkPtrAttributes(dest_ty, inst_ty, &in_memory_result)) break :optional;
|
||||
return sema.coerceCompatiblePtrs(block, dest_ty, inst, inst_src);
|
||||
}
|
||||
|
||||
@ -22843,14 +22844,12 @@ fn coerceExtra(
|
||||
single_item: {
|
||||
if (dest_info.size != .One) break :single_item;
|
||||
if (!inst_ty.isSinglePointer()) break :single_item;
|
||||
if (!sema.checkPtrAttributes(dest_ty, inst_ty, &in_memory_result)) break :pointer;
|
||||
const ptr_elem_ty = inst_ty.childType();
|
||||
const array_ty = dest_info.pointee_type;
|
||||
if (array_ty.zigTypeTag() != .Array) break :single_item;
|
||||
const array_elem_ty = array_ty.childType();
|
||||
const dest_is_mut = dest_info.mutable;
|
||||
if (inst_ty.isConstPtr() and dest_is_mut) break :single_item;
|
||||
if (inst_ty.isVolatilePtr() and !dest_info.@"volatile") break :single_item;
|
||||
if (inst_ty.ptrAddressSpace() != dest_info.@"addrspace") break :single_item;
|
||||
switch (try sema.coerceInMemoryAllowed(block, array_elem_ty, ptr_elem_ty, dest_is_mut, target, dest_ty_src, inst_src)) {
|
||||
.ok => {},
|
||||
else => break :single_item,
|
||||
@ -22861,14 +22860,11 @@ fn coerceExtra(
|
||||
// Coercions where the source is a single pointer to an array.
|
||||
src_array_ptr: {
|
||||
if (!inst_ty.isSinglePointer()) break :src_array_ptr;
|
||||
if (!sema.checkPtrAttributes(dest_ty, inst_ty, &in_memory_result)) break :pointer;
|
||||
const array_ty = inst_ty.childType();
|
||||
if (array_ty.zigTypeTag() != .Array) break :src_array_ptr;
|
||||
const len0 = array_ty.arrayLen() == 0;
|
||||
const array_elem_type = array_ty.childType();
|
||||
const dest_is_mut = dest_info.mutable;
|
||||
if (inst_ty.isConstPtr() and dest_is_mut and !len0) break :src_array_ptr;
|
||||
if (inst_ty.isVolatilePtr() and !dest_info.@"volatile") break :src_array_ptr;
|
||||
if (inst_ty.ptrAddressSpace() != dest_info.@"addrspace") break :src_array_ptr;
|
||||
|
||||
const dst_elem_type = dest_info.pointee_type;
|
||||
switch (try sema.coerceInMemoryAllowed(block, dst_elem_type, array_elem_type, dest_is_mut, target, dest_ty_src, inst_src)) {
|
||||
@ -22905,6 +22901,7 @@ fn coerceExtra(
|
||||
|
||||
// coercion from C pointer
|
||||
if (inst_ty.isCPtr()) src_c_ptr: {
|
||||
if (!sema.checkPtrAttributes(dest_ty, inst_ty, &in_memory_result)) break :src_c_ptr;
|
||||
// In this case we must add a safety check because the C pointer
|
||||
// could be null.
|
||||
const src_elem_ty = inst_ty.childType();
|
||||
@ -22920,7 +22917,7 @@ fn coerceExtra(
|
||||
// cast from *T and [*]T to *anyopaque
|
||||
// but don't do it if the source type is a double pointer
|
||||
if (dest_info.pointee_type.tag() == .anyopaque and inst_ty.zigTypeTag() == .Pointer and
|
||||
inst_ty.childType().zigTypeTag() != .Pointer)
|
||||
inst_ty.childType().zigTypeTag() != .Pointer and sema.checkPtrAttributes(dest_ty, inst_ty, &in_memory_result))
|
||||
{
|
||||
return sema.coerceCompatiblePtrs(block, dest_ty, inst, inst_src);
|
||||
}
|
||||
@ -22954,6 +22951,7 @@ fn coerceExtra(
|
||||
return try sema.coerceCompatiblePtrs(block, dest_ty, addr, inst_src);
|
||||
},
|
||||
.Pointer => p: {
|
||||
if (!sema.checkPtrAttributes(dest_ty, inst_ty, &in_memory_result)) break :p;
|
||||
const inst_info = inst_ty.ptrInfo().data;
|
||||
switch (try sema.coerceInMemoryAllowed(
|
||||
block,
|
||||
@ -22984,7 +22982,7 @@ fn coerceExtra(
|
||||
// pointer to anonymous struct to pointer to union
|
||||
if (inst_ty.isSinglePointer() and
|
||||
inst_ty.childType().isAnonStruct() and
|
||||
!dest_info.mutable)
|
||||
sema.checkPtrAttributes(dest_ty, inst_ty, &in_memory_result))
|
||||
{
|
||||
return sema.coerceAnonStructToUnionPtrs(block, dest_ty, dest_ty_src, inst, inst_src);
|
||||
}
|
||||
@ -22993,7 +22991,7 @@ fn coerceExtra(
|
||||
// pointer to anonymous struct to pointer to struct
|
||||
if (inst_ty.isSinglePointer() and
|
||||
inst_ty.childType().isAnonStruct() and
|
||||
!dest_info.mutable)
|
||||
sema.checkPtrAttributes(dest_ty, inst_ty, &in_memory_result))
|
||||
{
|
||||
return sema.coerceAnonStructToStructPtrs(block, dest_ty, dest_ty_src, inst, inst_src);
|
||||
}
|
||||
@ -23002,7 +23000,7 @@ fn coerceExtra(
|
||||
// pointer to tuple to pointer to array
|
||||
if (inst_ty.isSinglePointer() and
|
||||
inst_ty.childType().isTuple() and
|
||||
!dest_info.mutable)
|
||||
sema.checkPtrAttributes(dest_ty, inst_ty, &in_memory_result))
|
||||
{
|
||||
return sema.coerceTupleToArrayPtrs(block, dest_ty, dest_ty_src, inst, inst_src);
|
||||
}
|
||||
@ -23011,10 +23009,8 @@ fn coerceExtra(
|
||||
},
|
||||
.Slice => {
|
||||
// pointer to tuple to slice
|
||||
if (inst_ty.isSinglePointer() and
|
||||
inst_ty.childType().isTuple() and
|
||||
(!dest_info.mutable or inst_ty.ptrIsMutable() or inst_ty.childType().tupleFields().types.len == 0) and
|
||||
dest_info.size == .Slice)
|
||||
if (inst_ty.isSinglePointer() and inst_ty.childType().isTuple() and dest_info.size == .Slice and
|
||||
sema.checkPtrAttributes(dest_ty, inst_ty, &in_memory_result))
|
||||
{
|
||||
return sema.coerceTupleToSlicePtrs(block, dest_ty, dest_ty_src, inst, inst_src);
|
||||
}
|
||||
@ -23043,6 +23039,7 @@ fn coerceExtra(
|
||||
},
|
||||
.Many => p: {
|
||||
if (!inst_ty.isSlice()) break :p;
|
||||
if (!sema.checkPtrAttributes(dest_ty, inst_ty, &in_memory_result)) break :p;
|
||||
const inst_info = inst_ty.ptrInfo().data;
|
||||
|
||||
switch (try sema.coerceInMemoryAllowed(
|
||||
@ -25438,6 +25435,57 @@ fn coerceArrayPtrToSlice(
|
||||
return block.addTyOp(.array_to_slice, dest_ty, inst);
|
||||
}
|
||||
|
||||
fn checkPtrAttributes(sema: *Sema, dest_ty: Type, inst_ty: Type, in_memory_result: *InMemoryCoercionResult) bool {
|
||||
const dest_info = dest_ty.ptrInfo().data;
|
||||
const inst_info = inst_ty.ptrInfo().data;
|
||||
const len0 = (inst_info.pointee_type.zigTypeTag() == .Array and (inst_info.pointee_type.arrayLenIncludingSentinel() == 0 or
|
||||
(inst_info.pointee_type.arrayLen() == 0 and dest_info.sentinel == null and dest_info.size != .C and dest_info.size != .Many))) or
|
||||
(inst_info.pointee_type.isTuple() and inst_info.pointee_type.tupleFields().types.len == 0);
|
||||
|
||||
const ok_cv_qualifiers =
|
||||
((inst_info.mutable or !dest_info.mutable) or len0) and
|
||||
(!inst_info.@"volatile" or dest_info.@"volatile");
|
||||
|
||||
if (!ok_cv_qualifiers) {
|
||||
in_memory_result.* = .{ .ptr_qualifiers = .{
|
||||
.actual_const = !inst_info.mutable,
|
||||
.wanted_const = !dest_info.mutable,
|
||||
.actual_volatile = inst_info.@"volatile",
|
||||
.wanted_volatile = dest_info.@"volatile",
|
||||
} };
|
||||
return false;
|
||||
}
|
||||
if (dest_info.@"addrspace" != inst_info.@"addrspace") {
|
||||
in_memory_result.* = .{ .ptr_addrspace = .{
|
||||
.actual = inst_info.@"addrspace",
|
||||
.wanted = dest_info.@"addrspace",
|
||||
} };
|
||||
return false;
|
||||
}
|
||||
if (inst_info.@"align" == 0 and dest_info.@"align" == 0) return true;
|
||||
if (len0) return true;
|
||||
const target = sema.mod.getTarget();
|
||||
|
||||
const inst_align = if (inst_info.@"align" != 0)
|
||||
inst_info.@"align"
|
||||
else
|
||||
inst_info.pointee_type.abiAlignment(target);
|
||||
|
||||
const dest_align = if (dest_info.@"align" != 0)
|
||||
dest_info.@"align"
|
||||
else
|
||||
dest_info.pointee_type.abiAlignment(target);
|
||||
|
||||
if (dest_align > inst_align) {
|
||||
in_memory_result.* = .{ .ptr_alignment = .{
|
||||
.actual = inst_align,
|
||||
.wanted = dest_align,
|
||||
} };
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
fn coerceCompatiblePtrs(
|
||||
sema: *Sema,
|
||||
block: *Block,
|
||||
@ -25445,13 +25493,12 @@ fn coerceCompatiblePtrs(
|
||||
inst: Air.Inst.Ref,
|
||||
inst_src: LazySrcLoc,
|
||||
) !Air.Inst.Ref {
|
||||
// TODO check const/volatile/alignment
|
||||
const inst_ty = sema.typeOf(inst);
|
||||
if (try sema.resolveMaybeUndefVal(block, inst_src, inst)) |val| {
|
||||
// The comptime Value representation is compatible with both types.
|
||||
return sema.addConstant(dest_ty, val);
|
||||
}
|
||||
try sema.requireRuntimeBlock(block, inst_src, null);
|
||||
const inst_ty = sema.typeOf(inst);
|
||||
const inst_allows_zero = (inst_ty.zigTypeTag() == .Pointer and inst_ty.ptrAllowsZero()) or true;
|
||||
if (block.wantSafety() and inst_allows_zero and !dest_ty.ptrAllowsZero() and
|
||||
try sema.typeHasRuntimeBits(block, sema.src, dest_ty.elemType2()))
|
||||
|
@ -13,7 +13,7 @@ extern fn fopen([*c]const u8, [*c]const u8) [*c]FILE;
|
||||
const S = extern struct {
|
||||
state: c_short,
|
||||
|
||||
extern fn s_do_thing([*c]S, b: c_int) c_short;
|
||||
extern fn s_do_thing([*c]const S, b: c_int) c_short;
|
||||
};
|
||||
|
||||
test "Extern function calls in @TypeOf" {
|
||||
|
@ -1242,13 +1242,13 @@ test "implicit cast *[0]T to E![]const u8" {
|
||||
|
||||
var global_array: [4]u8 = undefined;
|
||||
test "cast from array reference to fn: comptime fn ptr" {
|
||||
const f = @ptrCast(*const fn () callconv(.C) void, &global_array);
|
||||
const f = @ptrCast(*align(1) const fn () callconv(.C) void, &global_array);
|
||||
try expect(@ptrToInt(f) == @ptrToInt(&global_array));
|
||||
}
|
||||
test "cast from array reference to fn: runtime fn ptr" {
|
||||
if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; // TODO
|
||||
|
||||
var f = @ptrCast(*const fn () callconv(.C) void, &global_array);
|
||||
var f = @ptrCast(*align(1) const fn () callconv(.C) void, &global_array);
|
||||
try expect(@ptrToInt(f) == @ptrToInt(&global_array));
|
||||
}
|
||||
|
||||
|
@ -322,11 +322,12 @@ test "empty array to slice" {
|
||||
|
||||
test "@ptrCast slice to pointer" {
|
||||
if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest;
|
||||
if (builtin.zig_backend == .stage2_c) return error.SkipZigTest;
|
||||
|
||||
const S = struct {
|
||||
fn doTheTest() !void {
|
||||
var array align(@alignOf(u16)) = [5]u8{ 0xff, 0xff, 0xff, 0xff, 0xff };
|
||||
var slice: []u8 = &array;
|
||||
var slice: []align(@alignOf(u16)) u8 = &array;
|
||||
var ptr = @ptrCast(*u16, slice);
|
||||
try expect(ptr.* == 65535);
|
||||
}
|
||||
|
@ -521,7 +521,7 @@ test "packed struct fields are ordered from LSB to MSB" {
|
||||
if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
|
||||
|
||||
var all: u64 = 0x7765443322221111;
|
||||
var bytes: [8]u8 = undefined;
|
||||
var bytes: [8]u8 align(@alignOf(Bitfields)) = undefined;
|
||||
@memcpy(&bytes, @ptrCast([*]u8, &all), 8);
|
||||
var bitfields = @ptrCast(*Bitfields, &bytes).*;
|
||||
|
||||
|
@ -293,7 +293,7 @@ test "Type.Struct" {
|
||||
try testing.expectEqual(@as(?*const anyopaque, null), infoB.fields[0].default_value);
|
||||
try testing.expectEqualSlices(u8, "y", infoB.fields[1].name);
|
||||
try testing.expectEqual(u32, infoB.fields[1].field_type);
|
||||
try testing.expectEqual(@as(u32, 5), @ptrCast(*const u32, infoB.fields[1].default_value.?).*);
|
||||
try testing.expectEqual(@as(u32, 5), @ptrCast(*align(1) const u32, infoB.fields[1].default_value.?).*);
|
||||
try testing.expectEqual(@as(usize, 0), infoB.decls.len);
|
||||
try testing.expectEqual(@as(bool, false), infoB.is_tuple);
|
||||
|
||||
@ -305,7 +305,7 @@ test "Type.Struct" {
|
||||
try testing.expectEqual(@as(u8, 3), @ptrCast(*const u8, infoC.fields[0].default_value.?).*);
|
||||
try testing.expectEqualSlices(u8, "y", infoC.fields[1].name);
|
||||
try testing.expectEqual(u32, infoC.fields[1].field_type);
|
||||
try testing.expectEqual(@as(u32, 5), @ptrCast(*const u32, infoC.fields[1].default_value.?).*);
|
||||
try testing.expectEqual(@as(u32, 5), @ptrCast(*align(1) const u32, infoC.fields[1].default_value.?).*);
|
||||
try testing.expectEqual(@as(usize, 0), infoC.decls.len);
|
||||
try testing.expectEqual(@as(bool, false), infoC.is_tuple);
|
||||
|
||||
|
@ -295,8 +295,8 @@ fn testStruct() !void {
|
||||
try expect(unpacked_struct_info.Struct.is_tuple == false);
|
||||
try expect(unpacked_struct_info.Struct.backing_integer == null);
|
||||
try expect(unpacked_struct_info.Struct.fields[0].alignment == @alignOf(u32));
|
||||
try expect(@ptrCast(*const u32, unpacked_struct_info.Struct.fields[0].default_value.?).* == 4);
|
||||
try expect(mem.eql(u8, "foobar", @ptrCast(*const *const [6:0]u8, unpacked_struct_info.Struct.fields[1].default_value.?).*));
|
||||
try expect(@ptrCast(*align(1) const u32, unpacked_struct_info.Struct.fields[0].default_value.?).* == 4);
|
||||
try expect(mem.eql(u8, "foobar", @ptrCast(*align(1) const *const [6:0]u8, unpacked_struct_info.Struct.fields[1].default_value.?).*));
|
||||
}
|
||||
|
||||
const TestStruct = struct {
|
||||
@ -321,7 +321,7 @@ fn testPackedStruct() !void {
|
||||
try expect(struct_info.Struct.fields[0].alignment == 0);
|
||||
try expect(struct_info.Struct.fields[2].field_type == f32);
|
||||
try expect(struct_info.Struct.fields[2].default_value == null);
|
||||
try expect(@ptrCast(*const u32, struct_info.Struct.fields[3].default_value.?).* == 4);
|
||||
try expect(@ptrCast(*align(1) const u32, struct_info.Struct.fields[3].default_value.?).* == 4);
|
||||
try expect(struct_info.Struct.fields[3].alignment == 0);
|
||||
try expect(struct_info.Struct.decls.len == 2);
|
||||
try expect(struct_info.Struct.decls[0].is_pub);
|
||||
|
@ -9,3 +9,4 @@ export fn entry() void {
|
||||
// target=native
|
||||
//
|
||||
// :3:22: error: expected type '[]u32', found '*const u32'
|
||||
// :3:22: note: cast discards const qualifier
|
||||
|
@ -0,0 +1,47 @@
|
||||
export fn a() void {
|
||||
var x: [*c]u8 = undefined;
|
||||
var y: *align(4) u8 = x;
|
||||
_ = y;
|
||||
}
|
||||
export fn b() void {
|
||||
var x: [*c]const u8 = undefined;
|
||||
var y: *u8 = x;
|
||||
_ = y;
|
||||
}
|
||||
export fn c() void {
|
||||
var x: [*c]u8 = undefined;
|
||||
var y: *u32 = x;
|
||||
_ = y;
|
||||
}
|
||||
export fn d() void {
|
||||
var y: *align(1) u32 = undefined;
|
||||
var x: [*c]u32 = y;
|
||||
_ = x;
|
||||
}
|
||||
export fn e() void {
|
||||
var y: *const u8 = undefined;
|
||||
var x: [*c]u8 = y;
|
||||
_ = x;
|
||||
}
|
||||
export fn f() void {
|
||||
var y: *u8 = undefined;
|
||||
var x: [*c]u32 = y;
|
||||
_ = x;
|
||||
}
|
||||
|
||||
// error
|
||||
// backend=stage2
|
||||
// target=native
|
||||
//
|
||||
// :3:27: error: expected type '*align(4) u8', found '[*c]u8'
|
||||
// :3:27: note: pointer alignment '1' cannot cast into pointer alignment '4'
|
||||
// :8:18: error: expected type '*u8', found '[*c]const u8'
|
||||
// :8:18: note: cast discards const qualifier
|
||||
// :13:19: error: expected type '*u32', found '[*c]u8'
|
||||
// :13:19: note: pointer type child 'u8' cannot cast into pointer type child 'u32'
|
||||
// :18:22: error: expected type '[*c]u32', found '*align(1) u32'
|
||||
// :18:22: note: pointer alignment '1' cannot cast into pointer alignment '4'
|
||||
// :23:21: error: expected type '[*c]u8', found '*const u8'
|
||||
// :23:21: note: cast discards const qualifier
|
||||
// :28:22: error: expected type '[*c]u32', found '*u8'
|
||||
// :28:22: note: pointer type child 'u8' cannot cast into pointer type child 'u32'
|
@ -0,0 +1,26 @@
|
||||
export fn entry() void {
|
||||
const buffer: [1]u8 = [_]u8{8};
|
||||
const sliceA: []u8 = &buffer;
|
||||
_ = sliceA;
|
||||
}
|
||||
export fn entry1() void {
|
||||
const str: *const [0:0]u8 = "";
|
||||
const slice: [:0]u8 = str;
|
||||
_ = slice;
|
||||
}
|
||||
export fn entry2() void {
|
||||
const str: *const [0:0]u8 = "";
|
||||
const many: [*]u8 = str;
|
||||
_ = many;
|
||||
}
|
||||
|
||||
// error
|
||||
// backend=stage2
|
||||
// target=native
|
||||
//
|
||||
// :3:26: error: expected type '[]u8', found '*const [1]u8'
|
||||
// :3:26: note: cast discards const qualifier
|
||||
// :8:27: error: expected type '[:0]u8', found '*const [0:0]u8'
|
||||
// :8:27: note: cast discards const qualifier
|
||||
// :13:25: error: expected type '[*]u8', found '*const [0:0]u8'
|
||||
// :13:25: note: cast discards const qualifier
|
@ -14,9 +14,8 @@ fn bar(x: []u32) void {
|
||||
}
|
||||
|
||||
// error
|
||||
// backend=stage1
|
||||
// backend=stage2
|
||||
// target=native
|
||||
//
|
||||
// tmp.zig:9:26: error: cast increases pointer alignment
|
||||
// tmp.zig:9:26: note: '*align(1) u32' has alignment 1
|
||||
// tmp.zig:9:26: note: '*[1]u32' has alignment 4
|
||||
// :9:22: error: expected type '*[1]u32', found '*align(1) u32'
|
||||
// :9:22: note: pointer alignment '1' cannot cast into pointer alignment '4'
|
@ -9,8 +9,8 @@ export fn foo() void {
|
||||
}
|
||||
|
||||
// error
|
||||
// backend=stage1
|
||||
// backend=stage2
|
||||
// target=native
|
||||
//
|
||||
// :5:28: error: cannot cast pointer to array literal to slice type '[]u8'
|
||||
// :5:28: note: cast discards const qualifier
|
||||
// :4:22: error: expected type '[]u8', found '*const [3:0]u8'
|
||||
// :4:22: note: cast discards const qualifier
|
@ -1,5 +1,5 @@
|
||||
export fn entry() void {
|
||||
const float: f32 = 5.99999999999994648725e-01;
|
||||
const float: f32 align(@alignOf(i64)) = 5.99999999999994648725e-01;
|
||||
const float_ptr = &float;
|
||||
const int_ptr = @ptrCast(*const i64, float_ptr);
|
||||
const int_val = int_ptr.*;
|
||||
|
@ -0,0 +1,11 @@
|
||||
export fn func() void {
|
||||
var strValue: [*c]u8 = undefined;
|
||||
strValue = strValue orelse "";
|
||||
}
|
||||
|
||||
// error
|
||||
// backend=stage2
|
||||
// target=native
|
||||
//
|
||||
// :3:32: error: expected type '[*c]u8', found '*const [0:0]u8'
|
||||
// :3:32: note: cast discards const qualifier
|
@ -0,0 +1,24 @@
|
||||
comptime {
|
||||
const c: [][]const u8 = &.{ "hello", "world" };
|
||||
_ = c;
|
||||
}
|
||||
comptime {
|
||||
const c: *[2][]const u8 = &.{ "hello", "world" };
|
||||
_ = c;
|
||||
}
|
||||
const S = struct { a: u8 = 1, b: u32 = 2 };
|
||||
comptime {
|
||||
const c: *S = &.{ .a = 2 };
|
||||
_ = c;
|
||||
}
|
||||
|
||||
// error
|
||||
// backend=stage2
|
||||
// target=native
|
||||
//
|
||||
// :2:29: error: expected type '[][]const u8', found '*const tuple{comptime *const [5:0]u8 = "hello", comptime *const [5:0]u8 = "world"}'
|
||||
// :2:29: note: cast discards const qualifier
|
||||
// :6:31: error: expected type '*[2][]const u8', found '*const tuple{comptime *const [5:0]u8 = "hello", comptime *const [5:0]u8 = "world"}'
|
||||
// :6:31: note: cast discards const qualifier
|
||||
// :11:19: error: expected type '*tmp.S', found '*const struct{comptime a: comptime_int = 2}'
|
||||
// :11:19: note: cast discards const qualifier
|
@ -1,7 +1,7 @@
|
||||
comptime {
|
||||
const array: [4]u8 = "aoeu".*;
|
||||
const sub_array = array[1..];
|
||||
const int_ptr = @ptrCast(*const u24, sub_array);
|
||||
const int_ptr = @ptrCast(*const u24, @alignCast(@alignOf(u24), sub_array));
|
||||
const deref = int_ptr.*;
|
||||
_ = deref;
|
||||
}
|
||||
|
@ -1,5 +1,5 @@
|
||||
export fn foo() void {
|
||||
const bytes = [1]u8{ 0xfa } ** 16;
|
||||
const bytes align(@alignOf([]const u8)) = [1]u8{0xfa} ** 16;
|
||||
var value = @ptrCast(*const []const u8, &bytes).*;
|
||||
_ = value;
|
||||
}
|
||||
|
@ -1,42 +0,0 @@
|
||||
export fn a() void {
|
||||
var x: [*c]u8 = undefined;
|
||||
var y: *align(4) u8 = x;
|
||||
_ = y;
|
||||
}
|
||||
export fn b() void {
|
||||
var x: [*c]const u8 = undefined;
|
||||
var y: *u8 = x;
|
||||
_ = y;
|
||||
}
|
||||
export fn c() void {
|
||||
var x: [*c]u8 = undefined;
|
||||
var y: *u32 = x;
|
||||
_ = y;
|
||||
}
|
||||
export fn d() void {
|
||||
var y: *align(1) u32 = undefined;
|
||||
var x: [*c]u32 = y;
|
||||
_ = x;
|
||||
}
|
||||
export fn e() void {
|
||||
var y: *const u8 = undefined;
|
||||
var x: [*c]u8 = y;
|
||||
_ = x;
|
||||
}
|
||||
export fn f() void {
|
||||
var y: *u8 = undefined;
|
||||
var x: [*c]u32 = y;
|
||||
_ = x;
|
||||
}
|
||||
|
||||
// error
|
||||
// backend=stage1
|
||||
// target=native
|
||||
//
|
||||
// tmp.zig:3:27: error: cast increases pointer alignment
|
||||
// tmp.zig:8:18: error: cast discards const qualifier
|
||||
// tmp.zig:13:19: error: expected type '*u32', found '[*c]u8'
|
||||
// tmp.zig:13:19: note: pointer type child 'u8' cannot cast into pointer type child 'u32'
|
||||
// tmp.zig:18:22: error: cast increases pointer alignment
|
||||
// tmp.zig:23:21: error: cast discards const qualifier
|
||||
// tmp.zig:28:22: error: expected type '[*c]u32', found '*u8'
|
@ -1,12 +0,0 @@
|
||||
export fn entry() void {
|
||||
const buffer: [1]u8 = [_]u8{8};
|
||||
const sliceA: []u8 = &buffer;
|
||||
_ = sliceA;
|
||||
}
|
||||
|
||||
// error
|
||||
// backend=stage1
|
||||
// target=native
|
||||
//
|
||||
// tmp.zig:3:27: error: cannot cast pointer to array literal to slice type '[]u8'
|
||||
// tmp.zig:3:27: note: cast discards const qualifier
|
@ -1,11 +0,0 @@
|
||||
export fn func() void {
|
||||
var strValue: [*c]u8 = undefined;
|
||||
strValue = strValue orelse "";
|
||||
}
|
||||
|
||||
// error
|
||||
// backend=stage1
|
||||
// target=native
|
||||
//
|
||||
// tmp.zig:3:32: error: expected type '[*c]u8', found '*const [0:0]u8'
|
||||
// tmp.zig:3:32: note: cast discards const qualifier
|
@ -1,24 +0,0 @@
|
||||
comptime {
|
||||
const c: [][]const u8 = &.{"hello", "world" };
|
||||
_ = c;
|
||||
}
|
||||
comptime {
|
||||
const c: *[2][]const u8 = &.{"hello", "world" };
|
||||
_ = c;
|
||||
}
|
||||
const S = struct {a: u8 = 1, b: u32 = 2};
|
||||
comptime {
|
||||
const c: *S = &.{};
|
||||
_ = c;
|
||||
}
|
||||
|
||||
// error
|
||||
// backend=stage1
|
||||
// target=native
|
||||
//
|
||||
// tmp.zig:2:31: error: cannot cast pointer to array literal to slice type '[][]const u8'
|
||||
// tmp.zig:2:31: note: cast discards const qualifier
|
||||
// tmp.zig:6:33: error: cannot cast pointer to array literal to '*[2][]const u8'
|
||||
// tmp.zig:6:33: note: cast discards const qualifier
|
||||
// tmp.zig:11:21: error: expected type '*S', found '*const struct:11:21'
|
||||
// tmp.zig:11:21: note: cast discards const qualifier
|
Loading…
Reference in New Issue
Block a user