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(
14381438 }
14391439 }
14401440 }
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", .{});
14421442}
14431443
14441444fn transOffsetOfExpr(
......@@ -2619,7 +2619,7 @@ fn transInitListExpr(
26192619 const source_loc = @ptrCast(*const clang.Expr, expr).getBeginLoc();
26202620
26212621 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", .{});
26232623 }
26242624
26252625 if (qual_type.isRecordType()) {
......@@ -3408,7 +3408,7 @@ fn transUnaryExprOrTypeTraitExpr(
34083408 c,
34093409 error.UnsupportedTranslation,
34103410 loc,
3411 "Unsupported type trait kind {}",
3411 "unsupported type trait kind {}",
34123412 .{kind},
34133413 ),
34143414 }
......@@ -3450,13 +3450,15 @@ fn transUnaryOperator(c: *Context, scope: *Scope, stmt: *const clang.UnaryOperat
34503450 return Tag.address_of.create(c.arena, try transExpr(c, scope, op_expr, used));
34513451 },
34523452 .Deref => {
3453 if (qualTypeWasDemotedToOpaque(c, stmt.getType()))
3454 return fail(c, error.UnsupportedTranslation, stmt.getBeginLoc(), "cannot dereference opaque type", .{});
3455
34533456 const node = try transExpr(c, scope, op_expr, used);
34543457 var is_ptr = false;
34553458 const fn_ty = qualTypeGetFnProto(op_expr.getType(), &is_ptr);
34563459 if (fn_ty != null and is_ptr)
34573460 return node;
3458 const unwrapped = try Tag.unwrap.create(c.arena, node);
3459 return Tag.deref.create(c.arena, unwrapped);
3461 return Tag.deref.create(c.arena, node);
34603462 },
34613463 .Plus => return transExpr(c, scope, op_expr, used),
34623464 .Minus => {
src/translate_c/ast.zig+1-1
......@@ -2294,7 +2294,6 @@ fn renderNodeGrouped(c: *Context, node: Node) !NodeIndex {
22942294 .single_pointer,
22952295 .unwrap,
22962296 .deref,
2297 .address_of,
22982297 .not,
22992298 .negate,
23002299 .negate_wrap,
......@@ -2349,6 +2348,7 @@ fn renderNodeGrouped(c: *Context, node: Node) !NodeIndex {
23492348 .container_init,
23502349 .container_init_dot,
23512350 .block,
2351 .address_of,
23522352 => return c.addNode(.{
23532353 .tag = .grouped_expression,
23542354 .main_token = try c.addToken(.l_paren, "("),
test/run_translated_c.zig+10
......@@ -3,6 +3,16 @@ const tests = @import("tests.zig");
33const nl = std.cstr.line_sep;
44
55pub 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
616 cases.add("division of floating literals",
717 \\#define _NO_CRT_STDIO_INLINE 1
818 \\#include <stdio.h>
test/translate_c.zig+18-4
......@@ -1515,7 +1515,7 @@ pub fn addCases(cases: *tests.TranslateCContext) void {
15151515 , &[_][]const u8{
15161516 \\pub export fn foo() void {
15171517 \\ var x: [*c]c_int = undefined;
1518 \\ x.?.* = 1;
1518 \\ x.* = 1;
15191519 \\}
15201520 });
15211521
......@@ -1529,7 +1529,7 @@ pub fn addCases(cases: *tests.TranslateCContext) void {
15291529 \\pub export fn foo() c_int {
15301530 \\ var x: c_int = 1234;
15311531 \\ var ptr: [*c]c_int = &x;
1532 \\ return ptr.?.*;
1532 \\ return ptr.*;
15331533 \\}
15341534 });
15351535
......@@ -3243,7 +3243,7 @@ pub fn addCases(cases: *tests.TranslateCContext) void {
32433243 \\ const tmp_2 = ref.*;
32443244 \\ ref.* += 1;
32453245 \\ break :blk_1 tmp_2;
3246 \\ }).?.* = tmp;
3246 \\ }).* = tmp;
32473247 \\ break :blk tmp;
32483248 \\ };
32493249 \\}
......@@ -3583,12 +3583,26 @@ pub fn addCases(cases: *tests.TranslateCContext) void {
35833583 \\ struct my_struct S = {.a = 1, .b = 2};
35843584 \\}
35853585 , &[_][]const u8{
3586 \\warning: Cannot initialize opaque type
3586 \\warning: cannot initialize opaque type
35873587 ,
35883588 \\warning: unable to translate function, demoted to extern
35893589 \\pub extern fn initialize() void;
35903590 });
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
35923606 cases.add("Function prototype declared within function",
35933607 \\int foo(void) {
35943608 \\ extern int bar(int, int);