Commit 0a6cd257b9

Evan Haas <evan@lagerdata.com>
2023-06-29 19:28:00
translate-c: Use `@constCast` and `@volatileCast` to remove CV-qualifiers
Instead of converting a pointer to an int and then back to a pointer.
1 parent 614bc67
Changed files (3)
src/translate_c/ast.zig
@@ -117,6 +117,10 @@ pub const Node = extern union {
         import_c_builtin,
         /// @intCast(operand)
         int_cast,
+        /// @constCast(operand)
+        const_cast,
+        /// @volatileCast(operand)
+        volatile_cast,
         /// @import("std").zig.c_translation.promoteIntLiteral(value, type, base)
         helpers_promoteIntLiteral,
         /// @import("std").zig.c_translation.signedRemainder(lhs, rhs)
@@ -278,6 +282,8 @@ pub const Node = extern union {
                 .ptr_from_int,
                 .ptr_cast,
                 .int_cast,
+                .const_cast,
+                .volatile_cast,
                 => Payload.UnOp,
 
                 .add,
@@ -1315,6 +1321,14 @@ fn renderNode(c: *Context, node: Node) Allocator.Error!NodeIndex {
             const payload = node.castTag(.int_cast).?.data;
             return renderBuiltinCall(c, "@intCast", &.{payload});
         },
+        .const_cast => {
+            const payload = node.castTag(.const_cast).?.data;
+            return renderBuiltinCall(c, "@constCast", &.{payload});
+        },
+        .volatile_cast => {
+            const payload = node.castTag(.volatile_cast).?.data;
+            return renderBuiltinCall(c, "@volatileCast", &.{payload});
+        },
         .signed_remainder => {
             const payload = node.castTag(.signed_remainder).?.data;
             const import_node = try renderStdImport(c, &.{ "zig", "c_translation", "signedRemainder" });
@@ -2291,6 +2305,8 @@ fn renderNodeGrouped(c: *Context, node: Node) !NodeIndex {
         .div_trunc,
         .signed_remainder,
         .int_cast,
+        .const_cast,
+        .volatile_cast,
         .as,
         .truncate,
         .bit_cast,
src/translate_c.zig
@@ -4063,12 +4063,12 @@ fn transCreateCompoundAssign(
     return block_scope.complete(c);
 }
 
-// Casting away const or volatile requires us to use @ptrFromInt
 fn removeCVQualifiers(c: *Context, dst_type_node: Node, expr: Node) Error!Node {
-    const int_from_ptr = try Tag.int_from_ptr.create(c.arena, expr);
+    const const_casted = try Tag.const_cast.create(c.arena, expr);
+    const volatile_casted = try Tag.volatile_cast.create(c.arena, const_casted);
     return Tag.as.create(c.arena, .{
         .lhs = dst_type_node,
-        .rhs = try Tag.ptr_from_int.create(c.arena, int_from_ptr),
+        .rhs = try Tag.ptr_cast.create(c.arena, volatile_casted),
     });
 }
 
test/translate_c.zig
@@ -3473,11 +3473,11 @@ pub fn addCases(cases: *tests.TranslateCContext) void {
         \\}
         \\pub export fn bar(arg_a: [*c]const c_int) void {
         \\    var a = arg_a;
-        \\    foo(@as([*c]c_int, @ptrFromInt(@intFromPtr(a))));
+        \\    foo(@as([*c]c_int, @ptrCast(@volatileCast(@constCast(a)))));
         \\}
         \\pub export fn baz(arg_a: [*c]volatile c_int) void {
         \\    var a = arg_a;
-        \\    foo(@as([*c]c_int, @ptrFromInt(@intFromPtr(a))));
+        \\    foo(@as([*c]c_int, @ptrCast(@volatileCast(@constCast(a)))));
         \\}
     });