| author | |
| committer | |
| log | 6664679c8c1d24e929630daf8392ca09620d4a94 |
| tree | 42c4fa816d5b802a0e9609580c86c22eaf98a36a |
| parent | 540b52931aeeee7c72c73361118d07ab986cf048 |
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 | } |
| 1443 | 1443 | ||
| 1444 | fn transOffsetOfExpr( | 1444 | fn 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(); |
| 2620 | 2620 | ||
| 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 | } |
| 2624 | 2624 | ||
| 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"); |
| 3 | const nl = std.cstr.line_sep; | 3 | const nl = std.cstr.line_sep; |
| 4 | 4 | ||
| 5 | pub fn addCases(cases: *tests.RunTranslatedCContext) void { | 5 | pub 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 1 | 17 | \\#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 | }); |
| 1521 | 1521 | ||
| ... | @@ -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 | }); |
| 1535 | 1535 | ||
| ... | @@ -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 type | 3586 | \\warning: cannot initialize opaque type |
| 3587 | , | 3587 | , |
| 3588 | \\warning: unable to translate function, demoted to extern | 3588 | \\warning: unable to translate function, demoted to extern |
| 3589 | \\pub extern fn initialize() void; | 3589 | \\pub extern fn initialize() void; |
| 3590 | }); | 3590 | }); |
| 3591 | 3591 | ||
| 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); |