diff --git a/src/translate_c.zig b/src/translate_c.zig index 0ea60f3242..daf775e93f 100644 --- a/src/translate_c.zig +++ b/src/translate_c.zig @@ -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( @@ -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()) { @@ -3408,7 +3408,7 @@ fn transUnaryExprOrTypeTraitExpr( c, error.UnsupportedTranslation, loc, - "Unsupported type trait kind {}", + "unsupported type trait kind {}", .{kind}, ), } @@ -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 => { diff --git a/src/translate_c/ast.zig b/src/translate_c/ast.zig index bf1e993ca5..8ee8b670c3 100644 --- a/src/translate_c/ast.zig +++ b/src/translate_c/ast.zig @@ -2294,7 +2294,6 @@ fn renderNodeGrouped(c: *Context, node: Node) !NodeIndex { .single_pointer, .unwrap, .deref, - .address_of, .not, .negate, .negate_wrap, @@ -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, "("), diff --git a/test/run_translated_c.zig b/test/run_translated_c.zig index 2aca445554..4440802c33 100644 --- a/test/run_translated_c.zig +++ b/test/run_translated_c.zig @@ -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 + \\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 diff --git a/test/translate_c.zig b/test/translate_c.zig index b4aa1e5915..d200265e1c 100644 --- a/test/translate_c.zig +++ b/test/translate_c.zig @@ -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; \\} }); @@ -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.*; \\} }); @@ -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; \\ }; \\} @@ -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);