authorgravatar for git@vexu.euVeikka Tuominen <git@vexu.eu> 2020-08-13 16:06:42+03:00
committergravatar for git@vexu.euVeikka Tuominen <git@vexu.eu> 2020-08-13 18:40:14+03:00
log13e472aa2a8113df6417c09727297a6106127f8e
tree86dd8d4836f87b048d509a5ceb0685d448bfef4c
parentc5368ba20c79b62d658c71033df9aeb7aa6e4581
signature Commit is signed but in an unrecognized format.

translate-c: add return if one is needed


5 files changed, 86 insertions(+), 22 deletions(-)

lib/std/hash/auto_hash.zig+1-1
......@@ -129,7 +129,7 @@ pub fn hash(hasher: anytype, key: anytype, comptime strat: HashStrategy) void {
129129 }
130130 },
131131
132 .Union => |info| blk: {
132 .Union => |info| {
133133 if (info.tag_type) |tag_type| {
134134 const tag = meta.activeTag(key);
135135 const s = hash(hasher, tag, strat);
src-self-hosted/Module.zig+2-2
......@@ -2798,7 +2798,7 @@ pub fn floatAdd(self: *Module, scope: *Scope, float_type: Type, src: usize, lhs:
27982798 val_payload.* = .{ .val = lhs_val + rhs_val };
27992799 break :blk &val_payload.base;
28002800 },
2801 128 => blk: {
2801 128 => {
28022802 return self.fail(scope, src, "TODO Implement addition for big floats", .{});
28032803 },
28042804 else => unreachable,
......@@ -2832,7 +2832,7 @@ pub fn floatSub(self: *Module, scope: *Scope, float_type: Type, src: usize, lhs:
28322832 val_payload.* = .{ .val = lhs_val - rhs_val };
28332833 break :blk &val_payload.base;
28342834 },
2835 128 => blk: {
2835 128 => {
28362836 return self.fail(scope, src, "TODO Implement substraction for big floats", .{});
28372837 },
28382838 else => unreachable,
src-self-hosted/translate_c.zig+40
......@@ -628,6 +628,46 @@ fn visitFnDecl(c: *Context, fn_decl: *const ZigClangFunctionDecl) Error!void {
628628 error.UnsupportedType,
629629 => return failDecl(c, fn_decl_loc, fn_name, "unable to translate function", .{}),
630630 };
631 // add return statement if the function didn't have one
632 blk: {
633 const fn_ty = @ptrCast(*const ZigClangFunctionType, fn_type);
634
635 if (ZigClangFunctionType_getNoReturnAttr(fn_ty)) break :blk;
636 const return_qt = ZigClangFunctionType_getReturnType(fn_ty);
637 if (isCVoid(return_qt)) break :blk;
638
639 if (block_scope.statements.items.len > 0) {
640 var last = block_scope.statements.items[block_scope.statements.items.len - 1];
641 while (true) {
642 switch (last.tag) {
643 .Block => {
644 const stmts = last.castTag(.Block).?.statements();
645 if (stmts.len == 0) break;
646
647 last = stmts[stmts.len - 1];
648 },
649 // no extra return needed
650 .Return => break :blk,
651 else => break,
652 }
653 }
654 }
655
656 const return_expr = try ast.Node.ControlFlowExpression.create(rp.c.arena, .{
657 .ltoken = try appendToken(rp.c, .Keyword_return, "return"),
658 .tag = .Return,
659 }, .{
660 .rhs = transZeroInitExpr(rp, scope, fn_decl_loc, ZigClangQualType_getTypePtr(return_qt)) catch |err| switch (err) {
661 error.OutOfMemory => |e| return e,
662 error.UnsupportedTranslation,
663 error.UnsupportedType,
664 => return failDecl(c, fn_decl_loc, fn_name, "unable to create a return value for function", .{}),
665 },
666 });
667 _ = try appendToken(rp.c, .Semicolon, ";");
668 try block_scope.statements.append(&return_expr.base);
669 }
670
631671 const body_node = try block_scope.complete(rp.c);
632672 proto_node.setTrailer("body_node", &body_node.base);
633673 return addTopLevelDecl(c, fn_name, &proto_node.base);
test/run_translated_c.zig-1
......@@ -15,7 +15,6 @@ pub fn addCases(cases: *tests.RunTranslatedCContext) void {
1515 \\ }
1616 \\ if (s0 != 1) abort();
1717 \\ if (s1 != 10) abort();
18 \\ return 0;
1918 \\}
2019 , "");
2120
test/translate_c.zig+43-18
......@@ -3,12 +3,33 @@ const std = @import("std");
33const CrossTarget = std.zig.CrossTarget;
44
55pub fn addCases(cases: *tests.TranslateCContext) void {
6 cases.add("missing return stmt",
7 \\int foo() {}
8 \\int bar() {
9 \\ int a = 2;
10 \\}
11 \\int baz() {
12 \\ return 0;
13 \\}
14 , &[_][]const u8{
15 \\pub export fn foo() c_int {
16 \\ return 0;
17 \\}
18 \\pub export fn bar() c_int {
19 \\ var a: c_int = 2;
20 \\ return 0;
21 \\}
22 \\pub export fn baz() c_int {
23 \\ return 0;
24 \\}
25 });
26
627 cases.add("alignof",
7 \\int main() {
28 \\void main() {
829 \\ int a = _Alignof(int);
930 \\}
1031 , &[_][]const u8{
11 \\pub export fn main() c_int {
32 \\pub export fn main() void {
1233 \\ var a: c_int = @bitCast(c_int, @truncate(c_uint, @alignOf(c_int)));
1334 \\}
1435 });
......@@ -539,6 +560,7 @@ pub fn addCases(cases: *tests.TranslateCContext) void {
539560 \\ c = (a * b);
540561 \\ c = @divTrunc(a, b);
541562 \\ c = @rem(a, b);
563 \\ return 0;
542564 \\}
543565 \\pub export fn u() c_uint {
544566 \\ var a: c_uint = undefined;
......@@ -549,6 +571,7 @@ pub fn addCases(cases: *tests.TranslateCContext) void {
549571 \\ c = (a *% b);
550572 \\ c = (a / b);
551573 \\ c = (a % b);
574 \\ return 0;
552575 \\}
553576 });
554577
......@@ -1596,13 +1619,13 @@ pub fn addCases(cases: *tests.TranslateCContext) void {
15961619 });
15971620
15981621 cases.add("worst-case assign",
1599 \\int foo() {
1622 \\void foo() {
16001623 \\ int a;
16011624 \\ int b;
16021625 \\ a = b = 2;
16031626 \\}
16041627 , &[_][]const u8{
1605 \\pub export fn foo() c_int {
1628 \\pub export fn foo() void {
16061629 \\ var a: c_int = undefined;
16071630 \\ var b: c_int = undefined;
16081631 \\ a = blk: {
......@@ -1650,11 +1673,12 @@ pub fn addCases(cases: *tests.TranslateCContext) void {
16501673 \\ a = 7;
16511674 \\ if (!true) break;
16521675 \\ }
1676 \\ return 0;
16531677 \\}
16541678 });
16551679
16561680 cases.add("for loops",
1657 \\int foo() {
1681 \\void foo() {
16581682 \\ for (int i = 2, b = 4; i + 2; i = 2) {
16591683 \\ int a = 2;
16601684 \\ a = 6, 5, 7;
......@@ -1662,7 +1686,7 @@ pub fn addCases(cases: *tests.TranslateCContext) void {
16621686 \\ char i = 2;
16631687 \\}
16641688 , &[_][]const u8{
1665 \\pub export fn foo() c_int {
1689 \\pub export fn foo() void {
16661690 \\ {
16671691 \\ var i: c_int = 2;
16681692 \\ var b: c_int = 4;
......@@ -1712,7 +1736,7 @@ pub fn addCases(cases: *tests.TranslateCContext) void {
17121736 });
17131737
17141738 cases.add("switch on int",
1715 \\int switch_fn(int i) {
1739 \\void switch_fn(int i) {
17161740 \\ int res = 0;
17171741 \\ switch (i) {
17181742 \\ case 0:
......@@ -1727,7 +1751,7 @@ pub fn addCases(cases: *tests.TranslateCContext) void {
17271751 \\ }
17281752 \\}
17291753 , &[_][]const u8{
1730 \\pub export fn switch_fn(arg_i: c_int) c_int {
1754 \\pub export fn switch_fn(arg_i: c_int) void {
17311755 \\ var i = arg_i;
17321756 \\ var res: c_int = 0;
17331757 \\ @"switch": {
......@@ -1787,13 +1811,13 @@ pub fn addCases(cases: *tests.TranslateCContext) void {
17871811 });
17881812
17891813 cases.add("assign",
1790 \\int max(int a) {
1814 \\void max(int a) {
17911815 \\ int tmp;
17921816 \\ tmp = a;
17931817 \\ a = tmp;
17941818 \\}
17951819 , &[_][]const u8{
1796 \\pub export fn max(arg_a: c_int) c_int {
1820 \\pub export fn max(arg_a: c_int) void {
17971821 \\ var a = arg_a;
17981822 \\ var tmp: c_int = undefined;
17991823 \\ tmp = a;
......@@ -2082,7 +2106,7 @@ pub fn addCases(cases: *tests.TranslateCContext) void {
20822106 \\ int b;
20832107 \\}a;
20842108 \\float b = 2.0f;
2085 \\int foo(void) {
2109 \\void foo(void) {
20862110 \\ struct Foo *c;
20872111 \\ a.b;
20882112 \\ c->b;
......@@ -2093,7 +2117,7 @@ pub fn addCases(cases: *tests.TranslateCContext) void {
20932117 \\};
20942118 \\pub extern var a: struct_Foo;
20952119 \\pub export var b: f32 = 2;
2096 \\pub export fn foo() c_int {
2120 \\pub export fn foo() void {
20972121 \\ var c: [*c]struct_Foo = undefined;
20982122 \\ _ = a.b;
20992123 \\ _ = c.*.b;
......@@ -2204,11 +2228,12 @@ pub fn addCases(cases: *tests.TranslateCContext) void {
22042228 \\ if (a < b) return b;
22052229 \\ if (a < b) return b else return a;
22062230 \\ if (a < b) {} else {}
2231 \\ return 0;
22072232 \\}
22082233 });
22092234
22102235 cases.add("if statements",
2211 \\int foo() {
2236 \\void foo() {
22122237 \\ if (2) {
22132238 \\ int a = 2;
22142239 \\ }
......@@ -2217,7 +2242,7 @@ pub fn addCases(cases: *tests.TranslateCContext) void {
22172242 \\ }
22182243 \\}
22192244 , &[_][]const u8{
2220 \\pub export fn foo() c_int {
2245 \\pub export fn foo() void {
22212246 \\ if (true) {
22222247 \\ var a: c_int = 2;
22232248 \\ }
......@@ -2811,12 +2836,12 @@ pub fn addCases(cases: *tests.TranslateCContext) void {
28112836 });
28122837
28132838 cases.add("arg name aliasing decl which comes after",
2814 \\int foo(int bar) {
2839 \\void foo(int bar) {
28152840 \\ bar = 2;
28162841 \\}
28172842 \\int bar = 4;
28182843 , &[_][]const u8{
2819 \\pub export fn foo(arg_bar_1: c_int) c_int {
2844 \\pub export fn foo(arg_bar_1: c_int) void {
28202845 \\ var bar_1 = arg_bar_1;
28212846 \\ bar_1 = 2;
28222847 \\}
......@@ -2824,12 +2849,12 @@ pub fn addCases(cases: *tests.TranslateCContext) void {
28242849 });
28252850
28262851 cases.add("arg name aliasing macro which comes after",
2827 \\int foo(int bar) {
2852 \\void foo(int bar) {
28282853 \\ bar = 2;
28292854 \\}
28302855 \\#define bar 4
28312856 , &[_][]const u8{
2832 \\pub export fn foo(arg_bar_1: c_int) c_int {
2857 \\pub export fn foo(arg_bar_1: c_int) void {
28332858 \\ var bar_1 = arg_bar_1;
28342859 \\ bar_1 = 2;
28352860 \\}