authorgravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2017-03-26 21:07:07-04:00
committergravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2017-03-26 21:07:07-04:00
loga32b5929ccf8cbf79396d8924097a1a911985dac
treec45c7413d1fb6eab9ba102f3a0b7d48df1738164
parent8aeea72654b2efbd068abe207b42170c4d27ee03

add stack protector safety when linking libc

* introduce zigrt file. it contains only weak symbols so that multiple instances can be merged. it contains __zig_panic so that multiple .o files can call the same panic function. * remove `@setFnVisible` builtin and add @setGlobalLinkage builtin which is more powerful * add `@panic` builtin function. * fix collision of symbols with extern prototypes and internal function names * add stack protector safety when linking against libc. To add the safety mechanism without libc requires implementing Thread Local Storage. See #276

19 files changed, 437 insertions(+), 185 deletions(-)

CMakeLists.txt+1-1
...@@ -233,8 +233,8 @@ install(FILES "${CMAKE_SOURCE_DIR}/std/sort.zig" DESTINATION "${ZIG_STD_DEST}")...@@ -233,8 +233,8 @@ install(FILES "${CMAKE_SOURCE_DIR}/std/sort.zig" DESTINATION "${ZIG_STD_DEST}")
233install(FILES "${CMAKE_SOURCE_DIR}/std/special/bootstrap.zig" DESTINATION "${ZIG_STD_DEST}/special")233install(FILES "${CMAKE_SOURCE_DIR}/std/special/bootstrap.zig" DESTINATION "${ZIG_STD_DEST}/special")
234install(FILES "${CMAKE_SOURCE_DIR}/std/special/builtin.zig" DESTINATION "${ZIG_STD_DEST}/special")234install(FILES "${CMAKE_SOURCE_DIR}/std/special/builtin.zig" DESTINATION "${ZIG_STD_DEST}/special")
235install(FILES "${CMAKE_SOURCE_DIR}/std/special/compiler_rt.zig" DESTINATION "${ZIG_STD_DEST}/special")235install(FILES "${CMAKE_SOURCE_DIR}/std/special/compiler_rt.zig" DESTINATION "${ZIG_STD_DEST}/special")
236install(FILES "${CMAKE_SOURCE_DIR}/std/special/panic.zig" DESTINATION "${ZIG_STD_DEST}/special")
237install(FILES "${CMAKE_SOURCE_DIR}/std/special/test_runner.zig" DESTINATION "${ZIG_STD_DEST}/special")236install(FILES "${CMAKE_SOURCE_DIR}/std/special/test_runner.zig" DESTINATION "${ZIG_STD_DEST}/special")
237install(FILES "${CMAKE_SOURCE_DIR}/std/special/zigrt.zig" DESTINATION "${ZIG_STD_DEST}/special")
238install(FILES "${CMAKE_SOURCE_DIR}/std/target.zig" DESTINATION "${ZIG_STD_DEST}")238install(FILES "${CMAKE_SOURCE_DIR}/std/target.zig" DESTINATION "${ZIG_STD_DEST}")
239239
240add_executable(run_tests ${TEST_SOURCES})240add_executable(run_tests ${TEST_SOURCES})
doc/emacs/zig-mode.el+1-1
...@@ -1,5 +1,5 @@...@@ -1,5 +1,5 @@
1(setq zig1(setq zig
2 '(("\\b\\(@sizeOf\\|@alignOf\\|@maxValue\\|@minValue\\|@memberCount\\|@typeOf\\|@addWithOverflow\\|@subWithOverflow\\|@mulWithOverflow\\|@shlWithOverflow\\|@cInclude\\|@cDefine\\|@cUndef\\|@compileVar\\|@generatedCode\\|@ctz\\|@clz\\|@import\\|@cImport\\|@errorName\\|@typeName\\|@isInteger\\|@isFloat\\|@canImplicitCast\\|@embedFile\\|@cmpxchg\\|@fence\\|@divExact\\|@truncate\\|@compileError\\|@compileLog\\|@intType\\|@unreachable\\|@setFnTest\\|@setFnVisible\\|@setDebugSafety\\|@alloca\\|@setGlobalAlign\\|@setGlobalSection\\)" . font-lock-builtin-face)2 '(("\\b\\(@sizeOf\\|@alignOf\\|@maxValue\\|@minValue\\|@memberCount\\|@typeOf\\|@addWithOverflow\\|@subWithOverflow\\|@mulWithOverflow\\|@shlWithOverflow\\|@cInclude\\|@cDefine\\|@cUndef\\|@compileVar\\|@generatedCode\\|@ctz\\|@clz\\|@import\\|@cImport\\|@errorName\\|@typeName\\|@isInteger\\|@isFloat\\|@canImplicitCast\\|@embedFile\\|@cmpxchg\\|@fence\\|@divExact\\|@truncate\\|@compileError\\|@compileLog\\|@intType\\|@unreachable\\|@setDebugSafety\\|@alloca\\|@setGlobalAlign\\|@setGlobalLinkage\\|@setGlobalSection\\)" . font-lock-builtin-face)
33
4("\\b\\(fn\\|use\\|while\\|for\\|break\\|continue\\|goto\\|if\\|else\\|switch\\|try\\|return\\|defer\\|asm\\|unreachable\\|const\\|var\\|extern\\|packed\\|export\\|pub\\|noalias\\|inline\\|comptime\\|nakedcc\\|coldcc\\|volatile\\|struct\\|enum\\|union\\)\\b" . font-lock-keyword-face)4("\\b\\(fn\\|use\\|while\\|for\\|break\\|continue\\|goto\\|if\\|else\\|switch\\|try\\|return\\|defer\\|asm\\|unreachable\\|const\\|var\\|extern\\|packed\\|export\\|pub\\|noalias\\|inline\\|comptime\\|nakedcc\\|coldcc\\|volatile\\|struct\\|enum\\|union\\)\\b" . font-lock-keyword-face)
55
doc/langref.md+7
...@@ -626,3 +626,10 @@ Sets the alignment property of a global variable....@@ -626,3 +626,10 @@ Sets the alignment property of a global variable.
626### @setGlobalSection(global_variable_name, section_name: []u8) -> bool626### @setGlobalSection(global_variable_name, section_name: []u8) -> bool
627627
628Puts the global variable in the specified section.628Puts the global variable in the specified section.
629
630### @panic(message: []const u8) -> noreturn
631
632Invokes the panic handler function. By default the panic handler function
633calls the public `panic` function exposed in the root source file, or
634if there is not one specified, invokes the one provided in
635`std/special/panic.zig`.
src/all_types.hpp+35-15
...@@ -237,6 +237,13 @@ enum VisibMod {...@@ -237,6 +237,13 @@ enum VisibMod {
237 VisibModExport,237 VisibModExport,
238};238};
239239
240enum GlobalLinkageId {
241 GlobalLinkageIdInternal,
242 GlobalLinkageIdStrong,
243 GlobalLinkageIdWeak,
244 GlobalLinkageIdLinkOnce,
245};
246
240enum TldId {247enum TldId {
241 TldIdVar,248 TldIdVar,
242 TldIdFn,249 TldIdFn,
...@@ -273,6 +280,8 @@ struct TldVar {...@@ -273,6 +280,8 @@ struct TldVar {
273 uint64_t alignment;280 uint64_t alignment;
274 AstNode *set_global_section_node;281 AstNode *set_global_section_node;
275 Buf *section_name;282 Buf *section_name;
283 AstNode *set_global_linkage_node;
284 GlobalLinkageId linkage;
276};285};
277286
278struct TldFn {287struct TldFn {
...@@ -1116,8 +1125,6 @@ struct FnTableEntry {...@@ -1116,8 +1125,6 @@ struct FnTableEntry {
1116 Buf symbol_name;1125 Buf symbol_name;
1117 TypeTableEntry *type_entry; // function type1126 TypeTableEntry *type_entry; // function type
1118 TypeTableEntry *implicit_return_type;1127 TypeTableEntry *implicit_return_type;
1119 bool internal_linkage;
1120 bool disable_export;
1121 bool is_test;1128 bool is_test;
1122 FnInline fn_inline;1129 FnInline fn_inline;
1123 FnAnalState anal_state;1130 FnAnalState anal_state;
...@@ -1128,7 +1135,6 @@ struct FnTableEntry {...@@ -1128,7 +1135,6 @@ struct FnTableEntry {
1128 Buf **param_names;1135 Buf **param_names;
11291136
1130 AstNode *fn_no_inline_set_node;1137 AstNode *fn_no_inline_set_node;
1131 AstNode *fn_export_set_node;
1132 AstNode *fn_static_eval_set_node;1138 AstNode *fn_static_eval_set_node;
11331139
1134 ZigList<IrInstruction *> alloca_list;1140 ZigList<IrInstruction *> alloca_list;
...@@ -1138,6 +1144,8 @@ struct FnTableEntry {...@@ -1138,6 +1144,8 @@ struct FnTableEntry {
1138 uint64_t alignment;1144 uint64_t alignment;
1139 AstNode *set_global_section_node;1145 AstNode *set_global_section_node;
1140 Buf *section_name;1146 Buf *section_name;
1147 AstNode *set_global_linkage_node;
1148 GlobalLinkageId linkage;
1141};1149};
11421150
1143uint32_t fn_table_entry_hash(FnTableEntry*);1151uint32_t fn_table_entry_hash(FnTableEntry*);
...@@ -1178,7 +1186,6 @@ enum BuiltinFnId {...@@ -1178,7 +1186,6 @@ enum BuiltinFnId {
1178 BuiltinFnIdDivExact,1186 BuiltinFnIdDivExact,
1179 BuiltinFnIdTruncate,1187 BuiltinFnIdTruncate,
1180 BuiltinFnIdIntType,1188 BuiltinFnIdIntType,
1181 BuiltinFnIdSetFnVisible,
1182 BuiltinFnIdSetDebugSafety,1189 BuiltinFnIdSetDebugSafety,
1183 BuiltinFnIdAlloca,1190 BuiltinFnIdAlloca,
1184 BuiltinFnIdTypeName,1191 BuiltinFnIdTypeName,
...@@ -1187,6 +1194,8 @@ enum BuiltinFnId {...@@ -1187,6 +1194,8 @@ enum BuiltinFnId {
1187 BuiltinFnIdCanImplicitCast,1194 BuiltinFnIdCanImplicitCast,
1188 BuiltinFnIdSetGlobalAlign,1195 BuiltinFnIdSetGlobalAlign,
1189 BuiltinFnIdSetGlobalSection,1196 BuiltinFnIdSetGlobalSection,
1197 BuiltinFnIdSetGlobalLinkage,
1198 BuiltinFnIdPanic,
1190};1199};
11911200
1192struct BuiltinFnEntry {1201struct BuiltinFnEntry {
...@@ -1300,7 +1309,8 @@ struct CodeGen {...@@ -1300,7 +1309,8 @@ struct CodeGen {
1300 HashMap<Scope *, IrInstruction *, fn_eval_hash, fn_eval_eql> memoized_fn_eval_table;1309 HashMap<Scope *, IrInstruction *, fn_eval_hash, fn_eval_eql> memoized_fn_eval_table;
1301 HashMap<ZigLLVMFnKey, LLVMValueRef, zig_llvm_fn_key_hash, zig_llvm_fn_key_eql> llvm_fn_table;1310 HashMap<ZigLLVMFnKey, LLVMValueRef, zig_llvm_fn_key_hash, zig_llvm_fn_key_eql> llvm_fn_table;
1302 HashMap<Buf *, ConstExprValue *, buf_hash, buf_eql_buf> compile_vars;1311 HashMap<Buf *, ConstExprValue *, buf_hash, buf_eql_buf> compile_vars;
1303 HashMap<Buf *, Tld *, buf_hash, buf_eql_buf> external_symbol_names;1312 HashMap<Buf *, Tld *, buf_hash, buf_eql_buf> exported_symbol_names;
1313 HashMap<Buf *, Tld *, buf_hash, buf_eql_buf> external_prototypes;
13041314
1305 ZigList<ImportTableEntry *> import_queue;1315 ZigList<ImportTableEntry *> import_queue;
1306 size_t import_queue_index;1316 size_t import_queue_index;
...@@ -1346,6 +1356,7 @@ struct CodeGen {...@@ -1346,6 +1356,7 @@ struct CodeGen {
1346 TypeTableEntry *entry_environ_enum;1356 TypeTableEntry *entry_environ_enum;
1347 TypeTableEntry *entry_oformat_enum;1357 TypeTableEntry *entry_oformat_enum;
1348 TypeTableEntry *entry_atomic_order_enum;1358 TypeTableEntry *entry_atomic_order_enum;
1359 TypeTableEntry *entry_global_linkage_enum;
1349 TypeTableEntry *entry_arg_tuple;1360 TypeTableEntry *entry_arg_tuple;
1350 } builtin_types;1361 } builtin_types;
13511362
...@@ -1378,7 +1389,7 @@ struct CodeGen {...@@ -1378,7 +1389,7 @@ struct CodeGen {
1378 bool is_native_target;1389 bool is_native_target;
1379 PackageTableEntry *root_package;1390 PackageTableEntry *root_package;
1380 PackageTableEntry *std_package;1391 PackageTableEntry *std_package;
1381 PackageTableEntry *panic_package;1392 PackageTableEntry *zigrt_package;
1382 Buf *root_out_name;1393 Buf *root_out_name;
1383 bool windows_subsystem_windows;1394 bool windows_subsystem_windows;
1384 bool windows_subsystem_console;1395 bool windows_subsystem_console;
...@@ -1388,6 +1399,7 @@ struct CodeGen {...@@ -1388,6 +1399,7 @@ struct CodeGen {
1388 Buf *mios_version_min;1399 Buf *mios_version_min;
1389 bool linker_rdynamic;1400 bool linker_rdynamic;
1390 const char *linker_script;1401 const char *linker_script;
1402 bool omit_zigrt;
13911403
1392 // The function definitions this module includes. There must be a corresponding1404 // The function definitions this module includes. There must be a corresponding
1393 // fn_protos entry.1405 // fn_protos entry.
...@@ -1401,7 +1413,8 @@ struct CodeGen {...@@ -1401,7 +1413,8 @@ struct CodeGen {
1401 OutType out_type;1413 OutType out_type;
1402 FnTableEntry *cur_fn;1414 FnTableEntry *cur_fn;
1403 FnTableEntry *main_fn;1415 FnTableEntry *main_fn;
1404 FnTableEntry *panic_fn;1416 FnTableEntry *user_panic_fn;
1417 FnTableEntry *extern_panic_fn;
1405 LLVMValueRef cur_ret_ptr;1418 LLVMValueRef cur_ret_ptr;
1406 LLVMValueRef cur_fn_val;1419 LLVMValueRef cur_fn_val;
1407 ZigList<LLVMBasicBlockRef> break_block_stack;1420 ZigList<LLVMBasicBlockRef> break_block_stack;
...@@ -1656,7 +1669,6 @@ enum IrInstructionId {...@@ -1656,7 +1669,6 @@ enum IrInstructionId {
1656 IrInstructionIdTypeOf,1669 IrInstructionIdTypeOf,
1657 IrInstructionIdToPtrType,1670 IrInstructionIdToPtrType,
1658 IrInstructionIdPtrTypeChild,1671 IrInstructionIdPtrTypeChild,
1659 IrInstructionIdSetFnVisible,
1660 IrInstructionIdSetDebugSafety,1672 IrInstructionIdSetDebugSafety,
1661 IrInstructionIdArrayType,1673 IrInstructionIdArrayType,
1662 IrInstructionIdSliceType,1674 IrInstructionIdSliceType,
...@@ -1718,7 +1730,9 @@ enum IrInstructionId {...@@ -1718,7 +1730,9 @@ enum IrInstructionId {
1718 IrInstructionIdCanImplicitCast,1730 IrInstructionIdCanImplicitCast,
1719 IrInstructionIdSetGlobalAlign,1731 IrInstructionIdSetGlobalAlign,
1720 IrInstructionIdSetGlobalSection,1732 IrInstructionIdSetGlobalSection,
1733 IrInstructionIdSetGlobalLinkage,
1721 IrInstructionIdDeclRef,1734 IrInstructionIdDeclRef,
1735 IrInstructionIdPanic,
1722};1736};
17231737
1724struct IrInstruction {1738struct IrInstruction {
...@@ -1999,13 +2013,6 @@ struct IrInstructionPtrTypeChild {...@@ -1999,13 +2013,6 @@ struct IrInstructionPtrTypeChild {
1999 IrInstruction *value;2013 IrInstruction *value;
2000};2014};
20012015
2002struct IrInstructionSetFnVisible {
2003 IrInstruction base;
2004
2005 IrInstruction *fn_value;
2006 IrInstruction *is_visible;
2007};
2008
2009struct IrInstructionSetDebugSafety {2016struct IrInstructionSetDebugSafety {
2010 IrInstruction base;2017 IrInstruction base;
20112018
...@@ -2439,6 +2446,13 @@ struct IrInstructionSetGlobalSection {...@@ -2439,6 +2446,13 @@ struct IrInstructionSetGlobalSection {
2439 IrInstruction *value;2446 IrInstruction *value;
2440};2447};
24412448
2449struct IrInstructionSetGlobalLinkage {
2450 IrInstruction base;
2451
2452 Tld *tld;
2453 IrInstruction *value;
2454};
2455
2442struct IrInstructionDeclRef {2456struct IrInstructionDeclRef {
2443 IrInstruction base;2457 IrInstruction base;
24442458
...@@ -2446,6 +2460,12 @@ struct IrInstructionDeclRef {...@@ -2446,6 +2460,12 @@ struct IrInstructionDeclRef {
2446 LVal lval;2460 LVal lval;
2447};2461};
24482462
2463struct IrInstructionPanic {
2464 IrInstruction base;
2465
2466 IrInstruction *msg;
2467};
2468
2449static const size_t slice_ptr_index = 0;2469static const size_t slice_ptr_index = 0;
2450static const size_t slice_len_index = 1;2470static const size_t slice_len_index = 1;
24512471
src/analyze.cpp+59-22
...@@ -1762,7 +1762,7 @@ static void get_fully_qualified_decl_name(Buf *buf, Tld *tld, uint8_t sep) {...@@ -1762,7 +1762,7 @@ static void get_fully_qualified_decl_name(Buf *buf, Tld *tld, uint8_t sep) {
1762 buf_append_buf(buf, tld->name);1762 buf_append_buf(buf, tld->name);
1763}1763}
17641764
1765FnTableEntry *create_fn_raw(FnInline inline_value, bool internal_linkage) {1765FnTableEntry *create_fn_raw(FnInline inline_value, GlobalLinkageId linkage) {
1766 FnTableEntry *fn_entry = allocate<FnTableEntry>(1);1766 FnTableEntry *fn_entry = allocate<FnTableEntry>(1);
17671767
1768 fn_entry->analyzed_executable.backward_branch_count = &fn_entry->prealloc_bbc;1768 fn_entry->analyzed_executable.backward_branch_count = &fn_entry->prealloc_bbc;
...@@ -1770,7 +1770,7 @@ FnTableEntry *create_fn_raw(FnInline inline_value, bool internal_linkage) {...@@ -1770,7 +1770,7 @@ FnTableEntry *create_fn_raw(FnInline inline_value, bool internal_linkage) {
1770 fn_entry->analyzed_executable.fn_entry = fn_entry;1770 fn_entry->analyzed_executable.fn_entry = fn_entry;
1771 fn_entry->ir_executable.fn_entry = fn_entry;1771 fn_entry->ir_executable.fn_entry = fn_entry;
1772 fn_entry->fn_inline = inline_value;1772 fn_entry->fn_inline = inline_value;
1773 fn_entry->internal_linkage = internal_linkage;1773 fn_entry->linkage = linkage;
17741774
1775 return fn_entry;1775 return fn_entry;
1776}1776}
...@@ -1780,8 +1780,9 @@ FnTableEntry *create_fn(AstNode *proto_node) {...@@ -1780,8 +1780,9 @@ FnTableEntry *create_fn(AstNode *proto_node) {
1780 AstNodeFnProto *fn_proto = &proto_node->data.fn_proto;1780 AstNodeFnProto *fn_proto = &proto_node->data.fn_proto;
17811781
1782 FnInline inline_value = fn_proto->is_inline ? FnInlineAlways : FnInlineAuto;1782 FnInline inline_value = fn_proto->is_inline ? FnInlineAlways : FnInlineAuto;
1783 bool internal_linkage = (fn_proto->visib_mod != VisibModExport && !proto_node->data.fn_proto.is_extern);1783 GlobalLinkageId linkage = (fn_proto->visib_mod == VisibModExport || proto_node->data.fn_proto.is_extern) ?
1784 FnTableEntry *fn_entry = create_fn_raw(inline_value, internal_linkage);1784 GlobalLinkageIdStrong : GlobalLinkageIdInternal;
1785 FnTableEntry *fn_entry = create_fn_raw(inline_value, linkage);
17851786
1786 fn_entry->proto_node = proto_node;1787 fn_entry->proto_node = proto_node;
1787 fn_entry->body_node = (proto_node->data.fn_proto.fn_def_node == nullptr) ? nullptr :1788 fn_entry->body_node = (proto_node->data.fn_proto.fn_def_node == nullptr) ? nullptr :
...@@ -1807,12 +1808,10 @@ static void wrong_panic_prototype(CodeGen *g, AstNode *proto_node, TypeTableEntr...@@ -1807,12 +1808,10 @@ static void wrong_panic_prototype(CodeGen *g, AstNode *proto_node, TypeTableEntr
1807 buf_ptr(&fn_type->name)));1808 buf_ptr(&fn_type->name)));
1808}1809}
18091810
1810static void typecheck_panic_fn(CodeGen *g) {1811static void typecheck_panic_fn(CodeGen *g, FnTableEntry *panic_fn) {
1811 assert(g->panic_fn);1812 AstNode *proto_node = panic_fn->proto_node;
1812
1813 AstNode *proto_node = g->panic_fn->proto_node;
1814 assert(proto_node->type == NodeTypeFnProto);1813 assert(proto_node->type == NodeTypeFnProto);
1815 TypeTableEntry *fn_type = g->panic_fn->type_entry;1814 TypeTableEntry *fn_type = panic_fn->type_entry;
1816 FnTypeId *fn_type_id = &fn_type->data.fn.fn_type_id;1815 FnTypeId *fn_type_id = &fn_type->data.fn.fn_type_id;
1817 if (fn_type_id->param_count != 1) {1816 if (fn_type_id->param_count != 1) {
1818 return wrong_panic_prototype(g, proto_node, fn_type);1817 return wrong_panic_prototype(g, proto_node, fn_type);
...@@ -1862,6 +1861,8 @@ static void resolve_decl_fn(CodeGen *g, TldFn *tld_fn) {...@@ -1862,6 +1861,8 @@ static void resolve_decl_fn(CodeGen *g, TldFn *tld_fn) {
1862 add_node_error(g, param_node, buf_sprintf("missing parameter name"));1861 add_node_error(g, param_node, buf_sprintf("missing parameter name"));
1863 }1862 }
1864 }1863 }
1864 } else if (fn_table_entry->linkage != GlobalLinkageIdInternal) {
1865 g->external_prototypes.put_unique(tld_fn->base.name, &tld_fn->base);
1865 }1866 }
18661867
1867 Scope *child_scope = fn_table_entry->fndef_scope ? &fn_table_entry->fndef_scope->base : tld_fn->base.parent_scope;1868 Scope *child_scope = fn_table_entry->fndef_scope ? &fn_table_entry->fndef_scope->base : tld_fn->base.parent_scope;
...@@ -1892,18 +1893,16 @@ static void resolve_decl_fn(CodeGen *g, TldFn *tld_fn) {...@@ -1892,18 +1893,16 @@ static void resolve_decl_fn(CodeGen *g, TldFn *tld_fn) {
1892 }1893 }
1893 }1894 }
1894 } else if (buf_eql_str(&fn_table_entry->symbol_name, "panic")) {1895 } else if (buf_eql_str(&fn_table_entry->symbol_name, "panic")) {
1895 g->panic_fn = fn_table_entry;1896 typecheck_panic_fn(g, fn_table_entry);
1896 typecheck_panic_fn(g);
1897 }1897 }
1898 } else if (import->package == g->panic_package && scope_is_root_decls(tld_fn->base.parent_scope)) {1898 } else if (import->package == g->zigrt_package && scope_is_root_decls(tld_fn->base.parent_scope)) {
1899 if (buf_eql_str(&fn_table_entry->symbol_name, "panic")) {1899 if (buf_eql_str(&fn_table_entry->symbol_name, "__zig_panic")) {
1900 g->panic_fn = fn_table_entry;1900 g->extern_panic_fn = fn_table_entry;
1901 typecheck_panic_fn(g);
1902 }1901 }
1903 }1902 }
1904 }1903 }
1905 } else if (source_node->type == NodeTypeTestDecl) {1904 } else if (source_node->type == NodeTypeTestDecl) {
1906 FnTableEntry *fn_table_entry = create_fn_raw(FnInlineAuto, false);1905 FnTableEntry *fn_table_entry = create_fn_raw(FnInlineAuto, GlobalLinkageIdStrong);
19071906
1908 get_fully_qualified_decl_name(&fn_table_entry->symbol_name, &tld_fn->base, '_');1907 get_fully_qualified_decl_name(&fn_table_entry->symbol_name, &tld_fn->base, '_');
19091908
...@@ -1931,16 +1930,12 @@ static void resolve_decl_comptime(CodeGen *g, TldCompTime *tld_comptime) {...@@ -1931,16 +1930,12 @@ static void resolve_decl_comptime(CodeGen *g, TldCompTime *tld_comptime) {
1931}1930}
19321931
1933static void add_top_level_decl(CodeGen *g, ScopeDecls *decls_scope, Tld *tld) {1932static void add_top_level_decl(CodeGen *g, ScopeDecls *decls_scope, Tld *tld) {
1934 if (tld->visib_mod == VisibModExport ||1933 if (tld->visib_mod == VisibModExport || (tld->id == TldIdVar && g->is_test_build)) {
1935 (buf_eql_str(tld->name, "panic") &&
1936 (decls_scope->import->package == g->panic_package || decls_scope->import == g->root_import)) ||
1937 (tld->id == TldIdVar && g->is_test_build))
1938 {
1939 g->resolve_queue.append(tld);1934 g->resolve_queue.append(tld);
1940 }1935 }
19411936
1942 if (tld->visib_mod == VisibModExport) {1937 if (tld->visib_mod == VisibModExport) {
1943 auto entry = g->external_symbol_names.put_unique(tld->name, tld);1938 auto entry = g->exported_symbol_names.put_unique(tld->name, tld);
1944 if (entry) {1939 if (entry) {
1945 Tld *other_tld = entry->value;1940 Tld *other_tld = entry->value;
1946 ErrorMsg *msg = add_node_error(g, tld->source_node,1941 ErrorMsg *msg = add_node_error(g, tld->source_node,
...@@ -2060,6 +2055,15 @@ void scan_decls(CodeGen *g, ScopeDecls *decls_scope, AstNode *node) {...@@ -2060,6 +2055,15 @@ void scan_decls(CodeGen *g, ScopeDecls *decls_scope, AstNode *node) {
2060 TldFn *tld_fn = allocate<TldFn>(1);2055 TldFn *tld_fn = allocate<TldFn>(1);
2061 init_tld(&tld_fn->base, TldIdFn, fn_name, visib_mod, node, &decls_scope->base);2056 init_tld(&tld_fn->base, TldIdFn, fn_name, visib_mod, node, &decls_scope->base);
2062 add_top_level_decl(g, decls_scope, &tld_fn->base);2057 add_top_level_decl(g, decls_scope, &tld_fn->base);
2058
2059 ImportTableEntry *import = get_scope_import(&decls_scope->base);
2060 if (import == g->root_import && scope_is_root_decls(&decls_scope->base) &&
2061 buf_eql_str(fn_name, "panic"))
2062 {
2063 g->compile_vars.put(buf_create_from_str("panic_implementation_provided"),
2064 create_const_bool(g, true));
2065 }
2066
2063 break;2067 break;
2064 }2068 }
2065 case NodeTypeUse:2069 case NodeTypeUse:
...@@ -4206,3 +4210,36 @@ ConstParent *get_const_val_parent(ConstExprValue *value) {...@@ -4206,3 +4210,36 @@ ConstParent *get_const_val_parent(ConstExprValue *value) {
4206 }4210 }
4207 return nullptr;4211 return nullptr;
4208}4212}
4213
4214FnTableEntry *get_extern_panic_fn(CodeGen *g) {
4215 if (g->extern_panic_fn)
4216 return g->extern_panic_fn;
4217
4218 FnTypeId fn_type_id = {0};
4219 fn_type_id.is_extern = true;
4220 fn_type_id.is_cold = true;
4221 fn_type_id.param_count = 2;
4222 fn_type_id.param_info = allocate<FnTypeParamInfo>(2);
4223 fn_type_id.next_param_index = 0;
4224 fn_type_id.param_info[0].type = get_pointer_to_type(g, g->builtin_types.entry_u8, true);
4225 fn_type_id.param_info[1].type = g->builtin_types.entry_usize;
4226 fn_type_id.return_type = g->builtin_types.entry_unreachable;
4227
4228 TypeTableEntry *fn_type = get_fn_type(g, &fn_type_id);
4229 assert(!type_is_invalid(fn_type));
4230
4231 FnTableEntry *fn_entry = create_fn_raw(FnInlineAuto, GlobalLinkageIdStrong);
4232 buf_init_from_str(&fn_entry->symbol_name, "__zig_panic");
4233
4234 TldFn *tld_fn = allocate<TldFn>(1);
4235 init_tld(&tld_fn->base, TldIdFn, &fn_entry->symbol_name, VisibModPrivate, nullptr, nullptr);
4236 tld_fn->fn_entry = fn_entry;
4237
4238 g->external_prototypes.put_unique(tld_fn->base.name, &tld_fn->base);
4239
4240 fn_entry->type_entry = fn_type;
4241
4242 g->extern_panic_fn = fn_entry;
4243 return g->extern_panic_fn;
4244}
4245
src/analyze.hpp+2-1
...@@ -72,7 +72,7 @@ VariableTableEntry *add_variable(CodeGen *g, AstNode *source_node, Scope *parent...@@ -72,7 +72,7 @@ VariableTableEntry *add_variable(CodeGen *g, AstNode *source_node, Scope *parent
72 bool is_const, ConstExprValue *init_value, Tld *src_tld);72 bool is_const, ConstExprValue *init_value, Tld *src_tld);
73TypeTableEntry *analyze_type_expr(CodeGen *g, Scope *scope, AstNode *node);73TypeTableEntry *analyze_type_expr(CodeGen *g, Scope *scope, AstNode *node);
74FnTableEntry *create_fn(AstNode *proto_node);74FnTableEntry *create_fn(AstNode *proto_node);
75FnTableEntry *create_fn_raw(FnInline inline_value, bool internal_linkage);75FnTableEntry *create_fn_raw(FnInline inline_value, GlobalLinkageId linkage);
76void init_fn_type_id(FnTypeId *fn_type_id, AstNode *proto_node, size_t param_count_alloc);76void init_fn_type_id(FnTypeId *fn_type_id, AstNode *proto_node, size_t param_count_alloc);
77AstNode *get_param_decl_node(FnTableEntry *fn_entry, size_t index);77AstNode *get_param_decl_node(FnTableEntry *fn_entry, size_t index);
78FnTableEntry *scope_get_fn_if_root(Scope *scope);78FnTableEntry *scope_get_fn_if_root(Scope *scope);
...@@ -148,5 +148,6 @@ void init_const_undefined(CodeGen *g, ConstExprValue *const_val);...@@ -148,5 +148,6 @@ void init_const_undefined(CodeGen *g, ConstExprValue *const_val);
148148
149TypeTableEntry *make_int_type(CodeGen *g, bool is_signed, size_t size_in_bits);149TypeTableEntry *make_int_type(CodeGen *g, bool is_signed, size_t size_in_bits);
150ConstParent *get_const_val_parent(ConstExprValue *value);150ConstParent *get_const_val_parent(ConstExprValue *value);
151FnTableEntry *get_extern_panic_fn(CodeGen *g);
151152
152#endif153#endif
src/codegen.cpp+127-21
...@@ -67,7 +67,8 @@ CodeGen *codegen_create(Buf *root_source_dir, const ZigTarget *target) {...@@ -67,7 +67,8 @@ CodeGen *codegen_create(Buf *root_source_dir, const ZigTarget *target) {
67 g->llvm_fn_table.init(16);67 g->llvm_fn_table.init(16);
68 g->memoized_fn_eval_table.init(16);68 g->memoized_fn_eval_table.init(16);
69 g->compile_vars.init(16);69 g->compile_vars.init(16);
70 g->external_symbol_names.init(8);70 g->exported_symbol_names.init(8);
71 g->external_prototypes.init(8);
71 g->is_release_build = false;72 g->is_release_build = false;
72 g->is_test_build = false;73 g->is_test_build = false;
73 g->want_h_file = true;74 g->want_h_file = true;
...@@ -140,6 +141,10 @@ void codegen_set_is_release(CodeGen *g, bool is_release_build) {...@@ -140,6 +141,10 @@ void codegen_set_is_release(CodeGen *g, bool is_release_build) {
140 g->is_release_build = is_release_build;141 g->is_release_build = is_release_build;
141}142}
142143
144void codegen_set_omit_zigrt(CodeGen *g, bool omit_zigrt) {
145 g->omit_zigrt = omit_zigrt;
146}
147
143void codegen_set_is_test(CodeGen *g, bool is_test_build) {148void codegen_set_is_test(CodeGen *g, bool is_test_build) {
144 g->is_test_build = is_test_build;149 g->is_test_build = is_test_build;
145}150}
...@@ -256,10 +261,22 @@ static void addLLVMAttr(LLVMValueRef val, LLVMAttributeIndex attr_index, const c...@@ -256,10 +261,22 @@ static void addLLVMAttr(LLVMValueRef val, LLVMAttributeIndex attr_index, const c
256 LLVMAddAttributeAtIndex(val, attr_index, llvm_attr);261 LLVMAddAttributeAtIndex(val, attr_index, llvm_attr);
257}262}
258263
264static void addLLVMAttrStr(LLVMValueRef val, LLVMAttributeIndex attr_index,
265 const char *attr_name, const char *attr_val)
266{
267 LLVMAttributeRef llvm_attr = LLVMCreateStringAttribute(LLVMGetGlobalContext(),
268 attr_name, strlen(attr_name), attr_val, strlen(attr_val));
269 LLVMAddAttributeAtIndex(val, attr_index, llvm_attr);
270}
271
259static void addLLVMFnAttr(LLVMValueRef fn_val, const char *attr_name) {272static void addLLVMFnAttr(LLVMValueRef fn_val, const char *attr_name) {
260 return addLLVMAttr(fn_val, -1, attr_name);273 return addLLVMAttr(fn_val, -1, attr_name);
261}274}
262275
276static void addLLVMFnAttrStr(LLVMValueRef fn_val, const char *attr_name, const char *attr_val) {
277 return addLLVMAttrStr(fn_val, -1, attr_name, attr_val);
278}
279
263static void addLLVMArgAttr(LLVMValueRef arg_val, unsigned param_index, const char *attr_name) {280static void addLLVMArgAttr(LLVMValueRef arg_val, unsigned param_index, const char *attr_name) {
264 return addLLVMAttr(arg_val, param_index + 1, attr_name);281 return addLLVMAttr(arg_val, param_index + 1, attr_name);
265}282}
...@@ -271,15 +288,19 @@ static void addLLVMCallsiteAttr(LLVMValueRef call_instr, unsigned param_index, c...@@ -271,15 +288,19 @@ static void addLLVMCallsiteAttr(LLVMValueRef call_instr, unsigned param_index, c
271 LLVMAddCallSiteAttribute(call_instr, param_index + 1, llvm_attr);288 LLVMAddCallSiteAttribute(call_instr, param_index + 1, llvm_attr);
272}289}
273290
291static bool is_symbol_available(CodeGen *g, Buf *name) {
292 return g->exported_symbol_names.maybe_get(name) == nullptr && g->external_prototypes.maybe_get(name) == nullptr;
293}
294
274static Buf *get_mangled_name(CodeGen *g, Buf *original_name, bool external_linkage) {295static Buf *get_mangled_name(CodeGen *g, Buf *original_name, bool external_linkage) {
275 if (external_linkage || g->external_symbol_names.maybe_get(original_name) == nullptr) {296 if (external_linkage || is_symbol_available(g, original_name)) {
276 return original_name;297 return original_name;
277 }298 }
278299
279 int n = 0;300 int n = 0;
280 for (;; n += 1) {301 for (;; n += 1) {
281 Buf *new_name = buf_sprintf("%s.%d", buf_ptr(original_name), n);302 Buf *new_name = buf_sprintf("%s.%d", buf_ptr(original_name), n);
282 if (g->external_symbol_names.maybe_get(new_name) == nullptr) {303 if (is_symbol_available(g, new_name)) {
283 return new_name;304 return new_name;
284 }305 }
285 }306 }
...@@ -289,11 +310,12 @@ static LLVMValueRef fn_llvm_value(CodeGen *g, FnTableEntry *fn_table_entry) {...@@ -289,11 +310,12 @@ static LLVMValueRef fn_llvm_value(CodeGen *g, FnTableEntry *fn_table_entry) {
289 if (fn_table_entry->llvm_value)310 if (fn_table_entry->llvm_value)
290 return fn_table_entry->llvm_value;311 return fn_table_entry->llvm_value;
291312
292 Buf *symbol_name = get_mangled_name(g, &fn_table_entry->symbol_name, !fn_table_entry->internal_linkage);313 bool external_linkage = (fn_table_entry->linkage != GlobalLinkageIdInternal);
314 Buf *symbol_name = get_mangled_name(g, &fn_table_entry->symbol_name, external_linkage);
293315
294 TypeTableEntry *fn_type = fn_table_entry->type_entry;316 TypeTableEntry *fn_type = fn_table_entry->type_entry;
295 LLVMTypeRef fn_llvm_type = fn_type->data.fn.raw_type_ref;317 LLVMTypeRef fn_llvm_type = fn_type->data.fn.raw_type_ref;
296 if (!fn_table_entry->internal_linkage && fn_table_entry->body_node == nullptr) {318 if (external_linkage && fn_table_entry->body_node == nullptr) {
297 LLVMValueRef existing_llvm_fn = LLVMGetNamedFunction(g->module, buf_ptr(symbol_name));319 LLVMValueRef existing_llvm_fn = LLVMGetNamedFunction(g->module, buf_ptr(symbol_name));
298 if (existing_llvm_fn) {320 if (existing_llvm_fn) {
299 fn_table_entry->llvm_value = LLVMConstBitCast(existing_llvm_fn, LLVMPointerType(fn_llvm_type, 0));321 fn_table_entry->llvm_value = LLVMConstBitCast(existing_llvm_fn, LLVMPointerType(fn_llvm_type, 0));
...@@ -318,12 +340,35 @@ static LLVMValueRef fn_llvm_value(CodeGen *g, FnTableEntry *fn_table_entry) {...@@ -318,12 +340,35 @@ static LLVMValueRef fn_llvm_value(CodeGen *g, FnTableEntry *fn_table_entry) {
318 addLLVMFnAttr(fn_table_entry->llvm_value, "naked");340 addLLVMFnAttr(fn_table_entry->llvm_value, "naked");
319 }341 }
320342
321 LLVMSetLinkage(fn_table_entry->llvm_value, fn_table_entry->internal_linkage ?343 switch (fn_table_entry->linkage) {
322 LLVMInternalLinkage : LLVMExternalLinkage);344 case GlobalLinkageIdInternal:
345 LLVMSetLinkage(fn_table_entry->llvm_value, LLVMInternalLinkage);
346 break;
347 case GlobalLinkageIdStrong:
348 LLVMSetLinkage(fn_table_entry->llvm_value, LLVMExternalLinkage);
349 break;
350 case GlobalLinkageIdWeak:
351 LLVMSetLinkage(fn_table_entry->llvm_value, LLVMWeakODRLinkage);
352 break;
353 case GlobalLinkageIdLinkOnce:
354 LLVMSetLinkage(fn_table_entry->llvm_value, LLVMLinkOnceODRLinkage);
355 break;
356 }
323357
324 if (fn_type->data.fn.fn_type_id.return_type->id == TypeTableEntryIdUnreachable) {358 if (fn_type->data.fn.fn_type_id.return_type->id == TypeTableEntryIdUnreachable) {
325 addLLVMFnAttr(fn_table_entry->llvm_value, "noreturn");359 addLLVMFnAttr(fn_table_entry->llvm_value, "noreturn");
326 }360 }
361
362 if (fn_table_entry->body_node != nullptr) {
363 bool want_fn_safety = !g->is_release_build && !fn_table_entry->def_scope->safety_off;
364 if (want_fn_safety) {
365 if (g->link_libc) {
366 addLLVMFnAttr(fn_table_entry->llvm_value, "sspstrong");
367 addLLVMFnAttrStr(fn_table_entry->llvm_value, "stack-protector-buffer-size", "4");
368 }
369 }
370 }
371
327 LLVMSetFunctionCallConv(fn_table_entry->llvm_value, fn_type->data.fn.calling_convention);372 LLVMSetFunctionCallConv(fn_table_entry->llvm_value, fn_type->data.fn.calling_convention);
328 if (fn_type->data.fn.fn_type_id.is_cold) {373 if (fn_type->data.fn.fn_type_id.is_cold) {
329 ZigLLVMAddFunctionAttrCold(fn_table_entry->llvm_value);374 ZigLLVMAddFunctionAttrCold(fn_table_entry->llvm_value);
...@@ -363,10 +408,11 @@ static ZigLLVMDIScope *get_di_scope(CodeGen *g, Scope *scope) {...@@ -363,10 +408,11 @@ static ZigLLVMDIScope *get_di_scope(CodeGen *g, Scope *scope) {
363 bool is_definition = fn_table_entry->body_node != nullptr;408 bool is_definition = fn_table_entry->body_node != nullptr;
364 unsigned flags = 0;409 unsigned flags = 0;
365 bool is_optimized = g->is_release_build;410 bool is_optimized = g->is_release_build;
411 bool is_internal_linkage = (fn_table_entry->linkage == GlobalLinkageIdInternal);
366 ZigLLVMDISubprogram *subprogram = ZigLLVMCreateFunction(g->dbuilder,412 ZigLLVMDISubprogram *subprogram = ZigLLVMCreateFunction(g->dbuilder,
367 get_di_scope(g, scope->parent), buf_ptr(&fn_table_entry->symbol_name), "",413 get_di_scope(g, scope->parent), buf_ptr(&fn_table_entry->symbol_name), "",
368 import->di_file, line_number,414 import->di_file, line_number,
369 fn_table_entry->type_entry->di_type, fn_table_entry->internal_linkage,415 fn_table_entry->type_entry->di_type, is_internal_linkage,
370 is_definition, scope_line, flags, is_optimized, nullptr);416 is_definition, scope_line, flags, is_optimized, nullptr);
371417
372 scope->di_scope = ZigLLVMSubprogramToScope(subprogram);418 scope->di_scope = ZigLLVMSubprogramToScope(subprogram);
...@@ -544,13 +590,28 @@ static LLVMValueRef get_panic_msg_ptr_val(CodeGen *g, PanicMsgId msg_id) {...@@ -544,13 +590,28 @@ static LLVMValueRef get_panic_msg_ptr_val(CodeGen *g, PanicMsgId msg_id) {
544 return val->llvm_global;590 return val->llvm_global;
545}591}
546592
547static void gen_debug_safety_crash(CodeGen *g, PanicMsgId msg_id) {593static void gen_panic(CodeGen *g, LLVMValueRef msg_arg) {
548 LLVMValueRef fn_val = fn_llvm_value(g, g->panic_fn);594 FnTableEntry *panic_fn = get_extern_panic_fn(g);
549 LLVMValueRef msg_arg = get_panic_msg_ptr_val(g, msg_id);595 LLVMValueRef fn_val = fn_llvm_value(g, panic_fn);
550 ZigLLVMBuildCall(g->builder, fn_val, &msg_arg, 1, g->panic_fn->type_entry->data.fn.calling_convention, "");596
597 TypeTableEntry *str_type = get_slice_type(g, g->builtin_types.entry_u8, true);
598 size_t ptr_index = str_type->data.structure.fields[slice_ptr_index].gen_index;
599 size_t len_index = str_type->data.structure.fields[slice_len_index].gen_index;
600 LLVMValueRef ptr_ptr = LLVMBuildStructGEP(g->builder, msg_arg, ptr_index, "");
601 LLVMValueRef len_ptr = LLVMBuildStructGEP(g->builder, msg_arg, len_index, "");
602
603 LLVMValueRef args[] = {
604 LLVMBuildLoad(g->builder, ptr_ptr, ""),
605 LLVMBuildLoad(g->builder, len_ptr, ""),
606 };
607 ZigLLVMBuildCall(g->builder, fn_val, args, 2, panic_fn->type_entry->data.fn.calling_convention, "");
551 LLVMBuildUnreachable(g->builder);608 LLVMBuildUnreachable(g->builder);
552}609}
553610
611static void gen_debug_safety_crash(CodeGen *g, PanicMsgId msg_id) {
612 gen_panic(g, get_panic_msg_ptr_val(g, msg_id));
613}
614
554static void add_bounds_check(CodeGen *g, LLVMValueRef target_val,615static void add_bounds_check(CodeGen *g, LLVMValueRef target_val,
555 LLVMIntPredicate lower_pred, LLVMValueRef lower_value,616 LLVMIntPredicate lower_pred, LLVMValueRef lower_value,
556 LLVMIntPredicate upper_pred, LLVMValueRef upper_value)617 LLVMIntPredicate upper_pred, LLVMValueRef upper_value)
...@@ -2564,6 +2625,11 @@ static LLVMValueRef ir_render_container_init_list(CodeGen *g, IrExecutable *exec...@@ -2564,6 +2625,11 @@ static LLVMValueRef ir_render_container_init_list(CodeGen *g, IrExecutable *exec
2564 return tmp_array_ptr;2625 return tmp_array_ptr;
2565}2626}
25662627
2628static LLVMValueRef ir_render_panic(CodeGen *g, IrExecutable *executable, IrInstructionPanic *instruction) {
2629 gen_panic(g, ir_llvm_value(g, instruction->msg));
2630 return nullptr;
2631}
2632
2567static void set_debug_location(CodeGen *g, IrInstruction *instruction) {2633static void set_debug_location(CodeGen *g, IrInstruction *instruction) {
2568 AstNode *source_node = instruction->source_node;2634 AstNode *source_node = instruction->source_node;
2569 Scope *scope = instruction->scope;2635 Scope *scope = instruction->scope;
...@@ -2584,7 +2650,6 @@ static LLVMValueRef ir_render_instruction(CodeGen *g, IrExecutable *executable,...@@ -2584,7 +2650,6 @@ static LLVMValueRef ir_render_instruction(CodeGen *g, IrExecutable *executable,
2584 case IrInstructionIdToPtrType:2650 case IrInstructionIdToPtrType:
2585 case IrInstructionIdPtrTypeChild:2651 case IrInstructionIdPtrTypeChild:
2586 case IrInstructionIdFieldPtr:2652 case IrInstructionIdFieldPtr:
2587 case IrInstructionIdSetFnVisible:
2588 case IrInstructionIdSetDebugSafety:2653 case IrInstructionIdSetDebugSafety:
2589 case IrInstructionIdArrayType:2654 case IrInstructionIdArrayType:
2590 case IrInstructionIdSliceType:2655 case IrInstructionIdSliceType:
...@@ -2615,7 +2680,9 @@ static LLVMValueRef ir_render_instruction(CodeGen *g, IrExecutable *executable,...@@ -2615,7 +2680,9 @@ static LLVMValueRef ir_render_instruction(CodeGen *g, IrExecutable *executable,
2615 case IrInstructionIdCanImplicitCast:2680 case IrInstructionIdCanImplicitCast:
2616 case IrInstructionIdSetGlobalAlign:2681 case IrInstructionIdSetGlobalAlign:
2617 case IrInstructionIdSetGlobalSection:2682 case IrInstructionIdSetGlobalSection:
2683 case IrInstructionIdSetGlobalLinkage:
2618 case IrInstructionIdDeclRef:2684 case IrInstructionIdDeclRef:
2685 case IrInstructionIdSwitchVar:
2619 zig_unreachable();2686 zig_unreachable();
2620 case IrInstructionIdReturn:2687 case IrInstructionIdReturn:
2621 return ir_render_return(g, executable, (IrInstructionReturn *)instruction);2688 return ir_render_return(g, executable, (IrInstructionReturn *)instruction);
...@@ -2721,8 +2788,8 @@ static LLVMValueRef ir_render_instruction(CodeGen *g, IrExecutable *executable,...@@ -2721,8 +2788,8 @@ static LLVMValueRef ir_render_instruction(CodeGen *g, IrExecutable *executable,
2721 return ir_render_int_to_enum(g, executable, (IrInstructionIntToEnum *)instruction);2788 return ir_render_int_to_enum(g, executable, (IrInstructionIntToEnum *)instruction);
2722 case IrInstructionIdContainerInitList:2789 case IrInstructionIdContainerInitList:
2723 return ir_render_container_init_list(g, executable, (IrInstructionContainerInitList *)instruction);2790 return ir_render_container_init_list(g, executable, (IrInstructionContainerInitList *)instruction);
2724 case IrInstructionIdSwitchVar:2791 case IrInstructionIdPanic:
2725 zig_panic("TODO render switch var instruction to LLVM");2792 return ir_render_panic(g, executable, (IrInstructionPanic *)instruction);
2726 }2793 }
2727 zig_unreachable();2794 zig_unreachable();
2728}2795}
...@@ -3659,6 +3726,18 @@ static const CIntTypeInfo c_int_type_infos[] = {...@@ -3659,6 +3726,18 @@ static const CIntTypeInfo c_int_type_infos[] = {
36593726
3660static const bool is_signed_list[] = { false, true, };3727static const bool is_signed_list[] = { false, true, };
36613728
3729struct GlobalLinkageValue {
3730 GlobalLinkageId id;
3731 const char *name;
3732};
3733
3734static const GlobalLinkageValue global_linkage_values[] = {
3735 {GlobalLinkageIdInternal, "Internal"},
3736 {GlobalLinkageIdStrong, "Strong"},
3737 {GlobalLinkageIdWeak, "Weak"},
3738 {GlobalLinkageIdLinkOnce, "LinkOnce"},
3739};
3740
3662static void define_builtin_types(CodeGen *g) {3741static void define_builtin_types(CodeGen *g) {
3663 {3742 {
3664 // if this type is anywhere in the AST, we should never hit codegen.3743 // if this type is anywhere in the AST, we should never hit codegen.
...@@ -3995,6 +4074,30 @@ static void define_builtin_types(CodeGen *g) {...@@ -3995,6 +4074,30 @@ static void define_builtin_types(CodeGen *g) {
3995 g->primitive_type_table.put(&entry->name, entry);4074 g->primitive_type_table.put(&entry->name, entry);
3996 }4075 }
39974076
4077 {
4078 TypeTableEntry *entry = new_type_table_entry(TypeTableEntryIdEnum);
4079 entry->zero_bits = true; // only allowed at compile time
4080 buf_init_from_str(&entry->name, "GlobalLinkage");
4081 uint32_t field_count = array_length(global_linkage_values);
4082 entry->data.enumeration.src_field_count = field_count;
4083 entry->data.enumeration.fields = allocate<TypeEnumField>(field_count);
4084 for (uint32_t i = 0; i < field_count; i += 1) {
4085 TypeEnumField *type_enum_field = &entry->data.enumeration.fields[i];
4086 const GlobalLinkageValue *value = &global_linkage_values[i];
4087 type_enum_field->name = buf_create_from_str(value->name);
4088 type_enum_field->value = i;
4089 type_enum_field->type_entry = g->builtin_types.entry_void;
4090 }
4091 entry->data.enumeration.complete = true;
4092 entry->data.enumeration.zero_bits_known = true;
4093
4094 TypeTableEntry *tag_type_entry = get_smallest_unsigned_int_type(g, field_count);
4095 entry->data.enumeration.tag_type = tag_type_entry;
4096
4097 g->builtin_types.entry_global_linkage_enum = entry;
4098 g->primitive_type_table.put(&entry->name, entry);
4099 }
4100
3998 {4101 {
3999 TypeTableEntry *entry = new_type_table_entry(TypeTableEntryIdEnum);4102 TypeTableEntry *entry = new_type_table_entry(TypeTableEntryIdEnum);
4000 entry->zero_bits = true; // only allowed at compile time4103 entry->zero_bits = true; // only allowed at compile time
...@@ -4145,11 +4248,12 @@ static void define_builtin_fns(CodeGen *g) {...@@ -4145,11 +4248,12 @@ static void define_builtin_fns(CodeGen *g) {
4145 create_builtin_fn(g, BuiltinFnIdCompileErr, "compileError", 1);4248 create_builtin_fn(g, BuiltinFnIdCompileErr, "compileError", 1);
4146 create_builtin_fn(g, BuiltinFnIdCompileLog, "compileLog", SIZE_MAX);4249 create_builtin_fn(g, BuiltinFnIdCompileLog, "compileLog", SIZE_MAX);
4147 create_builtin_fn(g, BuiltinFnIdIntType, "intType", 2);4250 create_builtin_fn(g, BuiltinFnIdIntType, "intType", 2);
4148 create_builtin_fn(g, BuiltinFnIdSetFnVisible, "setFnVisible", 2);
4149 create_builtin_fn(g, BuiltinFnIdSetDebugSafety, "setDebugSafety", 2);4251 create_builtin_fn(g, BuiltinFnIdSetDebugSafety, "setDebugSafety", 2);
4150 create_builtin_fn(g, BuiltinFnIdAlloca, "alloca", 2);4252 create_builtin_fn(g, BuiltinFnIdAlloca, "alloca", 2);
4151 create_builtin_fn(g, BuiltinFnIdSetGlobalAlign, "setGlobalAlign", 2);4253 create_builtin_fn(g, BuiltinFnIdSetGlobalAlign, "setGlobalAlign", 2);
4152 create_builtin_fn(g, BuiltinFnIdSetGlobalSection, "setGlobalSection", 2);4254 create_builtin_fn(g, BuiltinFnIdSetGlobalSection, "setGlobalSection", 2);
4255 create_builtin_fn(g, BuiltinFnIdSetGlobalLinkage, "setGlobalLinkage", 2);
4256 create_builtin_fn(g, BuiltinFnIdPanic, "panic", 1);
4153}4257}
41544258
4155static void add_compile_var(CodeGen *g, const char *name, ConstExprValue *value) {4259static void add_compile_var(CodeGen *g, const char *name, ConstExprValue *value) {
...@@ -4180,6 +4284,7 @@ static void define_builtin_compile_vars(CodeGen *g) {...@@ -4180,6 +4284,7 @@ static void define_builtin_compile_vars(CodeGen *g) {
41804284
4181 add_compile_var(g, "link_libs", const_val);4285 add_compile_var(g, "link_libs", const_val);
4182 }4286 }
4287 add_compile_var(g, "panic_implementation_provided", create_const_bool(g, false));
4183}4288}
41844289
4185static void init(CodeGen *g, Buf *source_path) {4290static void init(CodeGen *g, Buf *source_path) {
...@@ -4309,9 +4414,10 @@ static PackageTableEntry *create_bootstrap_pkg(CodeGen *g) {...@@ -4309,9 +4414,10 @@ static PackageTableEntry *create_bootstrap_pkg(CodeGen *g) {
4309 return package;4414 return package;
4310}4415}
43114416
4312static PackageTableEntry *create_panic_pkg(CodeGen *g) {4417static PackageTableEntry *create_zigrt_pkg(CodeGen *g) {
4313 PackageTableEntry *package = new_package(buf_ptr(g->zig_std_special_dir), "");4418 PackageTableEntry *package = new_package(buf_ptr(g->zig_std_special_dir), "");
4314 package->package_table.put(buf_create_from_str("std"), g->std_package);4419 package->package_table.put(buf_create_from_str("std"), g->std_package);
4420 package->package_table.put(buf_create_from_str("@root"), g->root_package);
4315 return package;4421 return package;
4316}4422}
43174423
...@@ -4337,9 +4443,9 @@ void codegen_add_root_code(CodeGen *g, Buf *src_dir, Buf *src_basename, Buf *sou...@@ -4337,9 +4443,9 @@ void codegen_add_root_code(CodeGen *g, Buf *src_dir, Buf *src_basename, Buf *sou
4337 if (!g->is_test_build && g->have_pub_main && (g->out_type == OutTypeObj || g->out_type == OutTypeExe)) {4443 if (!g->is_test_build && g->have_pub_main && (g->out_type == OutTypeObj || g->out_type == OutTypeExe)) {
4338 g->bootstrap_import = add_special_code(g, create_bootstrap_pkg(g), "bootstrap.zig");4444 g->bootstrap_import = add_special_code(g, create_bootstrap_pkg(g), "bootstrap.zig");
4339 }4445 }
4340 if (!g->have_pub_panic) {4446 if (!g->omit_zigrt) {
4341 g->panic_package = create_panic_pkg(g);4447 g->zigrt_package = create_zigrt_pkg(g);
4342 add_special_code(g, g->panic_package, "panic.zig");4448 add_special_code(g, g->zigrt_package, "zigrt.zig");
4343 }4449 }
43444450
4345 if (g->verbose) {4451 if (g->verbose) {
...@@ -4509,7 +4615,7 @@ void codegen_generate_h_file(CodeGen *g) {...@@ -4509,7 +4615,7 @@ void codegen_generate_h_file(CodeGen *g) {
4509 for (size_t fn_def_i = 0; fn_def_i < g->fn_defs.length; fn_def_i += 1) {4615 for (size_t fn_def_i = 0; fn_def_i < g->fn_defs.length; fn_def_i += 1) {
4510 FnTableEntry *fn_table_entry = g->fn_defs.at(fn_def_i);4616 FnTableEntry *fn_table_entry = g->fn_defs.at(fn_def_i);
45114617
4512 if (fn_table_entry->internal_linkage)4618 if (fn_table_entry->linkage == GlobalLinkageIdInternal)
4513 continue;4619 continue;
45144620
4515 FnTypeId *fn_type_id = &fn_table_entry->type_entry->data.fn.fn_type_id;4621 FnTypeId *fn_type_id = &fn_table_entry->type_entry->data.fn.fn_type_id;
src/codegen.hpp+1
...@@ -43,6 +43,7 @@ void codegen_set_rdynamic(CodeGen *g, bool rdynamic);...@@ -43,6 +43,7 @@ void codegen_set_rdynamic(CodeGen *g, bool rdynamic);
43void codegen_set_mmacosx_version_min(CodeGen *g, Buf *mmacosx_version_min);43void codegen_set_mmacosx_version_min(CodeGen *g, Buf *mmacosx_version_min);
44void codegen_set_mios_version_min(CodeGen *g, Buf *mios_version_min);44void codegen_set_mios_version_min(CodeGen *g, Buf *mios_version_min);
45void codegen_set_linker_script(CodeGen *g, const char *linker_script);45void codegen_set_linker_script(CodeGen *g, const char *linker_script);
46void codegen_set_omit_zigrt(CodeGen *g, bool omit_zigrt);
4647
47void codegen_add_root_code(CodeGen *g, Buf *source_dir, Buf *source_basename, Buf *source_code);48void codegen_add_root_code(CodeGen *g, Buf *source_dir, Buf *source_basename, Buf *source_code);
4849
src/ir.cpp+148-82
...@@ -276,10 +276,6 @@ static constexpr IrInstructionId ir_instruction_id(IrInstructionPtrTypeChild *)...@@ -276,10 +276,6 @@ static constexpr IrInstructionId ir_instruction_id(IrInstructionPtrTypeChild *)
276 return IrInstructionIdPtrTypeChild;276 return IrInstructionIdPtrTypeChild;
277}277}
278278
279static constexpr IrInstructionId ir_instruction_id(IrInstructionSetFnVisible *) {
280 return IrInstructionIdSetFnVisible;
281}
282
283static constexpr IrInstructionId ir_instruction_id(IrInstructionSetDebugSafety *) {279static constexpr IrInstructionId ir_instruction_id(IrInstructionSetDebugSafety *) {
284 return IrInstructionIdSetDebugSafety;280 return IrInstructionIdSetDebugSafety;
285}281}
...@@ -528,10 +524,18 @@ static constexpr IrInstructionId ir_instruction_id(IrInstructionSetGlobalSection...@@ -528,10 +524,18 @@ static constexpr IrInstructionId ir_instruction_id(IrInstructionSetGlobalSection
528 return IrInstructionIdSetGlobalSection;524 return IrInstructionIdSetGlobalSection;
529}525}
530526
527static constexpr IrInstructionId ir_instruction_id(IrInstructionSetGlobalLinkage *) {
528 return IrInstructionIdSetGlobalLinkage;
529}
530
531static constexpr IrInstructionId ir_instruction_id(IrInstructionDeclRef *) {531static constexpr IrInstructionId ir_instruction_id(IrInstructionDeclRef *) {
532 return IrInstructionIdDeclRef;532 return IrInstructionIdDeclRef;
533}533}
534534
535static constexpr IrInstructionId ir_instruction_id(IrInstructionPanic *) {
536 return IrInstructionIdPanic;
537}
538
535template<typename T>539template<typename T>
536static T *ir_create_instruction(IrBuilder *irb, Scope *scope, AstNode *source_node) {540static T *ir_create_instruction(IrBuilder *irb, Scope *scope, AstNode *source_node) {
537 T *special_instruction = allocate<T>(1);541 T *special_instruction = allocate<T>(1);
...@@ -1147,19 +1151,6 @@ static IrInstruction *ir_build_ptr_type_child(IrBuilder *irb, Scope *scope, AstN...@@ -1147,19 +1151,6 @@ static IrInstruction *ir_build_ptr_type_child(IrBuilder *irb, Scope *scope, AstN
1147 return &instruction->base;1151 return &instruction->base;
1148}1152}
11491153
1150static IrInstruction *ir_build_set_fn_visible(IrBuilder *irb, Scope *scope, AstNode *source_node, IrInstruction *fn_value,
1151 IrInstruction *is_visible)
1152{
1153 IrInstructionSetFnVisible *instruction = ir_build_instruction<IrInstructionSetFnVisible>(irb, scope, source_node);
1154 instruction->fn_value = fn_value;
1155 instruction->is_visible = is_visible;
1156
1157 ir_ref_instruction(fn_value, irb->current_basic_block);
1158 ir_ref_instruction(is_visible, irb->current_basic_block);
1159
1160 return &instruction->base;
1161}
1162
1163static IrInstruction *ir_build_set_debug_safety(IrBuilder *irb, Scope *scope, AstNode *source_node,1154static IrInstruction *ir_build_set_debug_safety(IrBuilder *irb, Scope *scope, AstNode *source_node,
1164 IrInstruction *scope_value, IrInstruction *debug_safety_on)1155 IrInstruction *scope_value, IrInstruction *debug_safety_on)
1165{1156{
...@@ -2092,6 +2083,19 @@ static IrInstruction *ir_build_set_global_section(IrBuilder *irb, Scope *scope,...@@ -2092,6 +2083,19 @@ static IrInstruction *ir_build_set_global_section(IrBuilder *irb, Scope *scope,
2092 return &instruction->base;2083 return &instruction->base;
2093}2084}
20942085
2086static IrInstruction *ir_build_set_global_linkage(IrBuilder *irb, Scope *scope, AstNode *source_node,
2087 Tld *tld, IrInstruction *value)
2088{
2089 IrInstructionSetGlobalLinkage *instruction = ir_build_instruction<IrInstructionSetGlobalLinkage>(
2090 irb, scope, source_node);
2091 instruction->tld = tld;
2092 instruction->value = value;
2093
2094 ir_ref_instruction(value, irb->current_basic_block);
2095
2096 return &instruction->base;
2097}
2098
2095static IrInstruction *ir_build_decl_ref(IrBuilder *irb, Scope *scope, AstNode *source_node,2099static IrInstruction *ir_build_decl_ref(IrBuilder *irb, Scope *scope, AstNode *source_node,
2096 Tld *tld, LVal lval)2100 Tld *tld, LVal lval)
2097{2101{
...@@ -2103,6 +2107,17 @@ static IrInstruction *ir_build_decl_ref(IrBuilder *irb, Scope *scope, AstNode *s...@@ -2103,6 +2107,17 @@ static IrInstruction *ir_build_decl_ref(IrBuilder *irb, Scope *scope, AstNode *s
2103 return &instruction->base;2107 return &instruction->base;
2104}2108}
21052109
2110static IrInstruction *ir_build_panic(IrBuilder *irb, Scope *scope, AstNode *source_node, IrInstruction *msg) {
2111 IrInstructionPanic *instruction = ir_build_instruction<IrInstructionPanic>(irb, scope, source_node);
2112 instruction->base.value.special = ConstValSpecialStatic;
2113 instruction->base.value.type = irb->codegen->builtin_types.entry_unreachable;
2114 instruction->msg = msg;
2115
2116 ir_ref_instruction(msg, irb->current_basic_block);
2117
2118 return &instruction->base;
2119}
2120
2106static IrInstruction *ir_instruction_br_get_dep(IrInstructionBr *instruction, size_t index) {2121static IrInstruction *ir_instruction_br_get_dep(IrInstructionBr *instruction, size_t index) {
2107 return nullptr;2122 return nullptr;
2108}2123}
...@@ -2287,14 +2302,6 @@ static IrInstruction *ir_instruction_ptrtypechild_get_dep(IrInstructionPtrTypeCh...@@ -2287,14 +2302,6 @@ static IrInstruction *ir_instruction_ptrtypechild_get_dep(IrInstructionPtrTypeCh
2287 }2302 }
2288}2303}
22892304
2290static IrInstruction *ir_instruction_setfnvisible_get_dep(IrInstructionSetFnVisible *instruction, size_t index) {
2291 switch (index) {
2292 case 0: return instruction->fn_value;
2293 case 1: return instruction->is_visible;
2294 default: return nullptr;
2295 }
2296}
2297
2298static IrInstruction *ir_instruction_setdebugsafety_get_dep(IrInstructionSetDebugSafety *instruction, size_t index) {2305static IrInstruction *ir_instruction_setdebugsafety_get_dep(IrInstructionSetDebugSafety *instruction, size_t index) {
2299 switch (index) {2306 switch (index) {
2300 case 0: return instruction->scope_value;2307 case 0: return instruction->scope_value;
...@@ -2742,10 +2749,24 @@ static IrInstruction *ir_instruction_setglobalsection_get_dep(IrInstructionSetGl...@@ -2742,10 +2749,24 @@ static IrInstruction *ir_instruction_setglobalsection_get_dep(IrInstructionSetGl
2742 }2749 }
2743}2750}
27442751
2752static IrInstruction *ir_instruction_setgloballinkage_get_dep(IrInstructionSetGlobalLinkage *instruction, size_t index) {
2753 switch (index) {
2754 case 0: return instruction->value;
2755 default: return nullptr;
2756 }
2757}
2758
2745static IrInstruction *ir_instruction_declref_get_dep(IrInstructionDeclRef *instruction, size_t index) {2759static IrInstruction *ir_instruction_declref_get_dep(IrInstructionDeclRef *instruction, size_t index) {
2746 return nullptr;2760 return nullptr;
2747}2761}
27482762
2763static IrInstruction *ir_instruction_panic_get_dep(IrInstructionPanic *instruction, size_t index) {
2764 switch (index) {
2765 case 0: return instruction->msg;
2766 default: return nullptr;
2767 }
2768}
2769
2749static IrInstruction *ir_instruction_get_dep(IrInstruction *instruction, size_t index) {2770static IrInstruction *ir_instruction_get_dep(IrInstruction *instruction, size_t index) {
2750 switch (instruction->id) {2771 switch (instruction->id) {
2751 case IrInstructionIdInvalid:2772 case IrInstructionIdInvalid:
...@@ -2804,8 +2825,6 @@ static IrInstruction *ir_instruction_get_dep(IrInstruction *instruction, size_t...@@ -2804,8 +2825,6 @@ static IrInstruction *ir_instruction_get_dep(IrInstruction *instruction, size_t
2804 return ir_instruction_toptrtype_get_dep((IrInstructionToPtrType *) instruction, index);2825 return ir_instruction_toptrtype_get_dep((IrInstructionToPtrType *) instruction, index);
2805 case IrInstructionIdPtrTypeChild:2826 case IrInstructionIdPtrTypeChild:
2806 return ir_instruction_ptrtypechild_get_dep((IrInstructionPtrTypeChild *) instruction, index);2827 return ir_instruction_ptrtypechild_get_dep((IrInstructionPtrTypeChild *) instruction, index);
2807 case IrInstructionIdSetFnVisible:
2808 return ir_instruction_setfnvisible_get_dep((IrInstructionSetFnVisible *) instruction, index);
2809 case IrInstructionIdSetDebugSafety:2828 case IrInstructionIdSetDebugSafety:
2810 return ir_instruction_setdebugsafety_get_dep((IrInstructionSetDebugSafety *) instruction, index);2829 return ir_instruction_setdebugsafety_get_dep((IrInstructionSetDebugSafety *) instruction, index);
2811 case IrInstructionIdArrayType:2830 case IrInstructionIdArrayType:
...@@ -2928,8 +2947,12 @@ static IrInstruction *ir_instruction_get_dep(IrInstruction *instruction, size_t...@@ -2928,8 +2947,12 @@ static IrInstruction *ir_instruction_get_dep(IrInstruction *instruction, size_t
2928 return ir_instruction_setglobalalign_get_dep((IrInstructionSetGlobalAlign *) instruction, index);2947 return ir_instruction_setglobalalign_get_dep((IrInstructionSetGlobalAlign *) instruction, index);
2929 case IrInstructionIdSetGlobalSection:2948 case IrInstructionIdSetGlobalSection:
2930 return ir_instruction_setglobalsection_get_dep((IrInstructionSetGlobalSection *) instruction, index);2949 return ir_instruction_setglobalsection_get_dep((IrInstructionSetGlobalSection *) instruction, index);
2950 case IrInstructionIdSetGlobalLinkage:
2951 return ir_instruction_setgloballinkage_get_dep((IrInstructionSetGlobalLinkage *) instruction, index);
2931 case IrInstructionIdDeclRef:2952 case IrInstructionIdDeclRef:
2932 return ir_instruction_declref_get_dep((IrInstructionDeclRef *) instruction, index);2953 return ir_instruction_declref_get_dep((IrInstructionDeclRef *) instruction, index);
2954 case IrInstructionIdPanic:
2955 return ir_instruction_panic_get_dep((IrInstructionPanic *) instruction, index);
2933 }2956 }
2934 zig_unreachable();2957 zig_unreachable();
2935}2958}
...@@ -3759,20 +3782,6 @@ static IrInstruction *ir_gen_builtin_fn_call(IrBuilder *irb, Scope *scope, AstNo...@@ -3759,20 +3782,6 @@ static IrInstruction *ir_gen_builtin_fn_call(IrBuilder *irb, Scope *scope, AstNo
3759 return arg;3782 return arg;
3760 return ir_build_typeof(irb, scope, node, arg);3783 return ir_build_typeof(irb, scope, node, arg);
3761 }3784 }
3762 case BuiltinFnIdSetFnVisible:
3763 {
3764 AstNode *arg0_node = node->data.fn_call_expr.params.at(0);
3765 IrInstruction *arg0_value = ir_gen_node(irb, arg0_node, scope);
3766 if (arg0_value == irb->codegen->invalid_instruction)
3767 return arg0_value;
3768
3769 AstNode *arg1_node = node->data.fn_call_expr.params.at(1);
3770 IrInstruction *arg1_value = ir_gen_node(irb, arg1_node, scope);
3771 if (arg1_value == irb->codegen->invalid_instruction)
3772 return arg1_value;
3773
3774 return ir_build_set_fn_visible(irb, scope, node, arg0_value, arg1_value);
3775 }
3776 case BuiltinFnIdSetDebugSafety:3785 case BuiltinFnIdSetDebugSafety:
3777 {3786 {
3778 AstNode *arg0_node = node->data.fn_call_expr.params.at(0);3787 AstNode *arg0_node = node->data.fn_call_expr.params.at(0);
...@@ -4145,6 +4154,7 @@ static IrInstruction *ir_gen_builtin_fn_call(IrBuilder *irb, Scope *scope, AstNo...@@ -4145,6 +4154,7 @@ static IrInstruction *ir_gen_builtin_fn_call(IrBuilder *irb, Scope *scope, AstNo
4145 }4154 }
4146 case BuiltinFnIdSetGlobalAlign:4155 case BuiltinFnIdSetGlobalAlign:
4147 case BuiltinFnIdSetGlobalSection:4156 case BuiltinFnIdSetGlobalSection:
4157 case BuiltinFnIdSetGlobalLinkage:
4148 {4158 {
4149 AstNode *arg0_node = node->data.fn_call_expr.params.at(0);4159 AstNode *arg0_node = node->data.fn_call_expr.params.at(0);
4150 if (arg0_node->type != NodeTypeSymbol) {4160 if (arg0_node->type != NodeTypeSymbol) {
...@@ -4170,10 +4180,23 @@ static IrInstruction *ir_gen_builtin_fn_call(IrBuilder *irb, Scope *scope, AstNo...@@ -4170,10 +4180,23 @@ static IrInstruction *ir_gen_builtin_fn_call(IrBuilder *irb, Scope *scope, AstNo
41704180
4171 if (builtin_fn->id == BuiltinFnIdSetGlobalAlign) {4181 if (builtin_fn->id == BuiltinFnIdSetGlobalAlign) {
4172 return ir_build_set_global_align(irb, scope, node, tld, arg1_value);4182 return ir_build_set_global_align(irb, scope, node, tld, arg1_value);
4173 } else {4183 } else if (builtin_fn->id == BuiltinFnIdSetGlobalSection) {
4174 return ir_build_set_global_section(irb, scope, node, tld, arg1_value);4184 return ir_build_set_global_section(irb, scope, node, tld, arg1_value);
4185 } else if (builtin_fn->id == BuiltinFnIdSetGlobalLinkage) {
4186 return ir_build_set_global_linkage(irb, scope, node, tld, arg1_value);
4187 } else {
4188 zig_unreachable();
4175 }4189 }
4176 }4190 }
4191 case BuiltinFnIdPanic:
4192 {
4193 AstNode *arg0_node = node->data.fn_call_expr.params.at(0);
4194 IrInstruction *arg0_value = ir_gen_node(irb, arg0_node, scope);
4195 if (arg0_value == irb->codegen->invalid_instruction)
4196 return arg0_value;
4197
4198 return ir_build_panic(irb, scope, node, arg0_value);
4199 }
4177 }4200 }
4178 zig_unreachable();4201 zig_unreachable();
4179}4202}
...@@ -4624,6 +4647,10 @@ static IrInstruction *ir_gen_this_literal(IrBuilder *irb, Scope *scope, AstNode...@@ -4624,6 +4647,10 @@ static IrInstruction *ir_gen_this_literal(IrBuilder *irb, Scope *scope, AstNode
4624 if (fn_entry)4647 if (fn_entry)
4625 return ir_build_const_fn(irb, scope, node, fn_entry);4648 return ir_build_const_fn(irb, scope, node, fn_entry);
46264649
4650 while (scope->id != ScopeIdBlock && scope->id != ScopeIdDecls) {
4651 scope = scope->parent;
4652 }
4653
4627 if (scope->id == ScopeIdDecls) {4654 if (scope->id == ScopeIdDecls) {
4628 ScopeDecls *decls_scope = (ScopeDecls *)scope;4655 ScopeDecls *decls_scope = (ScopeDecls *)scope;
4629 TypeTableEntry *container_type = decls_scope->container_type;4656 TypeTableEntry *container_type = decls_scope->container_type;
...@@ -7096,6 +7123,23 @@ static bool ir_resolve_atomic_order(IrAnalyze *ira, IrInstruction *value, Atomic...@@ -7096,6 +7123,23 @@ static bool ir_resolve_atomic_order(IrAnalyze *ira, IrInstruction *value, Atomic
7096 return true;7123 return true;
7097}7124}
70987125
7126static bool ir_resolve_global_linkage(IrAnalyze *ira, IrInstruction *value, GlobalLinkageId *out) {
7127 if (type_is_invalid(value->value.type))
7128 return false;
7129
7130 IrInstruction *casted_value = ir_implicit_cast(ira, value, ira->codegen->builtin_types.entry_global_linkage_enum);
7131 if (type_is_invalid(casted_value->value.type))
7132 return false;
7133
7134 ConstExprValue *const_val = ir_resolve_const(ira, casted_value, UndefBad);
7135 if (!const_val)
7136 return false;
7137
7138 *out = (GlobalLinkageId)const_val->data.x_enum.tag;
7139 return true;
7140}
7141
7142
7099static Buf *ir_resolve_str(IrAnalyze *ira, IrInstruction *value) {7143static Buf *ir_resolve_str(IrAnalyze *ira, IrInstruction *value) {
7100 if (type_is_invalid(value->value.type))7144 if (type_is_invalid(value->value.type))
7101 return nullptr;7145 return nullptr;
...@@ -9557,42 +9601,6 @@ static TypeTableEntry *ir_analyze_instruction_ptr_type_child(IrAnalyze *ira,...@@ -9557,42 +9601,6 @@ static TypeTableEntry *ir_analyze_instruction_ptr_type_child(IrAnalyze *ira,
9557 return ira->codegen->builtin_types.entry_type;9601 return ira->codegen->builtin_types.entry_type;
9558}9602}
95599603
9560static TypeTableEntry *ir_analyze_instruction_set_fn_visible(IrAnalyze *ira,
9561 IrInstructionSetFnVisible *set_fn_visible_instruction)
9562{
9563 IrInstruction *fn_value = set_fn_visible_instruction->fn_value->other;
9564 IrInstruction *is_visible_value = set_fn_visible_instruction->is_visible->other;
9565
9566 FnTableEntry *fn_entry = ir_resolve_fn(ira, fn_value);
9567 if (!fn_entry)
9568 return ira->codegen->builtin_types.entry_invalid;
9569
9570 bool want_export;
9571 if (!ir_resolve_bool(ira, is_visible_value, &want_export))
9572 return ira->codegen->builtin_types.entry_invalid;
9573
9574 AstNode *source_node = set_fn_visible_instruction->base.source_node;
9575 if (fn_entry->fn_export_set_node) {
9576 ErrorMsg *msg = ir_add_error_node(ira, source_node,
9577 buf_sprintf("function visibility set twice"));
9578 add_error_note(ira->codegen, msg, fn_entry->fn_export_set_node, buf_sprintf("first set here"));
9579 return ira->codegen->builtin_types.entry_invalid;
9580 }
9581 fn_entry->fn_export_set_node = source_node;
9582
9583 AstNodeFnProto *fn_proto = &fn_entry->proto_node->data.fn_proto;
9584 if (fn_proto->visib_mod != VisibModExport) {
9585 ErrorMsg *msg = ir_add_error_node(ira, source_node,
9586 buf_sprintf("function must be marked export to set function visibility"));
9587 add_error_note(ira->codegen, msg, fn_entry->proto_node, buf_sprintf("function declared here"));
9588 return ira->codegen->builtin_types.entry_invalid;
9589 }
9590 fn_entry->internal_linkage = !want_export;
9591
9592 ir_build_const_from(ira, &set_fn_visible_instruction->base);
9593 return ira->codegen->builtin_types.entry_void;
9594}
9595
9596static TypeTableEntry *ir_analyze_instruction_set_global_align(IrAnalyze *ira,9604static TypeTableEntry *ir_analyze_instruction_set_global_align(IrAnalyze *ira,
9597 IrInstructionSetGlobalAlign *instruction)9605 IrInstructionSetGlobalAlign *instruction)
9598{9606{
...@@ -9677,6 +9685,45 @@ static TypeTableEntry *ir_analyze_instruction_set_global_section(IrAnalyze *ira,...@@ -9677,6 +9685,45 @@ static TypeTableEntry *ir_analyze_instruction_set_global_section(IrAnalyze *ira,
9677 return ira->codegen->builtin_types.entry_void;9685 return ira->codegen->builtin_types.entry_void;
9678}9686}
96799687
9688static TypeTableEntry *ir_analyze_instruction_set_global_linkage(IrAnalyze *ira,
9689 IrInstructionSetGlobalLinkage *instruction)
9690{
9691 Tld *tld = instruction->tld;
9692 IrInstruction *linkage_value = instruction->value->other;
9693
9694 GlobalLinkageId linkage_scalar;
9695 if (!ir_resolve_global_linkage(ira, linkage_value, &linkage_scalar))
9696 return ira->codegen->builtin_types.entry_invalid;
9697
9698 AstNode **set_global_linkage_node;
9699 GlobalLinkageId *dest_linkage_ptr;
9700 if (tld->id == TldIdVar) {
9701 TldVar *tld_var = (TldVar *)tld;
9702 set_global_linkage_node = &tld_var->set_global_linkage_node;
9703 dest_linkage_ptr = &tld_var->linkage;
9704 } else if (tld->id == TldIdFn) {
9705 TldFn *tld_fn = (TldFn *)tld;
9706 FnTableEntry *fn_entry = tld_fn->fn_entry;
9707 set_global_linkage_node = &fn_entry->set_global_linkage_node;
9708 dest_linkage_ptr = &fn_entry->linkage;
9709 } else {
9710 // error is caught in pass1 IR gen
9711 zig_unreachable();
9712 }
9713
9714 AstNode *source_node = instruction->base.source_node;
9715 if (*set_global_linkage_node) {
9716 ErrorMsg *msg = ir_add_error_node(ira, source_node, buf_sprintf("linkage set twice"));
9717 add_error_note(ira->codegen, msg, *set_global_linkage_node, buf_sprintf("first set here"));
9718 return ira->codegen->builtin_types.entry_invalid;
9719 }
9720 *set_global_linkage_node = source_node;
9721 *dest_linkage_ptr = linkage_scalar;
9722
9723 ir_build_const_from(ira, &instruction->base);
9724 return ira->codegen->builtin_types.entry_void;
9725}
9726
9680static TypeTableEntry *ir_analyze_instruction_set_debug_safety(IrAnalyze *ira,9727static TypeTableEntry *ir_analyze_instruction_set_debug_safety(IrAnalyze *ira,
9681 IrInstructionSetDebugSafety *set_debug_safety_instruction)9728 IrInstructionSetDebugSafety *set_debug_safety_instruction)
9682{9729{
...@@ -12147,6 +12194,22 @@ static TypeTableEntry *ir_analyze_instruction_can_implicit_cast(IrAnalyze *ira,...@@ -12147,6 +12194,22 @@ static TypeTableEntry *ir_analyze_instruction_can_implicit_cast(IrAnalyze *ira,
12147 return ira->codegen->builtin_types.entry_bool;12194 return ira->codegen->builtin_types.entry_bool;
12148}12195}
1214912196
12197static TypeTableEntry *ir_analyze_instruction_panic(IrAnalyze *ira, IrInstructionPanic *instruction) {
12198 IrInstruction *msg = instruction->msg->other;
12199 if (type_is_invalid(msg->value.type))
12200 return ira->codegen->builtin_types.entry_invalid;
12201
12202 TypeTableEntry *str_type = get_slice_type(ira->codegen, ira->codegen->builtin_types.entry_u8, true);
12203 IrInstruction *casted_msg = ir_implicit_cast(ira, msg, str_type);
12204 if (type_is_invalid(casted_msg->value.type))
12205 return ira->codegen->builtin_types.entry_invalid;
12206
12207 IrInstruction *new_instruction = ir_build_panic(&ira->new_irb, instruction->base.scope,
12208 instruction->base.source_node, casted_msg);
12209 ir_link_new_instruction(new_instruction, &instruction->base);
12210 return ir_finish_anal(ira, ira->codegen->builtin_types.entry_unreachable);
12211}
12212
12150static TypeTableEntry *ir_analyze_instruction_decl_ref(IrAnalyze *ira,12213static TypeTableEntry *ir_analyze_instruction_decl_ref(IrAnalyze *ira,
12151 IrInstructionDeclRef *instruction)12214 IrInstructionDeclRef *instruction)
12152{12215{
...@@ -12266,12 +12329,12 @@ static TypeTableEntry *ir_analyze_instruction_nocast(IrAnalyze *ira, IrInstructi...@@ -12266,12 +12329,12 @@ static TypeTableEntry *ir_analyze_instruction_nocast(IrAnalyze *ira, IrInstructi
12266 return ir_analyze_instruction_to_ptr_type(ira, (IrInstructionToPtrType *)instruction);12329 return ir_analyze_instruction_to_ptr_type(ira, (IrInstructionToPtrType *)instruction);
12267 case IrInstructionIdPtrTypeChild:12330 case IrInstructionIdPtrTypeChild:
12268 return ir_analyze_instruction_ptr_type_child(ira, (IrInstructionPtrTypeChild *)instruction);12331 return ir_analyze_instruction_ptr_type_child(ira, (IrInstructionPtrTypeChild *)instruction);
12269 case IrInstructionIdSetFnVisible:
12270 return ir_analyze_instruction_set_fn_visible(ira, (IrInstructionSetFnVisible *)instruction);
12271 case IrInstructionIdSetGlobalAlign:12332 case IrInstructionIdSetGlobalAlign:
12272 return ir_analyze_instruction_set_global_align(ira, (IrInstructionSetGlobalAlign *)instruction);12333 return ir_analyze_instruction_set_global_align(ira, (IrInstructionSetGlobalAlign *)instruction);
12273 case IrInstructionIdSetGlobalSection:12334 case IrInstructionIdSetGlobalSection:
12274 return ir_analyze_instruction_set_global_section(ira, (IrInstructionSetGlobalSection *)instruction);12335 return ir_analyze_instruction_set_global_section(ira, (IrInstructionSetGlobalSection *)instruction);
12336 case IrInstructionIdSetGlobalLinkage:
12337 return ir_analyze_instruction_set_global_linkage(ira, (IrInstructionSetGlobalLinkage *)instruction);
12275 case IrInstructionIdSetDebugSafety:12338 case IrInstructionIdSetDebugSafety:
12276 return ir_analyze_instruction_set_debug_safety(ira, (IrInstructionSetDebugSafety *)instruction);12339 return ir_analyze_instruction_set_debug_safety(ira, (IrInstructionSetDebugSafety *)instruction);
12277 case IrInstructionIdSliceType:12340 case IrInstructionIdSliceType:
...@@ -12384,6 +12447,8 @@ static TypeTableEntry *ir_analyze_instruction_nocast(IrAnalyze *ira, IrInstructi...@@ -12384,6 +12447,8 @@ static TypeTableEntry *ir_analyze_instruction_nocast(IrAnalyze *ira, IrInstructi
12384 return ir_analyze_instruction_can_implicit_cast(ira, (IrInstructionCanImplicitCast *)instruction);12447 return ir_analyze_instruction_can_implicit_cast(ira, (IrInstructionCanImplicitCast *)instruction);
12385 case IrInstructionIdDeclRef:12448 case IrInstructionIdDeclRef:
12386 return ir_analyze_instruction_decl_ref(ira, (IrInstructionDeclRef *)instruction);12449 return ir_analyze_instruction_decl_ref(ira, (IrInstructionDeclRef *)instruction);
12450 case IrInstructionIdPanic:
12451 return ir_analyze_instruction_panic(ira, (IrInstructionPanic *)instruction);
12387 case IrInstructionIdMaybeWrap:12452 case IrInstructionIdMaybeWrap:
12388 case IrInstructionIdErrWrapCode:12453 case IrInstructionIdErrWrapCode:
12389 case IrInstructionIdErrWrapPayload:12454 case IrInstructionIdErrWrapPayload:
...@@ -12482,7 +12547,6 @@ bool ir_has_side_effects(IrInstruction *instruction) {...@@ -12482,7 +12547,6 @@ bool ir_has_side_effects(IrInstruction *instruction) {
12482 case IrInstructionIdCall:12547 case IrInstructionIdCall:
12483 case IrInstructionIdReturn:12548 case IrInstructionIdReturn:
12484 case IrInstructionIdUnreachable:12549 case IrInstructionIdUnreachable:
12485 case IrInstructionIdSetFnVisible:
12486 case IrInstructionIdSetDebugSafety:12550 case IrInstructionIdSetDebugSafety:
12487 case IrInstructionIdImport:12551 case IrInstructionIdImport:
12488 case IrInstructionIdCompileErr:12552 case IrInstructionIdCompileErr:
...@@ -12500,6 +12564,8 @@ bool ir_has_side_effects(IrInstruction *instruction) {...@@ -12500,6 +12564,8 @@ bool ir_has_side_effects(IrInstruction *instruction) {
12500 case IrInstructionIdCheckSwitchProngs:12564 case IrInstructionIdCheckSwitchProngs:
12501 case IrInstructionIdSetGlobalAlign:12565 case IrInstructionIdSetGlobalAlign:
12502 case IrInstructionIdSetGlobalSection:12566 case IrInstructionIdSetGlobalSection:
12567 case IrInstructionIdSetGlobalLinkage:
12568 case IrInstructionIdPanic:
12503 return true;12569 return true;
12504 case IrInstructionIdPhi:12570 case IrInstructionIdPhi:
12505 case IrInstructionIdUnOp:12571 case IrInstructionIdUnOp:
...@@ -12580,7 +12646,7 @@ bool ir_has_side_effects(IrInstruction *instruction) {...@@ -12580,7 +12646,7 @@ bool ir_has_side_effects(IrInstruction *instruction) {
12580}12646}
1258112647
12582FnTableEntry *ir_create_inline_fn(CodeGen *codegen, Buf *fn_name, VariableTableEntry *var, Scope *parent_scope) {12648FnTableEntry *ir_create_inline_fn(CodeGen *codegen, Buf *fn_name, VariableTableEntry *var, Scope *parent_scope) {
12583 FnTableEntry *fn_entry = create_fn_raw(FnInlineAuto, true);12649 FnTableEntry *fn_entry = create_fn_raw(FnInlineAuto, GlobalLinkageIdInternal);
12584 buf_init_from_buf(&fn_entry->symbol_name, fn_name);12650 buf_init_from_buf(&fn_entry->symbol_name, fn_name);
1258512651
12586 fn_entry->fndef_scope = create_fndef_scope(nullptr, parent_scope, fn_entry);12652 fn_entry->fndef_scope = create_fndef_scope(nullptr, parent_scope, fn_entry);
src/ir_print.cpp+20-11
...@@ -339,14 +339,6 @@ static void ir_print_enum_field_ptr(IrPrint *irp, IrInstructionEnumFieldPtr *ins...@@ -339,14 +339,6 @@ static void ir_print_enum_field_ptr(IrPrint *irp, IrInstructionEnumFieldPtr *ins
339 fprintf(irp->f, ")");339 fprintf(irp->f, ")");
340}340}
341341
342static void ir_print_set_fn_visible(IrPrint *irp, IrInstructionSetFnVisible *instruction) {
343 fprintf(irp->f, "@setFnVisible(");
344 ir_print_other_instruction(irp, instruction->fn_value);
345 fprintf(irp->f, ", ");
346 ir_print_other_instruction(irp, instruction->is_visible);
347 fprintf(irp->f, ")");
348}
349
350static void ir_print_set_debug_safety(IrPrint *irp, IrInstructionSetDebugSafety *instruction) {342static void ir_print_set_debug_safety(IrPrint *irp, IrInstructionSetDebugSafety *instruction) {
351 fprintf(irp->f, "@setDebugSafety(");343 fprintf(irp->f, "@setDebugSafety(");
352 ir_print_other_instruction(irp, instruction->scope_value);344 ir_print_other_instruction(irp, instruction->scope_value);
...@@ -849,6 +841,13 @@ static void ir_print_set_global_section(IrPrint *irp, IrInstructionSetGlobalSect...@@ -849,6 +841,13 @@ static void ir_print_set_global_section(IrPrint *irp, IrInstructionSetGlobalSect
849 fprintf(irp->f, ")");841 fprintf(irp->f, ")");
850}842}
851843
844static void ir_print_set_global_linkage(IrPrint *irp, IrInstructionSetGlobalLinkage *instruction) {
845 fprintf(irp->f, "@setGlobalLinkage(%s,", buf_ptr(instruction->tld->name));
846 ir_print_other_instruction(irp, instruction->value);
847 fprintf(irp->f, ")");
848}
849
850
852static void ir_print_decl_ref(IrPrint *irp, IrInstructionDeclRef *instruction) {851static void ir_print_decl_ref(IrPrint *irp, IrInstructionDeclRef *instruction) {
853 const char *ptr_str = instruction->lval.is_ptr ? "ptr " : "";852 const char *ptr_str = instruction->lval.is_ptr ? "ptr " : "";
854 const char *const_str = instruction->lval.is_const ? "const " : "";853 const char *const_str = instruction->lval.is_const ? "const " : "";
...@@ -856,6 +855,13 @@ static void ir_print_decl_ref(IrPrint *irp, IrInstructionDeclRef *instruction) {...@@ -856,6 +855,13 @@ static void ir_print_decl_ref(IrPrint *irp, IrInstructionDeclRef *instruction) {
856 fprintf(irp->f, "declref %s%s%s%s", const_str, volatile_str, ptr_str, buf_ptr(instruction->tld->name));855 fprintf(irp->f, "declref %s%s%s%s", const_str, volatile_str, ptr_str, buf_ptr(instruction->tld->name));
857}856}
858857
858static void ir_print_panic(IrPrint *irp, IrInstructionPanic *instruction) {
859 fprintf(irp->f, "@panic(");
860 ir_print_other_instruction(irp, instruction->msg);
861 fprintf(irp->f, ")");
862}
863
864
859static void ir_print_instruction(IrPrint *irp, IrInstruction *instruction) {865static void ir_print_instruction(IrPrint *irp, IrInstruction *instruction) {
860 ir_print_prefix(irp, instruction);866 ir_print_prefix(irp, instruction);
861 switch (instruction->id) {867 switch (instruction->id) {
...@@ -933,9 +939,6 @@ static void ir_print_instruction(IrPrint *irp, IrInstruction *instruction) {...@@ -933,9 +939,6 @@ static void ir_print_instruction(IrPrint *irp, IrInstruction *instruction) {
933 case IrInstructionIdEnumFieldPtr:939 case IrInstructionIdEnumFieldPtr:
934 ir_print_enum_field_ptr(irp, (IrInstructionEnumFieldPtr *)instruction);940 ir_print_enum_field_ptr(irp, (IrInstructionEnumFieldPtr *)instruction);
935 break;941 break;
936 case IrInstructionIdSetFnVisible:
937 ir_print_set_fn_visible(irp, (IrInstructionSetFnVisible *)instruction);
938 break;
939 case IrInstructionIdSetDebugSafety:942 case IrInstructionIdSetDebugSafety:
940 ir_print_set_debug_safety(irp, (IrInstructionSetDebugSafety *)instruction);943 ir_print_set_debug_safety(irp, (IrInstructionSetDebugSafety *)instruction);
941 break;944 break;
...@@ -1128,9 +1131,15 @@ static void ir_print_instruction(IrPrint *irp, IrInstruction *instruction) {...@@ -1128,9 +1131,15 @@ static void ir_print_instruction(IrPrint *irp, IrInstruction *instruction) {
1128 case IrInstructionIdSetGlobalSection:1131 case IrInstructionIdSetGlobalSection:
1129 ir_print_set_global_section(irp, (IrInstructionSetGlobalSection *)instruction);1132 ir_print_set_global_section(irp, (IrInstructionSetGlobalSection *)instruction);
1130 break;1133 break;
1134 case IrInstructionIdSetGlobalLinkage:
1135 ir_print_set_global_linkage(irp, (IrInstructionSetGlobalLinkage *)instruction);
1136 break;
1131 case IrInstructionIdDeclRef:1137 case IrInstructionIdDeclRef:
1132 ir_print_decl_ref(irp, (IrInstructionDeclRef *)instruction);1138 ir_print_decl_ref(irp, (IrInstructionDeclRef *)instruction);
1133 break;1139 break;
1140 case IrInstructionIdPanic:
1141 ir_print_panic(irp, (IrInstructionPanic *)instruction);
1142 break;
1134 }1143 }
1135 fprintf(irp->f, "\n");1144 fprintf(irp->f, "\n");
1136}1145}
src/link.cpp+1
...@@ -52,6 +52,7 @@ static Buf *build_o(CodeGen *parent_gen, const char *oname) {...@@ -52,6 +52,7 @@ static Buf *build_o(CodeGen *parent_gen, const char *oname) {
52 child_gen->link_libs.items[i] = parent_gen->link_libs.items[i];52 child_gen->link_libs.items[i] = parent_gen->link_libs.items[i];
53 }53 }
5454
55 codegen_set_omit_zigrt(child_gen, true);
55 child_gen->want_h_file = false;56 child_gen->want_h_file = false;
5657
57 codegen_set_is_release(child_gen, parent_gen->is_release_build);58 codegen_set_is_release(child_gen, parent_gen->is_release_build);
src/parseh.cpp+1-2
...@@ -635,8 +635,7 @@ static void visit_fn_decl(Context *c, const FunctionDecl *fn_decl) {...@@ -635,8 +635,7 @@ static void visit_fn_decl(Context *c, const FunctionDecl *fn_decl) {
635 }635 }
636 assert(fn_type->id == TypeTableEntryIdFn);636 assert(fn_type->id == TypeTableEntryIdFn);
637637
638 bool internal_linkage = false;638 FnTableEntry *fn_entry = create_fn_raw(FnInlineAuto, GlobalLinkageIdStrong);
639 FnTableEntry *fn_entry = create_fn_raw(FnInlineAuto, internal_linkage);
640 buf_init_from_buf(&fn_entry->symbol_name, fn_name);639 buf_init_from_buf(&fn_entry->symbol_name, fn_name);
641 fn_entry->type_entry = fn_type;640 fn_entry->type_entry = fn_type;
642641
std/special/bootstrap.zig+2-2
...@@ -13,7 +13,7 @@ var argc: usize = undefined;...@@ -13,7 +13,7 @@ var argc: usize = undefined;
13var argv: &&u8 = undefined;13var argv: &&u8 = undefined;
1414
15export nakedcc fn _start() -> noreturn {15export nakedcc fn _start() -> noreturn {
16 @setFnVisible(this, want_start_symbol);16 @setGlobalLinkage(_start, if (want_start_symbol) GlobalLinkage.Strong else GlobalLinkage.Internal);
17 if (!want_start_symbol) {17 if (!want_start_symbol) {
18 unreachable;18 unreachable;
19 }19 }
...@@ -47,7 +47,7 @@ fn callMainAndExit() -> noreturn {...@@ -47,7 +47,7 @@ fn callMainAndExit() -> noreturn {
47}47}
4848
49export fn main(c_argc: i32, c_argv: &&u8) -> i32 {49export fn main(c_argc: i32, c_argv: &&u8) -> i32 {
50 @setFnVisible(this, want_main_symbol);50 @setGlobalLinkage(main, if (want_main_symbol) GlobalLinkage.Strong else GlobalLinkage.Internal);
51 if (!want_main_symbol) {51 if (!want_main_symbol) {
52 unreachable;52 unreachable;
53 }53 }
std/special/builtin.zig+2-3
...@@ -30,7 +30,6 @@ export fn memcpy(noalias dest: ?&u8, noalias src: ?&const u8, n: usize) {...@@ -30,7 +30,6 @@ export fn memcpy(noalias dest: ?&u8, noalias src: ?&const u8, n: usize) {
30 d[index] = s[index];30 d[index] = s[index];
31}31}
3232
33// Avoid dragging in the debug safety mechanisms into this .o file.33export fn __stack_chk_fail() {
34pub fn panic(message: []const u8) -> noreturn {34 @panic("stack smashing detected");
35 unreachable;
36}35}
std/special/compiler_rt.zig+1-11
...@@ -1,13 +1,3 @@...@@ -1,13 +1,3 @@
1// Avoid dragging in the debug safety mechanisms into this .o file,
2// unless we're trying to test this file.
3pub fn panic(message: []const u8) -> noreturn {
4 if (@compileVar("is_test")) {
5 @import("std").debug.panic(message);
6 } else {
7 unreachable;
8 }
9}
10
11const CHAR_BIT = 8;1const CHAR_BIT = 8;
12const du_int = u64;2const du_int = u64;
13const di_int = i64;3const di_int = i64;
...@@ -262,7 +252,7 @@ export nakedcc fn __aeabi_uidivmod() {...@@ -262,7 +252,7 @@ export nakedcc fn __aeabi_uidivmod() {
262 unreachable;252 unreachable;
263 }253 }
264254
265 @setFnVisible(this, false);255 @setGlobalLinkage(__aeabi_uidivmod, GlobalLinkage.Internal);
266}256}
267257
268export fn __udivmodsi4(a: su_int, b: su_int, rem: &su_int) -> su_int {258export fn __udivmodsi4(a: su_int, b: su_int, rem: &su_int) -> su_int {
std/special/panic.zig deleted-12
...@@ -1,12 +0,0 @@
1// This file is included if and only if the user's main source file does not
2// include a public panic function.
3// If this file wants to import other files *by name*, support for that would
4// have to be added in the compiler.
5
6pub coldcc fn panic(message: []const u8) -> noreturn {
7 if (@compileVar("os") == Os.freestanding) {
8 while (true) {}
9 } else {
10 @import("std").debug.panic(message);
11 }
12}
std/special/zigrt.zig created+16
...@@ -0,0 +1,16 @@
1// This file contains functions that zig depends on to coordinate between
2// multiple .o files. The symbols are defined LinkOnce so that multiple
3// instances of zig_rt.zig do not conflict with each other.
4
5export coldcc fn __zig_panic(message_ptr: &const u8, message_len: usize) -> noreturn {
6 @setGlobalLinkage(__zig_panic, GlobalLinkage.Weak);
7 @setDebugSafety(this, false);
8
9 if (@compileVar("panic_implementation_provided")) {
10 @import("@root").panic(message_ptr[0...message_len]);
11 } else if (@compileVar("os") == Os.freestanding) {
12 while (true) {}
13 } else {
14 @import("std").debug.panic(message_ptr[0...message_len]);
15 }
16}
test/cases/misc.zig+1-1
...@@ -12,7 +12,7 @@ test "emptyFunctionWithComments" {...@@ -12,7 +12,7 @@ test "emptyFunctionWithComments" {
12}12}
1313
14export fn disabledExternFn() {14export fn disabledExternFn() {
15 @setFnVisible(this, false);15 @setGlobalLinkage(disabledExternFn, GlobalLinkage.Internal);
16}16}
1717
18test "callDisabledExternFn" {18test "callDisabledExternFn" {
test/run_tests.cpp+12
...@@ -1828,6 +1828,18 @@ export fn entry() {...@@ -1828,6 +1828,18 @@ export fn entry() {
1828//////////////////////////////////////////////////////////////////////////////1828//////////////////////////////////////////////////////////////////////////////
18291829
1830static void add_debug_safety_test_cases(void) {1830static void add_debug_safety_test_cases(void) {
1831 add_debug_safety_case("calling panic", R"SOURCE(
1832pub fn panic(message: []const u8) -> noreturn {
1833 @breakpoint();
1834 while (true) {}
1835}
1836pub fn main(args: [][]u8) -> %void {
1837 if (!@compileVar("is_release")) {
1838 @panic("oh no");
1839 }
1840}
1841 )SOURCE");
1842
1831 add_debug_safety_case("out of bounds slice access", R"SOURCE(1843 add_debug_safety_case("out of bounds slice access", R"SOURCE(
1832pub fn panic(message: []const u8) -> noreturn {1844pub fn panic(message: []const u8) -> noreturn {
1833 @breakpoint();1845 @breakpoint();