| author | |
| committer | |
| log | 237dfdbdc6f83071cff88489cc66cb83a2d65b00 |
| tree | 6aade70d5b9fa2ec5706dcd7c82e4c63822a6b2f |
| parent | 6f0f8a92ec7cf7eac8c05469a46398f47885614e |
closes #305 files changed, 58 insertions(+), 3 deletions(-)
src/all_types.hpp+1| ... | @@ -1362,6 +1362,7 @@ struct CodeGen { | ... | @@ -1362,6 +1362,7 @@ struct CodeGen { |
| 1362 | bool strip_debug_symbols; | 1362 | bool strip_debug_symbols; |
| 1363 | bool want_h_file; | 1363 | bool want_h_file; |
| 1364 | bool have_pub_main; | 1364 | bool have_pub_main; |
| 1365 | bool have_c_main; | ||
| 1365 | bool have_pub_panic; | 1366 | bool have_pub_panic; |
| 1366 | bool link_libc; | 1367 | bool link_libc; |
| 1367 | Buf *libc_lib_dir; | 1368 | Buf *libc_lib_dir; |
src/analyze.cpp+5| ... | @@ -2911,7 +2911,12 @@ ImportTableEntry *add_source_file(CodeGen *g, PackageTableEntry *package, | ... | @@ -2911,7 +2911,12 @@ ImportTableEntry *add_source_file(CodeGen *g, PackageTableEntry *package, |
| 2911 | } else if (buf_eql_str(proto_name, "panic")) { | 2911 | } else if (buf_eql_str(proto_name, "panic")) { |
| 2912 | g->have_pub_panic = true; | 2912 | g->have_pub_panic = true; |
| 2913 | } | 2913 | } |
| 2914 | } else if (proto_node->data.fn_proto.visib_mod == VisibModExport && buf_eql_str(proto_name, "main") && | ||
| 2915 | g->link_libc) | ||
| 2916 | { | ||
| 2917 | g->have_c_main = true; | ||
| 2914 | } | 2918 | } |
| 2919 | |||
| 2915 | } | 2920 | } |
| 2916 | } | 2921 | } |
| 2917 | 2922 |
src/codegen.cpp+3-1| ... | @@ -4726,7 +4726,9 @@ void codegen_add_root_code(CodeGen *g, Buf *src_dir, Buf *src_basename, Buf *sou | ... | @@ -4726,7 +4726,9 @@ void codegen_add_root_code(CodeGen *g, Buf *src_dir, Buf *src_basename, Buf *sou |
| 4726 | assert(g->root_out_name); | 4726 | assert(g->root_out_name); |
| 4727 | assert(g->out_type != OutTypeUnknown); | 4727 | assert(g->out_type != OutTypeUnknown); |
| 4728 | 4728 | ||
| 4729 | if (!g->is_test_build && g->have_pub_main && (g->out_type == OutTypeObj || g->out_type == OutTypeExe)) { | 4729 | if (!g->is_test_build && g->zig_target.os != ZigLLVM_UnknownOS && !g->have_c_main && |
| 4730 | ((g->have_pub_main && g->out_type == OutTypeObj) || g->out_type == OutTypeExe)) | ||
| 4731 | { | ||
| 4730 | g->bootstrap_import = add_special_code(g, create_bootstrap_pkg(g), "bootstrap.zig"); | 4732 | g->bootstrap_import = add_special_code(g, create_bootstrap_pkg(g), "bootstrap.zig"); |
| 4731 | } | 4733 | } |
| 4732 | if (!g->omit_zigrt) { | 4734 | if (!g->omit_zigrt) { |
std/special/bootstrap.zig+2-2| ... | @@ -12,8 +12,8 @@ const exit = std.os.posix.exit; | ... | @@ -12,8 +12,8 @@ const exit = std.os.posix.exit; |
| 12 | var argc_ptr: &usize = undefined; | 12 | var argc_ptr: &usize = undefined; |
| 13 | 13 | ||
| 14 | export nakedcc fn _start() -> noreturn { | 14 | export nakedcc fn _start() -> noreturn { |
| 15 | @setGlobalLinkage(_start, if (want_start_symbol) GlobalLinkage.Strong else GlobalLinkage.Internal); | ||
| 16 | if (!want_start_symbol) { | 15 | if (!want_start_symbol) { |
| 16 | @setGlobalLinkage(_start, GlobalLinkage.Internal); | ||
| 17 | unreachable; | 17 | unreachable; |
| 18 | } | 18 | } |
| 19 | 19 | ||
| ... | @@ -48,8 +48,8 @@ fn callMain(argc: usize, argv: &&u8, envp: &?&u8) -> %void { | ... | @@ -48,8 +48,8 @@ fn callMain(argc: usize, argv: &&u8, envp: &?&u8) -> %void { |
| 48 | } | 48 | } |
| 49 | 49 | ||
| 50 | export fn main(c_argc: i32, c_argv: &&u8, c_envp: &?&u8) -> i32 { | 50 | export fn main(c_argc: i32, c_argv: &&u8, c_envp: &?&u8) -> i32 { |
| 51 | @setGlobalLinkage(main, if (want_main_symbol) GlobalLinkage.Strong else GlobalLinkage.Internal); | ||
| 52 | if (!want_main_symbol) { | 51 | if (!want_main_symbol) { |
| 52 | @setGlobalLinkage(main, GlobalLinkage.Internal); | ||
| 53 | unreachable; | 53 | unreachable; |
| 54 | } | 54 | } |
| 55 | 55 |
test/run_tests.cpp+47| ... | @@ -161,6 +161,38 @@ static TestCase *add_compile_fail_case(const char *case_name, const char *source | ... | @@ -161,6 +161,38 @@ static TestCase *add_compile_fail_case(const char *case_name, const char *source |
| 161 | return test_case; | 161 | return test_case; |
| 162 | } | 162 | } |
| 163 | 163 | ||
| 164 | static TestCase *add_compile_fail_case_exe(const char *case_name, const char *source, size_t count, ...) { | ||
| 165 | va_list ap; | ||
| 166 | va_start(ap, count); | ||
| 167 | |||
| 168 | TestCase *test_case = allocate<TestCase>(1); | ||
| 169 | test_case->case_name = case_name; | ||
| 170 | test_case->source_files.resize(1); | ||
| 171 | test_case->source_files.at(0).relative_path = tmp_source_path; | ||
| 172 | test_case->source_files.at(0).source_code = source; | ||
| 173 | |||
| 174 | for (size_t i = 0; i < count; i += 1) { | ||
| 175 | const char *arg = va_arg(ap, const char *); | ||
| 176 | test_case->compile_errors.append(arg); | ||
| 177 | } | ||
| 178 | |||
| 179 | test_case->compiler_args.append("build_exe"); | ||
| 180 | test_case->compiler_args.append(tmp_source_path); | ||
| 181 | |||
| 182 | test_case->compiler_args.append("--name"); | ||
| 183 | test_case->compiler_args.append("test"); | ||
| 184 | |||
| 185 | test_case->compiler_args.append("--output"); | ||
| 186 | test_case->compiler_args.append(tmp_exe_path); | ||
| 187 | |||
| 188 | test_case->compiler_args.append("--release"); | ||
| 189 | test_case->compiler_args.append("--strip"); | ||
| 190 | |||
| 191 | test_cases.append(test_case); | ||
| 192 | |||
| 193 | return test_case; | ||
| 194 | } | ||
| 195 | |||
| 164 | static void add_debug_safety_case(const char *case_name, const char *source) { | 196 | static void add_debug_safety_case(const char *case_name, const char *source) { |
| 165 | TestCase *test_case = allocate<TestCase>(1); | 197 | TestCase *test_case = allocate<TestCase>(1); |
| 166 | test_case->is_debug_safety = true; | 198 | test_case->is_debug_safety = true; |
| ... | @@ -220,6 +252,11 @@ static TestCase *add_example_compile_extra(const char *root_source_file, bool li | ... | @@ -220,6 +252,11 @@ static TestCase *add_example_compile_extra(const char *root_source_file, bool li |
| 220 | test_case->compiler_args.append("build_exe"); | 252 | test_case->compiler_args.append("build_exe"); |
| 221 | test_case->compiler_args.append(buf_ptr(buf_sprintf("../%s", root_source_file))); | 253 | test_case->compiler_args.append(buf_ptr(buf_sprintf("../%s", root_source_file))); |
| 222 | 254 | ||
| 255 | if (libc) { | ||
| 256 | test_case->compiler_args.append("--library"); | ||
| 257 | test_case->compiler_args.append("c"); | ||
| 258 | } | ||
| 259 | |||
| 223 | test_cases.append(test_case); | 260 | test_cases.append(test_case); |
| 224 | 261 | ||
| 225 | return test_case; | 262 | return test_case; |
| ... | @@ -1952,6 +1989,16 @@ comptime { | ... | @@ -1952,6 +1989,16 @@ comptime { |
| 1952 | const another_foo_ptr = @fieldParentPtr(Foo, "b", &foo.a); | 1989 | const another_foo_ptr = @fieldParentPtr(Foo, "b", &foo.a); |
| 1953 | } | 1990 | } |
| 1954 | )SOURCE", 1, ".tmp_source.zig:9:29: error: field 'b' has index 1 but pointer value is index 0 of struct 'Foo'"); | 1991 | )SOURCE", 1, ".tmp_source.zig:9:29: error: field 'b' has index 1 but pointer value is index 0 of struct 'Foo'"); |
| 1992 | |||
| 1993 | add_compile_fail_case_exe("missing main fn in executable", R"SOURCE( | ||
| 1994 | )SOURCE", 1, "error: no member named 'main' in '"); | ||
| 1995 | |||
| 1996 | add_compile_fail_case_exe("private main fn", R"SOURCE( | ||
| 1997 | fn main() {} | ||
| 1998 | )SOURCE", 2, | ||
| 1999 | "error: 'main' is private", | ||
| 2000 | ".tmp_source.zig:2:1: note: declared here"); | ||
| 2001 | |||
| 1955 | } | 2002 | } |
| 1956 | 2003 | ||
| 1957 | ////////////////////////////////////////////////////////////////////////////// | 2004 | ////////////////////////////////////////////////////////////////////////////// |