mirror of
https://github.com/ziglang/zig.git
synced 2025-12-06 22:33:08 +00:00
Sema: improve compile error for casting double pointer to anyopaque pointer
Closes #12042
This commit is contained in:
parent
9607bd90e6
commit
d7314555f2
@ -302,7 +302,7 @@ pub fn Sentinel(comptime T: type, comptime sentinel_val: Elem(T)) type {
|
|||||||
.Array = .{
|
.Array = .{
|
||||||
.len = array_info.len,
|
.len = array_info.len,
|
||||||
.child = array_info.child,
|
.child = array_info.child,
|
||||||
.sentinel = &sentinel_val,
|
.sentinel = @ptrCast(?*const anyopaque, &sentinel_val),
|
||||||
},
|
},
|
||||||
}),
|
}),
|
||||||
.is_allowzero = info.is_allowzero,
|
.is_allowzero = info.is_allowzero,
|
||||||
@ -320,7 +320,7 @@ pub fn Sentinel(comptime T: type, comptime sentinel_val: Elem(T)) type {
|
|||||||
.address_space = info.address_space,
|
.address_space = info.address_space,
|
||||||
.child = info.child,
|
.child = info.child,
|
||||||
.is_allowzero = info.is_allowzero,
|
.is_allowzero = info.is_allowzero,
|
||||||
.sentinel = &sentinel_val,
|
.sentinel = @ptrCast(?*const anyopaque, &sentinel_val),
|
||||||
},
|
},
|
||||||
}),
|
}),
|
||||||
else => {},
|
else => {},
|
||||||
@ -338,7 +338,7 @@ pub fn Sentinel(comptime T: type, comptime sentinel_val: Elem(T)) type {
|
|||||||
.address_space = ptr_info.address_space,
|
.address_space = ptr_info.address_space,
|
||||||
.child = ptr_info.child,
|
.child = ptr_info.child,
|
||||||
.is_allowzero = ptr_info.is_allowzero,
|
.is_allowzero = ptr_info.is_allowzero,
|
||||||
.sentinel = &sentinel_val,
|
.sentinel = @ptrCast(?*const anyopaque, &sentinel_val),
|
||||||
},
|
},
|
||||||
}),
|
}),
|
||||||
},
|
},
|
||||||
|
|||||||
@ -42,7 +42,7 @@ export const _tls_used linksection(".rdata$T") = IMAGE_TLS_DIRECTORY{
|
|||||||
.StartAddressOfRawData = &_tls_start,
|
.StartAddressOfRawData = &_tls_start,
|
||||||
.EndAddressOfRawData = &_tls_end,
|
.EndAddressOfRawData = &_tls_end,
|
||||||
.AddressOfIndex = &_tls_index,
|
.AddressOfIndex = &_tls_index,
|
||||||
.AddressOfCallBacks = &__xl_a,
|
.AddressOfCallBacks = @ptrCast(*anyopaque, &__xl_a),
|
||||||
.SizeOfZeroFill = 0,
|
.SizeOfZeroFill = 0,
|
||||||
.Characteristics = 0,
|
.Characteristics = 0,
|
||||||
};
|
};
|
||||||
|
|||||||
35
src/Sema.zig
35
src/Sema.zig
@ -23928,9 +23928,20 @@ fn coerceExtra(
|
|||||||
// cast from ?*T and ?[*]T to ?*anyopaque
|
// cast from ?*T and ?[*]T to ?*anyopaque
|
||||||
// but don't do it if the source type is a double pointer
|
// but don't do it if the source type is a double pointer
|
||||||
if (dest_ty.isPtrLikeOptional() and dest_ty.elemType2().tag() == .anyopaque and
|
if (dest_ty.isPtrLikeOptional() and dest_ty.elemType2().tag() == .anyopaque and
|
||||||
inst_ty.isPtrLikeOptional() and inst_ty.elemType2().zigTypeTag() != .Pointer)
|
inst_ty.isPtrAtRuntime())
|
||||||
{
|
anyopaque_check: {
|
||||||
if (!sema.checkPtrAttributes(dest_ty, inst_ty, &in_memory_result)) break :optional;
|
if (!sema.checkPtrAttributes(dest_ty, inst_ty, &in_memory_result)) break :optional;
|
||||||
|
const elem_ty = inst_ty.elemType2();
|
||||||
|
if (elem_ty.zigTypeTag() == .Pointer or elem_ty.isPtrLikeOptional()) {
|
||||||
|
in_memory_result = .{ .double_ptr_to_anyopaque = .{
|
||||||
|
.actual = inst_ty,
|
||||||
|
.wanted = dest_ty,
|
||||||
|
} };
|
||||||
|
break :optional;
|
||||||
|
}
|
||||||
|
// Let the logic below handle wrapping the optional now that
|
||||||
|
// it has been checked to correctly coerce.
|
||||||
|
if (!inst_ty.isPtrLikeOptional()) break: anyopaque_check;
|
||||||
return sema.coerceCompatiblePtrs(block, dest_ty, inst, inst_src);
|
return sema.coerceCompatiblePtrs(block, dest_ty, inst, inst_src);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -24053,9 +24064,16 @@ fn coerceExtra(
|
|||||||
|
|
||||||
// cast from *T and [*]T to *anyopaque
|
// cast from *T and [*]T to *anyopaque
|
||||||
// but don't do it if the source type is a double pointer
|
// 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
|
if (dest_info.pointee_type.tag() == .anyopaque and inst_ty.zigTypeTag() == .Pointer) {
|
||||||
inst_ty.childType().zigTypeTag() != .Pointer and sema.checkPtrAttributes(dest_ty, inst_ty, &in_memory_result))
|
if (!sema.checkPtrAttributes(dest_ty, inst_ty, &in_memory_result)) break :pointer;
|
||||||
{
|
const elem_ty = inst_ty.elemType2();
|
||||||
|
if (elem_ty.zigTypeTag() == .Pointer or elem_ty.isPtrLikeOptional()) {
|
||||||
|
in_memory_result = .{ .double_ptr_to_anyopaque = .{
|
||||||
|
.actual = inst_ty,
|
||||||
|
.wanted = dest_ty,
|
||||||
|
} };
|
||||||
|
break :pointer;
|
||||||
|
}
|
||||||
return sema.coerceCompatiblePtrs(block, dest_ty, inst, inst_src);
|
return sema.coerceCompatiblePtrs(block, dest_ty, inst, inst_src);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -24537,6 +24555,7 @@ const InMemoryCoercionResult = union(enum) {
|
|||||||
ptr_allowzero: Pair,
|
ptr_allowzero: Pair,
|
||||||
ptr_bit_range: BitRange,
|
ptr_bit_range: BitRange,
|
||||||
ptr_alignment: IntPair,
|
ptr_alignment: IntPair,
|
||||||
|
double_ptr_to_anyopaque: Pair,
|
||||||
|
|
||||||
const Pair = struct {
|
const Pair = struct {
|
||||||
actual: Type,
|
actual: Type,
|
||||||
@ -24829,6 +24848,12 @@ const InMemoryCoercionResult = union(enum) {
|
|||||||
});
|
});
|
||||||
break;
|
break;
|
||||||
},
|
},
|
||||||
|
.double_ptr_to_anyopaque => |pair| {
|
||||||
|
try sema.errNote(block, src, msg, "cannot implicitly cast double pointer '{}' to anyopaque pointer '{}'", .{
|
||||||
|
pair.actual.fmt(sema.mod), pair.wanted.fmt(sema.mod),
|
||||||
|
});
|
||||||
|
break;
|
||||||
|
},
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|||||||
@ -3941,10 +3941,7 @@ pub const Type = extern union {
|
|||||||
.optional => {
|
.optional => {
|
||||||
var buf: Payload.ElemType = undefined;
|
var buf: Payload.ElemType = undefined;
|
||||||
const child_type = self.optionalChild(&buf);
|
const child_type = self.optionalChild(&buf);
|
||||||
// optionals of zero sized pointers behave like bools
|
|
||||||
if (!child_type.hasRuntimeBits()) return false;
|
|
||||||
if (child_type.zigTypeTag() != .Pointer) return false;
|
if (child_type.zigTypeTag() != .Pointer) return false;
|
||||||
|
|
||||||
const info = child_type.ptrInfo().data;
|
const info = child_type.ptrInfo().data;
|
||||||
switch (info.size) {
|
switch (info.size) {
|
||||||
.Slice, .C => return false,
|
.Slice, .C => return false,
|
||||||
|
|||||||
@ -1,14 +0,0 @@
|
|||||||
export fn entry() void {
|
|
||||||
var a: u32 = 1;
|
|
||||||
var ptr: *align(@alignOf(u32)) anyopaque = &a;
|
|
||||||
var b: *u32 = @ptrCast(*u32, ptr);
|
|
||||||
var ptr2: *anyopaque = &b;
|
|
||||||
_ = ptr2;
|
|
||||||
}
|
|
||||||
|
|
||||||
// error
|
|
||||||
// backend=stage2
|
|
||||||
// target=native
|
|
||||||
//
|
|
||||||
// :5:28: error: expected type '*anyopaque', found '**u32'
|
|
||||||
// :5:28: note: pointer type child '*u32' cannot cast into pointer type child 'anyopaque'
|
|
||||||
@ -0,0 +1,28 @@
|
|||||||
|
pub export fn entry1() void {
|
||||||
|
const x: usize = 5;
|
||||||
|
|
||||||
|
const ptr: *const anyopaque = &(&x);
|
||||||
|
_ = ptr;
|
||||||
|
}
|
||||||
|
pub export fn entry2() void {
|
||||||
|
var val: [*:0]u8 = undefined;
|
||||||
|
func(&val);
|
||||||
|
}
|
||||||
|
fn func(_: ?*anyopaque) void {}
|
||||||
|
pub export fn entry3() void {
|
||||||
|
var x: *?*usize = undefined;
|
||||||
|
|
||||||
|
const ptr: *const anyopaque = x;
|
||||||
|
_ = ptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
// error
|
||||||
|
// backend=stage2
|
||||||
|
// target=native
|
||||||
|
//
|
||||||
|
// :4:35: error: expected type '*const anyopaque', found '*const *const usize'
|
||||||
|
// :4:35: note: cannot implicitly cast double pointer '*const *const usize' to anyopaque pointer '*const anyopaque'
|
||||||
|
// :9:10: error: expected type '?*anyopaque', found '*[*:0]u8'
|
||||||
|
// :9:10: note: cannot implicitly cast double pointer '*[*:0]u8' to anyopaque pointer '?*anyopaque'
|
||||||
|
// :15:35: error: expected type '*const anyopaque', found '*?*usize'
|
||||||
|
// :15:35: note: cannot implicitly cast double pointer '*?*usize' to anyopaque pointer '*const anyopaque'
|
||||||
Loading…
x
Reference in New Issue
Block a user