authorgravatar for mlugg@mlugg.co.ukMatthew Lugg <mlugg@mlugg.co.uk> 2024-12-27 21:21:11+00:00
committergravatar for mlugg@mlugg.co.ukMatthew Lugg <mlugg@mlugg.co.uk> 2024-12-28 02:15:00+00:00
log01081cc8e8b79104f7992d60dbd1bc8682e8fedf
tree11c282b950ce46042fbeb6960ff494ea128547f8
parent5ee2816f6226eff8990749d44b1b9003b10c6170

AstGen: lower function addrspace expression correctly

Also, add some basic behavior tests for addrspace and linksection which would have caught this bug in CI.

4 files changed, 122 insertions(+), 14 deletions(-)

lib/std/zig/AstGen.zig+1-1
......@@ -4228,7 +4228,7 @@ fn fnDecl(
42284228 if (fn_proto.ast.addrspace_expr != 0) {
42294229 astgen.restoreSourceCursor(saved_cursor);
42304230 const addrspace_ty = try addrspace_gz.addBuiltinValue(fn_proto.ast.addrspace_expr, .address_space);
4231 const inst = try expr(&addrspace_gz, &addrspace_gz.base, .{ .rl = .{ .coerced_ty = addrspace_ty } }, fn_proto.ast.section_expr);
4231 const inst = try expr(&addrspace_gz, &addrspace_gz.base, .{ .rl = .{ .coerced_ty = addrspace_ty } }, fn_proto.ast.addrspace_expr);
42324232 _ = try addrspace_gz.addBreakWithSrcNode(.break_inline, decl_inst, inst, decl_node);
42334233 }
42344234
test/behavior.zig+1-1
......@@ -1,6 +1,7 @@
11const builtin = @import("builtin");
22
33test {
4 _ = @import("behavior/addrspace_and_linksection.zig");
45 _ = @import("behavior/align.zig");
56 _ = @import("behavior/alignof.zig");
67 _ = @import("behavior/array.zig");
......@@ -100,7 +101,6 @@ test {
100101 _ = @import("behavior/tuple_declarations.zig");
101102 _ = @import("behavior/type.zig");
102103 _ = @import("behavior/type_info.zig");
103 _ = @import("behavior/type_info_mul_linksection_addrspace_decls.zig");
104104 _ = @import("behavior/typename.zig");
105105 _ = @import("behavior/undefined.zig");
106106 _ = @import("behavior/underscore.zig");
test/behavior/addrspace_and_linksection.zig created+120
......@@ -0,0 +1,120 @@
1const builtin = @import("builtin");
2
3/// Elements are const_linksection, var_linksection, fn_linksection
4const linksections: ?[3][]const u8 = switch (builtin.target.ofmt) {
5 .elf => .{ ".rodata", ".data", ".text" },
6 .coff => .{ ".rdata", ".data", ".text" },
7 .macho => .{ "__TEXT,__const", "__DATA,__data", "__TEXT,__text" },
8 else => null,
9};
10const const_linksection = linksections.?[0];
11const var_linksection = linksections.?[1];
12const fn_linksection = linksections.?[2];
13
14test "addrspace on container-level const" {
15 const S = struct {
16 const a: u32 addrspace(.generic) = 123;
17 fn check(ptr: anytype) !void {
18 if (ptr.* != 123) return error.TestFailed;
19 }
20 };
21 try S.check(&S.a);
22 try comptime S.check(&S.a);
23}
24
25test "linksection on container-level const" {
26 if (linksections == null) return;
27 const S = struct {
28 const a: u32 linksection(const_linksection) = 123;
29 fn check(ptr: anytype) !void {
30 if (ptr.* != 123) return error.TestFailed;
31 }
32 };
33 try S.check(&S.a);
34 try comptime S.check(&S.a);
35}
36
37test "addrspace and linksection on container-level const" {
38 if (linksections == null) return;
39 const S = struct {
40 const a: u32 addrspace(.generic) linksection(const_linksection) = 123;
41 fn check(ptr: anytype) !void {
42 if (ptr.* != 123) return error.TestFailed;
43 }
44 };
45 try S.check(&S.a);
46 try comptime S.check(&S.a);
47}
48
49test "addrspace on container-level var" {
50 const S = struct {
51 var a: u32 addrspace(.generic) = 123;
52 fn check(ptr: anytype) !void {
53 if (ptr.* != 123) return error.TestFailed;
54 }
55 };
56 try S.check(&S.a);
57}
58
59test "linksection on container-level var" {
60 if (linksections == null) return;
61 const S = struct {
62 var a: u32 linksection(var_linksection) = 123;
63 fn check(ptr: anytype) !void {
64 if (ptr.* != 123) return error.TestFailed;
65 }
66 };
67 try S.check(&S.a);
68}
69
70test "addrspace and linksection on container-level var" {
71 if (linksections == null) return;
72 const S = struct {
73 var a: u32 addrspace(.generic) linksection(var_linksection) = 123;
74 fn check(ptr: anytype) !void {
75 if (ptr.* != 123) return error.TestFailed;
76 }
77 };
78 try S.check(&S.a);
79}
80
81test "addrspace on fn" {
82 const S = struct {
83 fn f() addrspace(.generic) u32 {
84 return 123;
85 }
86 fn check(fnPtr: anytype) !void {
87 if (fnPtr() != 123) return error.TestFailed;
88 }
89 };
90 try S.check(&S.f);
91 try comptime S.check(&S.f);
92}
93
94test "linksection on fn" {
95 if (linksections == null) return;
96 const S = struct {
97 fn f() linksection(fn_linksection) u32 {
98 return 123;
99 }
100 fn check(fnPtr: anytype) !void {
101 if (fnPtr() != 123) return error.TestFailed;
102 }
103 };
104 try S.check(&S.f);
105 try comptime S.check(&S.f);
106}
107
108test "addrspace and linksection on fn" {
109 if (linksections == null) return;
110 const S = struct {
111 fn f() addrspace(.generic) linksection(fn_linksection) u32 {
112 return 123;
113 }
114 fn check(fnPtr: anytype) !void {
115 if (fnPtr() != 123) return error.TestFailed;
116 }
117 };
118 try S.check(&S.f);
119 try comptime S.check(&S.f);
120}
test/behavior/type_info_mul_linksection_addrspace_decls.zig deleted-12
......@@ -1,12 +0,0 @@
1const std = @import("std");
2const expect = std.testing.expect;
3
4pub const a linksection("sec_a") = 0;
5pub const b linksection("sec_b") = 0;
6pub const c addrspace("space_c") = 0;
7pub const d addrspace("space_d") = 0;
8
9test {
10 const decls = @typeInfo(@This()).@"struct".decls;
11 try expect(decls.len == 4);
12}