authorgravatar for git@vexu.euVeikka Tuominen <git@vexu.eu> 2021-06-13 10:56:54+03:00
committergravatar for git@vexu.euVeikka Tuominen <git@vexu.eu> 2021-06-13 15:23:31+03:00
log6664679c8c1d24e929630daf8392ca09620d4a94
tree42c4fa816d5b802a0e9609580c86c22eaf98a36a
parent540b52931aeeee7c72c73361118d07ab986cf048

translate-c: don't bother with unwrapping pointers

Dereferencing a c pointer implicitly includes an unwrap, manually adding it just causes bugs.

4 files changed, 36 insertions(+), 10 deletions(-)

src/translate_c.zig+7-5
...@@ -1438,7 +1438,7 @@ fn transSimpleOffsetOfExpr(...@@ -1438,7 +1438,7 @@ fn transSimpleOffsetOfExpr(
1438 }1438 }
1439 }1439 }
1440 }1440 }
1441 return fail(c, error.UnsupportedTranslation, expr.getBeginLoc(), "Failed to translate simple OffsetOfExpr", .{});1441 return fail(c, error.UnsupportedTranslation, expr.getBeginLoc(), "failed to translate simple OffsetOfExpr", .{});
1442}1442}
14431443
1444fn transOffsetOfExpr(1444fn transOffsetOfExpr(
...@@ -2619,7 +2619,7 @@ fn transInitListExpr(...@@ -2619,7 +2619,7 @@ fn transInitListExpr(
2619 const source_loc = @ptrCast(*const clang.Expr, expr).getBeginLoc();2619 const source_loc = @ptrCast(*const clang.Expr, expr).getBeginLoc();
26202620
2621 if (qualTypeWasDemotedToOpaque(c, qt)) {2621 if (qualTypeWasDemotedToOpaque(c, qt)) {
2622 return fail(c, error.UnsupportedTranslation, source_loc, "Cannot initialize opaque type", .{});2622 return fail(c, error.UnsupportedTranslation, source_loc, "cannot initialize opaque type", .{});
2623 }2623 }
26242624
2625 if (qual_type.isRecordType()) {2625 if (qual_type.isRecordType()) {
...@@ -3408,7 +3408,7 @@ fn transUnaryExprOrTypeTraitExpr(...@@ -3408,7 +3408,7 @@ fn transUnaryExprOrTypeTraitExpr(
3408 c,3408 c,
3409 error.UnsupportedTranslation,3409 error.UnsupportedTranslation,
3410 loc,3410 loc,
3411 "Unsupported type trait kind {}",3411 "unsupported type trait kind {}",
3412 .{kind},3412 .{kind},
3413 ),3413 ),
3414 }3414 }
...@@ -3450,13 +3450,15 @@ fn transUnaryOperator(c: *Context, scope: *Scope, stmt: *const clang.UnaryOperat...@@ -3450,13 +3450,15 @@ fn transUnaryOperator(c: *Context, scope: *Scope, stmt: *const clang.UnaryOperat
3450 return Tag.address_of.create(c.arena, try transExpr(c, scope, op_expr, used));3450 return Tag.address_of.create(c.arena, try transExpr(c, scope, op_expr, used));
3451 },3451 },
3452 .Deref => {3452 .Deref => {
3453 if (qualTypeWasDemotedToOpaque(c, stmt.getType()))
3454 return fail(c, error.UnsupportedTranslation, stmt.getBeginLoc(), "cannot dereference opaque type", .{});
3455
3453 const node = try transExpr(c, scope, op_expr, used);3456 const node = try transExpr(c, scope, op_expr, used);
3454 var is_ptr = false;3457 var is_ptr = false;
3455 const fn_ty = qualTypeGetFnProto(op_expr.getType(), &is_ptr);3458 const fn_ty = qualTypeGetFnProto(op_expr.getType(), &is_ptr);
3456 if (fn_ty != null and is_ptr)3459 if (fn_ty != null and is_ptr)
3457 return node;3460 return node;
3458 const unwrapped = try Tag.unwrap.create(c.arena, node);3461 return Tag.deref.create(c.arena, node);
3459 return Tag.deref.create(c.arena, unwrapped);
3460 },3462 },
3461 .Plus => return transExpr(c, scope, op_expr, used),3463 .Plus => return transExpr(c, scope, op_expr, used),
3462 .Minus => {3464 .Minus => {
src/translate_c/ast.zig+1-1
...@@ -2294,7 +2294,6 @@ fn renderNodeGrouped(c: *Context, node: Node) !NodeIndex {...@@ -2294,7 +2294,6 @@ fn renderNodeGrouped(c: *Context, node: Node) !NodeIndex {
2294 .single_pointer,2294 .single_pointer,
2295 .unwrap,2295 .unwrap,
2296 .deref,2296 .deref,
2297 .address_of,
2298 .not,2297 .not,
2299 .negate,2298 .negate,
2300 .negate_wrap,2299 .negate_wrap,
...@@ -2349,6 +2348,7 @@ fn renderNodeGrouped(c: *Context, node: Node) !NodeIndex {...@@ -2349,6 +2348,7 @@ fn renderNodeGrouped(c: *Context, node: Node) !NodeIndex {
2349 .container_init,2348 .container_init,
2350 .container_init_dot,2349 .container_init_dot,
2351 .block,2350 .block,
2351 .address_of,
2352 => return c.addNode(.{2352 => return c.addNode(.{
2353 .tag = .grouped_expression,2353 .tag = .grouped_expression,
2354 .main_token = try c.addToken(.l_paren, "("),2354 .main_token = try c.addToken(.l_paren, "("),
test/run_translated_c.zig+10
...@@ -3,6 +3,16 @@ const tests = @import("tests.zig");...@@ -3,6 +3,16 @@ const tests = @import("tests.zig");
3const nl = std.cstr.line_sep;3const nl = std.cstr.line_sep;
44
5pub fn addCases(cases: *tests.RunTranslatedCContext) void {5pub fn addCases(cases: *tests.RunTranslatedCContext) void {
6 cases.add("dereference address of",
7 \\#include <stdlib.h>
8 \\int main(void) {
9 \\ int i = 0;
10 \\ *&i = 42;
11 \\ if (i != 42) abort();
12 \\ return 0;
13 \\}
14 , "");
15
6 cases.add("division of floating literals",16 cases.add("division of floating literals",
7 \\#define _NO_CRT_STDIO_INLINE 117 \\#define _NO_CRT_STDIO_INLINE 1
8 \\#include <stdio.h>18 \\#include <stdio.h>
test/translate_c.zig+18-4
...@@ -1515,7 +1515,7 @@ pub fn addCases(cases: *tests.TranslateCContext) void {...@@ -1515,7 +1515,7 @@ pub fn addCases(cases: *tests.TranslateCContext) void {
1515 , &[_][]const u8{1515 , &[_][]const u8{
1516 \\pub export fn foo() void {1516 \\pub export fn foo() void {
1517 \\ var x: [*c]c_int = undefined;1517 \\ var x: [*c]c_int = undefined;
1518 \\ x.?.* = 1;1518 \\ x.* = 1;
1519 \\}1519 \\}
1520 });1520 });
15211521
...@@ -1529,7 +1529,7 @@ pub fn addCases(cases: *tests.TranslateCContext) void {...@@ -1529,7 +1529,7 @@ pub fn addCases(cases: *tests.TranslateCContext) void {
1529 \\pub export fn foo() c_int {1529 \\pub export fn foo() c_int {
1530 \\ var x: c_int = 1234;1530 \\ var x: c_int = 1234;
1531 \\ var ptr: [*c]c_int = &x;1531 \\ var ptr: [*c]c_int = &x;
1532 \\ return ptr.?.*;1532 \\ return ptr.*;
1533 \\}1533 \\}
1534 });1534 });
15351535
...@@ -3243,7 +3243,7 @@ pub fn addCases(cases: *tests.TranslateCContext) void {...@@ -3243,7 +3243,7 @@ pub fn addCases(cases: *tests.TranslateCContext) void {
3243 \\ const tmp_2 = ref.*;3243 \\ const tmp_2 = ref.*;
3244 \\ ref.* += 1;3244 \\ ref.* += 1;
3245 \\ break :blk_1 tmp_2;3245 \\ break :blk_1 tmp_2;
3246 \\ }).?.* = tmp;3246 \\ }).* = tmp;
3247 \\ break :blk tmp;3247 \\ break :blk tmp;
3248 \\ };3248 \\ };
3249 \\}3249 \\}
...@@ -3583,12 +3583,26 @@ pub fn addCases(cases: *tests.TranslateCContext) void {...@@ -3583,12 +3583,26 @@ pub fn addCases(cases: *tests.TranslateCContext) void {
3583 \\ struct my_struct S = {.a = 1, .b = 2};3583 \\ struct my_struct S = {.a = 1, .b = 2};
3584 \\}3584 \\}
3585 , &[_][]const u8{3585 , &[_][]const u8{
3586 \\warning: Cannot initialize opaque type3586 \\warning: cannot initialize opaque type
3587 ,3587 ,
3588 \\warning: unable to translate function, demoted to extern3588 \\warning: unable to translate function, demoted to extern
3589 \\pub extern fn initialize() void;3589 \\pub extern fn initialize() void;
3590 });3590 });
35913591
3592 cases.add("Demote function that dereferences opaque type",
3593 \\struct my_struct {
3594 \\ unsigned a: 1;
3595 \\};
3596 \\void deref(struct my_struct *s) {
3597 \\ *s;
3598 \\}
3599 , &[_][]const u8{
3600 \\warning: cannot dereference opaque type
3601 ,
3602 \\warning: unable to translate function, demoted to extern
3603 \\pub extern fn deref(arg_s: ?*struct_my_struct) void;
3604 });
3605
3592 cases.add("Function prototype declared within function",3606 cases.add("Function prototype declared within function",
3593 \\int foo(void) {3607 \\int foo(void) {
3594 \\ extern int bar(int, int);3608 \\ extern int bar(int, int);