mirror of
https://github.com/ziglang/zig.git
synced 2026-02-13 21:08:36 +00:00
Sema: do not forcibly canonicalize unresolved pointer element type
Closes #13308
This commit is contained in:
parent
59dad43de2
commit
7f9e841f74
12
src/Sema.zig
12
src/Sema.zig
@ -16825,7 +16825,7 @@ fn zirPtrType(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air
|
||||
const bitoffset_src: LazySrcLoc = .{ .node_offset_ptr_bitoffset = extra.data.src_node };
|
||||
const hostsize_src: LazySrcLoc = .{ .node_offset_ptr_hostsize = extra.data.src_node };
|
||||
|
||||
const unresolved_elem_ty = blk: {
|
||||
const elem_ty = blk: {
|
||||
const air_inst = try sema.resolveInst(extra.data.elem_type);
|
||||
const ty = sema.analyzeAsType(block, elem_ty_src, air_inst) catch |err| {
|
||||
if (err == error.AnalysisFail and sema.err != null and sema.typeOf(air_inst).isSinglePointer()) {
|
||||
@ -16854,7 +16854,7 @@ fn zirPtrType(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air
|
||||
// Check if this happens to be the lazy alignment of our element type, in
|
||||
// which case we can make this 0 without resolving it.
|
||||
if (val.castTag(.lazy_align)) |payload| {
|
||||
if (payload.data.eql(unresolved_elem_ty, sema.mod)) {
|
||||
if (payload.data.eql(elem_ty, sema.mod)) {
|
||||
break :blk 0;
|
||||
}
|
||||
}
|
||||
@ -16887,14 +16887,6 @@ fn zirPtrType(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air
|
||||
return sema.fail(block, bitoffset_src, "bit offset starts after end of host integer", .{});
|
||||
}
|
||||
|
||||
const elem_ty = if (abi_align == 0)
|
||||
unresolved_elem_ty
|
||||
else t: {
|
||||
const elem_ty = try sema.resolveTypeFields(unresolved_elem_ty);
|
||||
try sema.resolveTypeLayout(elem_ty);
|
||||
break :t elem_ty;
|
||||
};
|
||||
|
||||
if (elem_ty.zigTypeTag() == .NoReturn) {
|
||||
return sema.fail(block, elem_ty_src, "pointer to noreturn not allowed", .{});
|
||||
} else if (elem_ty.zigTypeTag() == .Fn) {
|
||||
|
||||
12
src/type.zig
12
src/type.zig
@ -6491,8 +6491,16 @@ pub const Type = extern union {
|
||||
// type, we change it to 0 here. If this causes an assertion trip because the
|
||||
// pointee type needs to be resolved more, that needs to be done before calling
|
||||
// this ptr() function.
|
||||
if (d.@"align" != 0 and d.@"align" == d.pointee_type.abiAlignment(target)) {
|
||||
d.@"align" = 0;
|
||||
if (d.@"align" != 0) canonicalize: {
|
||||
if (d.pointee_type.castTag(.@"struct")) |struct_ty| {
|
||||
if (!struct_ty.data.haveLayout()) break :canonicalize;
|
||||
}
|
||||
if (d.pointee_type.cast(Payload.Union)) |union_ty| {
|
||||
if (!union_ty.data.haveLayout()) break :canonicalize;
|
||||
}
|
||||
if (d.@"align" == d.pointee_type.abiAlignment(target)) {
|
||||
d.@"align" = 0;
|
||||
}
|
||||
}
|
||||
|
||||
// Canonicalize host_size. If it matches the bit size of the pointee type,
|
||||
|
||||
@ -1406,3 +1406,15 @@ test "address of zero-bit field is equal to address of only field" {
|
||||
try std.testing.expectEqual(&a, a_ptr);
|
||||
}
|
||||
}
|
||||
|
||||
test "struct field has a pointer to an aligned version of itself" {
|
||||
if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
|
||||
|
||||
const E = struct {
|
||||
next: *align(1) @This(),
|
||||
};
|
||||
var e: E = undefined;
|
||||
e = .{ .next = &e };
|
||||
|
||||
try expect(&e == e.next);
|
||||
}
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user