authorgravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2020-02-18 18:45:25-05:00
committergravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2020-02-18 18:45:25-05:00
logcbc4e59e6805d27f0e889c0a9ff8488376cea5c0
tree0f5ca27a04c354639a61c65c6acb7e867fb0c5bf
parentccca4b5a5e98dd96aaeb365af6c1cfbe87dca181
parent30194f27fb5521b11442f1d13474eac3915051d7
signaturelock-open Commit is signed but in an unrecognized format.

Merge branch 'LemonBoy-c8c8c8c8'

closes #4502

5 files changed, 17 insertions(+), 3 deletions(-)

doc/langref.html.in+1-1
...@@ -7399,7 +7399,7 @@ comptime {...@@ -7399,7 +7399,7 @@ comptime {
7399 @export(internalName, .{ .name = "foo", .linkage = .Strong });7399 @export(internalName, .{ .name = "foo", .linkage = .Strong });
7400}7400}
74017401
7402extern fn internalName() void {}7402fn internalName() callconv(.C) void {}
7403 {#code_end#}7403 {#code_end#}
7404 <p>This is equivalent to:</p>7404 <p>This is equivalent to:</p>
7405 {#code_begin|obj#}7405 {#code_begin|obj#}
lib/std/zig/parser_test.zig+2
...@@ -92,10 +92,12 @@ test "zig fmt: convert extern/nakedcc/stdcallcc into callconv(...)" {...@@ -92,10 +92,12 @@ test "zig fmt: convert extern/nakedcc/stdcallcc into callconv(...)" {
92 \\nakedcc fn foo1() void {}92 \\nakedcc fn foo1() void {}
93 \\stdcallcc fn foo2() void {}93 \\stdcallcc fn foo2() void {}
94 \\extern fn foo3() void {}94 \\extern fn foo3() void {}
95 \\extern "mylib" fn foo4() void {}
95 ,96 ,
96 \\fn foo1() callconv(.Naked) void {}97 \\fn foo1() callconv(.Naked) void {}
97 \\fn foo2() callconv(.Stdcall) void {}98 \\fn foo2() callconv(.Stdcall) void {}
98 \\fn foo3() callconv(.C) void {}99 \\fn foo3() callconv(.C) void {}
100 \\fn foo4() callconv(.C) void {}
99 \\101 \\
100 );102 );
101}103}
lib/std/zig/render.zig+1
...@@ -1396,6 +1396,7 @@ fn renderExpression(...@@ -1396,6 +1396,7 @@ fn renderExpression(
1396 try renderToken(tree, stream, extern_export_inline_token, indent, start_col, Space.Space); // extern/export1396 try renderToken(tree, stream, extern_export_inline_token, indent, start_col, Space.Space); // extern/export
1397 } else {1397 } else {
1398 cc_rewrite_str = ".C";1398 cc_rewrite_str = ".C";
1399 fn_proto.lib_name = null;
1399 }1400 }
1400 }1401 }
14011402
src/parser.cpp+3
...@@ -689,6 +689,9 @@ static AstNode *ast_parse_top_level_decl(ParseContext *pc, VisibMod visib_mod, B...@@ -689,6 +689,9 @@ static AstNode *ast_parse_top_level_decl(ParseContext *pc, VisibMod visib_mod, B
689689
690 AstNode *res = fn_proto;690 AstNode *res = fn_proto;
691 if (body != nullptr) {691 if (body != nullptr) {
692 if (fn_proto->data.fn_proto.is_extern) {
693 ast_error(pc, first, "Extern functions have no body");
694 }
692 res = ast_create_node_copy_line_info(pc, NodeTypeFnDef, fn_proto);695 res = ast_create_node_copy_line_info(pc, NodeTypeFnDef, fn_proto);
693 res->data.fn_def.fn_proto = fn_proto;696 res->data.fn_def.fn_proto = fn_proto;
694 res->data.fn_def.body = body;697 res->data.fn_def.body = body;
test/compile_errors.zig+10-2
...@@ -3,15 +3,23 @@ const builtin = @import("builtin");...@@ -3,15 +3,23 @@ const builtin = @import("builtin");
3const Target = @import("std").Target;3const Target = @import("std").Target;
44
5pub fn addCases(cases: *tests.CompileErrorContext) void {5pub fn addCases(cases: *tests.CompileErrorContext) void {
6 cases.addTest("",6 cases.addTest("access invalid @typeInfo decl",
7 \\const A = B;7 \\const A = B;
8 \\test "Crash" {8 \\test "Crash" {
9 \\ _ = @typeInfo(@This()).Struct.decls;9 \\ _ = @typeInfo(@This()).Struct.decls[0];
10 \\}10 \\}
11 , &[_][]const u8{11 , &[_][]const u8{
12 "tmp.zig:1:11: error: use of undeclared identifier 'B'",12 "tmp.zig:1:11: error: use of undeclared identifier 'B'",
13 });13 });
1414
15 cases.addTest("reject extern function definitions with body",
16 \\extern "c" fn definitelyNotInLibC(a: i32, b: i32) i32 {
17 \\ return a + b;
18 \\}
19 , &[_][]const u8{
20 "tmp.zig:1:1: error: Extern functions have no body",
21 });
22
15 cases.addTest("duplicate field in anonymous struct literal",23 cases.addTest("duplicate field in anonymous struct literal",
16 \\export fn entry() void {24 \\export fn entry() void {
17 \\ const anon = .{25 \\ const anon = .{