Skip to content

Commit

Permalink
translate-c: don't bother with unwrapping pointers
Browse files Browse the repository at this point in the history
Dereferencing a c pointer implicitly includes an unwrap,
manually adding it just causes bugs.
  • Loading branch information
Vexu committed Jun 13, 2021
1 parent 540b529 commit 6664679
Show file tree
Hide file tree
Showing 4 changed files with 36 additions and 10 deletions.
12 changes: 7 additions & 5 deletions src/translate_c.zig
Original file line number Diff line number Diff line change
Expand Up @@ -1438,7 +1438,7 @@ fn transSimpleOffsetOfExpr(
}
}
}
return fail(c, error.UnsupportedTranslation, expr.getBeginLoc(), "Failed to translate simple OffsetOfExpr", .{});
return fail(c, error.UnsupportedTranslation, expr.getBeginLoc(), "failed to translate simple OffsetOfExpr", .{});
}

fn transOffsetOfExpr(
Expand Down Expand Up @@ -2619,7 +2619,7 @@ fn transInitListExpr(
const source_loc = @ptrCast(*const clang.Expr, expr).getBeginLoc();

if (qualTypeWasDemotedToOpaque(c, qt)) {
return fail(c, error.UnsupportedTranslation, source_loc, "Cannot initialize opaque type", .{});
return fail(c, error.UnsupportedTranslation, source_loc, "cannot initialize opaque type", .{});
}

if (qual_type.isRecordType()) {
Expand Down Expand Up @@ -3408,7 +3408,7 @@ fn transUnaryExprOrTypeTraitExpr(
c,
error.UnsupportedTranslation,
loc,
"Unsupported type trait kind {}",
"unsupported type trait kind {}",
.{kind},
),
}
Expand Down Expand Up @@ -3450,13 +3450,15 @@ fn transUnaryOperator(c: *Context, scope: *Scope, stmt: *const clang.UnaryOperat
return Tag.address_of.create(c.arena, try transExpr(c, scope, op_expr, used));
},
.Deref => {
if (qualTypeWasDemotedToOpaque(c, stmt.getType()))
return fail(c, error.UnsupportedTranslation, stmt.getBeginLoc(), "cannot dereference opaque type", .{});

const node = try transExpr(c, scope, op_expr, used);
var is_ptr = false;
const fn_ty = qualTypeGetFnProto(op_expr.getType(), &is_ptr);
if (fn_ty != null and is_ptr)
return node;
const unwrapped = try Tag.unwrap.create(c.arena, node);
return Tag.deref.create(c.arena, unwrapped);
return Tag.deref.create(c.arena, node);
},
.Plus => return transExpr(c, scope, op_expr, used),
.Minus => {
Expand Down
2 changes: 1 addition & 1 deletion src/translate_c/ast.zig
Original file line number Diff line number Diff line change
Expand Up @@ -2294,7 +2294,6 @@ fn renderNodeGrouped(c: *Context, node: Node) !NodeIndex {
.single_pointer,
.unwrap,
.deref,
.address_of,
.not,
.negate,
.negate_wrap,
Expand Down Expand Up @@ -2349,6 +2348,7 @@ fn renderNodeGrouped(c: *Context, node: Node) !NodeIndex {
.container_init,
.container_init_dot,
.block,
.address_of,
=> return c.addNode(.{
.tag = .grouped_expression,
.main_token = try c.addToken(.l_paren, "("),
Expand Down
10 changes: 10 additions & 0 deletions test/run_translated_c.zig
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,16 @@ const tests = @import("tests.zig");
const nl = std.cstr.line_sep;

pub fn addCases(cases: *tests.RunTranslatedCContext) void {
cases.add("dereference address of",
\\#include <stdlib.h>
\\int main(void) {
\\ int i = 0;
\\ *&i = 42;
\\ if (i != 42) abort();
\\ return 0;
\\}
, "");

cases.add("division of floating literals",
\\#define _NO_CRT_STDIO_INLINE 1
\\#include <stdio.h>
Expand Down
22 changes: 18 additions & 4 deletions test/translate_c.zig
Original file line number Diff line number Diff line change
Expand Up @@ -1515,7 +1515,7 @@ pub fn addCases(cases: *tests.TranslateCContext) void {
, &[_][]const u8{
\\pub export fn foo() void {
\\ var x: [*c]c_int = undefined;
\\ x.?.* = 1;
\\ x.* = 1;
\\}
});

Expand All @@ -1529,7 +1529,7 @@ pub fn addCases(cases: *tests.TranslateCContext) void {
\\pub export fn foo() c_int {
\\ var x: c_int = 1234;
\\ var ptr: [*c]c_int = &x;
\\ return ptr.?.*;
\\ return ptr.*;
\\}
});

Expand Down Expand Up @@ -3243,7 +3243,7 @@ pub fn addCases(cases: *tests.TranslateCContext) void {
\\ const tmp_2 = ref.*;
\\ ref.* += 1;
\\ break :blk_1 tmp_2;
\\ }).?.* = tmp;
\\ }).* = tmp;
\\ break :blk tmp;
\\ };
\\}
Expand Down Expand Up @@ -3583,12 +3583,26 @@ pub fn addCases(cases: *tests.TranslateCContext) void {
\\ struct my_struct S = {.a = 1, .b = 2};
\\}
, &[_][]const u8{
\\warning: Cannot initialize opaque type
\\warning: cannot initialize opaque type
,
\\warning: unable to translate function, demoted to extern
\\pub extern fn initialize() void;
});

cases.add("Demote function that dereferences opaque type",
\\struct my_struct {
\\ unsigned a: 1;
\\};
\\void deref(struct my_struct *s) {
\\ *s;
\\}
, &[_][]const u8{
\\warning: cannot dereference opaque type
,
\\warning: unable to translate function, demoted to extern
\\pub extern fn deref(arg_s: ?*struct_my_struct) void;
});

cases.add("Function prototype declared within function",
\\int foo(void) {
\\ extern int bar(int, int);
Expand Down

0 comments on commit 6664679

Please sign in to comment.