| author | |
| committer | |
| log | a32b5929ccf8cbf79396d8924097a1a911985dac |
| tree | c45c7413d1fb6eab9ba102f3a0b7d48df1738164 |
| parent | 8aeea72654b2efbd068abe207b42170c4d27ee03 |
* 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 #27619 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}") |
| 233 | install(FILES "${CMAKE_SOURCE_DIR}/std/special/bootstrap.zig" DESTINATION "${ZIG_STD_DEST}/special") | 233 | install(FILES "${CMAKE_SOURCE_DIR}/std/special/bootstrap.zig" DESTINATION "${ZIG_STD_DEST}/special") |
| 234 | install(FILES "${CMAKE_SOURCE_DIR}/std/special/builtin.zig" DESTINATION "${ZIG_STD_DEST}/special") | 234 | install(FILES "${CMAKE_SOURCE_DIR}/std/special/builtin.zig" DESTINATION "${ZIG_STD_DEST}/special") |
| 235 | install(FILES "${CMAKE_SOURCE_DIR}/std/special/compiler_rt.zig" DESTINATION "${ZIG_STD_DEST}/special") | 235 | install(FILES "${CMAKE_SOURCE_DIR}/std/special/compiler_rt.zig" DESTINATION "${ZIG_STD_DEST}/special") |
| 236 | install(FILES "${CMAKE_SOURCE_DIR}/std/special/panic.zig" DESTINATION "${ZIG_STD_DEST}/special") | ||
| 237 | install(FILES "${CMAKE_SOURCE_DIR}/std/special/test_runner.zig" DESTINATION "${ZIG_STD_DEST}/special") | 236 | install(FILES "${CMAKE_SOURCE_DIR}/std/special/test_runner.zig" DESTINATION "${ZIG_STD_DEST}/special") |
| 237 | install(FILES "${CMAKE_SOURCE_DIR}/std/special/zigrt.zig" DESTINATION "${ZIG_STD_DEST}/special") | ||
| 238 | install(FILES "${CMAKE_SOURCE_DIR}/std/target.zig" DESTINATION "${ZIG_STD_DEST}") | 238 | install(FILES "${CMAKE_SOURCE_DIR}/std/target.zig" DESTINATION "${ZIG_STD_DEST}") |
| 239 | 239 | ||
| 240 | add_executable(run_tests ${TEST_SOURCES}) | 240 | add_executable(run_tests ${TEST_SOURCES}) |
doc/emacs/zig-mode.el+1-1| ... | @@ -1,5 +1,5 @@ | ... | @@ -1,5 +1,5 @@ |
| 1 | (setq zig | 1 | (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) |
| 3 | 3 | ||
| 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) |
| 5 | 5 |
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) -> bool | 626 | ### @setGlobalSection(global_variable_name, section_name: []u8) -> bool |
| 627 | 627 | ||
| 628 | Puts the global variable in the specified section. | 628 | Puts the global variable in the specified section. |
| 629 | |||
| 630 | ### @panic(message: []const u8) -> noreturn | ||
| 631 | |||
| 632 | Invokes the panic handler function. By default the panic handler function | ||
| 633 | calls the public `panic` function exposed in the root source file, or | ||
| 634 | if 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 | }; |
| 239 | 239 | ||
| 240 | enum GlobalLinkageId { | ||
| 241 | GlobalLinkageIdInternal, | ||
| 242 | GlobalLinkageIdStrong, | ||
| 243 | GlobalLinkageIdWeak, | ||
| 244 | GlobalLinkageIdLinkOnce, | ||
| 245 | }; | ||
| 246 | |||
| 240 | enum TldId { | 247 | enum 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 | }; |
| 277 | 286 | ||
| 278 | struct TldFn { | 287 | struct 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 type | 1126 | 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; |
| 1129 | 1136 | ||
| 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; |
| 1133 | 1139 | ||
| 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 | }; |
| 1142 | 1150 | ||
| 1143 | uint32_t fn_table_entry_hash(FnTableEntry*); | 1151 | uint32_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 | }; |
| 1191 | 1200 | ||
| 1192 | struct BuiltinFnEntry { | 1201 | struct 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; | ||
| 1304 | 1314 | ||
| 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; |
| 1351 | 1362 | ||
| ... | @@ -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; | ||
| 1391 | 1403 | ||
| 1392 | // The function definitions this module includes. There must be a corresponding | 1404 | // 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 | }; |
| 1723 | 1737 | ||
| 1724 | struct IrInstruction { | 1738 | struct IrInstruction { |
| ... | @@ -1999,13 +2013,6 @@ struct IrInstructionPtrTypeChild { | ... | @@ -1999,13 +2013,6 @@ struct IrInstructionPtrTypeChild { |
| 1999 | IrInstruction *value; | 2013 | IrInstruction *value; |
| 2000 | }; | 2014 | }; |
| 2001 | 2015 | ||
| 2002 | struct IrInstructionSetFnVisible { | ||
| 2003 | IrInstruction base; | ||
| 2004 | |||
| 2005 | IrInstruction *fn_value; | ||
| 2006 | IrInstruction *is_visible; | ||
| 2007 | }; | ||
| 2008 | |||
| 2009 | struct IrInstructionSetDebugSafety { | 2016 | struct IrInstructionSetDebugSafety { |
| 2010 | IrInstruction base; | 2017 | IrInstruction base; |
| 2011 | 2018 | ||
| ... | @@ -2439,6 +2446,13 @@ struct IrInstructionSetGlobalSection { | ... | @@ -2439,6 +2446,13 @@ struct IrInstructionSetGlobalSection { |
| 2439 | IrInstruction *value; | 2446 | IrInstruction *value; |
| 2440 | }; | 2447 | }; |
| 2441 | 2448 | ||
| 2449 | struct IrInstructionSetGlobalLinkage { | ||
| 2450 | IrInstruction base; | ||
| 2451 | |||
| 2452 | Tld *tld; | ||
| 2453 | IrInstruction *value; | ||
| 2454 | }; | ||
| 2455 | |||
| 2442 | struct IrInstructionDeclRef { | 2456 | struct IrInstructionDeclRef { |
| 2443 | IrInstruction base; | 2457 | IrInstruction base; |
| 2444 | 2458 | ||
| ... | @@ -2446,6 +2460,12 @@ struct IrInstructionDeclRef { | ... | @@ -2446,6 +2460,12 @@ struct IrInstructionDeclRef { |
| 2446 | LVal lval; | 2460 | LVal lval; |
| 2447 | }; | 2461 | }; |
| 2448 | 2462 | ||
| 2463 | struct IrInstructionPanic { | ||
| 2464 | IrInstruction base; | ||
| 2465 | |||
| 2466 | IrInstruction *msg; | ||
| 2467 | }; | ||
| 2468 | |||
| 2449 | static const size_t slice_ptr_index = 0; | 2469 | static const size_t slice_ptr_index = 0; |
| 2450 | static const size_t slice_len_index = 1; | 2470 | static const size_t slice_len_index = 1; |
| 2451 | 2471 |
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 | } |
| 1764 | 1764 | ||
| 1765 | FnTableEntry *create_fn_raw(FnInline inline_value, bool internal_linkage) { | 1765 | FnTableEntry *create_fn_raw(FnInline inline_value, GlobalLinkageId linkage) { |
| 1766 | FnTableEntry *fn_entry = allocate<FnTableEntry>(1); | 1766 | FnTableEntry *fn_entry = allocate<FnTableEntry>(1); |
| 1767 | 1767 | ||
| 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; |
| 1774 | 1774 | ||
| 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; |
| 1781 | 1781 | ||
| 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); | ||
| 1785 | 1786 | ||
| 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 | } |
| 1809 | 1810 | ||
| 1810 | static void typecheck_panic_fn(CodeGen *g) { | 1811 | static 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 | } |
| 1866 | 1867 | ||
| 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); |
| 1907 | 1906 | ||
| 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, '_'); |
| 1909 | 1908 | ||
| ... | @@ -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 | } |
| 1932 | 1931 | ||
| 1933 | static void add_top_level_decl(CodeGen *g, ScopeDecls *decls_scope, Tld *tld) { | 1932 | static 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 | } |
| 1941 | 1936 | ||
| 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 | |||
| 4214 | FnTableEntry *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); |
| 73 | TypeTableEntry *analyze_type_expr(CodeGen *g, Scope *scope, AstNode *node); | 73 | TypeTableEntry *analyze_type_expr(CodeGen *g, Scope *scope, AstNode *node); |
| 74 | FnTableEntry *create_fn(AstNode *proto_node); | 74 | FnTableEntry *create_fn(AstNode *proto_node); |
| 75 | FnTableEntry *create_fn_raw(FnInline inline_value, bool internal_linkage); | 75 | FnTableEntry *create_fn_raw(FnInline inline_value, GlobalLinkageId linkage); |
| 76 | void init_fn_type_id(FnTypeId *fn_type_id, AstNode *proto_node, size_t param_count_alloc); | 76 | void init_fn_type_id(FnTypeId *fn_type_id, AstNode *proto_node, size_t param_count_alloc); |
| 77 | AstNode *get_param_decl_node(FnTableEntry *fn_entry, size_t index); | 77 | AstNode *get_param_decl_node(FnTableEntry *fn_entry, size_t index); |
| 78 | FnTableEntry *scope_get_fn_if_root(Scope *scope); | 78 | FnTableEntry *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); |
| 148 | 148 | ||
| 149 | TypeTableEntry *make_int_type(CodeGen *g, bool is_signed, size_t size_in_bits); | 149 | TypeTableEntry *make_int_type(CodeGen *g, bool is_signed, size_t size_in_bits); |
| 150 | ConstParent *get_const_val_parent(ConstExprValue *value); | 150 | ConstParent *get_const_val_parent(ConstExprValue *value); |
| 151 | FnTableEntry *get_extern_panic_fn(CodeGen *g); | ||
| 151 | 152 | ||
| 152 | #endif | 153 | #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 | } |
| 142 | 143 | ||
| 144 | void codegen_set_omit_zigrt(CodeGen *g, bool omit_zigrt) { | ||
| 145 | g->omit_zigrt = omit_zigrt; | ||
| 146 | } | ||
| 147 | |||
| 143 | void codegen_set_is_test(CodeGen *g, bool is_test_build) { | 148 | void 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 | } |
| 258 | 263 | ||
| 264 | static 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 | |||
| 259 | static void addLLVMFnAttr(LLVMValueRef fn_val, const char *attr_name) { | 272 | static 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 | } |
| 262 | 275 | ||
| 276 | static 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 | |||
| 263 | static void addLLVMArgAttr(LLVMValueRef arg_val, unsigned param_index, const char *attr_name) { | 280 | static 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 | } |
| 273 | 290 | ||
| 291 | static 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 | |||
| 274 | static Buf *get_mangled_name(CodeGen *g, Buf *original_name, bool external_linkage) { | 295 | static 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 | } |
| 278 | 299 | ||
| 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; |
| 291 | 312 | ||
| 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); | ||
| 293 | 315 | ||
| 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 | } |
| 320 | 342 | ||
| 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 | } | ||
| 323 | 357 | ||
| 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); |
| 371 | 417 | ||
| 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 | } |
| 546 | 592 | ||
| 547 | static void gen_debug_safety_crash(CodeGen *g, PanicMsgId msg_id) { | 593 | static 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 | } |
| 553 | 610 | ||
| 611 | static void gen_debug_safety_crash(CodeGen *g, PanicMsgId msg_id) { | ||
| 612 | gen_panic(g, get_panic_msg_ptr_val(g, msg_id)); | ||
| 613 | } | ||
| 614 | |||
| 554 | static void add_bounds_check(CodeGen *g, LLVMValueRef target_val, | 615 | static 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 | } |
| 2566 | 2627 | ||
| 2628 | static 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 | |||
| 2567 | static void set_debug_location(CodeGen *g, IrInstruction *instruction) { | 2633 | static 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[] = { |
| 3659 | 3726 | ||
| 3660 | static const bool is_signed_list[] = { false, true, }; | 3727 | static const bool is_signed_list[] = { false, true, }; |
| 3661 | 3728 | ||
| 3729 | struct GlobalLinkageValue { | ||
| 3730 | GlobalLinkageId id; | ||
| 3731 | const char *name; | ||
| 3732 | }; | ||
| 3733 | |||
| 3734 | static const GlobalLinkageValue global_linkage_values[] = { | ||
| 3735 | {GlobalLinkageIdInternal, "Internal"}, | ||
| 3736 | {GlobalLinkageIdStrong, "Strong"}, | ||
| 3737 | {GlobalLinkageIdWeak, "Weak"}, | ||
| 3738 | {GlobalLinkageIdLinkOnce, "LinkOnce"}, | ||
| 3739 | }; | ||
| 3740 | |||
| 3662 | static void define_builtin_types(CodeGen *g) { | 3741 | static 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 | } |
| 3997 | 4076 | ||
| 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 time | 4103 | 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 | } |
| 4154 | 4258 | ||
| 4155 | static void add_compile_var(CodeGen *g, const char *name, ConstExprValue *value) { | 4259 | static 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) { |
| 4180 | 4284 | ||
| 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 | } |
| 4184 | 4289 | ||
| 4185 | static void init(CodeGen *g, Buf *source_path) { | 4290 | static 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 | } |
| 4311 | 4416 | ||
| 4312 | static PackageTableEntry *create_panic_pkg(CodeGen *g) { | 4417 | static 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 | } |
| 4317 | 4423 | ||
| ... | @@ -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 | } |
| 4344 | 4450 | ||
| 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); |
| 4511 | 4617 | ||
| 4512 | if (fn_table_entry->internal_linkage) | 4618 | if (fn_table_entry->linkage == GlobalLinkageIdInternal) |
| 4513 | continue; | 4619 | continue; |
| 4514 | 4620 | ||
| 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); |
| 43 | void codegen_set_mmacosx_version_min(CodeGen *g, Buf *mmacosx_version_min); | 43 | void codegen_set_mmacosx_version_min(CodeGen *g, Buf *mmacosx_version_min); |
| 44 | void codegen_set_mios_version_min(CodeGen *g, Buf *mios_version_min); | 44 | void codegen_set_mios_version_min(CodeGen *g, Buf *mios_version_min); |
| 45 | void codegen_set_linker_script(CodeGen *g, const char *linker_script); | 45 | void codegen_set_linker_script(CodeGen *g, const char *linker_script); |
| 46 | void codegen_set_omit_zigrt(CodeGen *g, bool omit_zigrt); | ||
| 46 | 47 | ||
| 47 | void codegen_add_root_code(CodeGen *g, Buf *source_dir, Buf *source_basename, Buf *source_code); | 48 | void codegen_add_root_code(CodeGen *g, Buf *source_dir, Buf *source_basename, Buf *source_code); |
| 48 | 49 |
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 | } |
| 278 | 278 | ||
| 279 | static constexpr IrInstructionId ir_instruction_id(IrInstructionSetFnVisible *) { | ||
| 280 | return IrInstructionIdSetFnVisible; | ||
| 281 | } | ||
| 282 | |||
| 283 | static constexpr IrInstructionId ir_instruction_id(IrInstructionSetDebugSafety *) { | 279 | static 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 | } |
| 530 | 526 | ||
| 527 | static constexpr IrInstructionId ir_instruction_id(IrInstructionSetGlobalLinkage *) { | ||
| 528 | return IrInstructionIdSetGlobalLinkage; | ||
| 529 | } | ||
| 530 | |||
| 531 | static constexpr IrInstructionId ir_instruction_id(IrInstructionDeclRef *) { | 531 | static constexpr IrInstructionId ir_instruction_id(IrInstructionDeclRef *) { |
| 532 | return IrInstructionIdDeclRef; | 532 | return IrInstructionIdDeclRef; |
| 533 | } | 533 | } |
| 534 | 534 | ||
| 535 | static constexpr IrInstructionId ir_instruction_id(IrInstructionPanic *) { | ||
| 536 | return IrInstructionIdPanic; | ||
| 537 | } | ||
| 538 | |||
| 535 | template<typename T> | 539 | template<typename T> |
| 536 | static T *ir_create_instruction(IrBuilder *irb, Scope *scope, AstNode *source_node) { | 540 | static 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 | } |
| 1149 | 1153 | ||
| 1150 | static 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 | |||
| 1163 | static IrInstruction *ir_build_set_debug_safety(IrBuilder *irb, Scope *scope, AstNode *source_node, | 1154 | static 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 | } |
| 2094 | 2085 | ||
| 2086 | static 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 | |||
| 2095 | static IrInstruction *ir_build_decl_ref(IrBuilder *irb, Scope *scope, AstNode *source_node, | 2099 | static 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 | } |
| 2105 | 2109 | ||
| 2110 | static 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 | |||
| 2106 | static IrInstruction *ir_instruction_br_get_dep(IrInstructionBr *instruction, size_t index) { | 2121 | static 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 | } |
| 2289 | 2304 | ||
| 2290 | static 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 | |||
| 2298 | static IrInstruction *ir_instruction_setdebugsafety_get_dep(IrInstructionSetDebugSafety *instruction, size_t index) { | 2305 | static 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 | } |
| 2744 | 2751 | ||
| 2752 | static 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 | |||
| 2745 | static IrInstruction *ir_instruction_declref_get_dep(IrInstructionDeclRef *instruction, size_t index) { | 2759 | static IrInstruction *ir_instruction_declref_get_dep(IrInstructionDeclRef *instruction, size_t index) { |
| 2746 | return nullptr; | 2760 | return nullptr; |
| 2747 | } | 2761 | } |
| 2748 | 2762 | ||
| 2763 | static 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 | |||
| 2749 | static IrInstruction *ir_instruction_get_dep(IrInstruction *instruction, size_t index) { | 2770 | static 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 |
| 4170 | 4180 | ||
| 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); |
| 4626 | 4649 | ||
| 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 | } |
| 7098 | 7125 | ||
| 7126 | static 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 | |||
| 7099 | static Buf *ir_resolve_str(IrAnalyze *ira, IrInstruction *value) { | 7143 | static 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 | } |
| 9559 | 9603 | ||
| 9560 | static 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 | |||
| 9596 | static TypeTableEntry *ir_analyze_instruction_set_global_align(IrAnalyze *ira, | 9604 | static 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 | } |
| 9679 | 9687 | ||
| 9688 | static 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 | |||
| 9680 | static TypeTableEntry *ir_analyze_instruction_set_debug_safety(IrAnalyze *ira, | 9727 | static 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 | } |
| 12149 | 12196 | ||
| 12197 | static 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 | |||
| 12150 | static TypeTableEntry *ir_analyze_instruction_decl_ref(IrAnalyze *ira, | 12213 | static 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 | } |
| 12581 | 12647 | ||
| 12582 | FnTableEntry *ir_create_inline_fn(CodeGen *codegen, Buf *fn_name, VariableTableEntry *var, Scope *parent_scope) { | 12648 | FnTableEntry *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); |
| 12585 | 12651 | ||
| 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 | } |
| 341 | 341 | ||
| 342 | static 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 | |||
| 350 | static void ir_print_set_debug_safety(IrPrint *irp, IrInstructionSetDebugSafety *instruction) { | 342 | static 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 | } |
| 851 | 843 | ||
| 844 | static 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 | |||
| 852 | static void ir_print_decl_ref(IrPrint *irp, IrInstructionDeclRef *instruction) { | 851 | static 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 | } |
| 858 | 857 | ||
| 858 | static 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 | |||
| 859 | static void ir_print_instruction(IrPrint *irp, IrInstruction *instruction) { | 865 | static 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 | } |
| 54 | 54 | ||
| 55 | codegen_set_omit_zigrt(child_gen, true); | ||
| 55 | child_gen->want_h_file = false; | 56 | child_gen->want_h_file = false; |
| 56 | 57 | ||
| 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); |
| 637 | 637 | ||
| 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; |
| 642 | 641 |
std/special/bootstrap.zig+2-2| ... | @@ -13,7 +13,7 @@ var argc: usize = undefined; | ... | @@ -13,7 +13,7 @@ var argc: usize = undefined; |
| 13 | var argv: &&u8 = undefined; | 13 | var argv: &&u8 = undefined; |
| 14 | 14 | ||
| 15 | export nakedcc fn _start() -> noreturn { | 15 | export 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 | } |
| 48 | 48 | ||
| 49 | export fn main(c_argc: i32, c_argv: &&u8) -> i32 { | 49 | export 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 | } |
| 32 | 32 | ||
| 33 | // Avoid dragging in the debug safety mechanisms into this .o file. | 33 | export fn __stack_chk_fail() { |
| 34 | pub 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. | ||
| 3 | pub fn panic(message: []const u8) -> noreturn { | ||
| 4 | if (@compileVar("is_test")) { | ||
| 5 | @import("std").debug.panic(message); | ||
| 6 | } else { | ||
| 7 | unreachable; | ||
| 8 | } | ||
| 9 | } | ||
| 10 | |||
| 11 | const CHAR_BIT = 8; | 1 | const CHAR_BIT = 8; |
| 12 | const du_int = u64; | 2 | const du_int = u64; |
| 13 | const di_int = i64; | 3 | const 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 | } |
| 264 | 254 | ||
| 265 | @setFnVisible(this, false); | 255 | @setGlobalLinkage(__aeabi_uidivmod, GlobalLinkage.Internal); |
| 266 | } | 256 | } |
| 267 | 257 | ||
| 268 | export fn __udivmodsi4(a: su_int, b: su_int, rem: &su_int) -> su_int { | 258 | export 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 | |||
| 6 | pub 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 | |||
| 5 | export 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 | } |
| 13 | 13 | ||
| 14 | export fn disabledExternFn() { | 14 | export fn disabledExternFn() { |
| 15 | @setFnVisible(this, false); | 15 | @setGlobalLinkage(disabledExternFn, GlobalLinkage.Internal); |
| 16 | } | 16 | } |
| 17 | 17 | ||
| 18 | test "callDisabledExternFn" { | 18 | test "callDisabledExternFn" { |
test/run_tests.cpp+12| ... | @@ -1828,6 +1828,18 @@ export fn entry() { | ... | @@ -1828,6 +1828,18 @@ export fn entry() { |
| 1828 | ////////////////////////////////////////////////////////////////////////////// | 1828 | ////////////////////////////////////////////////////////////////////////////// |
| 1829 | 1829 | ||
| 1830 | static void add_debug_safety_test_cases(void) { | 1830 | static void add_debug_safety_test_cases(void) { |
| 1831 | add_debug_safety_case("calling panic", R"SOURCE( | ||
| 1832 | pub fn panic(message: []const u8) -> noreturn { | ||
| 1833 | @breakpoint(); | ||
| 1834 | while (true) {} | ||
| 1835 | } | ||
| 1836 | pub 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( |
| 1832 | pub fn panic(message: []const u8) -> noreturn { | 1844 | pub fn panic(message: []const u8) -> noreturn { |
| 1833 | @breakpoint(); | 1845 | @breakpoint(); |