aboutsummaryrefslogtreecommitdiff
path: root/gnu/packages/patches/zig-0.10.0-1638-re-add-qualCast.patch
blob: 32745f468c38f399a3d7a9f675b345f184c0f205 (about) (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
From 6b5ac4fe191a277b3f6c129e75e62c25e70ed017 Mon Sep 17 00:00:00 2001
From: motiejus <foo@bar>
Date: Fri, 8 Nov 2024 19:12:33 +0200
Subject: [PATCH] 0.10.0-1638-g7199d7c777: re-add @qualCast

---
 src/AstGen.zig    |  2 ++
 src/BuiltinFn.zig |  8 ++++++++
 src/Sema.zig      | 44 ++++++++++++++++++++++++++++++++++++++++++++
 src/Zir.zig       |  6 ++++++
 src/print_zir.zig |  1 +
 5 files changed, 61 insertions(+)

diff --git a/src/AstGen.zig b/src/AstGen.zig
index 40eef32d4e..f04713fab5 100644
--- a/src/AstGen.zig
+++ b/src/AstGen.zig
@@ -2531,6 +2531,7 @@ fn addEnsureResult(gz: *GenZir, maybe_unused_result: Zir.Inst.Ref, statement: As
             .bit_size_of,
             .typeof_log2_int_type,
             .ptr_to_int,
+            .qual_cast,
             .align_of,
             .bool_to_int,
             .embed_file,
@@ -8038,6 +8039,7 @@ fn builtinCall(
         .float_cast   => return typeCast(gz, scope, ri, node, params[0], params[1], .float_cast),
         .int_cast     => return typeCast(gz, scope, ri, node, params[0], params[1], .int_cast),
         .ptr_cast     => return typeCast(gz, scope, ri, node, params[0], params[1], .ptr_cast),
+        .qual_cast    => return typeCast(gz, scope, ri, node, params[0], params[1], .qual_cast),
         .truncate     => return typeCast(gz, scope, ri, node, params[0], params[1], .truncate),
         // zig fmt: on
 
diff --git a/src/BuiltinFn.zig b/src/BuiltinFn.zig
index 20edbabe47..78d492a99b 100644
--- a/src/BuiltinFn.zig
+++ b/src/BuiltinFn.zig
@@ -76,6 +76,7 @@ pub const Tag = enum {
     prefetch,
     ptr_cast,
     ptr_to_int,
+    qual_cast,
     rem,
     return_address,
     select,
@@ -683,6 +684,13 @@ pub const list = list: {
                 .param_count = 1,
             },
         },
+        .{
+            "@qualCast",
+            .{
+                .tag = .qual_cast,
+                .param_count = 2,
+            },
+        },
         .{
             "@rem",
             .{
diff --git a/src/Sema.zig b/src/Sema.zig
index cf6350e35f..f76c5bd3c4 100644
--- a/src/Sema.zig
+++ b/src/Sema.zig
@@ -1015,6 +1015,7 @@ fn analyzeBodyInner(
             .float_cast                   => try sema.zirFloatCast(block, inst),
             .int_cast                     => try sema.zirIntCast(block, inst),
             .ptr_cast                     => try sema.zirPtrCast(block, inst),
+            .qual_cast                    => try sema.zirQualCast(block, inst),
             .truncate                     => try sema.zirTruncate(block, inst),
             .align_cast                   => try sema.zirAlignCast(block, inst),
             .has_decl                     => try sema.zirHasDecl(block, inst),
@@ -19661,6 +19662,49 @@ fn zirPtrCast(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air
     return block.addBitCast(aligned_dest_ty, ptr);
 }
 
+fn zirQualCast(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.Inst.Ref {
+    const inst_data = sema.code.instructions.items(.data)[inst].pl_node;
+    const src = inst_data.src();
+    const dest_ty_src: LazySrcLoc = .{ .node_offset_builtin_call_arg0 = inst_data.src_node };
+    const operand_src: LazySrcLoc = .{ .node_offset_builtin_call_arg1 = inst_data.src_node };
+    const extra = sema.code.extraData(Zir.Inst.Bin, inst_data.payload_index).data;
+    const dest_ty = try sema.resolveType(block, dest_ty_src, extra.lhs);
+    const operand = try sema.resolveInst(extra.rhs);
+    const operand_ty = sema.typeOf(operand);
+
+    try sema.checkPtrType(block, dest_ty_src, dest_ty);
+    try sema.checkPtrOperand(block, operand_src, operand_ty);
+
+    var operand_payload = operand_ty.ptrInfo();
+    var dest_info = dest_ty.ptrInfo();
+
+    operand_payload.data.mutable = dest_info.data.mutable;
+    operand_payload.data.@"volatile" = dest_info.data.@"volatile";
+
+    const altered_operand_ty = Type.initPayload(&operand_payload.base);
+    if (!altered_operand_ty.eql(dest_ty, sema.mod)) {
+        const msg = msg: {
+            const msg = try sema.errMsg(block, src, "'@qualCast' can only modify 'const' and 'volatile' qualifiers", .{});
+            errdefer msg.destroy(sema.gpa);
+
+            dest_info.data.mutable = !operand_ty.isConstPtr();
+            dest_info.data.@"volatile" = operand_ty.isVolatilePtr();
+            const altered_dest_ty = Type.initPayload(&dest_info.base);
+            try sema.errNote(block, src, msg, "expected type '{}'", .{altered_dest_ty.fmt(sema.mod)});
+            try sema.errNote(block, src, msg, "got type '{}'", .{operand_ty.fmt(sema.mod)});
+            break :msg msg;
+        };
+        return sema.failWithOwnedErrorMsg(msg);
+    }
+
+    if (try sema.resolveMaybeUndefVal(operand)) |operand_val| {
+        return sema.addConstant(dest_ty, operand_val);
+    }
+
+    try sema.requireRuntimeBlock(block, src, null);
+    return block.addBitCast(dest_ty, operand);
+}
+
 fn zirConstCast(sema: *Sema, block: *Block, extended: Zir.Inst.Extended.InstData) CompileError!Air.Inst.Ref {
     const extra = sema.code.extraData(Zir.Inst.UnNode, extended.operand).data;
     const src = LazySrcLoc.nodeOffset(extra.node);
diff --git a/src/Zir.zig b/src/Zir.zig
index 58f9fdff14..338712c0b7 100644
--- a/src/Zir.zig
+++ b/src/Zir.zig
@@ -857,6 +857,9 @@ pub const Inst = struct {
         /// Implements the `@ptrCast` builtin.
         /// Uses `pl_node` with payload `Bin`. `lhs` is dest type, `rhs` is operand.
         ptr_cast,
+        /// Implements the `@qualCast` builtin.
+        /// Uses `pl_node` with payload `Bin`. `lhs` is dest type, `rhs` is operand.
+        qual_cast,
         /// Implements the `@truncate` builtin.
         /// Uses `pl_node` with payload `Bin`. `lhs` is dest type, `rhs` is operand.
         truncate,
@@ -1195,6 +1198,7 @@ pub const Inst = struct {
                 .float_cast,
                 .int_cast,
                 .ptr_cast,
+                .qual_cast,
                 .truncate,
                 .align_cast,
                 .has_field,
@@ -1484,6 +1488,7 @@ pub const Inst = struct {
                 .float_cast,
                 .int_cast,
                 .ptr_cast,
+                .qual_cast,
                 .truncate,
                 .align_cast,
                 .has_field,
@@ -1755,6 +1760,7 @@ pub const Inst = struct {
                 .float_cast = .pl_node,
                 .int_cast = .pl_node,
                 .ptr_cast = .pl_node,
+                .qual_cast = .pl_node,
                 .truncate = .pl_node,
                 .align_cast = .pl_node,
                 .typeof_builtin = .pl_node,
diff --git a/src/print_zir.zig b/src/print_zir.zig
index 8d97000582..c2485a8cb4 100644
--- a/src/print_zir.zig
+++ b/src/print_zir.zig
@@ -332,6 +332,7 @@ const Writer = struct {
             .float_cast,
             .int_cast,
             .ptr_cast,
+            .qual_cast,
             .truncate,
             .align_cast,
             .div_exact,
-- 
2.44.1