| author | |
| committer | |
| log | 1fdebc1dc4881a00766f7c2b4b2d8ee6ad6e79b6 |
| tree | c6dc0f8f2ce01f7d38d1c5921eaa11f2d163c589 |
| parent | 68f63323437e1b974be7a9982f5d70b95624878b |
46 files changed, 1486 insertions(+), 1193 deletions(-)
doc/langref.html.in+3-5| ... | ... | @@ -5815,13 +5815,13 @@ TopLevelItem = ErrorValueDecl | CompTimeExpression(Block) | TopLevelDecl | TestD |
| 5815 | 5815 | |
| 5816 | 5816 | TestDecl = "test" String Block |
| 5817 | 5817 | |
| 5818 | TopLevelDecl = option(VisibleMod) (FnDef | ExternDecl | GlobalVarDecl | UseDecl) | |
| 5818 | TopLevelDecl = option("pub") (FnDef | ExternDecl | GlobalVarDecl | UseDecl) | |
| 5819 | 5819 | |
| 5820 | 5820 | ErrorValueDecl = "error" Symbol ";" |
| 5821 | 5821 | |
| 5822 | 5822 | GlobalVarDecl = VariableDeclaration ";" |
| 5823 | 5823 | |
| 5824 | VariableDeclaration = option("comptime") ("var" | "const") Symbol option(":" TypeExpr) option("align" "(" Expression ")") "=" Expression | |
| 5824 | VariableDeclaration = option("comptime") ("var" | "const") Symbol option(":" TypeExpr) option("align" "(" Expression ")") option("section" "(" Expression ")") "=" Expression | |
| 5825 | 5825 | |
| 5826 | 5826 | ContainerMember = (ContainerField | FnDef | GlobalVarDecl) |
| 5827 | 5827 | |
| ... | ... | @@ -5831,9 +5831,7 @@ UseDecl = "use" Expression ";" |
| 5831 | 5831 | |
| 5832 | 5832 | ExternDecl = "extern" option(String) (FnProto | VariableDeclaration) ";" |
| 5833 | 5833 | |
| 5834 | FnProto = option("coldcc" | "nakedcc" | "stdcallcc") "fn" option(Symbol) ParamDeclList option("align" "(" Expression ")") option("->" TypeExpr) | |
| 5835 | ||
| 5836 | VisibleMod = "pub" | "export" | |
| 5834 | FnProto = option("coldcc" | "nakedcc" | "stdcallcc") "fn" option(Symbol) ParamDeclList option("align" "(" Expression ")") option("section" "(" Expression ")") option("->" TypeExpr) | |
| 5837 | 5835 | |
| 5838 | 5836 | FnDef = option("inline" | "extern") FnProto Block |
| 5839 | 5837 |
example/hello_world/hello_libc.zig+6-2| ... | ... | @@ -5,9 +5,13 @@ const c = @cImport({ |
| 5 | 5 | @cInclude("string.h"); |
| 6 | 6 | }); |
| 7 | 7 | |
| 8 | const msg = c"Hello, world!\n"; | |
| 8 | comptime { | |
| 9 | @export("main", main); | |
| 10 | } | |
| 11 | ||
| 12 | extern fn main(argc: c_int, argv: &&u8) -> c_int { | |
| 13 | const msg = c"Hello, world!\n"; | |
| 9 | 14 | |
| 10 | export fn main(argc: c_int, argv: &&u8) -> c_int { | |
| 11 | 15 | if (c.printf(msg) != c_int(c.strlen(msg))) |
| 12 | 16 | return -1; |
| 13 | 17 |
example/mix_o_files/base64.zig+4-1| ... | ... | @@ -1,6 +1,9 @@ |
| 1 | 1 | const base64 = @import("std").base64; |
| 2 | 2 | |
| 3 | export fn decode_base_64(dest_ptr: &u8, dest_len: usize, source_ptr: &const u8, source_len: usize) -> usize { | |
| 3 | comptime { | |
| 4 | @export("decode_base_64", decode_base_64); | |
| 5 | } | |
| 6 | extern fn decode_base_64(dest_ptr: &u8, dest_len: usize, source_ptr: &const u8, source_len: usize) -> usize { | |
| 4 | 7 | const src = source_ptr[0..source_len]; |
| 5 | 8 | const dest = dest_ptr[0..dest_len]; |
| 6 | 9 | const base64_decoder = base64.standard_decoder_unsafe; |
example/shared_library/mathtest.zig+4-1| ... | ... | @@ -1,3 +1,6 @@ |
| 1 | export fn add(a: i32, b: i32) -> i32 { | |
| 1 | comptime { | |
| 2 | @export("add", add); | |
| 3 | } | |
| 4 | extern fn add(a: i32, b: i32) -> i32 { | |
| 2 | 5 | a + b |
| 3 | 6 | } |
src/all_types.hpp+33-28| ... | ... | @@ -37,6 +37,7 @@ struct IrBasicBlock; |
| 37 | 37 | struct ScopeDecls; |
| 38 | 38 | struct ZigWindowsSDK; |
| 39 | 39 | struct Tld; |
| 40 | struct TldExport; | |
| 40 | 41 | |
| 41 | 42 | struct IrGotoItem { |
| 42 | 43 | AstNode *source_node; |
| ... | ... | @@ -272,7 +273,6 @@ enum ReturnKnowledge { |
| 272 | 273 | enum VisibMod { |
| 273 | 274 | VisibModPrivate, |
| 274 | 275 | VisibModPub, |
| 275 | VisibModExport, | |
| 276 | 276 | }; |
| 277 | 277 | |
| 278 | 278 | enum GlobalLinkageId { |
| ... | ... | @@ -313,11 +313,14 @@ struct TldVar { |
| 313 | 313 | Tld base; |
| 314 | 314 | |
| 315 | 315 | VariableTableEntry *var; |
| 316 | AstNode *set_global_section_node; | |
| 317 | Buf *section_name; | |
| 318 | AstNode *set_global_linkage_node; | |
| 319 | GlobalLinkageId linkage; | |
| 320 | 316 | Buf *extern_lib_name; |
| 317 | Buf *section_name; | |
| 318 | ||
| 319 | size_t export_count; | |
| 320 | union { | |
| 321 | TldExport *tld; // if export_count == 1 | |
| 322 | TldExport **tld_list; // if export_count > 1 | |
| 323 | } export_data; | |
| 321 | 324 | }; |
| 322 | 325 | |
| 323 | 326 | struct TldFn { |
| ... | ... | @@ -432,6 +435,8 @@ struct AstNodeFnProto { |
| 432 | 435 | Buf *lib_name; |
| 433 | 436 | // populated if the "align A" is present |
| 434 | 437 | AstNode *align_expr; |
| 438 | // populated if the "section(S)" is present | |
| 439 | AstNode *section_expr; | |
| 435 | 440 | }; |
| 436 | 441 | |
| 437 | 442 | struct AstNodeFnDef { |
| ... | ... | @@ -487,8 +492,10 @@ struct AstNodeVariableDeclaration { |
| 487 | 492 | AstNode *expr; |
| 488 | 493 | // populated if this is an extern declaration |
| 489 | 494 | Buf *lib_name; |
| 490 | // populated if the "align A" is present | |
| 495 | // populated if the "align(A)" is present | |
| 491 | 496 | AstNode *align_expr; |
| 497 | // populated if the "section(S)" is present | |
| 498 | AstNode *section_expr; | |
| 492 | 499 | }; |
| 493 | 500 | |
| 494 | 501 | struct AstNodeErrorValueDecl { |
| ... | ... | @@ -1177,6 +1184,12 @@ enum FnInline { |
| 1177 | 1184 | FnInlineNever, |
| 1178 | 1185 | }; |
| 1179 | 1186 | |
| 1187 | struct FnExport { | |
| 1188 | Buf name; | |
| 1189 | GlobalLinkageId linkage; | |
| 1190 | AstNode *source_node; | |
| 1191 | }; | |
| 1192 | ||
| 1180 | 1193 | struct FnTableEntry { |
| 1181 | 1194 | LLVMValueRef llvm_value; |
| 1182 | 1195 | const char *llvm_name; |
| ... | ... | @@ -1204,12 +1217,11 @@ struct FnTableEntry { |
| 1204 | 1217 | ZigList<IrInstruction *> alloca_list; |
| 1205 | 1218 | ZigList<VariableTableEntry *> variable_list; |
| 1206 | 1219 | |
| 1207 | AstNode *set_global_section_node; | |
| 1208 | 1220 | Buf *section_name; |
| 1209 | AstNode *set_global_linkage_node; | |
| 1210 | GlobalLinkageId linkage; | |
| 1211 | 1221 | AstNode *set_alignstack_node; |
| 1212 | 1222 | uint32_t alignstack_value; |
| 1223 | ||
| 1224 | ZigList<FnExport> export_list; | |
| 1213 | 1225 | }; |
| 1214 | 1226 | |
| 1215 | 1227 | uint32_t fn_table_entry_hash(FnTableEntry*); |
| ... | ... | @@ -1258,8 +1270,6 @@ enum BuiltinFnId { |
| 1258 | 1270 | BuiltinFnIdSetFloatMode, |
| 1259 | 1271 | BuiltinFnIdTypeName, |
| 1260 | 1272 | BuiltinFnIdCanImplicitCast, |
| 1261 | BuiltinFnIdSetGlobalSection, | |
| 1262 | BuiltinFnIdSetGlobalLinkage, | |
| 1263 | 1273 | BuiltinFnIdPanic, |
| 1264 | 1274 | BuiltinFnIdPtrCast, |
| 1265 | 1275 | BuiltinFnIdBitCast, |
| ... | ... | @@ -1279,6 +1289,8 @@ enum BuiltinFnId { |
| 1279 | 1289 | BuiltinFnIdOpaqueType, |
| 1280 | 1290 | BuiltinFnIdSetAlignStack, |
| 1281 | 1291 | BuiltinFnIdArgType, |
| 1292 | BuiltinFnIdExport, | |
| 1293 | BuiltinFnIdExportWithLinkage, | |
| 1282 | 1294 | }; |
| 1283 | 1295 | |
| 1284 | 1296 | struct BuiltinFnEntry { |
| ... | ... | @@ -1425,7 +1437,7 @@ struct CodeGen { |
| 1425 | 1437 | HashMap<GenericFnTypeId *, FnTableEntry *, generic_fn_type_id_hash, generic_fn_type_id_eql> generic_table; |
| 1426 | 1438 | HashMap<Scope *, IrInstruction *, fn_eval_hash, fn_eval_eql> memoized_fn_eval_table; |
| 1427 | 1439 | HashMap<ZigLLVMFnKey, LLVMValueRef, zig_llvm_fn_key_hash, zig_llvm_fn_key_eql> llvm_fn_table; |
| 1428 | HashMap<Buf *, Tld *, buf_hash, buf_eql_buf> exported_symbol_names; | |
| 1440 | HashMap<Buf *, AstNode *, buf_hash, buf_eql_buf> exported_symbol_names; | |
| 1429 | 1441 | HashMap<Buf *, Tld *, buf_hash, buf_eql_buf> external_prototypes; |
| 1430 | 1442 | |
| 1431 | 1443 | |
| ... | ... | @@ -1886,8 +1898,6 @@ enum IrInstructionId { |
| 1886 | 1898 | IrInstructionIdCheckStatementIsVoid, |
| 1887 | 1899 | IrInstructionIdTypeName, |
| 1888 | 1900 | IrInstructionIdCanImplicitCast, |
| 1889 | IrInstructionIdSetGlobalSection, | |
| 1890 | IrInstructionIdSetGlobalLinkage, | |
| 1891 | 1901 | IrInstructionIdDeclRef, |
| 1892 | 1902 | IrInstructionIdPanic, |
| 1893 | 1903 | IrInstructionIdTagName, |
| ... | ... | @@ -1901,6 +1911,7 @@ enum IrInstructionId { |
| 1901 | 1911 | IrInstructionIdOpaqueType, |
| 1902 | 1912 | IrInstructionIdSetAlignStack, |
| 1903 | 1913 | IrInstructionIdArgType, |
| 1914 | IrInstructionIdExport, | |
| 1904 | 1915 | }; |
| 1905 | 1916 | |
| 1906 | 1917 | struct IrInstruction { |
| ... | ... | @@ -2626,20 +2637,6 @@ struct IrInstructionCanImplicitCast { |
| 2626 | 2637 | IrInstruction *target_value; |
| 2627 | 2638 | }; |
| 2628 | 2639 | |
| 2629 | struct IrInstructionSetGlobalSection { | |
| 2630 | IrInstruction base; | |
| 2631 | ||
| 2632 | Tld *tld; | |
| 2633 | IrInstruction *value; | |
| 2634 | }; | |
| 2635 | ||
| 2636 | struct IrInstructionSetGlobalLinkage { | |
| 2637 | IrInstruction base; | |
| 2638 | ||
| 2639 | Tld *tld; | |
| 2640 | IrInstruction *value; | |
| 2641 | }; | |
| 2642 | ||
| 2643 | 2640 | struct IrInstructionDeclRef { |
| 2644 | 2641 | IrInstruction base; |
| 2645 | 2642 | |
| ... | ... | @@ -2728,6 +2725,14 @@ struct IrInstructionArgType { |
| 2728 | 2725 | IrInstruction *arg_index; |
| 2729 | 2726 | }; |
| 2730 | 2727 | |
| 2728 | struct IrInstructionExport { | |
| 2729 | IrInstruction base; | |
| 2730 | ||
| 2731 | IrInstruction *name; | |
| 2732 | IrInstruction *linkage; | |
| 2733 | IrInstruction *target; | |
| 2734 | }; | |
| 2735 | ||
| 2731 | 2736 | static const size_t slice_ptr_index = 0; |
| 2732 | 2737 | static const size_t slice_len_index = 1; |
| 2733 | 2738 |
src/analyze.cpp+66-63| ... | ... | @@ -1062,7 +1062,7 @@ void init_fn_type_id(FnTypeId *fn_type_id, AstNode *proto_node, size_t param_cou |
| 1062 | 1062 | AstNodeFnProto *fn_proto = &proto_node->data.fn_proto; |
| 1063 | 1063 | |
| 1064 | 1064 | if (fn_proto->cc == CallingConventionUnspecified) { |
| 1065 | bool extern_abi = fn_proto->is_extern || (fn_proto->visib_mod == VisibModExport); | |
| 1065 | bool extern_abi = fn_proto->is_extern; | |
| 1066 | 1066 | fn_type_id->cc = extern_abi ? CallingConventionC : CallingConventionUnspecified; |
| 1067 | 1067 | } else { |
| 1068 | 1068 | fn_type_id->cc = fn_proto->cc; |
| ... | ... | @@ -1093,6 +1093,38 @@ static bool analyze_const_align(CodeGen *g, Scope *scope, AstNode *node, uint32_ |
| 1093 | 1093 | return true; |
| 1094 | 1094 | } |
| 1095 | 1095 | |
| 1096 | static bool analyze_const_string(CodeGen *g, Scope *scope, AstNode *node, Buf **out_buffer) { | |
| 1097 | TypeTableEntry *ptr_type = get_pointer_to_type(g, g->builtin_types.entry_u8, true); | |
| 1098 | TypeTableEntry *str_type = get_slice_type(g, ptr_type); | |
| 1099 | IrInstruction *instr = analyze_const_value(g, scope, node, str_type, nullptr); | |
| 1100 | if (type_is_invalid(instr->value.type)) | |
| 1101 | return false; | |
| 1102 | ||
| 1103 | ConstExprValue *ptr_field = &instr->value.data.x_struct.fields[slice_ptr_index]; | |
| 1104 | ConstExprValue *len_field = &instr->value.data.x_struct.fields[slice_len_index]; | |
| 1105 | ||
| 1106 | assert(ptr_field->data.x_ptr.special == ConstPtrSpecialBaseArray); | |
| 1107 | ConstExprValue *array_val = ptr_field->data.x_ptr.data.base_array.array_val; | |
| 1108 | expand_undef_array(g, array_val); | |
| 1109 | size_t len = bigint_as_unsigned(&len_field->data.x_bigint); | |
| 1110 | Buf *result = buf_alloc(); | |
| 1111 | buf_resize(result, len); | |
| 1112 | for (size_t i = 0; i < len; i += 1) { | |
| 1113 | size_t new_index = ptr_field->data.x_ptr.data.base_array.elem_index + i; | |
| 1114 | ConstExprValue *char_val = &array_val->data.x_array.s_none.elements[new_index]; | |
| 1115 | if (char_val->special == ConstValSpecialUndef) { | |
| 1116 | add_node_error(g, node, buf_sprintf("use of undefined value")); | |
| 1117 | return false; | |
| 1118 | } | |
| 1119 | uint64_t big_c = bigint_as_unsigned(&char_val->data.x_bigint); | |
| 1120 | assert(big_c <= UINT8_MAX); | |
| 1121 | uint8_t c = (uint8_t)big_c; | |
| 1122 | buf_ptr(result)[i] = c; | |
| 1123 | } | |
| 1124 | *out_buffer = result; | |
| 1125 | return true; | |
| 1126 | } | |
| 1127 | ||
| 1096 | 1128 | static TypeTableEntry *analyze_fn_type(CodeGen *g, AstNode *proto_node, Scope *child_scope) { |
| 1097 | 1129 | assert(proto_node->type == NodeTypeFnProto); |
| 1098 | 1130 | AstNodeFnProto *fn_proto = &proto_node->data.fn_proto; |
| ... | ... | @@ -2472,7 +2504,7 @@ static void get_fully_qualified_decl_name(Buf *buf, Tld *tld, uint8_t sep) { |
| 2472 | 2504 | buf_append_buf(buf, tld->name); |
| 2473 | 2505 | } |
| 2474 | 2506 | |
| 2475 | FnTableEntry *create_fn_raw(FnInline inline_value, GlobalLinkageId linkage) { | |
| 2507 | FnTableEntry *create_fn_raw(FnInline inline_value) { | |
| 2476 | 2508 | FnTableEntry *fn_entry = allocate<FnTableEntry>(1); |
| 2477 | 2509 | |
| 2478 | 2510 | fn_entry->analyzed_executable.backward_branch_count = &fn_entry->prealloc_bbc; |
| ... | ... | @@ -2480,7 +2512,6 @@ FnTableEntry *create_fn_raw(FnInline inline_value, GlobalLinkageId linkage) { |
| 2480 | 2512 | fn_entry->analyzed_executable.fn_entry = fn_entry; |
| 2481 | 2513 | fn_entry->ir_executable.fn_entry = fn_entry; |
| 2482 | 2514 | fn_entry->fn_inline = inline_value; |
| 2483 | fn_entry->linkage = linkage; | |
| 2484 | 2515 | |
| 2485 | 2516 | return fn_entry; |
| 2486 | 2517 | } |
| ... | ... | @@ -2490,9 +2521,7 @@ FnTableEntry *create_fn(AstNode *proto_node) { |
| 2490 | 2521 | AstNodeFnProto *fn_proto = &proto_node->data.fn_proto; |
| 2491 | 2522 | |
| 2492 | 2523 | FnInline inline_value = fn_proto->is_inline ? FnInlineAlways : FnInlineAuto; |
| 2493 | GlobalLinkageId linkage = (fn_proto->visib_mod == VisibModExport || proto_node->data.fn_proto.is_extern) ? | |
| 2494 | GlobalLinkageIdStrong : GlobalLinkageIdInternal; | |
| 2495 | FnTableEntry *fn_entry = create_fn_raw(inline_value, linkage); | |
| 2524 | FnTableEntry *fn_entry = create_fn_raw(inline_value); | |
| 2496 | 2525 | |
| 2497 | 2526 | fn_entry->proto_node = proto_node; |
| 2498 | 2527 | fn_entry->body_node = (proto_node->data.fn_proto.fn_def_node == nullptr) ? nullptr : |
| ... | ... | @@ -2572,7 +2601,7 @@ static void resolve_decl_fn(CodeGen *g, TldFn *tld_fn) { |
| 2572 | 2601 | add_node_error(g, param_node, buf_sprintf("missing parameter name")); |
| 2573 | 2602 | } |
| 2574 | 2603 | } |
| 2575 | } else if (fn_table_entry->linkage != GlobalLinkageIdInternal) { | |
| 2604 | } else { | |
| 2576 | 2605 | g->external_prototypes.put_unique(tld_fn->base.name, &tld_fn->base); |
| 2577 | 2606 | } |
| 2578 | 2607 | |
| ... | ... | @@ -2580,6 +2609,15 @@ static void resolve_decl_fn(CodeGen *g, TldFn *tld_fn) { |
| 2580 | 2609 | |
| 2581 | 2610 | fn_table_entry->type_entry = analyze_fn_type(g, source_node, child_scope); |
| 2582 | 2611 | |
| 2612 | if (fn_proto->section_expr != nullptr) { | |
| 2613 | if (fn_table_entry->body_node == nullptr) { | |
| 2614 | add_node_error(g, fn_proto->section_expr, | |
| 2615 | buf_sprintf("cannot set section of external function '%s'", buf_ptr(&fn_table_entry->symbol_name))); | |
| 2616 | } else { | |
| 2617 | analyze_const_string(g, child_scope, fn_proto->section_expr, &fn_table_entry->section_name); | |
| 2618 | } | |
| 2619 | } | |
| 2620 | ||
| 2583 | 2621 | if (fn_table_entry->type_entry->id == TypeTableEntryIdInvalid) { |
| 2584 | 2622 | tld_fn->base.resolution = TldResolutionInvalid; |
| 2585 | 2623 | return; |
| ... | ... | @@ -2594,15 +2632,12 @@ static void resolve_decl_fn(CodeGen *g, TldFn *tld_fn) { |
| 2594 | 2632 | { |
| 2595 | 2633 | if (g->have_pub_main && buf_eql_str(&fn_table_entry->symbol_name, "main")) { |
| 2596 | 2634 | g->main_fn = fn_table_entry; |
| 2597 | ||
| 2598 | if (tld_fn->base.visib_mod != VisibModExport) { | |
| 2599 | TypeTableEntry *err_void = get_error_type(g, g->builtin_types.entry_void); | |
| 2600 | TypeTableEntry *actual_return_type = fn_table_entry->type_entry->data.fn.fn_type_id.return_type; | |
| 2601 | if (actual_return_type != err_void) { | |
| 2602 | add_node_error(g, fn_proto->return_type, | |
| 2603 | buf_sprintf("expected return type of main to be '%%void', instead is '%s'", | |
| 2604 | buf_ptr(&actual_return_type->name))); | |
| 2605 | } | |
| 2635 | TypeTableEntry *err_void = get_error_type(g, g->builtin_types.entry_void); | |
| 2636 | TypeTableEntry *actual_return_type = fn_table_entry->type_entry->data.fn.fn_type_id.return_type; | |
| 2637 | if (actual_return_type != err_void) { | |
| 2638 | add_node_error(g, fn_proto->return_type, | |
| 2639 | buf_sprintf("expected return type of main to be '%%void', instead is '%s'", | |
| 2640 | buf_ptr(&actual_return_type->name))); | |
| 2606 | 2641 | } |
| 2607 | 2642 | } else if ((import->package == g->panic_package || g->have_pub_panic) && |
| 2608 | 2643 | buf_eql_str(&fn_table_entry->symbol_name, "panic")) |
| ... | ... | @@ -2613,7 +2648,7 @@ static void resolve_decl_fn(CodeGen *g, TldFn *tld_fn) { |
| 2613 | 2648 | } |
| 2614 | 2649 | } |
| 2615 | 2650 | } else if (source_node->type == NodeTypeTestDecl) { |
| 2616 | FnTableEntry *fn_table_entry = create_fn_raw(FnInlineAuto, GlobalLinkageIdStrong); | |
| 2651 | FnTableEntry *fn_table_entry = create_fn_raw(FnInlineAuto); | |
| 2617 | 2652 | |
| 2618 | 2653 | get_fully_qualified_decl_name(&fn_table_entry->symbol_name, &tld_fn->base, '_'); |
| 2619 | 2654 | |
| ... | ... | @@ -2640,20 +2675,6 @@ static void resolve_decl_comptime(CodeGen *g, TldCompTime *tld_comptime) { |
| 2640 | 2675 | } |
| 2641 | 2676 | |
| 2642 | 2677 | static void add_top_level_decl(CodeGen *g, ScopeDecls *decls_scope, Tld *tld) { |
| 2643 | if (tld->visib_mod == VisibModExport) { | |
| 2644 | g->resolve_queue.append(tld); | |
| 2645 | } | |
| 2646 | ||
| 2647 | if (tld->visib_mod == VisibModExport) { | |
| 2648 | auto entry = g->exported_symbol_names.put_unique(tld->name, tld); | |
| 2649 | if (entry) { | |
| 2650 | Tld *other_tld = entry->value; | |
| 2651 | ErrorMsg *msg = add_node_error(g, tld->source_node, | |
| 2652 | buf_sprintf("exported symbol collision: '%s'", buf_ptr(tld->name))); | |
| 2653 | add_error_note(g, msg, other_tld->source_node, buf_sprintf("other symbol is here")); | |
| 2654 | } | |
| 2655 | } | |
| 2656 | ||
| 2657 | 2678 | { |
| 2658 | 2679 | auto entry = decls_scope->decl_table.put_unique(tld->name, tld); |
| 2659 | 2680 | if (entry) { |
| ... | ... | @@ -2729,7 +2750,6 @@ static void preview_comptime_decl(CodeGen *g, AstNode *node, ScopeDecls *decls_s |
| 2729 | 2750 | g->resolve_queue.append(&tld_comptime->base); |
| 2730 | 2751 | } |
| 2731 | 2752 | |
| 2732 | ||
| 2733 | 2753 | void init_tld(Tld *tld, TldId id, Buf *name, VisibMod visib_mod, AstNode *source_node, |
| 2734 | 2754 | Scope *parent_scope) |
| 2735 | 2755 | { |
| ... | ... | @@ -2985,7 +3005,6 @@ static void resolve_decl_var(CodeGen *g, TldVar *tld_var) { |
| 2985 | 3005 | AstNodeVariableDeclaration *var_decl = &source_node->data.variable_declaration; |
| 2986 | 3006 | |
| 2987 | 3007 | bool is_const = var_decl->is_const; |
| 2988 | bool is_export = (tld_var->base.visib_mod == VisibModExport); | |
| 2989 | 3008 | bool is_extern = var_decl->is_extern; |
| 2990 | 3009 | |
| 2991 | 3010 | TypeTableEntry *explicit_type = nullptr; |
| ... | ... | @@ -2994,20 +3013,13 @@ static void resolve_decl_var(CodeGen *g, TldVar *tld_var) { |
| 2994 | 3013 | explicit_type = validate_var_type(g, var_decl->type, proposed_type); |
| 2995 | 3014 | } |
| 2996 | 3015 | |
| 2997 | if (is_export && is_extern) { | |
| 2998 | add_node_error(g, source_node, buf_sprintf("variable is both export and extern")); | |
| 2999 | } | |
| 3000 | ||
| 3001 | 3016 | VarLinkage linkage; |
| 3002 | if (is_export) { | |
| 3003 | linkage = VarLinkageExport; | |
| 3004 | } else if (is_extern) { | |
| 3017 | if (is_extern) { | |
| 3005 | 3018 | linkage = VarLinkageExternal; |
| 3006 | 3019 | } else { |
| 3007 | 3020 | linkage = VarLinkageInternal; |
| 3008 | 3021 | } |
| 3009 | 3022 | |
| 3010 | ||
| 3011 | 3023 | IrInstruction *init_value = nullptr; |
| 3012 | 3024 | |
| 3013 | 3025 | // TODO more validation for types that can't be used for export/extern variables |
| ... | ... | @@ -3056,6 +3068,15 @@ static void resolve_decl_var(CodeGen *g, TldVar *tld_var) { |
| 3056 | 3068 | } |
| 3057 | 3069 | } |
| 3058 | 3070 | |
| 3071 | if (var_decl->section_expr != nullptr) { | |
| 3072 | if (var_decl->is_extern) { | |
| 3073 | add_node_error(g, var_decl->section_expr, | |
| 3074 | buf_sprintf("cannot set section of external variable '%s'", buf_ptr(var_decl->symbol))); | |
| 3075 | } else if (!analyze_const_string(g, tld_var->base.parent_scope, var_decl->section_expr, &tld_var->section_name)) { | |
| 3076 | tld_var->section_name = nullptr; | |
| 3077 | } | |
| 3078 | } | |
| 3079 | ||
| 3059 | 3080 | g->global_vars.append(tld_var); |
| 3060 | 3081 | } |
| 3061 | 3082 | |
| ... | ... | @@ -3724,8 +3745,10 @@ ImportTableEntry *add_source_file(CodeGen *g, PackageTableEntry *package, Buf *a |
| 3724 | 3745 | Buf *proto_name = proto_node->data.fn_proto.name; |
| 3725 | 3746 | |
| 3726 | 3747 | bool is_pub = (proto_node->data.fn_proto.visib_mod == VisibModPub); |
| 3748 | bool ok_cc = (proto_node->data.fn_proto.cc == CallingConventionUnspecified || | |
| 3749 | proto_node->data.fn_proto.cc == CallingConventionCold); | |
| 3727 | 3750 | |
| 3728 | if (is_pub) { | |
| 3751 | if (is_pub && ok_cc) { | |
| 3729 | 3752 | if (buf_eql_str(proto_name, "main")) { |
| 3730 | 3753 | g->have_pub_main = true; |
| 3731 | 3754 | g->windows_subsystem_windows = false; |
| ... | ... | @@ -3733,28 +3756,7 @@ ImportTableEntry *add_source_file(CodeGen *g, PackageTableEntry *package, Buf *a |
| 3733 | 3756 | } else if (buf_eql_str(proto_name, "panic")) { |
| 3734 | 3757 | g->have_pub_panic = true; |
| 3735 | 3758 | } |
| 3736 | } else if (proto_node->data.fn_proto.visib_mod == VisibModExport && buf_eql_str(proto_name, "main") && | |
| 3737 | g->libc_link_lib != nullptr) | |
| 3738 | { | |
| 3739 | g->have_c_main = true; | |
| 3740 | g->windows_subsystem_windows = false; | |
| 3741 | g->windows_subsystem_console = true; | |
| 3742 | } else if (proto_node->data.fn_proto.visib_mod == VisibModExport && buf_eql_str(proto_name, "WinMain") && | |
| 3743 | g->zig_target.os == ZigLLVM_Win32) | |
| 3744 | { | |
| 3745 | g->have_winmain = true; | |
| 3746 | g->windows_subsystem_windows = true; | |
| 3747 | g->windows_subsystem_console = false; | |
| 3748 | } else if (proto_node->data.fn_proto.visib_mod == VisibModExport && | |
| 3749 | buf_eql_str(proto_name, "WinMainCRTStartup") && g->zig_target.os == ZigLLVM_Win32) | |
| 3750 | { | |
| 3751 | g->have_winmain_crt_startup = true; | |
| 3752 | } else if (proto_node->data.fn_proto.visib_mod == VisibModExport && | |
| 3753 | buf_eql_str(proto_name, "DllMainCRTStartup") && g->zig_target.os == ZigLLVM_Win32) | |
| 3754 | { | |
| 3755 | g->have_dllmain_crt_startup = true; | |
| 3756 | 3759 | } |
| 3757 | ||
| 3758 | 3760 | } |
| 3759 | 3761 | } |
| 3760 | 3762 | |
| ... | ... | @@ -5445,3 +5447,4 @@ uint32_t type_ptr_hash(const TypeTableEntry *ptr) { |
| 5445 | 5447 | bool type_ptr_eql(const TypeTableEntry *a, const TypeTableEntry *b) { |
| 5446 | 5448 | return a == b; |
| 5447 | 5449 | } |
| 5450 |
src/analyze.hpp+2| ... | ... | @@ -182,4 +182,6 @@ uint32_t get_abi_alignment(CodeGen *g, TypeTableEntry *type_entry); |
| 182 | 182 | TypeTableEntry *get_align_amt_type(CodeGen *g); |
| 183 | 183 | PackageTableEntry *new_anonymous_package(void); |
| 184 | 184 | |
| 185 | Buf *const_value_to_buffer(ConstExprValue *const_val); | |
| 186 | ||
| 185 | 187 | #endif |
src/ast_render.cpp+20-1| ... | ... | @@ -78,7 +78,6 @@ static const char *visib_mod_string(VisibMod mod) { |
| 78 | 78 | switch (mod) { |
| 79 | 79 | case VisibModPub: return "pub "; |
| 80 | 80 | case VisibModPrivate: return ""; |
| 81 | case VisibModExport: return "export "; | |
| 82 | 81 | } |
| 83 | 82 | zig_unreachable(); |
| 84 | 83 | } |
| ... | ... | @@ -440,6 +439,16 @@ static void render_node_extra(AstRender *ar, AstNode *node, bool grouped) { |
| 440 | 439 | } |
| 441 | 440 | } |
| 442 | 441 | fprintf(ar->f, ")"); |
| 442 | if (node->data.fn_proto.align_expr) { | |
| 443 | fprintf(ar->f, " align("); | |
| 444 | render_node_grouped(ar, node->data.fn_proto.align_expr); | |
| 445 | fprintf(ar->f, ")"); | |
| 446 | } | |
| 447 | if (node->data.fn_proto.section_expr) { | |
| 448 | fprintf(ar->f, " section("); | |
| 449 | render_node_grouped(ar, node->data.fn_proto.section_expr); | |
| 450 | fprintf(ar->f, ")"); | |
| 451 | } | |
| 443 | 452 | |
| 444 | 453 | AstNode *return_type_node = node->data.fn_proto.return_type; |
| 445 | 454 | if (return_type_node != nullptr) { |
| ... | ... | @@ -526,6 +535,16 @@ static void render_node_extra(AstRender *ar, AstNode *node, bool grouped) { |
| 526 | 535 | fprintf(ar->f, ": "); |
| 527 | 536 | render_node_grouped(ar, node->data.variable_declaration.type); |
| 528 | 537 | } |
| 538 | if (node->data.variable_declaration.align_expr) { | |
| 539 | fprintf(ar->f, "align("); | |
| 540 | render_node_grouped(ar, node->data.variable_declaration.align_expr); | |
| 541 | fprintf(ar->f, ") "); | |
| 542 | } | |
| 543 | if (node->data.variable_declaration.section_expr) { | |
| 544 | fprintf(ar->f, "section("); | |
| 545 | render_node_grouped(ar, node->data.variable_declaration.section_expr); | |
| 546 | fprintf(ar->f, ") "); | |
| 547 | } | |
| 529 | 548 | if (node->data.variable_declaration.expr) { |
| 530 | 549 | fprintf(ar->f, " = "); |
| 531 | 550 | render_node_grouped(ar, node->data.variable_declaration.expr); |
src/codegen.cpp+68-38| ... | ... | @@ -391,24 +391,51 @@ static void add_uwtable_attr(CodeGen *g, LLVMValueRef fn_val) { |
| 391 | 391 | } |
| 392 | 392 | } |
| 393 | 393 | |
| 394 | static LLVMLinkage to_llvm_linkage(GlobalLinkageId id) { | |
| 395 | switch (id) { | |
| 396 | case GlobalLinkageIdInternal: | |
| 397 | return LLVMInternalLinkage; | |
| 398 | case GlobalLinkageIdStrong: | |
| 399 | return LLVMExternalLinkage; | |
| 400 | case GlobalLinkageIdWeak: | |
| 401 | return LLVMWeakODRLinkage; | |
| 402 | case GlobalLinkageIdLinkOnce: | |
| 403 | return LLVMLinkOnceODRLinkage; | |
| 404 | } | |
| 405 | zig_unreachable(); | |
| 406 | } | |
| 407 | ||
| 394 | 408 | static LLVMValueRef fn_llvm_value(CodeGen *g, FnTableEntry *fn_table_entry) { |
| 395 | 409 | if (fn_table_entry->llvm_value) |
| 396 | 410 | return fn_table_entry->llvm_value; |
| 397 | 411 | |
| 398 | bool external_linkage = (fn_table_entry->linkage != GlobalLinkageIdInternal); | |
| 399 | Buf *symbol_name = get_mangled_name(g, &fn_table_entry->symbol_name, external_linkage); | |
| 412 | Buf *unmangled_name = &fn_table_entry->symbol_name; | |
| 413 | Buf *symbol_name; | |
| 414 | GlobalLinkageId linkage; | |
| 415 | if (fn_table_entry->body_node == nullptr) { | |
| 416 | symbol_name = unmangled_name; | |
| 417 | linkage = GlobalLinkageIdStrong; | |
| 418 | } else if (fn_table_entry->export_list.length == 0) { | |
| 419 | symbol_name = get_mangled_name(g, unmangled_name, false); | |
| 420 | linkage = GlobalLinkageIdInternal; | |
| 421 | } else { | |
| 422 | FnExport *fn_export = &fn_table_entry->export_list.items[0]; | |
| 423 | symbol_name = &fn_export->name; | |
| 424 | linkage = fn_export->linkage; | |
| 425 | } | |
| 400 | 426 | |
| 427 | bool external_linkage = linkage != GlobalLinkageIdInternal; | |
| 401 | 428 | if (fn_table_entry->type_entry->data.fn.fn_type_id.cc == CallingConventionStdcall && external_linkage && |
| 402 | 429 | g->zig_target.arch.arch == ZigLLVM_x86) |
| 403 | 430 | { |
| 404 | // prevent name mangling | |
| 431 | // prevent llvm name mangling | |
| 405 | 432 | symbol_name = buf_sprintf("\x01_%s", buf_ptr(symbol_name)); |
| 406 | 433 | } |
| 407 | 434 | |
| 408 | 435 | |
| 409 | 436 | TypeTableEntry *fn_type = fn_table_entry->type_entry; |
| 410 | 437 | LLVMTypeRef fn_llvm_type = fn_type->data.fn.raw_type_ref; |
| 411 | if (external_linkage && fn_table_entry->body_node == nullptr) { | |
| 438 | if (fn_table_entry->body_node == nullptr) { | |
| 412 | 439 | LLVMValueRef existing_llvm_fn = LLVMGetNamedFunction(g->module, buf_ptr(symbol_name)); |
| 413 | 440 | if (existing_llvm_fn) { |
| 414 | 441 | fn_table_entry->llvm_value = LLVMConstBitCast(existing_llvm_fn, LLVMPointerType(fn_llvm_type, 0)); |
| ... | ... | @@ -418,6 +445,12 @@ static LLVMValueRef fn_llvm_value(CodeGen *g, FnTableEntry *fn_table_entry) { |
| 418 | 445 | } |
| 419 | 446 | } else { |
| 420 | 447 | fn_table_entry->llvm_value = LLVMAddFunction(g->module, buf_ptr(symbol_name), fn_llvm_type); |
| 448 | ||
| 449 | for (size_t i = 1; i < fn_table_entry->export_list.length; i += 1) { | |
| 450 | FnExport *fn_export = &fn_table_entry->export_list.items[i]; | |
| 451 | LLVMAddAlias(g->module, LLVMTypeOf(fn_table_entry->llvm_value), | |
| 452 | fn_table_entry->llvm_value, buf_ptr(&fn_export->name)); | |
| 453 | } | |
| 421 | 454 | } |
| 422 | 455 | fn_table_entry->llvm_name = LLVMGetValueName(fn_table_entry->llvm_value); |
| 423 | 456 | |
| ... | ... | @@ -445,20 +478,10 @@ static LLVMValueRef fn_llvm_value(CodeGen *g, FnTableEntry *fn_table_entry) { |
| 445 | 478 | } |
| 446 | 479 | } |
| 447 | 480 | |
| 448 | switch (fn_table_entry->linkage) { | |
| 449 | case GlobalLinkageIdInternal: | |
| 450 | LLVMSetLinkage(fn_table_entry->llvm_value, LLVMInternalLinkage); | |
| 451 | LLVMSetUnnamedAddr(fn_table_entry->llvm_value, true); | |
| 452 | break; | |
| 453 | case GlobalLinkageIdStrong: | |
| 454 | LLVMSetLinkage(fn_table_entry->llvm_value, LLVMExternalLinkage); | |
| 455 | break; | |
| 456 | case GlobalLinkageIdWeak: | |
| 457 | LLVMSetLinkage(fn_table_entry->llvm_value, LLVMWeakODRLinkage); | |
| 458 | break; | |
| 459 | case GlobalLinkageIdLinkOnce: | |
| 460 | LLVMSetLinkage(fn_table_entry->llvm_value, LLVMLinkOnceODRLinkage); | |
| 461 | break; | |
| 481 | LLVMSetLinkage(fn_table_entry->llvm_value, to_llvm_linkage(linkage)); | |
| 482 | ||
| 483 | if (linkage == GlobalLinkageIdInternal) { | |
| 484 | LLVMSetUnnamedAddr(fn_table_entry->llvm_value, true); | |
| 462 | 485 | } |
| 463 | 486 | |
| 464 | 487 | if (fn_type->data.fn.fn_type_id.return_type->id == TypeTableEntryIdUnreachable) { |
| ... | ... | @@ -565,7 +588,8 @@ static ZigLLVMDIScope *get_di_scope(CodeGen *g, Scope *scope) { |
| 565 | 588 | bool is_definition = fn_table_entry->body_node != nullptr; |
| 566 | 589 | unsigned flags = 0; |
| 567 | 590 | bool is_optimized = g->build_mode != BuildModeDebug; |
| 568 | bool is_internal_linkage = (fn_table_entry->linkage == GlobalLinkageIdInternal); | |
| 591 | bool is_internal_linkage = (fn_table_entry->body_node != nullptr && | |
| 592 | fn_table_entry->export_list.length == 0); | |
| 569 | 593 | ZigLLVMDISubprogram *subprogram = ZigLLVMCreateFunction(g->dbuilder, |
| 570 | 594 | get_di_scope(g, scope->parent), buf_ptr(&fn_table_entry->symbol_name), "", |
| 571 | 595 | import->di_file, line_number, |
| ... | ... | @@ -3487,8 +3511,6 @@ static LLVMValueRef ir_render_instruction(CodeGen *g, IrExecutable *executable, |
| 3487 | 3511 | case IrInstructionIdCheckStatementIsVoid: |
| 3488 | 3512 | case IrInstructionIdTypeName: |
| 3489 | 3513 | case IrInstructionIdCanImplicitCast: |
| 3490 | case IrInstructionIdSetGlobalSection: | |
| 3491 | case IrInstructionIdSetGlobalLinkage: | |
| 3492 | 3514 | case IrInstructionIdDeclRef: |
| 3493 | 3515 | case IrInstructionIdSwitchVar: |
| 3494 | 3516 | case IrInstructionIdOffsetOf: |
| ... | ... | @@ -3499,6 +3521,7 @@ static LLVMValueRef ir_render_instruction(CodeGen *g, IrExecutable *executable, |
| 3499 | 3521 | case IrInstructionIdSetAlignStack: |
| 3500 | 3522 | case IrInstructionIdArgType: |
| 3501 | 3523 | case IrInstructionIdTagType: |
| 3524 | case IrInstructionIdExport: | |
| 3502 | 3525 | zig_unreachable(); |
| 3503 | 3526 | case IrInstructionIdReturn: |
| 3504 | 3527 | return ir_render_return(g, executable, (IrInstructionReturn *)instruction); |
| ... | ... | @@ -4969,8 +4992,6 @@ static void define_builtin_fns(CodeGen *g) { |
| 4969 | 4992 | create_builtin_fn(g, BuiltinFnIdIntType, "IntType", 2); // TODO rename to Int |
| 4970 | 4993 | create_builtin_fn(g, BuiltinFnIdSetDebugSafety, "setDebugSafety", 2); |
| 4971 | 4994 | create_builtin_fn(g, BuiltinFnIdSetFloatMode, "setFloatMode", 2); |
| 4972 | create_builtin_fn(g, BuiltinFnIdSetGlobalSection, "setGlobalSection", 2); | |
| 4973 | create_builtin_fn(g, BuiltinFnIdSetGlobalLinkage, "setGlobalLinkage", 2); | |
| 4974 | 4995 | create_builtin_fn(g, BuiltinFnIdPanic, "panic", 1); |
| 4975 | 4996 | create_builtin_fn(g, BuiltinFnIdPtrCast, "ptrCast", 2); |
| 4976 | 4997 | create_builtin_fn(g, BuiltinFnIdBitCast, "bitCast", 2); |
| ... | ... | @@ -4995,6 +5016,8 @@ static void define_builtin_fns(CodeGen *g) { |
| 4995 | 5016 | create_builtin_fn(g, BuiltinFnIdOpaqueType, "OpaqueType", 0); |
| 4996 | 5017 | create_builtin_fn(g, BuiltinFnIdSetAlignStack, "setAlignStack", 1); |
| 4997 | 5018 | create_builtin_fn(g, BuiltinFnIdArgType, "ArgType", 2); |
| 5019 | create_builtin_fn(g, BuiltinFnIdExport, "export", 2); | |
| 5020 | create_builtin_fn(g, BuiltinFnIdExportWithLinkage, "exportWithLinkage", 3); | |
| 4998 | 5021 | } |
| 4999 | 5022 | |
| 5000 | 5023 | static const char *bool_to_str(bool b) { |
| ... | ... | @@ -5433,6 +5456,27 @@ static void gen_root_source(CodeGen *g) { |
| 5433 | 5456 | assert(g->root_out_name); |
| 5434 | 5457 | assert(g->out_type != OutTypeUnknown); |
| 5435 | 5458 | |
| 5459 | { | |
| 5460 | // Zig has lazy top level definitions. Here we semantically analyze the panic function. | |
| 5461 | ImportTableEntry *import_with_panic; | |
| 5462 | if (g->have_pub_panic) { | |
| 5463 | import_with_panic = g->root_import; | |
| 5464 | } else { | |
| 5465 | g->panic_package = create_panic_pkg(g); | |
| 5466 | import_with_panic = add_special_code(g, g->panic_package, "panic.zig"); | |
| 5467 | } | |
| 5468 | scan_import(g, import_with_panic); | |
| 5469 | Tld *panic_tld = find_decl(g, &import_with_panic->decls_scope->base, buf_create_from_str("panic")); | |
| 5470 | assert(panic_tld != nullptr); | |
| 5471 | resolve_top_level_decl(g, panic_tld, false, nullptr); | |
| 5472 | } | |
| 5473 | ||
| 5474 | ||
| 5475 | if (!g->error_during_imports) { | |
| 5476 | semantic_analyze(g); | |
| 5477 | } | |
| 5478 | report_errors_and_maybe_exit(g); | |
| 5479 | ||
| 5436 | 5480 | if (!g->is_test_build && g->zig_target.os != ZigLLVM_UnknownOS && |
| 5437 | 5481 | !g->have_c_main && !g->have_winmain && !g->have_winmain_crt_startup && |
| 5438 | 5482 | ((g->have_pub_main && g->out_type == OutTypeObj) || g->out_type == OutTypeExe)) |
| ... | ... | @@ -5442,20 +5486,6 @@ static void gen_root_source(CodeGen *g) { |
| 5442 | 5486 | if (g->zig_target.os == ZigLLVM_Win32 && !g->have_dllmain_crt_startup && g->out_type == OutTypeLib) { |
| 5443 | 5487 | g->bootstrap_import = add_special_code(g, create_bootstrap_pkg(g, g->root_package), "bootstrap_lib.zig"); |
| 5444 | 5488 | } |
| 5445 | ImportTableEntry *import_with_panic; | |
| 5446 | if (g->have_pub_panic) { | |
| 5447 | import_with_panic = g->root_import; | |
| 5448 | } else { | |
| 5449 | g->panic_package = create_panic_pkg(g); | |
| 5450 | import_with_panic = add_special_code(g, g->panic_package, "panic.zig"); | |
| 5451 | } | |
| 5452 | // Zig has lazy top level definitions. Here we semantically analyze the panic function. | |
| 5453 | { | |
| 5454 | scan_import(g, import_with_panic); | |
| 5455 | Tld *panic_tld = find_decl(g, &import_with_panic->decls_scope->base, buf_create_from_str("panic")); | |
| 5456 | assert(panic_tld != nullptr); | |
| 5457 | resolve_top_level_decl(g, panic_tld, false, nullptr); | |
| 5458 | } | |
| 5459 | 5489 | |
| 5460 | 5490 | if (!g->error_during_imports) { |
| 5461 | 5491 | semantic_analyze(g); |
| ... | ... | @@ -5682,7 +5712,7 @@ static void gen_h_file(CodeGen *g) { |
| 5682 | 5712 | for (size_t fn_def_i = 0; fn_def_i < g->fn_defs.length; fn_def_i += 1) { |
| 5683 | 5713 | FnTableEntry *fn_table_entry = g->fn_defs.at(fn_def_i); |
| 5684 | 5714 | |
| 5685 | if (fn_table_entry->linkage == GlobalLinkageIdInternal) | |
| 5715 | if (fn_table_entry->export_list.length == 0) | |
| 5686 | 5716 | continue; |
| 5687 | 5717 | |
| 5688 | 5718 | FnTypeId *fn_type_id = &fn_table_entry->type_entry->data.fn.fn_type_id; |
src/ir.cpp+264-195| ... | ... | @@ -207,6 +207,10 @@ static constexpr IrInstructionId ir_instruction_id(IrInstructionDeclVar *) { |
| 207 | 207 | return IrInstructionIdDeclVar; |
| 208 | 208 | } |
| 209 | 209 | |
| 210 | static constexpr IrInstructionId ir_instruction_id(IrInstructionExport *) { | |
| 211 | return IrInstructionIdExport; | |
| 212 | } | |
| 213 | ||
| 210 | 214 | static constexpr IrInstructionId ir_instruction_id(IrInstructionLoadPtr *) { |
| 211 | 215 | return IrInstructionIdLoadPtr; |
| 212 | 216 | } |
| ... | ... | @@ -523,14 +527,6 @@ static constexpr IrInstructionId ir_instruction_id(IrInstructionCanImplicitCast |
| 523 | 527 | return IrInstructionIdCanImplicitCast; |
| 524 | 528 | } |
| 525 | 529 | |
| 526 | static constexpr IrInstructionId ir_instruction_id(IrInstructionSetGlobalSection *) { | |
| 527 | return IrInstructionIdSetGlobalSection; | |
| 528 | } | |
| 529 | ||
| 530 | static constexpr IrInstructionId ir_instruction_id(IrInstructionSetGlobalLinkage *) { | |
| 531 | return IrInstructionIdSetGlobalLinkage; | |
| 532 | } | |
| 533 | ||
| 534 | 530 | static constexpr IrInstructionId ir_instruction_id(IrInstructionDeclRef *) { |
| 535 | 531 | return IrInstructionIdDeclRef; |
| 536 | 532 | } |
| ... | ... | @@ -1205,6 +1201,24 @@ static IrInstruction *ir_build_var_decl_from(IrBuilder *irb, IrInstruction *old_ |
| 1205 | 1201 | return new_instruction; |
| 1206 | 1202 | } |
| 1207 | 1203 | |
| 1204 | static IrInstruction *ir_build_export(IrBuilder *irb, Scope *scope, AstNode *source_node, | |
| 1205 | IrInstruction *name, IrInstruction *target, IrInstruction *linkage) | |
| 1206 | { | |
| 1207 | IrInstructionExport *export_instruction = ir_build_instruction<IrInstructionExport>( | |
| 1208 | irb, scope, source_node); | |
| 1209 | export_instruction->base.value.special = ConstValSpecialStatic; | |
| 1210 | export_instruction->base.value.type = irb->codegen->builtin_types.entry_void; | |
| 1211 | export_instruction->name = name; | |
| 1212 | export_instruction->target = target; | |
| 1213 | export_instruction->linkage = linkage; | |
| 1214 | ||
| 1215 | ir_ref_instruction(name, irb->current_basic_block); | |
| 1216 | ir_ref_instruction(target, irb->current_basic_block); | |
| 1217 | if (linkage) ir_ref_instruction(linkage, irb->current_basic_block); | |
| 1218 | ||
| 1219 | return &export_instruction->base; | |
| 1220 | } | |
| 1221 | ||
| 1208 | 1222 | static IrInstruction *ir_build_load_ptr(IrBuilder *irb, Scope *scope, AstNode *source_node, IrInstruction *ptr) { |
| 1209 | 1223 | IrInstructionLoadPtr *instruction = ir_build_instruction<IrInstructionLoadPtr>(irb, scope, source_node); |
| 1210 | 1224 | instruction->ptr = ptr; |
| ... | ... | @@ -2159,32 +2173,6 @@ static IrInstruction *ir_build_can_implicit_cast(IrBuilder *irb, Scope *scope, A |
| 2159 | 2173 | return &instruction->base; |
| 2160 | 2174 | } |
| 2161 | 2175 | |
| 2162 | static IrInstruction *ir_build_set_global_section(IrBuilder *irb, Scope *scope, AstNode *source_node, | |
| 2163 | Tld *tld, IrInstruction *value) | |
| 2164 | { | |
| 2165 | IrInstructionSetGlobalSection *instruction = ir_build_instruction<IrInstructionSetGlobalSection>( | |
| 2166 | irb, scope, source_node); | |
| 2167 | instruction->tld = tld; | |
| 2168 | instruction->value = value; | |
| 2169 | ||
| 2170 | ir_ref_instruction(value, irb->current_basic_block); | |
| 2171 | ||
| 2172 | return &instruction->base; | |
| 2173 | } | |
| 2174 | ||
| 2175 | static IrInstruction *ir_build_set_global_linkage(IrBuilder *irb, Scope *scope, AstNode *source_node, | |
| 2176 | Tld *tld, IrInstruction *value) | |
| 2177 | { | |
| 2178 | IrInstructionSetGlobalLinkage *instruction = ir_build_instruction<IrInstructionSetGlobalLinkage>( | |
| 2179 | irb, scope, source_node); | |
| 2180 | instruction->tld = tld; | |
| 2181 | instruction->value = value; | |
| 2182 | ||
| 2183 | ir_ref_instruction(value, irb->current_basic_block); | |
| 2184 | ||
| 2185 | return &instruction->base; | |
| 2186 | } | |
| 2187 | ||
| 2188 | 2176 | static IrInstruction *ir_build_decl_ref(IrBuilder *irb, Scope *scope, AstNode *source_node, |
| 2189 | 2177 | Tld *tld, LVal lval) |
| 2190 | 2178 | { |
| ... | ... | @@ -2396,6 +2384,21 @@ static IrInstruction *ir_instruction_declvar_get_dep(IrInstructionDeclVar *instr |
| 2396 | 2384 | return nullptr; |
| 2397 | 2385 | } |
| 2398 | 2386 | |
| 2387 | static IrInstruction *ir_instruction_export_get_dep(IrInstructionExport *instruction, size_t index) { | |
| 2388 | if (index < 1) return instruction->name; | |
| 2389 | index -= 1; | |
| 2390 | ||
| 2391 | if (index < 1) return instruction->target; | |
| 2392 | index -= 1; | |
| 2393 | ||
| 2394 | if (instruction->linkage != nullptr) { | |
| 2395 | if (index < 1) return instruction->linkage; | |
| 2396 | index -= 1; | |
| 2397 | } | |
| 2398 | ||
| 2399 | return nullptr; | |
| 2400 | } | |
| 2401 | ||
| 2399 | 2402 | static IrInstruction *ir_instruction_loadptr_get_dep(IrInstructionLoadPtr *instruction, size_t index) { |
| 2400 | 2403 | switch (index) { |
| 2401 | 2404 | case 0: return instruction->ptr; |
| ... | ... | @@ -2979,20 +2982,6 @@ static IrInstruction *ir_instruction_canimplicitcast_get_dep(IrInstructionCanImp |
| 2979 | 2982 | } |
| 2980 | 2983 | } |
| 2981 | 2984 | |
| 2982 | static IrInstruction *ir_instruction_setglobalsection_get_dep(IrInstructionSetGlobalSection *instruction, size_t index) { | |
| 2983 | switch (index) { | |
| 2984 | case 0: return instruction->value; | |
| 2985 | default: return nullptr; | |
| 2986 | } | |
| 2987 | } | |
| 2988 | ||
| 2989 | static IrInstruction *ir_instruction_setgloballinkage_get_dep(IrInstructionSetGlobalLinkage *instruction, size_t index) { | |
| 2990 | switch (index) { | |
| 2991 | case 0: return instruction->value; | |
| 2992 | default: return nullptr; | |
| 2993 | } | |
| 2994 | } | |
| 2995 | ||
| 2996 | 2985 | static IrInstruction *ir_instruction_declref_get_dep(IrInstructionDeclRef *instruction, size_t index) { |
| 2997 | 2986 | return nullptr; |
| 2998 | 2987 | } |
| ... | ... | @@ -3106,6 +3095,8 @@ static IrInstruction *ir_instruction_get_dep(IrInstruction *instruction, size_t |
| 3106 | 3095 | return ir_instruction_binop_get_dep((IrInstructionBinOp *) instruction, index); |
| 3107 | 3096 | case IrInstructionIdDeclVar: |
| 3108 | 3097 | return ir_instruction_declvar_get_dep((IrInstructionDeclVar *) instruction, index); |
| 3098 | case IrInstructionIdExport: | |
| 3099 | return ir_instruction_export_get_dep((IrInstructionExport *) instruction, index); | |
| 3109 | 3100 | case IrInstructionIdLoadPtr: |
| 3110 | 3101 | return ir_instruction_loadptr_get_dep((IrInstructionLoadPtr *) instruction, index); |
| 3111 | 3102 | case IrInstructionIdStorePtr: |
| ... | ... | @@ -3264,10 +3255,6 @@ static IrInstruction *ir_instruction_get_dep(IrInstruction *instruction, size_t |
| 3264 | 3255 | return ir_instruction_typename_get_dep((IrInstructionTypeName *) instruction, index); |
| 3265 | 3256 | case IrInstructionIdCanImplicitCast: |
| 3266 | 3257 | return ir_instruction_canimplicitcast_get_dep((IrInstructionCanImplicitCast *) instruction, index); |
| 3267 | case IrInstructionIdSetGlobalSection: | |
| 3268 | return ir_instruction_setglobalsection_get_dep((IrInstructionSetGlobalSection *) instruction, index); | |
| 3269 | case IrInstructionIdSetGlobalLinkage: | |
| 3270 | return ir_instruction_setgloballinkage_get_dep((IrInstructionSetGlobalLinkage *) instruction, index); | |
| 3271 | 3258 | case IrInstructionIdDeclRef: |
| 3272 | 3259 | return ir_instruction_declref_get_dep((IrInstructionDeclRef *) instruction, index); |
| 3273 | 3260 | case IrInstructionIdPanic: |
| ... | ... | @@ -4528,39 +4515,6 @@ static IrInstruction *ir_gen_builtin_fn_call(IrBuilder *irb, Scope *scope, AstNo |
| 4528 | 4515 | |
| 4529 | 4516 | return ir_build_can_implicit_cast(irb, scope, node, arg0_value, arg1_value); |
| 4530 | 4517 | } |
| 4531 | case BuiltinFnIdSetGlobalSection: | |
| 4532 | case BuiltinFnIdSetGlobalLinkage: | |
| 4533 | { | |
| 4534 | AstNode *arg0_node = node->data.fn_call_expr.params.at(0); | |
| 4535 | if (arg0_node->type != NodeTypeSymbol) { | |
| 4536 | add_node_error(irb->codegen, arg0_node, buf_sprintf("expected identifier")); | |
| 4537 | return irb->codegen->invalid_instruction; | |
| 4538 | } | |
| 4539 | Buf *variable_name = arg0_node->data.symbol_expr.symbol; | |
| 4540 | Tld *tld = find_decl(irb->codegen, scope, variable_name); | |
| 4541 | if (!tld) { | |
| 4542 | add_node_error(irb->codegen, node, buf_sprintf("use of undeclared identifier '%s'", | |
| 4543 | buf_ptr(variable_name))); | |
| 4544 | return irb->codegen->invalid_instruction; | |
| 4545 | } | |
| 4546 | if (tld->id != TldIdVar && tld->id != TldIdFn) { | |
| 4547 | add_node_error(irb->codegen, node, buf_sprintf("'%s' must be global variable or function", | |
| 4548 | buf_ptr(variable_name))); | |
| 4549 | return irb->codegen->invalid_instruction; | |
| 4550 | } | |
| 4551 | AstNode *arg1_node = node->data.fn_call_expr.params.at(1); | |
| 4552 | IrInstruction *arg1_value = ir_gen_node(irb, arg1_node, scope); | |
| 4553 | if (arg1_value == irb->codegen->invalid_instruction) | |
| 4554 | return arg1_value; | |
| 4555 | ||
| 4556 | if (builtin_fn->id == BuiltinFnIdSetGlobalSection) { | |
| 4557 | return ir_build_set_global_section(irb, scope, node, tld, arg1_value); | |
| 4558 | } else if (builtin_fn->id == BuiltinFnIdSetGlobalLinkage) { | |
| 4559 | return ir_build_set_global_linkage(irb, scope, node, tld, arg1_value); | |
| 4560 | } else { | |
| 4561 | zig_unreachable(); | |
| 4562 | } | |
| 4563 | } | |
| 4564 | 4518 | case BuiltinFnIdPanic: |
| 4565 | 4519 | { |
| 4566 | 4520 | AstNode *arg0_node = node->data.fn_call_expr.params.at(0); |
| ... | ... | @@ -4784,6 +4738,31 @@ static IrInstruction *ir_gen_builtin_fn_call(IrBuilder *irb, Scope *scope, AstNo |
| 4784 | 4738 | |
| 4785 | 4739 | return ir_build_arg_type(irb, scope, node, arg0_value, arg1_value); |
| 4786 | 4740 | } |
| 4741 | case BuiltinFnIdExport: | |
| 4742 | case BuiltinFnIdExportWithLinkage: | |
| 4743 | { | |
| 4744 | AstNode *arg0_node = node->data.fn_call_expr.params.at(0); | |
| 4745 | IrInstruction *arg0_value = ir_gen_node(irb, arg0_node, scope); | |
| 4746 | if (arg0_value == irb->codegen->invalid_instruction) | |
| 4747 | return arg0_value; | |
| 4748 | ||
| 4749 | AstNode *arg1_node = node->data.fn_call_expr.params.at(1); | |
| 4750 | IrInstruction *arg1_value = ir_gen_node(irb, arg1_node, scope); | |
| 4751 | if (arg1_value == irb->codegen->invalid_instruction) | |
| 4752 | return arg1_value; | |
| 4753 | ||
| 4754 | IrInstruction *arg2_value; | |
| 4755 | if (builtin_fn->id == BuiltinFnIdExportWithLinkage) { | |
| 4756 | AstNode *arg2_node = node->data.fn_call_expr.params.at(2); | |
| 4757 | arg2_value = ir_gen_node(irb, arg2_node, scope); | |
| 4758 | if (arg2_value == irb->codegen->invalid_instruction) | |
| 4759 | return arg2_value; | |
| 4760 | } else { | |
| 4761 | arg2_value = nullptr; | |
| 4762 | } | |
| 4763 | ||
| 4764 | return ir_build_export(irb, scope, node, arg0_value, arg1_value, arg2_value); | |
| 4765 | } | |
| 4787 | 4766 | } |
| 4788 | 4767 | zig_unreachable(); |
| 4789 | 4768 | } |
| ... | ... | @@ -5106,6 +5085,11 @@ static IrInstruction *ir_gen_var_decl(IrBuilder *irb, Scope *scope, AstNode *nod |
| 5106 | 5085 | return align_value; |
| 5107 | 5086 | } |
| 5108 | 5087 | |
| 5088 | if (variable_declaration->section_expr != nullptr) { | |
| 5089 | add_node_error(irb->codegen, variable_declaration->section_expr, | |
| 5090 | buf_sprintf("cannot set section of local variable '%s'", buf_ptr(variable_declaration->symbol))); | |
| 5091 | } | |
| 5092 | ||
| 5109 | 5093 | IrInstruction *init_value = ir_gen_node(irb, variable_declaration->expr, scope); |
| 5110 | 5094 | if (init_value == irb->codegen->invalid_instruction) |
| 5111 | 5095 | return init_value; |
| ... | ... | @@ -6355,6 +6339,10 @@ static IrInstruction *ir_gen_node_raw(IrBuilder *irb, AstNode *node, Scope *scop |
| 6355 | 6339 | case NodeTypeSwitchRange: |
| 6356 | 6340 | case NodeTypeStructField: |
| 6357 | 6341 | case NodeTypeLabel: |
| 6342 | case NodeTypeFnDef: | |
| 6343 | case NodeTypeFnDecl: | |
| 6344 | case NodeTypeErrorValueDecl: | |
| 6345 | case NodeTypeTestDecl: | |
| 6358 | 6346 | zig_unreachable(); |
| 6359 | 6347 | case NodeTypeBlock: |
| 6360 | 6348 | return ir_lval_wrap(irb, scope, ir_gen_block(irb, scope, node), lval); |
| ... | ... | @@ -6436,14 +6424,6 @@ static IrInstruction *ir_gen_node_raw(IrBuilder *irb, AstNode *node, Scope *scop |
| 6436 | 6424 | return ir_lval_wrap(irb, scope, ir_gen_container_decl(irb, scope, node), lval); |
| 6437 | 6425 | case NodeTypeFnProto: |
| 6438 | 6426 | return ir_lval_wrap(irb, scope, ir_gen_fn_proto(irb, scope, node), lval); |
| 6439 | case NodeTypeFnDef: | |
| 6440 | zig_panic("TODO IR gen NodeTypeFnDef"); | |
| 6441 | case NodeTypeFnDecl: | |
| 6442 | zig_panic("TODO IR gen NodeTypeFnDecl"); | |
| 6443 | case NodeTypeErrorValueDecl: | |
| 6444 | zig_panic("TODO IR gen NodeTypeErrorValueDecl"); | |
| 6445 | case NodeTypeTestDecl: | |
| 6446 | zig_panic("TODO IR gen NodeTypeTestDecl"); | |
| 6447 | 6427 | } |
| 6448 | 6428 | zig_unreachable(); |
| 6449 | 6429 | } |
| ... | ... | @@ -10481,6 +10461,194 @@ static TypeTableEntry *ir_analyze_instruction_decl_var(IrAnalyze *ira, IrInstruc |
| 10481 | 10461 | return ira->codegen->builtin_types.entry_void; |
| 10482 | 10462 | } |
| 10483 | 10463 | |
| 10464 | static TypeTableEntry *ir_analyze_instruction_export(IrAnalyze *ira, IrInstructionExport *instruction) { | |
| 10465 | IrInstruction *name = instruction->name->other; | |
| 10466 | Buf *symbol_name = ir_resolve_str(ira, name); | |
| 10467 | if (symbol_name == nullptr) { | |
| 10468 | return ira->codegen->builtin_types.entry_invalid; | |
| 10469 | } | |
| 10470 | ||
| 10471 | IrInstruction *target = instruction->target->other; | |
| 10472 | if (type_is_invalid(target->value.type)) { | |
| 10473 | return ira->codegen->builtin_types.entry_invalid; | |
| 10474 | } | |
| 10475 | ||
| 10476 | GlobalLinkageId global_linkage_id = GlobalLinkageIdStrong; | |
| 10477 | if (instruction->linkage != nullptr) { | |
| 10478 | IrInstruction *linkage_value = instruction->linkage->other; | |
| 10479 | if (!ir_resolve_global_linkage(ira, linkage_value, &global_linkage_id)) { | |
| 10480 | return ira->codegen->builtin_types.entry_invalid; | |
| 10481 | } | |
| 10482 | } | |
| 10483 | ||
| 10484 | auto entry = ira->codegen->exported_symbol_names.put_unique(symbol_name, instruction->base.source_node); | |
| 10485 | if (entry) { | |
| 10486 | AstNode *other_export_node = entry->value; | |
| 10487 | ErrorMsg *msg = ir_add_error(ira, &instruction->base, | |
| 10488 | buf_sprintf("exported symbol collision: '%s'", buf_ptr(symbol_name))); | |
| 10489 | add_error_note(ira->codegen, msg, other_export_node, buf_sprintf("other symbol is here")); | |
| 10490 | } | |
| 10491 | ||
| 10492 | switch (target->value.type->id) { | |
| 10493 | case TypeTableEntryIdInvalid: | |
| 10494 | case TypeTableEntryIdVar: | |
| 10495 | case TypeTableEntryIdUnreachable: | |
| 10496 | zig_unreachable(); | |
| 10497 | case TypeTableEntryIdFn: { | |
| 10498 | FnTableEntry *fn_entry = target->value.data.x_fn.fn_entry; | |
| 10499 | CallingConvention cc = fn_entry->type_entry->data.fn.fn_type_id.cc; | |
| 10500 | switch (cc) { | |
| 10501 | case CallingConventionUnspecified: { | |
| 10502 | ErrorMsg *msg = ir_add_error(ira, target, | |
| 10503 | buf_sprintf("exported function must specify calling convention")); | |
| 10504 | add_error_note(ira->codegen, msg, fn_entry->proto_node, buf_sprintf("declared here")); | |
| 10505 | } break; | |
| 10506 | case CallingConventionC: | |
| 10507 | if (buf_eql_str(symbol_name, "main") && ira->codegen->libc_link_lib != nullptr) { | |
| 10508 | ira->codegen->have_c_main = true; | |
| 10509 | ira->codegen->windows_subsystem_windows = false; | |
| 10510 | ira->codegen->windows_subsystem_console = true; | |
| 10511 | } else if (buf_eql_str(symbol_name, "WinMain") && | |
| 10512 | ira->codegen->zig_target.os == ZigLLVM_Win32) | |
| 10513 | { | |
| 10514 | ira->codegen->have_winmain = true; | |
| 10515 | ira->codegen->windows_subsystem_windows = true; | |
| 10516 | ira->codegen->windows_subsystem_console = false; | |
| 10517 | } else if (buf_eql_str(symbol_name, "WinMainCRTStartup") && | |
| 10518 | ira->codegen->zig_target.os == ZigLLVM_Win32) | |
| 10519 | { | |
| 10520 | ira->codegen->have_winmain_crt_startup = true; | |
| 10521 | } else if (buf_eql_str(symbol_name, "DllMainCRTStartup") && | |
| 10522 | ira->codegen->zig_target.os == ZigLLVM_Win32) | |
| 10523 | { | |
| 10524 | ira->codegen->have_dllmain_crt_startup = true; | |
| 10525 | } | |
| 10526 | // fallthrough | |
| 10527 | case CallingConventionNaked: | |
| 10528 | case CallingConventionCold: | |
| 10529 | case CallingConventionStdcall: { | |
| 10530 | FnExport *fn_export = fn_entry->export_list.add_one(); | |
| 10531 | memset(fn_export, 0, sizeof(FnExport)); | |
| 10532 | buf_init_from_buf(&fn_export->name, symbol_name); | |
| 10533 | fn_export->linkage = global_linkage_id; | |
| 10534 | fn_export->source_node = instruction->base.source_node; | |
| 10535 | } break; | |
| 10536 | } | |
| 10537 | } break; | |
| 10538 | case TypeTableEntryIdStruct: | |
| 10539 | if (is_slice(target->value.type)) { | |
| 10540 | ir_add_error(ira, target, | |
| 10541 | buf_sprintf("unable to export value of type '%s'", buf_ptr(&target->value.type->name))); | |
| 10542 | } else if (target->value.type->data.structure.layout != ContainerLayoutExtern) { | |
| 10543 | ErrorMsg *msg = ir_add_error(ira, target, | |
| 10544 | buf_sprintf("exported struct value must be declared extern")); | |
| 10545 | add_error_note(ira->codegen, msg, target->value.type->data.structure.decl_node, buf_sprintf("declared here")); | |
| 10546 | } | |
| 10547 | break; | |
| 10548 | case TypeTableEntryIdUnion: | |
| 10549 | if (target->value.type->data.unionation.layout != ContainerLayoutExtern) { | |
| 10550 | ErrorMsg *msg = ir_add_error(ira, target, | |
| 10551 | buf_sprintf("exported union value must be declared extern")); | |
| 10552 | add_error_note(ira->codegen, msg, target->value.type->data.unionation.decl_node, buf_sprintf("declared here")); | |
| 10553 | } | |
| 10554 | break; | |
| 10555 | case TypeTableEntryIdEnum: | |
| 10556 | if (target->value.type->data.enumeration.layout != ContainerLayoutExtern) { | |
| 10557 | ErrorMsg *msg = ir_add_error(ira, target, | |
| 10558 | buf_sprintf("exported enum value must be declared extern")); | |
| 10559 | add_error_note(ira->codegen, msg, target->value.type->data.enumeration.decl_node, buf_sprintf("declared here")); | |
| 10560 | } | |
| 10561 | break; | |
| 10562 | case TypeTableEntryIdMetaType: { | |
| 10563 | TypeTableEntry *type_value = target->value.data.x_type; | |
| 10564 | switch (type_value->id) { | |
| 10565 | case TypeTableEntryIdInvalid: | |
| 10566 | case TypeTableEntryIdVar: | |
| 10567 | zig_unreachable(); | |
| 10568 | case TypeTableEntryIdStruct: | |
| 10569 | if (is_slice(type_value)) { | |
| 10570 | ir_add_error(ira, target, | |
| 10571 | buf_sprintf("unable to export type '%s'", buf_ptr(&type_value->name))); | |
| 10572 | } else if (type_value->data.structure.layout != ContainerLayoutExtern) { | |
| 10573 | ErrorMsg *msg = ir_add_error(ira, target, | |
| 10574 | buf_sprintf("exported struct must be declared extern")); | |
| 10575 | add_error_note(ira->codegen, msg, type_value->data.structure.decl_node, buf_sprintf("declared here")); | |
| 10576 | } | |
| 10577 | break; | |
| 10578 | case TypeTableEntryIdUnion: | |
| 10579 | if (type_value->data.unionation.layout != ContainerLayoutExtern) { | |
| 10580 | ErrorMsg *msg = ir_add_error(ira, target, | |
| 10581 | buf_sprintf("exported union must be declared extern")); | |
| 10582 | add_error_note(ira->codegen, msg, type_value->data.unionation.decl_node, buf_sprintf("declared here")); | |
| 10583 | } | |
| 10584 | break; | |
| 10585 | case TypeTableEntryIdEnum: | |
| 10586 | if (type_value->data.enumeration.layout != ContainerLayoutExtern) { | |
| 10587 | ErrorMsg *msg = ir_add_error(ira, target, | |
| 10588 | buf_sprintf("exported enum must be declared extern")); | |
| 10589 | add_error_note(ira->codegen, msg, type_value->data.enumeration.decl_node, buf_sprintf("declared here")); | |
| 10590 | } | |
| 10591 | break; | |
| 10592 | case TypeTableEntryIdFn: { | |
| 10593 | if (type_value->data.fn.fn_type_id.cc == CallingConventionUnspecified) { | |
| 10594 | ir_add_error(ira, target, | |
| 10595 | buf_sprintf("exported function type must specify calling convention")); | |
| 10596 | } | |
| 10597 | } break; | |
| 10598 | case TypeTableEntryIdInt: | |
| 10599 | case TypeTableEntryIdFloat: | |
| 10600 | case TypeTableEntryIdPointer: | |
| 10601 | case TypeTableEntryIdArray: | |
| 10602 | case TypeTableEntryIdBool: | |
| 10603 | break; | |
| 10604 | case TypeTableEntryIdMetaType: | |
| 10605 | case TypeTableEntryIdVoid: | |
| 10606 | case TypeTableEntryIdUnreachable: | |
| 10607 | case TypeTableEntryIdNumLitFloat: | |
| 10608 | case TypeTableEntryIdNumLitInt: | |
| 10609 | case TypeTableEntryIdUndefLit: | |
| 10610 | case TypeTableEntryIdNullLit: | |
| 10611 | case TypeTableEntryIdMaybe: | |
| 10612 | case TypeTableEntryIdErrorUnion: | |
| 10613 | case TypeTableEntryIdPureError: | |
| 10614 | case TypeTableEntryIdNamespace: | |
| 10615 | case TypeTableEntryIdBlock: | |
| 10616 | case TypeTableEntryIdBoundFn: | |
| 10617 | case TypeTableEntryIdArgTuple: | |
| 10618 | case TypeTableEntryIdOpaque: | |
| 10619 | ir_add_error(ira, target, | |
| 10620 | buf_sprintf("invalid export target '%s'", buf_ptr(&type_value->name))); | |
| 10621 | break; | |
| 10622 | } | |
| 10623 | } break; | |
| 10624 | case TypeTableEntryIdVoid: | |
| 10625 | case TypeTableEntryIdBool: | |
| 10626 | case TypeTableEntryIdInt: | |
| 10627 | case TypeTableEntryIdFloat: | |
| 10628 | case TypeTableEntryIdPointer: | |
| 10629 | case TypeTableEntryIdArray: | |
| 10630 | case TypeTableEntryIdNumLitFloat: | |
| 10631 | case TypeTableEntryIdNumLitInt: | |
| 10632 | case TypeTableEntryIdUndefLit: | |
| 10633 | case TypeTableEntryIdNullLit: | |
| 10634 | case TypeTableEntryIdMaybe: | |
| 10635 | case TypeTableEntryIdErrorUnion: | |
| 10636 | case TypeTableEntryIdPureError: | |
| 10637 | zig_panic("TODO export const value of type %s", buf_ptr(&target->value.type->name)); | |
| 10638 | case TypeTableEntryIdNamespace: | |
| 10639 | case TypeTableEntryIdBlock: | |
| 10640 | case TypeTableEntryIdBoundFn: | |
| 10641 | case TypeTableEntryIdArgTuple: | |
| 10642 | case TypeTableEntryIdOpaque: | |
| 10643 | ir_add_error(ira, target, | |
| 10644 | buf_sprintf("invalid export target type '%s'", buf_ptr(&target->value.type->name))); | |
| 10645 | break; | |
| 10646 | } | |
| 10647 | ||
| 10648 | ir_build_const_from(ira, &instruction->base); | |
| 10649 | return ira->codegen->builtin_types.entry_void; | |
| 10650 | } | |
| 10651 | ||
| 10484 | 10652 | static bool ir_analyze_fn_call_inline_arg(IrAnalyze *ira, AstNode *fn_proto_node, |
| 10485 | 10653 | IrInstruction *arg, Scope **exec_scope, size_t *next_proto_i) |
| 10486 | 10654 | { |
| ... | ... | @@ -12399,102 +12567,6 @@ static TypeTableEntry *ir_analyze_instruction_ptr_type_child(IrAnalyze *ira, |
| 12399 | 12567 | return ira->codegen->builtin_types.entry_type; |
| 12400 | 12568 | } |
| 12401 | 12569 | |
| 12402 | static TypeTableEntry *ir_analyze_instruction_set_global_section(IrAnalyze *ira, | |
| 12403 | IrInstructionSetGlobalSection *instruction) | |
| 12404 | { | |
| 12405 | Tld *tld = instruction->tld; | |
| 12406 | IrInstruction *section_value = instruction->value->other; | |
| 12407 | ||
| 12408 | resolve_top_level_decl(ira->codegen, tld, true, instruction->base.source_node); | |
| 12409 | if (tld->resolution == TldResolutionInvalid) | |
| 12410 | return ira->codegen->builtin_types.entry_invalid; | |
| 12411 | ||
| 12412 | Buf *section_name = ir_resolve_str(ira, section_value); | |
| 12413 | if (!section_name) | |
| 12414 | return ira->codegen->builtin_types.entry_invalid; | |
| 12415 | ||
| 12416 | AstNode **set_global_section_node; | |
| 12417 | Buf **section_name_ptr; | |
| 12418 | if (tld->id == TldIdVar) { | |
| 12419 | TldVar *tld_var = (TldVar *)tld; | |
| 12420 | set_global_section_node = &tld_var->set_global_section_node; | |
| 12421 | section_name_ptr = &tld_var->section_name; | |
| 12422 | ||
| 12423 | if (tld_var->var->linkage == VarLinkageExternal) { | |
| 12424 | ErrorMsg *msg = ir_add_error(ira, &instruction->base, | |
| 12425 | buf_sprintf("cannot set section of external variable '%s'", buf_ptr(&tld_var->var->name))); | |
| 12426 | add_error_note(ira->codegen, msg, tld->source_node, buf_sprintf("declared here")); | |
| 12427 | return ira->codegen->builtin_types.entry_invalid; | |
| 12428 | } | |
| 12429 | } else if (tld->id == TldIdFn) { | |
| 12430 | TldFn *tld_fn = (TldFn *)tld; | |
| 12431 | FnTableEntry *fn_entry = tld_fn->fn_entry; | |
| 12432 | set_global_section_node = &fn_entry->set_global_section_node; | |
| 12433 | section_name_ptr = &fn_entry->section_name; | |
| 12434 | ||
| 12435 | if (fn_entry->def_scope == nullptr) { | |
| 12436 | ErrorMsg *msg = ir_add_error(ira, &instruction->base, | |
| 12437 | buf_sprintf("cannot set section of external function '%s'", buf_ptr(&fn_entry->symbol_name))); | |
| 12438 | add_error_note(ira->codegen, msg, tld->source_node, buf_sprintf("declared here")); | |
| 12439 | return ira->codegen->builtin_types.entry_invalid; | |
| 12440 | } | |
| 12441 | } else { | |
| 12442 | // error is caught in pass1 IR gen | |
| 12443 | zig_unreachable(); | |
| 12444 | } | |
| 12445 | ||
| 12446 | AstNode *source_node = instruction->base.source_node; | |
| 12447 | if (*set_global_section_node) { | |
| 12448 | ErrorMsg *msg = ir_add_error_node(ira, source_node, buf_sprintf("section set twice")); | |
| 12449 | add_error_note(ira->codegen, msg, *set_global_section_node, buf_sprintf("first set here")); | |
| 12450 | return ira->codegen->builtin_types.entry_invalid; | |
| 12451 | } | |
| 12452 | *set_global_section_node = source_node; | |
| 12453 | *section_name_ptr = section_name; | |
| 12454 | ||
| 12455 | ir_build_const_from(ira, &instruction->base); | |
| 12456 | return ira->codegen->builtin_types.entry_void; | |
| 12457 | } | |
| 12458 | ||
| 12459 | static TypeTableEntry *ir_analyze_instruction_set_global_linkage(IrAnalyze *ira, | |
| 12460 | IrInstructionSetGlobalLinkage *instruction) | |
| 12461 | { | |
| 12462 | Tld *tld = instruction->tld; | |
| 12463 | IrInstruction *linkage_value = instruction->value->other; | |
| 12464 | ||
| 12465 | GlobalLinkageId linkage_scalar; | |
| 12466 | if (!ir_resolve_global_linkage(ira, linkage_value, &linkage_scalar)) | |
| 12467 | return ira->codegen->builtin_types.entry_invalid; | |
| 12468 | ||
| 12469 | AstNode **set_global_linkage_node; | |
| 12470 | GlobalLinkageId *dest_linkage_ptr; | |
| 12471 | if (tld->id == TldIdVar) { | |
| 12472 | TldVar *tld_var = (TldVar *)tld; | |
| 12473 | set_global_linkage_node = &tld_var->set_global_linkage_node; | |
| 12474 | dest_linkage_ptr = &tld_var->linkage; | |
| 12475 | } else if (tld->id == TldIdFn) { | |
| 12476 | TldFn *tld_fn = (TldFn *)tld; | |
| 12477 | FnTableEntry *fn_entry = tld_fn->fn_entry; | |
| 12478 | set_global_linkage_node = &fn_entry->set_global_linkage_node; | |
| 12479 | dest_linkage_ptr = &fn_entry->linkage; | |
| 12480 | } else { | |
| 12481 | // error is caught in pass1 IR gen | |
| 12482 | zig_unreachable(); | |
| 12483 | } | |
| 12484 | ||
| 12485 | AstNode *source_node = instruction->base.source_node; | |
| 12486 | if (*set_global_linkage_node) { | |
| 12487 | ErrorMsg *msg = ir_add_error_node(ira, source_node, buf_sprintf("linkage set twice")); | |
| 12488 | add_error_note(ira->codegen, msg, *set_global_linkage_node, buf_sprintf("first set here")); | |
| 12489 | return ira->codegen->builtin_types.entry_invalid; | |
| 12490 | } | |
| 12491 | *set_global_linkage_node = source_node; | |
| 12492 | *dest_linkage_ptr = linkage_scalar; | |
| 12493 | ||
| 12494 | ir_build_const_from(ira, &instruction->base); | |
| 12495 | return ira->codegen->builtin_types.entry_void; | |
| 12496 | } | |
| 12497 | ||
| 12498 | 12570 | static TypeTableEntry *ir_analyze_instruction_set_debug_safety(IrAnalyze *ira, |
| 12499 | 12571 | IrInstructionSetDebugSafety *set_debug_safety_instruction) |
| 12500 | 12572 | { |
| ... | ... | @@ -16165,10 +16237,6 @@ static TypeTableEntry *ir_analyze_instruction_nocast(IrAnalyze *ira, IrInstructi |
| 16165 | 16237 | return ir_analyze_instruction_to_ptr_type(ira, (IrInstructionToPtrType *)instruction); |
| 16166 | 16238 | case IrInstructionIdPtrTypeChild: |
| 16167 | 16239 | return ir_analyze_instruction_ptr_type_child(ira, (IrInstructionPtrTypeChild *)instruction); |
| 16168 | case IrInstructionIdSetGlobalSection: | |
| 16169 | return ir_analyze_instruction_set_global_section(ira, (IrInstructionSetGlobalSection *)instruction); | |
| 16170 | case IrInstructionIdSetGlobalLinkage: | |
| 16171 | return ir_analyze_instruction_set_global_linkage(ira, (IrInstructionSetGlobalLinkage *)instruction); | |
| 16172 | 16240 | case IrInstructionIdSetDebugSafety: |
| 16173 | 16241 | return ir_analyze_instruction_set_debug_safety(ira, (IrInstructionSetDebugSafety *)instruction); |
| 16174 | 16242 | case IrInstructionIdSetFloatMode: |
| ... | ... | @@ -16311,6 +16379,8 @@ static TypeTableEntry *ir_analyze_instruction_nocast(IrAnalyze *ira, IrInstructi |
| 16311 | 16379 | return ir_analyze_instruction_arg_type(ira, (IrInstructionArgType *)instruction); |
| 16312 | 16380 | case IrInstructionIdTagType: |
| 16313 | 16381 | return ir_analyze_instruction_tag_type(ira, (IrInstructionTagType *)instruction); |
| 16382 | case IrInstructionIdExport: | |
| 16383 | return ir_analyze_instruction_export(ira, (IrInstructionExport *)instruction); | |
| 16314 | 16384 | } |
| 16315 | 16385 | zig_unreachable(); |
| 16316 | 16386 | } |
| ... | ... | @@ -16418,12 +16488,11 @@ bool ir_has_side_effects(IrInstruction *instruction) { |
| 16418 | 16488 | case IrInstructionIdOverflowOp: // TODO when we support multiple returns this can be side effect free |
| 16419 | 16489 | case IrInstructionIdCheckSwitchProngs: |
| 16420 | 16490 | case IrInstructionIdCheckStatementIsVoid: |
| 16421 | case IrInstructionIdSetGlobalSection: | |
| 16422 | case IrInstructionIdSetGlobalLinkage: | |
| 16423 | 16491 | case IrInstructionIdPanic: |
| 16424 | 16492 | case IrInstructionIdSetEvalBranchQuota: |
| 16425 | 16493 | case IrInstructionIdPtrTypeOf: |
| 16426 | 16494 | case IrInstructionIdSetAlignStack: |
| 16495 | case IrInstructionIdExport: | |
| 16427 | 16496 | return true; |
| 16428 | 16497 | case IrInstructionIdPhi: |
| 16429 | 16498 | case IrInstructionIdUnOp: |
src/ir_print.cpp+21-19| ... | ... | @@ -899,19 +899,6 @@ static void ir_print_ptr_type_of(IrPrint *irp, IrInstructionPtrTypeOf *instructi |
| 899 | 899 | ir_print_other_instruction(irp, instruction->child_type); |
| 900 | 900 | } |
| 901 | 901 | |
| 902 | static void ir_print_set_global_section(IrPrint *irp, IrInstructionSetGlobalSection *instruction) { | |
| 903 | fprintf(irp->f, "@setGlobalSection(%s,", buf_ptr(instruction->tld->name)); | |
| 904 | ir_print_other_instruction(irp, instruction->value); | |
| 905 | fprintf(irp->f, ")"); | |
| 906 | } | |
| 907 | ||
| 908 | static void ir_print_set_global_linkage(IrPrint *irp, IrInstructionSetGlobalLinkage *instruction) { | |
| 909 | fprintf(irp->f, "@setGlobalLinkage(%s,", buf_ptr(instruction->tld->name)); | |
| 910 | ir_print_other_instruction(irp, instruction->value); | |
| 911 | fprintf(irp->f, ")"); | |
| 912 | } | |
| 913 | ||
| 914 | ||
| 915 | 902 | static void ir_print_decl_ref(IrPrint *irp, IrInstructionDeclRef *instruction) { |
| 916 | 903 | const char *ptr_str = instruction->lval.is_ptr ? "ptr " : ""; |
| 917 | 904 | const char *const_str = instruction->lval.is_const ? "const " : ""; |
| ... | ... | @@ -991,6 +978,24 @@ static void ir_print_enum_tag_type(IrPrint *irp, IrInstructionTagType *instructi |
| 991 | 978 | fprintf(irp->f, ")"); |
| 992 | 979 | } |
| 993 | 980 | |
| 981 | static void ir_print_export(IrPrint *irp, IrInstructionExport *instruction) { | |
| 982 | if (instruction->linkage == nullptr) { | |
| 983 | fprintf(irp->f, "@export("); | |
| 984 | ir_print_other_instruction(irp, instruction->name); | |
| 985 | fprintf(irp->f, ","); | |
| 986 | ir_print_other_instruction(irp, instruction->target); | |
| 987 | fprintf(irp->f, ")"); | |
| 988 | } else { | |
| 989 | fprintf(irp->f, "@exportWithLinkage("); | |
| 990 | ir_print_other_instruction(irp, instruction->name); | |
| 991 | fprintf(irp->f, ","); | |
| 992 | ir_print_other_instruction(irp, instruction->target); | |
| 993 | fprintf(irp->f, ","); | |
| 994 | ir_print_other_instruction(irp, instruction->linkage); | |
| 995 | fprintf(irp->f, ")"); | |
| 996 | } | |
| 997 | } | |
| 998 | ||
| 994 | 999 | |
| 995 | 1000 | static void ir_print_instruction(IrPrint *irp, IrInstruction *instruction) { |
| 996 | 1001 | ir_print_prefix(irp, instruction); |
| ... | ... | @@ -1267,12 +1272,6 @@ static void ir_print_instruction(IrPrint *irp, IrInstruction *instruction) { |
| 1267 | 1272 | case IrInstructionIdPtrTypeOf: |
| 1268 | 1273 | ir_print_ptr_type_of(irp, (IrInstructionPtrTypeOf *)instruction); |
| 1269 | 1274 | break; |
| 1270 | case IrInstructionIdSetGlobalSection: | |
| 1271 | ir_print_set_global_section(irp, (IrInstructionSetGlobalSection *)instruction); | |
| 1272 | break; | |
| 1273 | case IrInstructionIdSetGlobalLinkage: | |
| 1274 | ir_print_set_global_linkage(irp, (IrInstructionSetGlobalLinkage *)instruction); | |
| 1275 | break; | |
| 1276 | 1275 | case IrInstructionIdDeclRef: |
| 1277 | 1276 | ir_print_decl_ref(irp, (IrInstructionDeclRef *)instruction); |
| 1278 | 1277 | break; |
| ... | ... | @@ -1306,6 +1305,9 @@ static void ir_print_instruction(IrPrint *irp, IrInstruction *instruction) { |
| 1306 | 1305 | case IrInstructionIdTagType: |
| 1307 | 1306 | ir_print_enum_tag_type(irp, (IrInstructionTagType *)instruction); |
| 1308 | 1307 | break; |
| 1308 | case IrInstructionIdExport: | |
| 1309 | ir_print_export(irp, (IrInstructionExport *)instruction); | |
| 1310 | break; | |
| 1309 | 1311 | } |
| 1310 | 1312 | fprintf(irp->f, "\n"); |
| 1311 | 1313 | } |
src/parser.cpp+20-8| ... | ... | @@ -1600,6 +1600,14 @@ static AstNode *ast_parse_variable_declaration_expr(ParseContext *pc, size_t *to |
| 1600 | 1600 | next_token = &pc->tokens->at(*token_index); |
| 1601 | 1601 | } |
| 1602 | 1602 | |
| 1603 | if (next_token->id == TokenIdKeywordSection) { | |
| 1604 | *token_index += 1; | |
| 1605 | ast_eat_token(pc, token_index, TokenIdLParen); | |
| 1606 | node->data.variable_declaration.section_expr = ast_parse_expression(pc, token_index, true); | |
| 1607 | ast_eat_token(pc, token_index, TokenIdRParen); | |
| 1608 | next_token = &pc->tokens->at(*token_index); | |
| 1609 | } | |
| 1610 | ||
| 1603 | 1611 | if (next_token->id == TokenIdEq) { |
| 1604 | 1612 | *token_index += 1; |
| 1605 | 1613 | node->data.variable_declaration.expr = ast_parse_expression(pc, token_index, true); |
| ... | ... | @@ -2144,7 +2152,7 @@ static bool statement_terminates_without_semicolon(AstNode *node) { |
| 2144 | 2152 | |
| 2145 | 2153 | /* |
| 2146 | 2154 | Block = "{" many(Statement) option(Expression) "}" |
| 2147 | Statement = Label | VariableDeclaration ";" | Defer(Block) | Defer(Expression) ";" | BlockExpression(Block) | Expression ";" | ";" | |
| 2155 | Statement = Label | VariableDeclaration ";" | Defer(Block) | Defer(Expression) ";" | BlockExpression(Block) | Expression ";" | ";" | ExportDecl | |
| 2148 | 2156 | */ |
| 2149 | 2157 | static AstNode *ast_parse_block(ParseContext *pc, size_t *token_index, bool mandatory) { |
| 2150 | 2158 | Token *last_token = &pc->tokens->at(*token_index); |
| ... | ... | @@ -2205,7 +2213,7 @@ static AstNode *ast_parse_block(ParseContext *pc, size_t *token_index, bool mand |
| 2205 | 2213 | } |
| 2206 | 2214 | |
| 2207 | 2215 | /* |
| 2208 | FnProto = option("coldcc" | "nakedcc" | "stdcallcc") "fn" option(Symbol) ParamDeclList option("align" "(" Expression ")") option("->" TypeExpr) | |
| 2216 | FnProto = option("coldcc" | "nakedcc" | "stdcallcc") "fn" option(Symbol) ParamDeclList option("align" "(" Expression ")") option("section" "(" Expression ")") option("-&gt;" TypeExpr) | |
| 2209 | 2217 | */ |
| 2210 | 2218 | static AstNode *ast_parse_fn_proto(ParseContext *pc, size_t *token_index, bool mandatory, VisibMod visib_mod) { |
| 2211 | 2219 | Token *first_token = &pc->tokens->at(*token_index); |
| ... | ... | @@ -2259,6 +2267,14 @@ static AstNode *ast_parse_fn_proto(ParseContext *pc, size_t *token_index, bool m |
| 2259 | 2267 | ast_eat_token(pc, token_index, TokenIdRParen); |
| 2260 | 2268 | next_token = &pc->tokens->at(*token_index); |
| 2261 | 2269 | } |
| 2270 | if (next_token->id == TokenIdKeywordSection) { | |
| 2271 | *token_index += 1; | |
| 2272 | ast_eat_token(pc, token_index, TokenIdLParen); | |
| 2273 | ||
| 2274 | node->data.fn_proto.section_expr = ast_parse_expression(pc, token_index, true); | |
| 2275 | ast_eat_token(pc, token_index, TokenIdRParen); | |
| 2276 | next_token = &pc->tokens->at(*token_index); | |
| 2277 | } | |
| 2262 | 2278 | if (next_token->id == TokenIdArrow) { |
| 2263 | 2279 | *token_index += 1; |
| 2264 | 2280 | node->data.fn_proto.return_type = ast_parse_type_expr(pc, token_index, false); |
| ... | ... | @@ -2447,9 +2463,6 @@ static AstNode *ast_parse_container_decl(ParseContext *pc, size_t *token_index, |
| 2447 | 2463 | if (visib_tok->id == TokenIdKeywordPub) { |
| 2448 | 2464 | *token_index += 1; |
| 2449 | 2465 | visib_mod = VisibModPub; |
| 2450 | } else if (visib_tok->id == TokenIdKeywordExport) { | |
| 2451 | *token_index += 1; | |
| 2452 | visib_mod = VisibModExport; | |
| 2453 | 2466 | } else { |
| 2454 | 2467 | visib_mod = VisibModPrivate; |
| 2455 | 2468 | } |
| ... | ... | @@ -2580,9 +2593,6 @@ static void ast_parse_top_level_decls(ParseContext *pc, size_t *token_index, Zig |
| 2580 | 2593 | if (visib_tok->id == TokenIdKeywordPub) { |
| 2581 | 2594 | *token_index += 1; |
| 2582 | 2595 | visib_mod = VisibModPub; |
| 2583 | } else if (visib_tok->id == TokenIdKeywordExport) { | |
| 2584 | *token_index += 1; | |
| 2585 | visib_mod = VisibModExport; | |
| 2586 | 2596 | } else { |
| 2587 | 2597 | visib_mod = VisibModPrivate; |
| 2588 | 2598 | } |
| ... | ... | @@ -2669,6 +2679,7 @@ void ast_visit_node_children(AstNode *node, void (*visit)(AstNode **, void *cont |
| 2669 | 2679 | visit_field(&node->data.fn_proto.return_type, visit, context); |
| 2670 | 2680 | visit_node_list(&node->data.fn_proto.params, visit, context); |
| 2671 | 2681 | visit_field(&node->data.fn_proto.align_expr, visit, context); |
| 2682 | visit_field(&node->data.fn_proto.section_expr, visit, context); | |
| 2672 | 2683 | break; |
| 2673 | 2684 | case NodeTypeFnDef: |
| 2674 | 2685 | visit_field(&node->data.fn_def.fn_proto, visit, context); |
| ... | ... | @@ -2696,6 +2707,7 @@ void ast_visit_node_children(AstNode *node, void (*visit)(AstNode **, void *cont |
| 2696 | 2707 | visit_field(&node->data.variable_declaration.type, visit, context); |
| 2697 | 2708 | visit_field(&node->data.variable_declaration.expr, visit, context); |
| 2698 | 2709 | visit_field(&node->data.variable_declaration.align_expr, visit, context); |
| 2710 | visit_field(&node->data.variable_declaration.section_expr, visit, context); | |
| 2699 | 2711 | break; |
| 2700 | 2712 | case NodeTypeErrorValueDecl: |
| 2701 | 2713 | // none |
src/tokenizer.cpp+2-2| ... | ... | @@ -119,7 +119,6 @@ static const struct ZigKeyword zig_keywords[] = { |
| 119 | 119 | {"else", TokenIdKeywordElse}, |
| 120 | 120 | {"enum", TokenIdKeywordEnum}, |
| 121 | 121 | {"error", TokenIdKeywordError}, |
| 122 | {"export", TokenIdKeywordExport}, | |
| 123 | 122 | {"extern", TokenIdKeywordExtern}, |
| 124 | 123 | {"false", TokenIdKeywordFalse}, |
| 125 | 124 | {"fn", TokenIdKeywordFn}, |
| ... | ... | @@ -134,6 +133,7 @@ static const struct ZigKeyword zig_keywords[] = { |
| 134 | 133 | {"packed", TokenIdKeywordPacked}, |
| 135 | 134 | {"pub", TokenIdKeywordPub}, |
| 136 | 135 | {"return", TokenIdKeywordReturn}, |
| 136 | {"section", TokenIdKeywordSection}, | |
| 137 | 137 | {"stdcallcc", TokenIdKeywordStdcallCC}, |
| 138 | 138 | {"struct", TokenIdKeywordStruct}, |
| 139 | 139 | {"switch", TokenIdKeywordSwitch}, |
| ... | ... | @@ -1518,7 +1518,6 @@ const char * token_name(TokenId id) { |
| 1518 | 1518 | case TokenIdKeywordElse: return "else"; |
| 1519 | 1519 | case TokenIdKeywordEnum: return "enum"; |
| 1520 | 1520 | case TokenIdKeywordError: return "error"; |
| 1521 | case TokenIdKeywordExport: return "export"; | |
| 1522 | 1521 | case TokenIdKeywordExtern: return "extern"; |
| 1523 | 1522 | case TokenIdKeywordFalse: return "false"; |
| 1524 | 1523 | case TokenIdKeywordFn: return "fn"; |
| ... | ... | @@ -1533,6 +1532,7 @@ const char * token_name(TokenId id) { |
| 1533 | 1532 | case TokenIdKeywordPacked: return "packed"; |
| 1534 | 1533 | case TokenIdKeywordPub: return "pub"; |
| 1535 | 1534 | case TokenIdKeywordReturn: return "return"; |
| 1535 | case TokenIdKeywordSection: return "section"; | |
| 1536 | 1536 | case TokenIdKeywordStdcallCC: return "stdcallcc"; |
| 1537 | 1537 | case TokenIdKeywordStruct: return "struct"; |
| 1538 | 1538 | case TokenIdKeywordSwitch: return "switch"; |
src/tokenizer.hpp+1-1| ... | ... | @@ -47,6 +47,7 @@ enum TokenId { |
| 47 | 47 | TokenIdFloatLiteral, |
| 48 | 48 | TokenIdIntLiteral, |
| 49 | 49 | TokenIdKeywordAlign, |
| 50 | TokenIdKeywordSection, | |
| 50 | 51 | TokenIdKeywordAnd, |
| 51 | 52 | TokenIdKeywordAsm, |
| 52 | 53 | TokenIdKeywordBreak, |
| ... | ... | @@ -58,7 +59,6 @@ enum TokenId { |
| 58 | 59 | TokenIdKeywordElse, |
| 59 | 60 | TokenIdKeywordEnum, |
| 60 | 61 | TokenIdKeywordError, |
| 61 | TokenIdKeywordExport, | |
| 62 | 62 | TokenIdKeywordExtern, |
| 63 | 63 | TokenIdKeywordFalse, |
| 64 | 64 | TokenIdKeywordFn, |
src/translate_c.cpp+2-4| ... | ... | @@ -73,7 +73,6 @@ struct Context { |
| 73 | 73 | ImportTableEntry *import; |
| 74 | 74 | ZigList<ErrorMsg *> *errors; |
| 75 | 75 | VisibMod visib_mod; |
| 76 | VisibMod export_visib_mod; | |
| 77 | 76 | AstNode *root; |
| 78 | 77 | HashMap<const void *, AstNode *, ptr_hash, ptr_eq> decl_table; |
| 79 | 78 | HashMap<Buf *, AstNode *, buf_hash, buf_eql_buf> macro_table; |
| ... | ... | @@ -3251,7 +3250,8 @@ static void visit_fn_decl(Context *c, const FunctionDecl *fn_decl) { |
| 3251 | 3250 | |
| 3252 | 3251 | StorageClass sc = fn_decl->getStorageClass(); |
| 3253 | 3252 | if (sc == SC_None) { |
| 3254 | proto_node->data.fn_proto.visib_mod = fn_decl->hasBody() ? c->export_visib_mod : c->visib_mod; | |
| 3253 | // TODO add export decl | |
| 3254 | proto_node->data.fn_proto.visib_mod = c->visib_mod; | |
| 3255 | 3255 | } else if (sc == SC_Extern || sc == SC_Static) { |
| 3256 | 3256 | proto_node->data.fn_proto.visib_mod = c->visib_mod; |
| 3257 | 3257 | } else if (sc == SC_PrivateExtern) { |
| ... | ... | @@ -4274,10 +4274,8 @@ int parse_h_file(ImportTableEntry *import, ZigList<ErrorMsg *> *errors, const ch |
| 4274 | 4274 | c->errors = errors; |
| 4275 | 4275 | if (buf_ends_with_str(buf_create_from_str(target_file), ".h")) { |
| 4276 | 4276 | c->visib_mod = VisibModPub; |
| 4277 | c->export_visib_mod = VisibModPub; | |
| 4278 | 4277 | } else { |
| 4279 | 4278 | c->visib_mod = VisibModPub; |
| 4280 | c->export_visib_mod = VisibModExport; | |
| 4281 | 4279 | } |
| 4282 | 4280 | c->decl_table.init(8); |
| 4283 | 4281 | c->macro_table.init(8); |
std/debug.zig-2| ... | ... | @@ -96,8 +96,6 @@ const WHITE = "\x1b[37;1m"; |
| 96 | 96 | const DIM = "\x1b[2m"; |
| 97 | 97 | const RESET = "\x1b[0m"; |
| 98 | 98 | |
| 99 | pub var user_main_fn: ?fn() -> %void = null; | |
| 100 | ||
| 101 | 99 | error PathNotFound; |
| 102 | 100 | error InvalidDebugInfo; |
| 103 | 101 |
std/elf.zig+31-31| ... | ... | @@ -188,39 +188,39 @@ pub const Elf = struct { |
| 188 | 188 | if (elf.is_64) { |
| 189 | 189 | if (sh_entry_size != 64) return error.InvalidFormat; |
| 190 | 190 | |
| 191 | for (elf.section_headers) |*section| { | |
| 192 | section.name = %return in.readInt(elf.endian, u32); | |
| 193 | section.sh_type = %return in.readInt(elf.endian, u32); | |
| 194 | section.flags = %return in.readInt(elf.endian, u64); | |
| 195 | section.addr = %return in.readInt(elf.endian, u64); | |
| 196 | section.offset = %return in.readInt(elf.endian, u64); | |
| 197 | section.size = %return in.readInt(elf.endian, u64); | |
| 198 | section.link = %return in.readInt(elf.endian, u32); | |
| 199 | section.info = %return in.readInt(elf.endian, u32); | |
| 200 | section.addr_align = %return in.readInt(elf.endian, u64); | |
| 201 | section.ent_size = %return in.readInt(elf.endian, u64); | |
| 191 | for (elf.section_headers) |*elf_section| { | |
| 192 | elf_section.name = %return in.readInt(elf.endian, u32); | |
| 193 | elf_section.sh_type = %return in.readInt(elf.endian, u32); | |
| 194 | elf_section.flags = %return in.readInt(elf.endian, u64); | |
| 195 | elf_section.addr = %return in.readInt(elf.endian, u64); | |
| 196 | elf_section.offset = %return in.readInt(elf.endian, u64); | |
| 197 | elf_section.size = %return in.readInt(elf.endian, u64); | |
| 198 | elf_section.link = %return in.readInt(elf.endian, u32); | |
| 199 | elf_section.info = %return in.readInt(elf.endian, u32); | |
| 200 | elf_section.addr_align = %return in.readInt(elf.endian, u64); | |
| 201 | elf_section.ent_size = %return in.readInt(elf.endian, u64); | |
| 202 | 202 | } |
| 203 | 203 | } else { |
| 204 | 204 | if (sh_entry_size != 40) return error.InvalidFormat; |
| 205 | 205 | |
| 206 | for (elf.section_headers) |*section| { | |
| 206 | for (elf.section_headers) |*elf_section| { | |
| 207 | 207 | // TODO (multiple occurences) allow implicit cast from %u32 -> %u64 ? |
| 208 | section.name = %return in.readInt(elf.endian, u32); | |
| 209 | section.sh_type = %return in.readInt(elf.endian, u32); | |
| 210 | section.flags = u64(%return in.readInt(elf.endian, u32)); | |
| 211 | section.addr = u64(%return in.readInt(elf.endian, u32)); | |
| 212 | section.offset = u64(%return in.readInt(elf.endian, u32)); | |
| 213 | section.size = u64(%return in.readInt(elf.endian, u32)); | |
| 214 | section.link = %return in.readInt(elf.endian, u32); | |
| 215 | section.info = %return in.readInt(elf.endian, u32); | |
| 216 | section.addr_align = u64(%return in.readInt(elf.endian, u32)); | |
| 217 | section.ent_size = u64(%return in.readInt(elf.endian, u32)); | |
| 208 | elf_section.name = %return in.readInt(elf.endian, u32); | |
| 209 | elf_section.sh_type = %return in.readInt(elf.endian, u32); | |
| 210 | elf_section.flags = u64(%return in.readInt(elf.endian, u32)); | |
| 211 | elf_section.addr = u64(%return in.readInt(elf.endian, u32)); | |
| 212 | elf_section.offset = u64(%return in.readInt(elf.endian, u32)); | |
| 213 | elf_section.size = u64(%return in.readInt(elf.endian, u32)); | |
| 214 | elf_section.link = %return in.readInt(elf.endian, u32); | |
| 215 | elf_section.info = %return in.readInt(elf.endian, u32); | |
| 216 | elf_section.addr_align = u64(%return in.readInt(elf.endian, u32)); | |
| 217 | elf_section.ent_size = u64(%return in.readInt(elf.endian, u32)); | |
| 218 | 218 | } |
| 219 | 219 | } |
| 220 | 220 | |
| 221 | for (elf.section_headers) |*section| { | |
| 222 | if (section.sh_type != SHT_NOBITS) { | |
| 223 | const file_end_offset = %return math.add(u64, section.offset, section.size); | |
| 221 | for (elf.section_headers) |*elf_section| { | |
| 222 | if (elf_section.sh_type != SHT_NOBITS) { | |
| 223 | const file_end_offset = %return math.add(u64, elf_section.offset, elf_section.size); | |
| 224 | 224 | if (stream_end < file_end_offset) return error.InvalidFormat; |
| 225 | 225 | } |
| 226 | 226 | } |
| ... | ... | @@ -243,10 +243,10 @@ pub const Elf = struct { |
| 243 | 243 | var file_stream = io.FileInStream.init(elf.in_file); |
| 244 | 244 | const in = &file_stream.stream; |
| 245 | 245 | |
| 246 | for (elf.section_headers) |*section| { | |
| 247 | if (section.sh_type == SHT_NULL) continue; | |
| 246 | for (elf.section_headers) |*elf_section| { | |
| 247 | if (elf_section.sh_type == SHT_NULL) continue; | |
| 248 | 248 | |
| 249 | const name_offset = elf.string_section.offset + section.name; | |
| 249 | const name_offset = elf.string_section.offset + elf_section.name; | |
| 250 | 250 | %return elf.in_file.seekTo(name_offset); |
| 251 | 251 | |
| 252 | 252 | for (name) |expected_c| { |
| ... | ... | @@ -256,7 +256,7 @@ pub const Elf = struct { |
| 256 | 256 | |
| 257 | 257 | { |
| 258 | 258 | const null_byte = %return in.readByte(); |
| 259 | if (null_byte == 0) return section; | |
| 259 | if (null_byte == 0) return elf_section; | |
| 260 | 260 | } |
| 261 | 261 | |
| 262 | 262 | next_section: |
| ... | ... | @@ -265,7 +265,7 @@ pub const Elf = struct { |
| 265 | 265 | return null; |
| 266 | 266 | } |
| 267 | 267 | |
| 268 | pub fn seekToSection(elf: &Elf, section: &SectionHeader) -> %void { | |
| 269 | %return elf.in_file.seekTo(section.offset); | |
| 268 | pub fn seekToSection(elf: &Elf, elf_section: &SectionHeader) -> %void { | |
| 269 | %return elf.in_file.seekTo(elf_section.offset); | |
| 270 | 270 | } |
| 271 | 271 | }; |
std/mem.zig+1| ... | ... | @@ -4,6 +4,7 @@ const math = @import("math/index.zig"); |
| 4 | 4 | const builtin = @import("builtin"); |
| 5 | 5 | |
| 6 | 6 | pub const Cmp = math.Cmp; |
| 7 | error OutOfMemory; | |
| 7 | 8 | |
| 8 | 9 | pub const Allocator = struct { |
| 9 | 10 | /// Allocate byte_count bytes and return them in a slice, with the |
std/os/linux.zig-22| ... | ... | @@ -651,28 +651,6 @@ pub const iovec = extern struct { |
| 651 | 651 | iov_len: usize, |
| 652 | 652 | }; |
| 653 | 653 | |
| 654 | // | |
| 655 | //const IF_NAMESIZE = 16; | |
| 656 | // | |
| 657 | //export struct ifreq { | |
| 658 | // ifrn_name: [IF_NAMESIZE]u8, | |
| 659 | // union { | |
| 660 | // ifru_addr: sockaddr, | |
| 661 | // ifru_dstaddr: sockaddr, | |
| 662 | // ifru_broadaddr: sockaddr, | |
| 663 | // ifru_netmask: sockaddr, | |
| 664 | // ifru_hwaddr: sockaddr, | |
| 665 | // ifru_flags: i16, | |
| 666 | // ifru_ivalue: i32, | |
| 667 | // ifru_mtu: i32, | |
| 668 | // ifru_map: ifmap, | |
| 669 | // ifru_slave: [IF_NAMESIZE]u8, | |
| 670 | // ifru_newname: [IF_NAMESIZE]u8, | |
| 671 | // ifru_data: &u8, | |
| 672 | // } ifr_ifru; | |
| 673 | //} | |
| 674 | // | |
| 675 | ||
| 676 | 654 | pub fn getsockname(fd: i32, noalias addr: &sockaddr, noalias len: &socklen_t) -> usize { |
| 677 | 655 | arch.syscall3(arch.SYS_getsockname, usize(fd), @ptrToInt(addr), @ptrToInt(len)) |
| 678 | 656 | } |
std/os/linux_i386.zig-10| ... | ... | @@ -502,13 +502,3 @@ pub nakedcc fn restore_rt() { |
| 502 | 502 | : [number] "{eax}" (usize(SYS_rt_sigreturn)) |
| 503 | 503 | : "rcx", "r11") |
| 504 | 504 | } |
| 505 | ||
| 506 | export struct msghdr { | |
| 507 | msg_name: &u8, | |
| 508 | msg_namelen: socklen_t, | |
| 509 | msg_iov: &iovec, | |
| 510 | msg_iovlen: i32, | |
| 511 | msg_control: &u8, | |
| 512 | msg_controllen: socklen_t, | |
| 513 | msg_flags: i32, | |
| 514 | } |
std/special/bootstrap.zig+11-24| ... | ... | @@ -5,20 +5,19 @@ const root = @import("@root"); |
| 5 | 5 | const std = @import("std"); |
| 6 | 6 | const builtin = @import("builtin"); |
| 7 | 7 | |
| 8 | const is_windows = builtin.os == builtin.Os.windows; | |
| 9 | const want_main_symbol = builtin.link_libc; | |
| 10 | const want_start_symbol = !want_main_symbol and !is_windows; | |
| 11 | const want_WinMainCRTStartup = is_windows and !builtin.link_libc; | |
| 12 | ||
| 13 | 8 | var argc_ptr: &usize = undefined; |
| 14 | 9 | |
| 15 | ||
| 16 | export nakedcc fn _start() -> noreturn { | |
| 17 | if (!want_start_symbol) { | |
| 18 | @setGlobalLinkage(_start, builtin.GlobalLinkage.Internal); | |
| 19 | unreachable; | |
| 10 | comptime { | |
| 11 | if (builtin.link_libc) { | |
| 12 | @export("main", main); | |
| 13 | } else if (builtin.os == builtin.Os.windows) { | |
| 14 | @export("WinMainCRTStartup", WinMainCRTStartup); | |
| 15 | } else { | |
| 16 | @export("_start", _start); | |
| 20 | 17 | } |
| 18 | } | |
| 21 | 19 | |
| 20 | nakedcc fn _start() -> noreturn { | |
| 22 | 21 | switch (builtin.arch) { |
| 23 | 22 | builtin.Arch.x86_64 => { |
| 24 | 23 | argc_ptr = asm("lea (%%rsp), %[argc]": [argc] "=r" (-> &usize)); |
| ... | ... | @@ -33,14 +32,9 @@ export nakedcc fn _start() -> noreturn { |
| 33 | 32 | @noInlineCall(posixCallMainAndExit); |
| 34 | 33 | } |
| 35 | 34 | |
| 36 | export fn WinMainCRTStartup() -> noreturn { | |
| 37 | if (!want_WinMainCRTStartup) { | |
| 38 | @setGlobalLinkage(WinMainCRTStartup, builtin.GlobalLinkage.Internal); | |
| 39 | unreachable; | |
| 40 | } | |
| 35 | extern fn WinMainCRTStartup() -> noreturn { | |
| 41 | 36 | @setAlignStack(16); |
| 42 | 37 | |
| 43 | std.debug.user_main_fn = root.main; | |
| 44 | 38 | root.main() %% std.os.windows.ExitProcess(1); |
| 45 | 39 | std.os.windows.ExitProcess(0); |
| 46 | 40 | } |
| ... | ... | @@ -60,17 +54,10 @@ fn callMain(argc: usize, argv: &&u8, envp: &?&u8) -> %void { |
| 60 | 54 | while (envp[env_count] != null) : (env_count += 1) {} |
| 61 | 55 | std.os.posix_environ_raw = @ptrCast(&&u8, envp)[0..env_count]; |
| 62 | 56 | |
| 63 | std.debug.user_main_fn = root.main; | |
| 64 | ||
| 65 | 57 | return root.main(); |
| 66 | 58 | } |
| 67 | 59 | |
| 68 | export fn main(c_argc: i32, c_argv: &&u8, c_envp: &?&u8) -> i32 { | |
| 69 | if (!want_main_symbol) { | |
| 70 | @setGlobalLinkage(main, builtin.GlobalLinkage.Internal); | |
| 71 | unreachable; | |
| 72 | } | |
| 73 | ||
| 60 | extern fn main(c_argc: i32, c_argv: &&u8, c_envp: &?&u8) -> i32 { | |
| 74 | 61 | callMain(usize(c_argc), c_argv, c_envp) %% return 1; |
| 75 | 62 | return 0; |
| 76 | 63 | } |
std/special/bootstrap_lib.zig+5-1| ... | ... | @@ -2,7 +2,11 @@ |
| 2 | 2 | |
| 3 | 3 | const std = @import("std"); |
| 4 | 4 | |
| 5 | export stdcallcc fn _DllMainCRTStartup(hinstDLL: std.os.windows.HINSTANCE, fdwReason: std.os.windows.DWORD, | |
| 5 | comptime { | |
| 6 | @export("_DllMainCRTStartup", _DllMainCRTStartup); | |
| 7 | } | |
| 8 | ||
| 9 | stdcallcc fn _DllMainCRTStartup(hinstDLL: std.os.windows.HINSTANCE, fdwReason: std.os.windows.DWORD, | |
| 6 | 10 | lpReserved: std.os.windows.LPVOID) -> std.os.windows.BOOL |
| 7 | 11 | { |
| 8 | 12 | return std.os.windows.TRUE; |
std/special/builtin.zig+23-13| ... | ... | @@ -13,10 +13,24 @@ pub coldcc fn panic(msg: []const u8) -> noreturn { |
| 13 | 13 | } |
| 14 | 14 | } |
| 15 | 15 | |
| 16 | comptime { | |
| 17 | @export("memset", memset); | |
| 18 | @export("memcpy", memcpy); | |
| 19 | @export("fmodf", fmodf); | |
| 20 | @export("fmod", fmod); | |
| 21 | @export("floorf", floorf); | |
| 22 | @export("ceilf", ceilf); | |
| 23 | @export("floor", floor); | |
| 24 | @export("ceil", ceil); | |
| 25 | if (builtin.mode != builtin.Mode.ReleaseFast and builtin.os != builtin.Os.windows) { | |
| 26 | @export("__stack_chk_fail", __stack_chk_fail); | |
| 27 | } | |
| 28 | } | |
| 29 | ||
| 16 | 30 | // Note that memset does not return `dest`, like the libc API. |
| 17 | 31 | // The semantics of memset is dictated by the corresponding |
| 18 | 32 | // LLVM intrinsics, not by the libc API. |
| 19 | export fn memset(dest: ?&u8, c: u8, n: usize) { | |
| 33 | extern fn memset(dest: ?&u8, c: u8, n: usize) { | |
| 20 | 34 | @setDebugSafety(this, false); |
| 21 | 35 | |
| 22 | 36 | var index: usize = 0; |
| ... | ... | @@ -27,7 +41,7 @@ export fn memset(dest: ?&u8, c: u8, n: usize) { |
| 27 | 41 | // Note that memcpy does not return `dest`, like the libc API. |
| 28 | 42 | // The semantics of memcpy is dictated by the corresponding |
| 29 | 43 | // LLVM intrinsics, not by the libc API. |
| 30 | export fn memcpy(noalias dest: ?&u8, noalias src: ?&const u8, n: usize) { | |
| 44 | extern fn memcpy(noalias dest: ?&u8, noalias src: ?&const u8, n: usize) { | |
| 31 | 45 | @setDebugSafety(this, false); |
| 32 | 46 | |
| 33 | 47 | var index: usize = 0; |
| ... | ... | @@ -35,25 +49,21 @@ export fn memcpy(noalias dest: ?&u8, noalias src: ?&const u8, n: usize) { |
| 35 | 49 | (??dest)[index] = (??src)[index]; |
| 36 | 50 | } |
| 37 | 51 | |
| 38 | export fn __stack_chk_fail() -> noreturn { | |
| 39 | if (builtin.mode == builtin.Mode.ReleaseFast or builtin.os == builtin.Os.windows) { | |
| 40 | @setGlobalLinkage(__stack_chk_fail, builtin.GlobalLinkage.Internal); | |
| 41 | unreachable; | |
| 42 | } | |
| 52 | extern fn __stack_chk_fail() -> noreturn { | |
| 43 | 53 | @panic("stack smashing detected"); |
| 44 | 54 | } |
| 45 | 55 | |
| 46 | 56 | const math = @import("../math/index.zig"); |
| 47 | 57 | |
| 48 | export fn fmodf(x: f32, y: f32) -> f32 { generic_fmod(f32, x, y) } | |
| 49 | export fn fmod(x: f64, y: f64) -> f64 { generic_fmod(f64, x, y) } | |
| 58 | extern fn fmodf(x: f32, y: f32) -> f32 { generic_fmod(f32, x, y) } | |
| 59 | extern fn fmod(x: f64, y: f64) -> f64 { generic_fmod(f64, x, y) } | |
| 50 | 60 | |
| 51 | 61 | // TODO add intrinsics for these (and probably the double version too) |
| 52 | 62 | // and have the math stuff use the intrinsic. same as @mod and @rem |
| 53 | export fn floorf(x: f32) -> f32 { math.floor(x) } | |
| 54 | export fn ceilf(x: f32) -> f32 { math.ceil(x) } | |
| 55 | export fn floor(x: f64) -> f64 { math.floor(x) } | |
| 56 | export fn ceil(x: f64) -> f64 { math.ceil(x) } | |
| 63 | extern fn floorf(x: f32) -> f32 { math.floor(x) } | |
| 64 | extern fn ceilf(x: f32) -> f32 { math.ceil(x) } | |
| 65 | extern fn floor(x: f64) -> f64 { math.floor(x) } | |
| 66 | extern fn ceil(x: f64) -> f64 { math.ceil(x) } | |
| 57 | 67 | |
| 58 | 68 | fn generic_fmod(comptime T: type, x: T, y: T) -> T { |
| 59 | 69 | @setDebugSafety(this, false); |
std/special/compiler_rt/aulldiv.zig+54-65| ... | ... | @@ -1,66 +1,55 @@ |
| 1 | const builtin = @import("builtin"); | |
| 2 | const linkage = if (builtin.is_test) builtin.GlobalLinkage.Internal else builtin.GlobalLinkage.Strong; | |
| 3 | const is_win32 = builtin.os == builtin.Os.windows and builtin.arch == builtin.Arch.i386; | |
| 4 | ||
| 5 | export nakedcc fn _aulldiv() { | |
| 6 | if (is_win32) { | |
| 7 | @setDebugSafety(this, false); | |
| 8 | @setGlobalLinkage(_aulldiv, linkage); | |
| 9 | asm volatile ( | |
| 10 | \\.intel_syntax noprefix | |
| 11 | \\ | |
| 12 | \\ push ebx | |
| 13 | \\ push esi | |
| 14 | \\ mov eax,dword ptr [esp+18h] | |
| 15 | \\ or eax,eax | |
| 16 | \\ jne L1 | |
| 17 | \\ mov ecx,dword ptr [esp+14h] | |
| 18 | \\ mov eax,dword ptr [esp+10h] | |
| 19 | \\ xor edx,edx | |
| 20 | \\ div ecx | |
| 21 | \\ mov ebx,eax | |
| 22 | \\ mov eax,dword ptr [esp+0Ch] | |
| 23 | \\ div ecx | |
| 24 | \\ mov edx,ebx | |
| 25 | \\ jmp L2 | |
| 26 | \\ L1: | |
| 27 | \\ mov ecx,eax | |
| 28 | \\ mov ebx,dword ptr [esp+14h] | |
| 29 | \\ mov edx,dword ptr [esp+10h] | |
| 30 | \\ mov eax,dword ptr [esp+0Ch] | |
| 31 | \\ L3: | |
| 32 | \\ shr ecx,1 | |
| 33 | \\ rcr ebx,1 | |
| 34 | \\ shr edx,1 | |
| 35 | \\ rcr eax,1 | |
| 36 | \\ or ecx,ecx | |
| 37 | \\ jne L3 | |
| 38 | \\ div ebx | |
| 39 | \\ mov esi,eax | |
| 40 | \\ mul dword ptr [esp+18h] | |
| 41 | \\ mov ecx,eax | |
| 42 | \\ mov eax,dword ptr [esp+14h] | |
| 43 | \\ mul esi | |
| 44 | \\ add edx,ecx | |
| 45 | \\ jb L4 | |
| 46 | \\ cmp edx,dword ptr [esp+10h] | |
| 47 | \\ ja L4 | |
| 48 | \\ jb L5 | |
| 49 | \\ cmp eax,dword ptr [esp+0Ch] | |
| 50 | \\ jbe L5 | |
| 51 | \\ L4: | |
| 52 | \\ dec esi | |
| 53 | \\ L5: | |
| 54 | \\ xor edx,edx | |
| 55 | \\ mov eax,esi | |
| 56 | \\ L2: | |
| 57 | \\ pop esi | |
| 58 | \\ pop ebx | |
| 59 | \\ ret 10h | |
| 60 | ); | |
| 61 | unreachable; | |
| 62 | } | |
| 63 | ||
| 64 | @setGlobalLinkage(_aulldiv, builtin.GlobalLinkage.Internal); | |
| 65 | unreachable; | |
| 1 | pub nakedcc fn _aulldiv() { | |
| 2 | @setDebugSafety(this, false); | |
| 3 | asm volatile ( | |
| 4 | \\.intel_syntax noprefix | |
| 5 | \\ | |
| 6 | \\ push ebx | |
| 7 | \\ push esi | |
| 8 | \\ mov eax,dword ptr [esp+18h] | |
| 9 | \\ or eax,eax | |
| 10 | \\ jne L1 | |
| 11 | \\ mov ecx,dword ptr [esp+14h] | |
| 12 | \\ mov eax,dword ptr [esp+10h] | |
| 13 | \\ xor edx,edx | |
| 14 | \\ div ecx | |
| 15 | \\ mov ebx,eax | |
| 16 | \\ mov eax,dword ptr [esp+0Ch] | |
| 17 | \\ div ecx | |
| 18 | \\ mov edx,ebx | |
| 19 | \\ jmp L2 | |
| 20 | \\ L1: | |
| 21 | \\ mov ecx,eax | |
| 22 | \\ mov ebx,dword ptr [esp+14h] | |
| 23 | \\ mov edx,dword ptr [esp+10h] | |
| 24 | \\ mov eax,dword ptr [esp+0Ch] | |
| 25 | \\ L3: | |
| 26 | \\ shr ecx,1 | |
| 27 | \\ rcr ebx,1 | |
| 28 | \\ shr edx,1 | |
| 29 | \\ rcr eax,1 | |
| 30 | \\ or ecx,ecx | |
| 31 | \\ jne L3 | |
| 32 | \\ div ebx | |
| 33 | \\ mov esi,eax | |
| 34 | \\ mul dword ptr [esp+18h] | |
| 35 | \\ mov ecx,eax | |
| 36 | \\ mov eax,dword ptr [esp+14h] | |
| 37 | \\ mul esi | |
| 38 | \\ add edx,ecx | |
| 39 | \\ jb L4 | |
| 40 | \\ cmp edx,dword ptr [esp+10h] | |
| 41 | \\ ja L4 | |
| 42 | \\ jb L5 | |
| 43 | \\ cmp eax,dword ptr [esp+0Ch] | |
| 44 | \\ jbe L5 | |
| 45 | \\ L4: | |
| 46 | \\ dec esi | |
| 47 | \\ L5: | |
| 48 | \\ xor edx,edx | |
| 49 | \\ mov eax,esi | |
| 50 | \\ L2: | |
| 51 | \\ pop esi | |
| 52 | \\ pop ebx | |
| 53 | \\ ret 10h | |
| 54 | ); | |
| 66 | 55 | } |
std/special/compiler_rt/aullrem.zig+55-66| ... | ... | @@ -1,67 +1,56 @@ |
| 1 | const builtin = @import("builtin"); | |
| 2 | const linkage = if (builtin.is_test) builtin.GlobalLinkage.Internal else builtin.GlobalLinkage.Strong; | |
| 3 | const is_win32 = builtin.os == builtin.Os.windows and builtin.arch == builtin.Arch.i386; | |
| 4 | ||
| 5 | export nakedcc fn _aullrem() { | |
| 6 | if (is_win32) { | |
| 7 | @setDebugSafety(this, false); | |
| 8 | @setGlobalLinkage(_aullrem, linkage); | |
| 9 | asm volatile ( | |
| 10 | \\.intel_syntax noprefix | |
| 11 | \\ | |
| 12 | \\ push ebx | |
| 13 | \\ mov eax,dword ptr [esp+14h] | |
| 14 | \\ or eax,eax | |
| 15 | \\ jne L1a | |
| 16 | \\ mov ecx,dword ptr [esp+10h] | |
| 17 | \\ mov eax,dword ptr [esp+0Ch] | |
| 18 | \\ xor edx,edx | |
| 19 | \\ div ecx | |
| 20 | \\ mov eax,dword ptr [esp+8] | |
| 21 | \\ div ecx | |
| 22 | \\ mov eax,edx | |
| 23 | \\ xor edx,edx | |
| 24 | \\ jmp L2a | |
| 25 | \\ L1a: | |
| 26 | \\ mov ecx,eax | |
| 27 | \\ mov ebx,dword ptr [esp+10h] | |
| 28 | \\ mov edx,dword ptr [esp+0Ch] | |
| 29 | \\ mov eax,dword ptr [esp+8] | |
| 30 | \\ L3a: | |
| 31 | \\ shr ecx,1 | |
| 32 | \\ rcr ebx,1 | |
| 33 | \\ shr edx,1 | |
| 34 | \\ rcr eax,1 | |
| 35 | \\ or ecx,ecx | |
| 36 | \\ jne L3a | |
| 37 | \\ div ebx | |
| 38 | \\ mov ecx,eax | |
| 39 | \\ mul dword ptr [esp+14h] | |
| 40 | \\ xchg eax,ecx | |
| 41 | \\ mul dword ptr [esp+10h] | |
| 42 | \\ add edx,ecx | |
| 43 | \\ jb L4a | |
| 44 | \\ cmp edx,dword ptr [esp+0Ch] | |
| 45 | \\ ja L4a | |
| 46 | \\ jb L5a | |
| 47 | \\ cmp eax,dword ptr [esp+8] | |
| 48 | \\ jbe L5a | |
| 49 | \\ L4a: | |
| 50 | \\ sub eax,dword ptr [esp+10h] | |
| 51 | \\ sbb edx,dword ptr [esp+14h] | |
| 52 | \\ L5a: | |
| 53 | \\ sub eax,dword ptr [esp+8] | |
| 54 | \\ sbb edx,dword ptr [esp+0Ch] | |
| 55 | \\ neg edx | |
| 56 | \\ neg eax | |
| 57 | \\ sbb edx,0 | |
| 58 | \\ L2a: | |
| 59 | \\ pop ebx | |
| 60 | \\ ret 10h | |
| 61 | ); | |
| 62 | unreachable; | |
| 63 | } | |
| 64 | ||
| 65 | @setGlobalLinkage(_aullrem, builtin.GlobalLinkage.Internal); | |
| 66 | unreachable; | |
| 1 | pub nakedcc fn _aullrem() { | |
| 2 | @setDebugSafety(this, false); | |
| 3 | asm volatile ( | |
| 4 | \\.intel_syntax noprefix | |
| 5 | \\ | |
| 6 | \\ push ebx | |
| 7 | \\ mov eax,dword ptr [esp+14h] | |
| 8 | \\ or eax,eax | |
| 9 | \\ jne L1a | |
| 10 | \\ mov ecx,dword ptr [esp+10h] | |
| 11 | \\ mov eax,dword ptr [esp+0Ch] | |
| 12 | \\ xor edx,edx | |
| 13 | \\ div ecx | |
| 14 | \\ mov eax,dword ptr [esp+8] | |
| 15 | \\ div ecx | |
| 16 | \\ mov eax,edx | |
| 17 | \\ xor edx,edx | |
| 18 | \\ jmp L2a | |
| 19 | \\ L1a: | |
| 20 | \\ mov ecx,eax | |
| 21 | \\ mov ebx,dword ptr [esp+10h] | |
| 22 | \\ mov edx,dword ptr [esp+0Ch] | |
| 23 | \\ mov eax,dword ptr [esp+8] | |
| 24 | \\ L3a: | |
| 25 | \\ shr ecx,1 | |
| 26 | \\ rcr ebx,1 | |
| 27 | \\ shr edx,1 | |
| 28 | \\ rcr eax,1 | |
| 29 | \\ or ecx,ecx | |
| 30 | \\ jne L3a | |
| 31 | \\ div ebx | |
| 32 | \\ mov ecx,eax | |
| 33 | \\ mul dword ptr [esp+14h] | |
| 34 | \\ xchg eax,ecx | |
| 35 | \\ mul dword ptr [esp+10h] | |
| 36 | \\ add edx,ecx | |
| 37 | \\ jb L4a | |
| 38 | \\ cmp edx,dword ptr [esp+0Ch] | |
| 39 | \\ ja L4a | |
| 40 | \\ jb L5a | |
| 41 | \\ cmp eax,dword ptr [esp+8] | |
| 42 | \\ jbe L5a | |
| 43 | \\ L4a: | |
| 44 | \\ sub eax,dword ptr [esp+10h] | |
| 45 | \\ sbb edx,dword ptr [esp+14h] | |
| 46 | \\ L5a: | |
| 47 | \\ sub eax,dword ptr [esp+8] | |
| 48 | \\ sbb edx,dword ptr [esp+0Ch] | |
| 49 | \\ neg edx | |
| 50 | \\ neg eax | |
| 51 | \\ sbb edx,0 | |
| 52 | \\ L2a: | |
| 53 | \\ pop ebx | |
| 54 | \\ ret 10h | |
| 55 | ); | |
| 67 | 56 | } |
std/special/compiler_rt/comparetf2.zig+3-42| ... | ... | @@ -20,11 +20,9 @@ const infRep = exponentMask; |
| 20 | 20 | |
| 21 | 21 | const builtin = @import("builtin"); |
| 22 | 22 | const is_test = builtin.is_test; |
| 23 | const linkage = @import("index.zig").linkage; | |
| 24 | 23 | |
| 25 | export fn __letf2(a: f128, b: f128) -> c_int { | |
| 24 | pub extern fn __letf2(a: f128, b: f128) -> c_int { | |
| 26 | 25 | @setDebugSafety(this, is_test); |
| 27 | @setGlobalLinkage(__letf2, linkage); | |
| 28 | 26 | |
| 29 | 27 | const aInt = @bitCast(rep_t, a); |
| 30 | 28 | const bInt = @bitCast(rep_t, b); |
| ... | ... | @@ -63,14 +61,6 @@ export fn __letf2(a: f128, b: f128) -> c_int { |
| 63 | 61 | }; |
| 64 | 62 | } |
| 65 | 63 | |
| 66 | // Alias for libgcc compatibility | |
| 67 | // TODO https://github.com/zig-lang/zig/issues/420 | |
| 68 | export fn __cmptf2(a: f128, b: f128) -> c_int { | |
| 69 | @setGlobalLinkage(__cmptf2, linkage); | |
| 70 | @setDebugSafety(this, is_test); | |
| 71 | return __letf2(a, b); | |
| 72 | } | |
| 73 | ||
| 74 | 64 | // TODO https://github.com/zig-lang/zig/issues/305 |
| 75 | 65 | // and then make the return types of some of these functions the enum instead of c_int |
| 76 | 66 | const GE_LESS = c_int(-1); |
| ... | ... | @@ -78,8 +68,7 @@ const GE_EQUAL = c_int(0); |
| 78 | 68 | const GE_GREATER = c_int(1); |
| 79 | 69 | const GE_UNORDERED = c_int(-1); // Note: different from LE_UNORDERED |
| 80 | 70 | |
| 81 | export fn __getf2(a: f128, b: f128) -> c_int { | |
| 82 | @setGlobalLinkage(__getf2, linkage); | |
| 71 | pub extern fn __getf2(a: f128, b: f128) -> c_int { | |
| 83 | 72 | @setDebugSafety(this, is_test); |
| 84 | 73 | |
| 85 | 74 | const aInt = @bitCast(srep_t, a); |
| ... | ... | @@ -108,38 +97,10 @@ export fn __getf2(a: f128, b: f128) -> c_int { |
| 108 | 97 | }; |
| 109 | 98 | } |
| 110 | 99 | |
| 111 | export fn __unordtf2(a: f128, b: f128) -> c_int { | |
| 112 | @setGlobalLinkage(__unordtf2, linkage); | |
| 100 | pub extern fn __unordtf2(a: f128, b: f128) -> c_int { | |
| 113 | 101 | @setDebugSafety(this, is_test); |
| 114 | 102 | |
| 115 | 103 | const aAbs = @bitCast(rep_t, a) & absMask; |
| 116 | 104 | const bAbs = @bitCast(rep_t, b) & absMask; |
| 117 | 105 | return c_int(aAbs > infRep or bAbs > infRep); |
| 118 | 106 | } |
| 119 | ||
| 120 | // The following are alternative names for the preceding routines. | |
| 121 | // TODO use aliases https://github.com/zig-lang/zig/issues/462 | |
| 122 | ||
| 123 | export fn __eqtf2(a: f128, b: f128) -> c_int { | |
| 124 | @setGlobalLinkage(__eqtf2, linkage); | |
| 125 | @setDebugSafety(this, is_test); | |
| 126 | return __letf2(a, b); | |
| 127 | } | |
| 128 | ||
| 129 | export fn __lttf2(a: f128, b: f128) -> c_int { | |
| 130 | @setGlobalLinkage(__lttf2, linkage); | |
| 131 | @setDebugSafety(this, is_test); | |
| 132 | return __letf2(a, b); | |
| 133 | } | |
| 134 | ||
| 135 | export fn __netf2(a: f128, b: f128) -> c_int { | |
| 136 | @setGlobalLinkage(__netf2, linkage); | |
| 137 | @setDebugSafety(this, is_test); | |
| 138 | return __letf2(a, b); | |
| 139 | } | |
| 140 | ||
| 141 | export fn __gttf2(a: f128, b: f128) -> c_int { | |
| 142 | @setGlobalLinkage(__gttf2, linkage); | |
| 143 | @setDebugSafety(this, is_test); | |
| 144 | return __getf2(a, b); | |
| 145 | } |
std/special/compiler_rt/fixunsdfdi.zig+1-3| ... | ... | @@ -1,10 +1,8 @@ |
| 1 | 1 | const fixuint = @import("fixuint.zig").fixuint; |
| 2 | 2 | const builtin = @import("builtin"); |
| 3 | const linkage = @import("index.zig").linkage; | |
| 4 | 3 | |
| 5 | export fn __fixunsdfdi(a: f64) -> u64 { | |
| 4 | pub extern fn __fixunsdfdi(a: f64) -> u64 { | |
| 6 | 5 | @setDebugSafety(this, builtin.is_test); |
| 7 | @setGlobalLinkage(__fixunsdfdi, linkage); | |
| 8 | 6 | return fixuint(f64, u64, a); |
| 9 | 7 | } |
| 10 | 8 |
std/special/compiler_rt/fixunsdfsi.zig+1-3| ... | ... | @@ -1,10 +1,8 @@ |
| 1 | 1 | const fixuint = @import("fixuint.zig").fixuint; |
| 2 | 2 | const builtin = @import("builtin"); |
| 3 | const linkage = @import("index.zig").linkage; | |
| 4 | 3 | |
| 5 | export fn __fixunsdfsi(a: f64) -> u32 { | |
| 4 | pub extern fn __fixunsdfsi(a: f64) -> u32 { | |
| 6 | 5 | @setDebugSafety(this, builtin.is_test); |
| 7 | @setGlobalLinkage(__fixunsdfsi, linkage); | |
| 8 | 6 | return fixuint(f64, u32, a); |
| 9 | 7 | } |
| 10 | 8 |
std/special/compiler_rt/fixunsdfti.zig+1-3| ... | ... | @@ -1,10 +1,8 @@ |
| 1 | 1 | const fixuint = @import("fixuint.zig").fixuint; |
| 2 | 2 | const builtin = @import("builtin"); |
| 3 | const linkage = @import("index.zig").linkage; | |
| 4 | 3 | |
| 5 | export fn __fixunsdfti(a: f64) -> u128 { | |
| 4 | pub extern fn __fixunsdfti(a: f64) -> u128 { | |
| 6 | 5 | @setDebugSafety(this, builtin.is_test); |
| 7 | @setGlobalLinkage(__fixunsdfti, linkage); | |
| 8 | 6 | return fixuint(f64, u128, a); |
| 9 | 7 | } |
| 10 | 8 |
std/special/compiler_rt/fixunssfdi.zig+1-3| ... | ... | @@ -1,10 +1,8 @@ |
| 1 | 1 | const fixuint = @import("fixuint.zig").fixuint; |
| 2 | 2 | const builtin = @import("builtin"); |
| 3 | const linkage = @import("index.zig").linkage; | |
| 4 | 3 | |
| 5 | export fn __fixunssfdi(a: f32) -> u64 { | |
| 4 | pub extern fn __fixunssfdi(a: f32) -> u64 { | |
| 6 | 5 | @setDebugSafety(this, builtin.is_test); |
| 7 | @setGlobalLinkage(__fixunssfdi, linkage); | |
| 8 | 6 | return fixuint(f32, u64, a); |
| 9 | 7 | } |
| 10 | 8 |
std/special/compiler_rt/fixunssfsi.zig+1-3| ... | ... | @@ -1,10 +1,8 @@ |
| 1 | 1 | const fixuint = @import("fixuint.zig").fixuint; |
| 2 | 2 | const builtin = @import("builtin"); |
| 3 | const linkage = @import("index.zig").linkage; | |
| 4 | 3 | |
| 5 | export fn __fixunssfsi(a: f32) -> u32 { | |
| 4 | pub extern fn __fixunssfsi(a: f32) -> u32 { | |
| 6 | 5 | @setDebugSafety(this, builtin.is_test); |
| 7 | @setGlobalLinkage(__fixunssfsi, linkage); | |
| 8 | 6 | return fixuint(f32, u32, a); |
| 9 | 7 | } |
| 10 | 8 |
std/special/compiler_rt/fixunssfti.zig+1-3| ... | ... | @@ -1,10 +1,8 @@ |
| 1 | 1 | const fixuint = @import("fixuint.zig").fixuint; |
| 2 | 2 | const builtin = @import("builtin"); |
| 3 | const linkage = @import("index.zig").linkage; | |
| 4 | 3 | |
| 5 | export fn __fixunssfti(a: f32) -> u128 { | |
| 4 | pub extern fn __fixunssfti(a: f32) -> u128 { | |
| 6 | 5 | @setDebugSafety(this, builtin.is_test); |
| 7 | @setGlobalLinkage(__fixunssfti, linkage); | |
| 8 | 6 | return fixuint(f32, u128, a); |
| 9 | 7 | } |
| 10 | 8 |
std/special/compiler_rt/fixunstfdi.zig+1-3| ... | ... | @@ -1,10 +1,8 @@ |
| 1 | 1 | const fixuint = @import("fixuint.zig").fixuint; |
| 2 | 2 | const builtin = @import("builtin"); |
| 3 | const linkage = @import("index.zig").linkage; | |
| 4 | 3 | |
| 5 | export fn __fixunstfdi(a: f128) -> u64 { | |
| 4 | pub extern fn __fixunstfdi(a: f128) -> u64 { | |
| 6 | 5 | @setDebugSafety(this, builtin.is_test); |
| 7 | @setGlobalLinkage(__fixunstfdi, linkage); | |
| 8 | 6 | return fixuint(f128, u64, a); |
| 9 | 7 | } |
| 10 | 8 |
std/special/compiler_rt/fixunstfsi.zig+1-3| ... | ... | @@ -1,10 +1,8 @@ |
| 1 | 1 | const fixuint = @import("fixuint.zig").fixuint; |
| 2 | 2 | const builtin = @import("builtin"); |
| 3 | const linkage = @import("index.zig").linkage; | |
| 4 | 3 | |
| 5 | export fn __fixunstfsi(a: f128) -> u32 { | |
| 4 | pub extern fn __fixunstfsi(a: f128) -> u32 { | |
| 6 | 5 | @setDebugSafety(this, builtin.is_test); |
| 7 | @setGlobalLinkage(__fixunstfsi, linkage); | |
| 8 | 6 | return fixuint(f128, u32, a); |
| 9 | 7 | } |
| 10 | 8 |
std/special/compiler_rt/fixunstfti.zig+1-3| ... | ... | @@ -1,10 +1,8 @@ |
| 1 | 1 | const fixuint = @import("fixuint.zig").fixuint; |
| 2 | 2 | const builtin = @import("builtin"); |
| 3 | const linkage = @import("index.zig").linkage; | |
| 4 | 3 | |
| 5 | export fn __fixunstfti(a: f128) -> u128 { | |
| 4 | pub extern fn __fixunstfti(a: f128) -> u128 { | |
| 6 | 5 | @setDebugSafety(this, builtin.is_test); |
| 7 | @setGlobalLinkage(__fixunstfti, linkage); | |
| 8 | 6 | return fixuint(f128, u128, a); |
| 9 | 7 | } |
| 10 | 8 |
std/special/compiler_rt/index.zig+165-176| ... | ... | @@ -1,33 +1,74 @@ |
| 1 | comptime { | |
| 2 | _ = @import("comparetf2.zig"); | |
| 3 | _ = @import("fixunsdfdi.zig"); | |
| 4 | _ = @import("fixunsdfsi.zig"); | |
| 5 | _ = @import("fixunsdfti.zig"); | |
| 6 | _ = @import("fixunssfdi.zig"); | |
| 7 | _ = @import("fixunssfsi.zig"); | |
| 8 | _ = @import("fixunssfti.zig"); | |
| 9 | _ = @import("fixunstfdi.zig"); | |
| 10 | _ = @import("fixunstfsi.zig"); | |
| 11 | _ = @import("fixunstfti.zig"); | |
| 12 | _ = @import("udivmoddi4.zig"); | |
| 13 | _ = @import("udivmodti4.zig"); | |
| 14 | _ = @import("udivti3.zig"); | |
| 15 | _ = @import("umodti3.zig"); | |
| 16 | _ = @import("aulldiv.zig"); | |
| 17 | _ = @import("aullrem.zig"); | |
| 18 | } | |
| 19 | ||
| 20 | 1 | const builtin = @import("builtin"); |
| 21 | 2 | const is_test = builtin.is_test; |
| 22 | const assert = @import("../../debug.zig").assert; | |
| 23 | 3 | |
| 4 | comptime { | |
| 5 | const linkage = if (is_test) builtin.GlobalLinkage.Internal else builtin.GlobalLinkage.Weak; | |
| 6 | const strong_linkage = if (is_test) builtin.GlobalLinkage.Internal else builtin.GlobalLinkage.Strong; | |
| 7 | ||
| 8 | @exportWithLinkage("__letf2", @import("comparetf2.zig").__letf2, linkage); | |
| 9 | @exportWithLinkage("__getf2", @import("comparetf2.zig").__getf2, linkage); | |
| 10 | ||
| 11 | if (!is_test) { | |
| 12 | // only create these aliases when not testing | |
| 13 | @exportWithLinkage("__cmptf2", @import("comparetf2.zig").__letf2, linkage); | |
| 14 | @exportWithLinkage("__eqtf2", @import("comparetf2.zig").__letf2, linkage); | |
| 15 | @exportWithLinkage("__lttf2", @import("comparetf2.zig").__letf2, linkage); | |
| 16 | @exportWithLinkage("__netf2", @import("comparetf2.zig").__letf2, linkage); | |
| 17 | @exportWithLinkage("__gttf2", @import("comparetf2.zig").__getf2, linkage); | |
| 18 | } | |
| 19 | ||
| 20 | @exportWithLinkage("__unordtf2", @import("comparetf2.zig").__unordtf2, linkage); | |
| 21 | ||
| 22 | @exportWithLinkage("__fixunssfsi", @import("fixunssfsi.zig").__fixunssfsi, linkage); | |
| 23 | @exportWithLinkage("__fixunssfdi", @import("fixunssfdi.zig").__fixunssfdi, linkage); | |
| 24 | @exportWithLinkage("__fixunssfti", @import("fixunssfti.zig").__fixunssfti, linkage); | |
| 25 | ||
| 26 | @exportWithLinkage("__fixunsdfsi", @import("fixunsdfsi.zig").__fixunsdfsi, linkage); | |
| 27 | @exportWithLinkage("__fixunsdfdi", @import("fixunsdfdi.zig").__fixunsdfdi, linkage); | |
| 28 | @exportWithLinkage("__fixunsdfti", @import("fixunsdfti.zig").__fixunsdfti, linkage); | |
| 29 | ||
| 30 | @exportWithLinkage("__fixunstfsi", @import("fixunstfsi.zig").__fixunstfsi, linkage); | |
| 31 | @exportWithLinkage("__fixunstfdi", @import("fixunstfdi.zig").__fixunstfdi, linkage); | |
| 32 | @exportWithLinkage("__fixunstfti", @import("fixunstfti.zig").__fixunstfti, linkage); | |
| 33 | ||
| 34 | @exportWithLinkage("__udivmoddi4", @import("udivmoddi4.zig").__udivmoddi4, linkage); | |
| 35 | @exportWithLinkage("__udivmodti4", @import("udivmodti4.zig").__udivmodti4, linkage); | |
| 24 | 36 | |
| 25 | const win32 = builtin.os == builtin.Os.windows and builtin.arch == builtin.Arch.i386; | |
| 26 | const win64 = builtin.os == builtin.Os.windows and builtin.arch == builtin.Arch.x86_64; | |
| 27 | const win32_nocrt = win32 and !builtin.link_libc; | |
| 28 | const win64_nocrt = win64 and !builtin.link_libc; | |
| 29 | pub const linkage = if (builtin.is_test) builtin.GlobalLinkage.Internal else builtin.GlobalLinkage.Weak; | |
| 30 | const strong_linkage = if (builtin.is_test) builtin.GlobalLinkage.Internal else builtin.GlobalLinkage.Strong; | |
| 37 | @exportWithLinkage("__udivti3", @import("udivti3.zig").__udivti3, linkage); | |
| 38 | @exportWithLinkage("__umodti3", @import("umodti3.zig").__umodti3, linkage); | |
| 39 | ||
| 40 | @exportWithLinkage("__udivsi3", __udivsi3, linkage); | |
| 41 | @exportWithLinkage("__udivdi3", __udivdi3, linkage); | |
| 42 | @exportWithLinkage("__umoddi3", __umoddi3, linkage); | |
| 43 | @exportWithLinkage("__udivmodsi4", __udivmodsi4, linkage); | |
| 44 | ||
| 45 | if (isArmArch()) { | |
| 46 | @exportWithLinkage("__aeabi_uldivmod", __aeabi_uldivmod, linkage); | |
| 47 | @exportWithLinkage("__aeabi_uidivmod", __aeabi_uidivmod, linkage); | |
| 48 | @exportWithLinkage("__aeabi_uidiv", __udivsi3, linkage); | |
| 49 | } | |
| 50 | if (builtin.os == builtin.Os.windows) { | |
| 51 | switch (builtin.arch) { | |
| 52 | builtin.Arch.i386 => { | |
| 53 | if (!builtin.link_libc) { | |
| 54 | @exportWithLinkage("_chkstk", _chkstk, strong_linkage); | |
| 55 | @exportWithLinkage("__chkstk_ms", __chkstk_ms, linkage); | |
| 56 | } | |
| 57 | @exportWithLinkage("_aulldiv", @import("aulldiv.zig")._aulldiv, strong_linkage); | |
| 58 | @exportWithLinkage("_aullrem", @import("aullrem.zig")._aullrem, strong_linkage); | |
| 59 | }, | |
| 60 | builtin.Arch.x86_64 => { | |
| 61 | if (!builtin.link_libc) { | |
| 62 | @exportWithLinkage("__chkstk", __chkstk, strong_linkage); | |
| 63 | @exportWithLinkage("___chkstk_ms", ___chkstk_ms, linkage); | |
| 64 | } | |
| 65 | }, | |
| 66 | else => {}, | |
| 67 | } | |
| 68 | } | |
| 69 | } | |
| 70 | ||
| 71 | const assert = @import("../../debug.zig").assert; | |
| 31 | 72 | |
| 32 | 73 | const __udivmoddi4 = @import("udivmoddi4.zig").__udivmoddi4; |
| 33 | 74 | |
| ... | ... | @@ -41,15 +82,13 @@ pub coldcc fn panic(msg: []const u8) -> noreturn { |
| 41 | 82 | } |
| 42 | 83 | } |
| 43 | 84 | |
| 44 | export fn __udivdi3(a: u64, b: u64) -> u64 { | |
| 85 | extern fn __udivdi3(a: u64, b: u64) -> u64 { | |
| 45 | 86 | @setDebugSafety(this, is_test); |
| 46 | @setGlobalLinkage(__udivdi3, linkage); | |
| 47 | 87 | return __udivmoddi4(a, b, null); |
| 48 | 88 | } |
| 49 | 89 | |
| 50 | export fn __umoddi3(a: u64, b: u64) -> u64 { | |
| 90 | extern fn __umoddi3(a: u64, b: u64) -> u64 { | |
| 51 | 91 | @setDebugSafety(this, is_test); |
| 52 | @setGlobalLinkage(__umoddi3, linkage); | |
| 53 | 92 | |
| 54 | 93 | var r: u64 = undefined; |
| 55 | 94 | _ = __udivmoddi4(a, b, &r); |
| ... | ... | @@ -60,17 +99,11 @@ const AeabiUlDivModResult = extern struct { |
| 60 | 99 | quot: u64, |
| 61 | 100 | rem: u64, |
| 62 | 101 | }; |
| 63 | export fn __aeabi_uldivmod(numerator: u64, denominator: u64) -> AeabiUlDivModResult { | |
| 102 | extern fn __aeabi_uldivmod(numerator: u64, denominator: u64) -> AeabiUlDivModResult { | |
| 64 | 103 | @setDebugSafety(this, is_test); |
| 65 | if (comptime isArmArch()) { | |
| 66 | @setGlobalLinkage(__aeabi_uldivmod, linkage); | |
| 67 | var result: AeabiUlDivModResult = undefined; | |
| 68 | result.quot = __udivmoddi4(numerator, denominator, &result.rem); | |
| 69 | return result; | |
| 70 | } | |
| 71 | ||
| 72 | @setGlobalLinkage(__aeabi_uldivmod, builtin.GlobalLinkage.Internal); | |
| 73 | unreachable; | |
| 104 | var result: AeabiUlDivModResult = undefined; | |
| 105 | result.quot = __udivmoddi4(numerator, denominator, &result.rem); | |
| 106 | return result; | |
| 74 | 107 | } |
| 75 | 108 | |
| 76 | 109 | fn isArmArch() -> bool { |
| ... | ... | @@ -98,156 +131,124 @@ fn isArmArch() -> bool { |
| 98 | 131 | }; |
| 99 | 132 | } |
| 100 | 133 | |
| 101 | export nakedcc fn __aeabi_uidivmod() { | |
| 134 | nakedcc fn __aeabi_uidivmod() { | |
| 102 | 135 | @setDebugSafety(this, false); |
| 103 | ||
| 104 | if (comptime isArmArch()) { | |
| 105 | @setGlobalLinkage(__aeabi_uidivmod, linkage); | |
| 106 | asm volatile ( | |
| 107 | \\ push { lr } | |
| 108 | \\ sub sp, sp, #4 | |
| 109 | \\ mov r2, sp | |
| 110 | \\ bl __udivmodsi4 | |
| 111 | \\ ldr r1, [sp] | |
| 112 | \\ add sp, sp, #4 | |
| 113 | \\ pop { pc } | |
| 114 | ::: "r2", "r1"); | |
| 115 | unreachable; | |
| 116 | } | |
| 117 | ||
| 118 | @setGlobalLinkage(__aeabi_uidivmod, builtin.GlobalLinkage.Internal); | |
| 136 | asm volatile ( | |
| 137 | \\ push { lr } | |
| 138 | \\ sub sp, sp, #4 | |
| 139 | \\ mov r2, sp | |
| 140 | \\ bl __udivmodsi4 | |
| 141 | \\ ldr r1, [sp] | |
| 142 | \\ add sp, sp, #4 | |
| 143 | \\ pop { pc } | |
| 144 | ::: "r2", "r1"); | |
| 119 | 145 | } |
| 120 | 146 | |
| 121 | 147 | // _chkstk (_alloca) routine - probe stack between %esp and (%esp-%eax) in 4k increments, |
| 122 | 148 | // then decrement %esp by %eax. Preserves all registers except %esp and flags. |
| 123 | 149 | // This routine is windows specific |
| 124 | 150 | // http://msdn.microsoft.com/en-us/library/ms648426.aspx |
| 125 | export nakedcc fn _chkstk() align(4) { | |
| 151 | nakedcc fn _chkstk() align(4) { | |
| 126 | 152 | @setDebugSafety(this, false); |
| 127 | 153 | |
| 128 | if (win32_nocrt) { | |
| 129 | @setGlobalLinkage(_chkstk, strong_linkage); | |
| 130 | asm volatile ( | |
| 131 | \\ push %%ecx | |
| 132 | \\ push %%eax | |
| 133 | \\ cmp $0x1000,%%eax | |
| 134 | \\ lea 12(%%esp),%%ecx | |
| 135 | \\ jb 1f | |
| 136 | \\ 2: | |
| 137 | \\ sub $0x1000,%%ecx | |
| 138 | \\ test %%ecx,(%%ecx) | |
| 139 | \\ sub $0x1000,%%eax | |
| 140 | \\ cmp $0x1000,%%eax | |
| 141 | \\ ja 2b | |
| 142 | \\ 1: | |
| 143 | \\ sub %%eax,%%ecx | |
| 144 | \\ test %%ecx,(%%ecx) | |
| 145 | \\ pop %%eax | |
| 146 | \\ pop %%ecx | |
| 147 | \\ ret | |
| 148 | ); | |
| 149 | unreachable; | |
| 150 | } | |
| 151 | ||
| 152 | @setGlobalLinkage(_chkstk, builtin.GlobalLinkage.Internal); | |
| 154 | asm volatile ( | |
| 155 | \\ push %%ecx | |
| 156 | \\ push %%eax | |
| 157 | \\ cmp $0x1000,%%eax | |
| 158 | \\ lea 12(%%esp),%%ecx | |
| 159 | \\ jb 1f | |
| 160 | \\ 2: | |
| 161 | \\ sub $0x1000,%%ecx | |
| 162 | \\ test %%ecx,(%%ecx) | |
| 163 | \\ sub $0x1000,%%eax | |
| 164 | \\ cmp $0x1000,%%eax | |
| 165 | \\ ja 2b | |
| 166 | \\ 1: | |
| 167 | \\ sub %%eax,%%ecx | |
| 168 | \\ test %%ecx,(%%ecx) | |
| 169 | \\ pop %%eax | |
| 170 | \\ pop %%ecx | |
| 171 | \\ ret | |
| 172 | ); | |
| 153 | 173 | } |
| 154 | 174 | |
| 155 | export nakedcc fn __chkstk() align(4) { | |
| 175 | nakedcc fn __chkstk() align(4) { | |
| 156 | 176 | @setDebugSafety(this, false); |
| 157 | 177 | |
| 158 | if (win64_nocrt) { | |
| 159 | @setGlobalLinkage(__chkstk, strong_linkage); | |
| 160 | asm volatile ( | |
| 161 | \\ push %%rcx | |
| 162 | \\ push %%rax | |
| 163 | \\ cmp $0x1000,%%rax | |
| 164 | \\ lea 24(%%rsp),%%rcx | |
| 165 | \\ jb 1f | |
| 166 | \\2: | |
| 167 | \\ sub $0x1000,%%rcx | |
| 168 | \\ test %%rcx,(%%rcx) | |
| 169 | \\ sub $0x1000,%%rax | |
| 170 | \\ cmp $0x1000,%%rax | |
| 171 | \\ ja 2b | |
| 172 | \\1: | |
| 173 | \\ sub %%rax,%%rcx | |
| 174 | \\ test %%rcx,(%%rcx) | |
| 175 | \\ pop %%rax | |
| 176 | \\ pop %%rcx | |
| 177 | \\ ret | |
| 178 | ); | |
| 179 | unreachable; | |
| 180 | } | |
| 181 | ||
| 182 | @setGlobalLinkage(__chkstk, builtin.GlobalLinkage.Internal); | |
| 178 | asm volatile ( | |
| 179 | \\ push %%rcx | |
| 180 | \\ push %%rax | |
| 181 | \\ cmp $0x1000,%%rax | |
| 182 | \\ lea 24(%%rsp),%%rcx | |
| 183 | \\ jb 1f | |
| 184 | \\2: | |
| 185 | \\ sub $0x1000,%%rcx | |
| 186 | \\ test %%rcx,(%%rcx) | |
| 187 | \\ sub $0x1000,%%rax | |
| 188 | \\ cmp $0x1000,%%rax | |
| 189 | \\ ja 2b | |
| 190 | \\1: | |
| 191 | \\ sub %%rax,%%rcx | |
| 192 | \\ test %%rcx,(%%rcx) | |
| 193 | \\ pop %%rax | |
| 194 | \\ pop %%rcx | |
| 195 | \\ ret | |
| 196 | ); | |
| 183 | 197 | } |
| 184 | 198 | |
| 185 | 199 | // _chkstk routine |
| 186 | 200 | // This routine is windows specific |
| 187 | 201 | // http://msdn.microsoft.com/en-us/library/ms648426.aspx |
| 188 | export nakedcc fn __chkstk_ms() align(4) { | |
| 202 | nakedcc fn __chkstk_ms() align(4) { | |
| 189 | 203 | @setDebugSafety(this, false); |
| 190 | 204 | |
| 191 | if (win32_nocrt) { | |
| 192 | @setGlobalLinkage(__chkstk_ms, linkage); | |
| 193 | asm volatile ( | |
| 194 | \\ push %%ecx | |
| 195 | \\ push %%eax | |
| 196 | \\ cmp $0x1000,%%eax | |
| 197 | \\ lea 12(%%esp),%%ecx | |
| 198 | \\ jb 1f | |
| 199 | \\ 2: | |
| 200 | \\ sub $0x1000,%%ecx | |
| 201 | \\ test %%ecx,(%%ecx) | |
| 202 | \\ sub $0x1000,%%eax | |
| 203 | \\ cmp $0x1000,%%eax | |
| 204 | \\ ja 2b | |
| 205 | \\ 1: | |
| 206 | \\ sub %%eax,%%ecx | |
| 207 | \\ test %%ecx,(%%ecx) | |
| 208 | \\ pop %%eax | |
| 209 | \\ pop %%ecx | |
| 210 | \\ ret | |
| 211 | ); | |
| 212 | unreachable; | |
| 213 | } | |
| 214 | ||
| 215 | @setGlobalLinkage(__chkstk_ms, builtin.GlobalLinkage.Internal); | |
| 205 | asm volatile ( | |
| 206 | \\ push %%ecx | |
| 207 | \\ push %%eax | |
| 208 | \\ cmp $0x1000,%%eax | |
| 209 | \\ lea 12(%%esp),%%ecx | |
| 210 | \\ jb 1f | |
| 211 | \\ 2: | |
| 212 | \\ sub $0x1000,%%ecx | |
| 213 | \\ test %%ecx,(%%ecx) | |
| 214 | \\ sub $0x1000,%%eax | |
| 215 | \\ cmp $0x1000,%%eax | |
| 216 | \\ ja 2b | |
| 217 | \\ 1: | |
| 218 | \\ sub %%eax,%%ecx | |
| 219 | \\ test %%ecx,(%%ecx) | |
| 220 | \\ pop %%eax | |
| 221 | \\ pop %%ecx | |
| 222 | \\ ret | |
| 223 | ); | |
| 216 | 224 | } |
| 217 | 225 | |
| 218 | export nakedcc fn ___chkstk_ms() align(4) { | |
| 226 | nakedcc fn ___chkstk_ms() align(4) { | |
| 219 | 227 | @setDebugSafety(this, false); |
| 220 | 228 | |
| 221 | if (win64_nocrt) { | |
| 222 | @setGlobalLinkage(___chkstk_ms, linkage); | |
| 223 | asm volatile ( | |
| 224 | \\ push %%rcx | |
| 225 | \\ push %%rax | |
| 226 | \\ cmp $0x1000,%%rax | |
| 227 | \\ lea 24(%%rsp),%%rcx | |
| 228 | \\ jb 1f | |
| 229 | \\2: | |
| 230 | \\ sub $0x1000,%%rcx | |
| 231 | \\ test %%rcx,(%%rcx) | |
| 232 | \\ sub $0x1000,%%rax | |
| 233 | \\ cmp $0x1000,%%rax | |
| 234 | \\ ja 2b | |
| 235 | \\1: | |
| 236 | \\ sub %%rax,%%rcx | |
| 237 | \\ test %%rcx,(%%rcx) | |
| 238 | \\ pop %%rax | |
| 239 | \\ pop %%rcx | |
| 240 | \\ ret | |
| 241 | ); | |
| 242 | unreachable; | |
| 243 | } | |
| 244 | ||
| 245 | @setGlobalLinkage(___chkstk_ms, builtin.GlobalLinkage.Internal); | |
| 229 | asm volatile ( | |
| 230 | \\ push %%rcx | |
| 231 | \\ push %%rax | |
| 232 | \\ cmp $0x1000,%%rax | |
| 233 | \\ lea 24(%%rsp),%%rcx | |
| 234 | \\ jb 1f | |
| 235 | \\2: | |
| 236 | \\ sub $0x1000,%%rcx | |
| 237 | \\ test %%rcx,(%%rcx) | |
| 238 | \\ sub $0x1000,%%rax | |
| 239 | \\ cmp $0x1000,%%rax | |
| 240 | \\ ja 2b | |
| 241 | \\1: | |
| 242 | \\ sub %%rax,%%rcx | |
| 243 | \\ test %%rcx,(%%rcx) | |
| 244 | \\ pop %%rax | |
| 245 | \\ pop %%rcx | |
| 246 | \\ ret | |
| 247 | ); | |
| 246 | 248 | } |
| 247 | 249 | |
| 248 | export fn __udivmodsi4(a: u32, b: u32, rem: &u32) -> u32 { | |
| 250 | extern fn __udivmodsi4(a: u32, b: u32, rem: &u32) -> u32 { | |
| 249 | 251 | @setDebugSafety(this, is_test); |
| 250 | @setGlobalLinkage(__udivmodsi4, linkage); | |
| 251 | 252 | |
| 252 | 253 | const d = __udivsi3(a, b); |
| 253 | 254 | *rem = u32(i32(a) -% (i32(d) * i32(b))); |
| ... | ... | @@ -255,19 +256,8 @@ export fn __udivmodsi4(a: u32, b: u32, rem: &u32) -> u32 { |
| 255 | 256 | } |
| 256 | 257 | |
| 257 | 258 | |
| 258 | // TODO make this an alias instead of an extra function call | |
| 259 | // https://github.com/andrewrk/zig/issues/256 | |
| 260 | ||
| 261 | export fn __aeabi_uidiv(n: u32, d: u32) -> u32 { | |
| 259 | extern fn __udivsi3(n: u32, d: u32) -> u32 { | |
| 262 | 260 | @setDebugSafety(this, is_test); |
| 263 | @setGlobalLinkage(__aeabi_uidiv, linkage); | |
| 264 | ||
| 265 | return __udivsi3(n, d); | |
| 266 | } | |
| 267 | ||
| 268 | export fn __udivsi3(n: u32, d: u32) -> u32 { | |
| 269 | @setDebugSafety(this, is_test); | |
| 270 | @setGlobalLinkage(__udivsi3, linkage); | |
| 271 | 261 | |
| 272 | 262 | const n_uword_bits: c_uint = u32.bit_count; |
| 273 | 263 | // special cases |
| ... | ... | @@ -463,4 +453,3 @@ fn test_one_udivsi3(a: u32, b: u32, expected_q: u32) { |
| 463 | 453 | const q: u32 = __udivsi3(a, b); |
| 464 | 454 | assert(q == expected_q); |
| 465 | 455 | } |
| 466 |
std/special/compiler_rt/udivmoddi4.zig+1-3| ... | ... | @@ -1,10 +1,8 @@ |
| 1 | 1 | const udivmod = @import("udivmod.zig").udivmod; |
| 2 | 2 | const builtin = @import("builtin"); |
| 3 | const linkage = @import("index.zig").linkage; | |
| 4 | 3 | |
| 5 | export fn __udivmoddi4(a: u64, b: u64, maybe_rem: ?&u64) -> u64 { | |
| 4 | pub extern fn __udivmoddi4(a: u64, b: u64, maybe_rem: ?&u64) -> u64 { | |
| 6 | 5 | @setDebugSafety(this, builtin.is_test); |
| 7 | @setGlobalLinkage(__udivmoddi4, linkage); | |
| 8 | 6 | return udivmod(u64, a, b, maybe_rem); |
| 9 | 7 | } |
| 10 | 8 |
std/special/compiler_rt/udivmodti4.zig+1-3| ... | ... | @@ -1,10 +1,8 @@ |
| 1 | 1 | const udivmod = @import("udivmod.zig").udivmod; |
| 2 | 2 | const builtin = @import("builtin"); |
| 3 | const linkage = @import("index.zig").linkage; | |
| 4 | 3 | |
| 5 | export fn __udivmodti4(a: u128, b: u128, maybe_rem: ?&u128) -> u128 { | |
| 4 | pub extern fn __udivmodti4(a: u128, b: u128, maybe_rem: ?&u128) -> u128 { | |
| 6 | 5 | @setDebugSafety(this, builtin.is_test); |
| 7 | @setGlobalLinkage(__udivmodti4, linkage); | |
| 8 | 6 | return udivmod(u128, a, b, maybe_rem); |
| 9 | 7 | } |
| 10 | 8 |
std/special/compiler_rt/udivti3.zig+1-3| ... | ... | @@ -1,9 +1,7 @@ |
| 1 | 1 | const __udivmodti4 = @import("udivmodti4.zig").__udivmodti4; |
| 2 | 2 | const builtin = @import("builtin"); |
| 3 | const linkage = @import("index.zig").linkage; | |
| 4 | 3 | |
| 5 | export fn __udivti3(a: u128, b: u128) -> u128 { | |
| 4 | pub extern fn __udivti3(a: u128, b: u128) -> u128 { | |
| 6 | 5 | @setDebugSafety(this, builtin.is_test); |
| 7 | @setGlobalLinkage(__udivti3, linkage); | |
| 8 | 6 | return __udivmodti4(a, b, null); |
| 9 | 7 | } |
std/special/compiler_rt/umodti3.zig+1-3| ... | ... | @@ -1,10 +1,8 @@ |
| 1 | 1 | const __udivmodti4 = @import("udivmodti4.zig").__udivmodti4; |
| 2 | 2 | const builtin = @import("builtin"); |
| 3 | const linkage = @import("index.zig").linkage; | |
| 4 | 3 | |
| 5 | export fn __umodti3(a: u128, b: u128) -> u128 { | |
| 4 | pub extern fn __umodti3(a: u128, b: u128) -> u128 { | |
| 6 | 5 | @setDebugSafety(this, builtin.is_test); |
| 7 | @setGlobalLinkage(__umodti3, linkage); | |
| 8 | 6 | var r: u128 = undefined; |
| 9 | 7 | _ = __udivmodti4(a, b, &r); |
| 10 | 8 | return r; |
test/cases/asm.zig+7-6| ... | ... | @@ -2,23 +2,24 @@ const config = @import("builtin"); |
| 2 | 2 | const assert = @import("std").debug.assert; |
| 3 | 3 | |
| 4 | 4 | comptime { |
| 5 | @export("derp", derp); | |
| 5 | 6 | if (config.arch == config.Arch.x86_64 and config.os == config.Os.linux) { |
| 6 | 7 | asm volatile ( |
| 7 | \\.globl aoeu; | |
| 8 | \\.type aoeu, @function; | |
| 9 | \\.set aoeu, derp; | |
| 8 | \\.globl my_aoeu_symbol_asdf; | |
| 9 | \\.type my_aoeu_symbol_asdf, @function; | |
| 10 | \\.set my_aoeu_symbol_asdf, derp; | |
| 10 | 11 | ); |
| 11 | 12 | } |
| 12 | 13 | } |
| 13 | 14 | |
| 14 | 15 | test "module level assembly" { |
| 15 | 16 | if (config.arch == config.Arch.x86_64 and config.os == config.Os.linux) { |
| 16 | assert(aoeu() == 1234); | |
| 17 | assert(my_aoeu_symbol_asdf() == 1234); | |
| 17 | 18 | } |
| 18 | 19 | } |
| 19 | 20 | |
| 20 | extern fn aoeu() -> i32; | |
| 21 | extern fn my_aoeu_symbol_asdf() -> i32; | |
| 21 | 22 | |
| 22 | export fn derp() -> i32 { | |
| 23 | extern fn derp() -> i32 { | |
| 23 | 24 | return 1234; |
| 24 | 25 | } |
test/cases/misc.zig+20-3| ... | ... | @@ -12,8 +12,10 @@ test "empty function with comments" { |
| 12 | 12 | emptyFunctionWithComments(); |
| 13 | 13 | } |
| 14 | 14 | |
| 15 | export fn disabledExternFn() { | |
| 16 | @setGlobalLinkage(disabledExternFn, builtin.GlobalLinkage.Internal); | |
| 15 | comptime { | |
| 16 | @exportWithLinkage("disabledExternFn", disabledExternFn, builtin.GlobalLinkage.Internal) | |
| 17 | } | |
| 18 | extern fn disabledExternFn() { | |
| 17 | 19 | } |
| 18 | 20 | |
| 19 | 21 | test "call disabled extern fn" { |
| ... | ... | @@ -533,7 +535,10 @@ var global_ptr = &gdt[0]; |
| 533 | 535 | // can't really run this test but we can make sure it has no compile error |
| 534 | 536 | // and generates code |
| 535 | 537 | const vram = @intToPtr(&volatile u8, 0x20000000)[0..0x8000]; |
| 536 | export fn writeToVRam() { | |
| 538 | comptime { | |
| 539 | @export("writeToVRam", writeToVRam); | |
| 540 | } | |
| 541 | extern fn writeToVRam() { | |
| 537 | 542 | vram[0] = 'X'; |
| 538 | 543 | } |
| 539 | 544 | |
| ... | ... | @@ -557,3 +562,15 @@ fn hereIsAnOpaqueType(ptr: &OpaqueA) -> &OpaqueA { |
| 557 | 562 | var a = ptr; |
| 558 | 563 | return a; |
| 559 | 564 | } |
| 565 | ||
| 566 | test "function and variable in weird section" { | |
| 567 | if (builtin.os == builtin.Os.linux or builtin.os == builtin.Os.windows) { | |
| 568 | // macos can't handle this | |
| 569 | assert(fnInWeirdSection() == 1234); | |
| 570 | } | |
| 571 | } | |
| 572 | ||
| 573 | var varInWeirdSection: i32 section(".data2") = 1234; | |
| 574 | fn fnInWeirdSection() section(".text2") -> i32 { | |
| 575 | return varInWeirdSection; | |
| 576 | } |
test/compare_output.zig+11-5| ... | ... | @@ -4,7 +4,8 @@ const tests = @import("tests.zig"); |
| 4 | 4 | pub fn addCases(cases: &tests.CompareOutputContext) { |
| 5 | 5 | cases.addC("hello world with libc", |
| 6 | 6 | \\const c = @cImport(@cInclude("stdio.h")); |
| 7 | \\export fn main(argc: c_int, argv: &&u8) -> c_int { | |
| 7 | \\comptime { @export("main", main); } | |
| 8 | \\extern fn main(argc: c_int, argv: &&u8) -> c_int { | |
| 8 | 9 | \\ _ = c.puts(c"Hello, world!"); |
| 9 | 10 | \\ return 0; |
| 10 | 11 | \\} |
| ... | ... | @@ -137,7 +138,8 @@ pub fn addCases(cases: &tests.CompareOutputContext) { |
| 137 | 138 | \\ @cInclude("stdio.h"); |
| 138 | 139 | \\}); |
| 139 | 140 | \\ |
| 140 | \\export fn main(argc: c_int, argv: &&u8) -> c_int { | |
| 141 | \\comptime { @export("main", main); } | |
| 142 | \\extern fn main(argc: c_int, argv: &&u8) -> c_int { | |
| 141 | 143 | \\ if (is_windows) { |
| 142 | 144 | \\ // we want actual \n, not \r\n |
| 143 | 145 | \\ _ = c._setmode(1, c._O_BINARY); |
| ... | ... | @@ -282,7 +284,10 @@ pub fn addCases(cases: &tests.CompareOutputContext) { |
| 282 | 284 | cases.addC("expose function pointer to C land", |
| 283 | 285 | \\const c = @cImport(@cInclude("stdlib.h")); |
| 284 | 286 | \\ |
| 285 | \\export fn compare_fn(a: ?&const c_void, b: ?&const c_void) -> c_int { | |
| 287 | \\comptime { | |
| 288 | \\ @export("main", main); | |
| 289 | \\} | |
| 290 | \\extern fn compare_fn(a: ?&const c_void, b: ?&const c_void) -> c_int { | |
| 286 | 291 | \\ const a_int = @ptrCast(&align(1) i32, a ?? unreachable); |
| 287 | 292 | \\ const b_int = @ptrCast(&align(1) i32, b ?? unreachable); |
| 288 | 293 | \\ if (*a_int < *b_int) { |
| ... | ... | @@ -294,7 +299,7 @@ pub fn addCases(cases: &tests.CompareOutputContext) { |
| 294 | 299 | \\ } |
| 295 | 300 | \\} |
| 296 | 301 | \\ |
| 297 | \\export fn main() -> c_int { | |
| 302 | \\extern fn main() -> c_int { | |
| 298 | 303 | \\ var array = []u32 { 1, 7, 3, 2, 0, 9, 4, 8, 6, 5 }; |
| 299 | 304 | \\ |
| 300 | 305 | \\ c.qsort(@ptrCast(&c_void, &array[0]), c_ulong(array.len), @sizeOf(i32), compare_fn); |
| ... | ... | @@ -322,7 +327,8 @@ pub fn addCases(cases: &tests.CompareOutputContext) { |
| 322 | 327 | \\ @cInclude("stdio.h"); |
| 323 | 328 | \\}); |
| 324 | 329 | \\ |
| 325 | \\export fn main(argc: c_int, argv: &&u8) -> c_int { | |
| 330 | \\comptime { @export("main", main); } | |
| 331 | \\extern fn main(argc: c_int, argv: &&u8) -> c_int { | |
| 326 | 332 | \\ if (is_windows) { |
| 327 | 333 | \\ // we want actual \n, not \r\n |
| 328 | 334 | \\ _ = c._setmode(1, c._O_BINARY); |
test/compile_errors.zig+535-287| ... | ... | @@ -1,253 +1,328 @@ |
| 1 | 1 | const tests = @import("tests.zig"); |
| 2 | 2 | |
| 3 | 3 | pub fn addCases(cases: &tests.CompileErrorContext) { |
| 4 | cases.add("wrong return type for main", | |
| 5 | \\pub fn main() { } | |
| 6 | , ".tmp_source.zig:1:15: error: expected return type of main to be '%void', instead is 'void'"); | |
| 7 | ||
| 8 | cases.add("double ?? on main return value", | |
| 9 | \\pub fn main() -> ??void { | |
| 10 | \\} | |
| 11 | , ".tmp_source.zig:1:18: error: expected return type of main to be '%void', instead is '??void'"); | |
| 12 | ||
| 13 | cases.add("setting a section on an extern variable", | |
| 14 | \\extern var foo: i32 section(".text2"); | |
| 15 | \\extern fn entry() -> i32 { | |
| 16 | \\ return foo; | |
| 17 | \\} | |
| 18 | \\comptime { @export("entry", entry); } | |
| 19 | , | |
| 20 | ".tmp_source.zig:1:29: error: cannot set section of external variable 'foo'"); | |
| 21 | ||
| 22 | cases.add("setting a section on a local variable", | |
| 23 | \\extern fn entry() -> i32 { | |
| 24 | \\ var foo: i32 section(".text2") = 1234; | |
| 25 | \\ return foo; | |
| 26 | \\} | |
| 27 | \\comptime { @export("entry", entry); } | |
| 28 | , | |
| 29 | ".tmp_source.zig:2:26: error: cannot set section of local variable 'foo'"); | |
| 30 | ||
| 31 | cases.add("setting a section on an extern fn", | |
| 32 | \\extern fn foo() section(".text2"); | |
| 33 | \\extern fn entry() { | |
| 34 | \\ foo(); | |
| 35 | \\} | |
| 36 | \\comptime { @export("entry", entry); } | |
| 37 | , | |
| 38 | ".tmp_source.zig:1:25: error: cannot set section of external function 'foo'"); | |
| 39 | ||
| 40 | cases.add("wrong types given to exportWithLinkage", | |
| 41 | \\extern fn entry() { } | |
| 42 | \\comptime { | |
| 43 | \\ @exportWithLinkage("entry", entry, u32(1234)); | |
| 44 | \\} | |
| 45 | , | |
| 46 | ".tmp_source.zig:3:43: error: expected type 'GlobalLinkage', found 'u32'"); | |
| 47 | ||
| 4 | 48 | cases.add("implicit semicolon - block statement", |
| 5 | \\export fn entry() { | |
| 49 | \\extern fn entry() { | |
| 6 | 50 | \\ {} |
| 7 | 51 | \\ var good = {}; |
| 8 | 52 | \\ ({}) |
| 9 | 53 | \\ var bad = {}; |
| 10 | 54 | \\} |
| 55 | \\comptime {@export("entry", entry);} | |
| 11 | 56 | , ".tmp_source.zig:5:5: error: invalid token: 'var'"); |
| 12 | 57 | |
| 13 | 58 | cases.add("implicit semicolon - block expr", |
| 14 | \\export fn entry() { | |
| 59 | \\extern fn entry() { | |
| 15 | 60 | \\ _ = {}; |
| 16 | 61 | \\ var good = {}; |
| 17 | 62 | \\ _ = {} |
| 18 | 63 | \\ var bad = {}; |
| 19 | 64 | \\} |
| 65 | \\comptime {@export("entry", entry);} | |
| 20 | 66 | , ".tmp_source.zig:5:5: error: invalid token: 'var'"); |
| 21 | 67 | |
| 22 | 68 | cases.add("implicit semicolon - comptime statement", |
| 23 | \\export fn entry() { | |
| 69 | \\extern fn entry() { | |
| 24 | 70 | \\ comptime {} |
| 25 | 71 | \\ var good = {}; |
| 26 | 72 | \\ comptime ({}) |
| 27 | 73 | \\ var bad = {}; |
| 28 | 74 | \\} |
| 75 | \\comptime {@export("entry", entry);} | |
| 29 | 76 | , ".tmp_source.zig:5:5: error: invalid token: 'var'"); |
| 30 | 77 | |
| 31 | 78 | cases.add("implicit semicolon - comptime expression", |
| 32 | \\export fn entry() { | |
| 79 | \\extern fn entry() { | |
| 33 | 80 | \\ _ = comptime {}; |
| 34 | 81 | \\ var good = {}; |
| 35 | 82 | \\ _ = comptime {} |
| 36 | 83 | \\ var bad = {}; |
| 37 | 84 | \\} |
| 85 | \\comptime {@export("entry", entry);} | |
| 38 | 86 | , ".tmp_source.zig:5:5: error: invalid token: 'var'"); |
| 39 | 87 | |
| 40 | 88 | cases.add("implicit semicolon - defer", |
| 41 | \\export fn entry() { | |
| 89 | \\extern fn entry() { | |
| 42 | 90 | \\ defer {} |
| 43 | 91 | \\ var good = {}; |
| 44 | 92 | \\ defer ({}) |
| 45 | 93 | \\ var bad = {}; |
| 46 | 94 | \\} |
| 95 | \\comptime {@export("entry", entry);} | |
| 47 | 96 | , ".tmp_source.zig:5:5: error: expected token ';', found 'var'"); |
| 48 | 97 | |
| 49 | 98 | cases.add("implicit semicolon - if statement", |
| 50 | \\export fn entry() { | |
| 99 | \\extern fn entry() { | |
| 51 | 100 | \\ if(true) {} |
| 52 | 101 | \\ var good = {}; |
| 53 | 102 | \\ if(true) ({}) |
| 54 | 103 | \\ var bad = {}; |
| 55 | 104 | \\} |
| 105 | \\comptime {@export("entry", entry);} | |
| 56 | 106 | , ".tmp_source.zig:5:5: error: invalid token: 'var'"); |
| 57 | 107 | |
| 58 | 108 | cases.add("implicit semicolon - if expression", |
| 59 | \\export fn entry() { | |
| 109 | \\extern fn entry() { | |
| 60 | 110 | \\ _ = if(true) {}; |
| 61 | 111 | \\ var good = {}; |
| 62 | 112 | \\ _ = if(true) {} |
| 63 | 113 | \\ var bad = {}; |
| 64 | 114 | \\} |
| 115 | \\comptime {@export("entry", entry);} | |
| 65 | 116 | , ".tmp_source.zig:5:5: error: invalid token: 'var'"); |
| 66 | 117 | |
| 67 | 118 | cases.add("implicit semicolon - if-else statement", |
| 68 | \\export fn entry() { | |
| 119 | \\extern fn entry() { | |
| 69 | 120 | \\ if(true) {} else {} |
| 70 | 121 | \\ var good = {}; |
| 71 | 122 | \\ if(true) ({}) else ({}) |
| 72 | 123 | \\ var bad = {}; |
| 73 | 124 | \\} |
| 125 | \\comptime {@export("entry", entry);} | |
| 74 | 126 | , ".tmp_source.zig:5:5: error: invalid token: 'var'"); |
| 75 | 127 | |
| 76 | 128 | cases.add("implicit semicolon - if-else expression", |
| 77 | \\export fn entry() { | |
| 129 | \\extern fn entry() { | |
| 78 | 130 | \\ _ = if(true) {} else {}; |
| 79 | 131 | \\ var good = {}; |
| 80 | 132 | \\ _ = if(true) {} else {} |
| 81 | 133 | \\ var bad = {}; |
| 82 | 134 | \\} |
| 135 | \\comptime {@export("entry", entry);} | |
| 83 | 136 | , ".tmp_source.zig:5:5: error: invalid token: 'var'"); |
| 84 | 137 | |
| 85 | 138 | cases.add("implicit semicolon - if-else-if statement", |
| 86 | \\export fn entry() { | |
| 139 | \\extern fn entry() { | |
| 87 | 140 | \\ if(true) {} else if(true) {} |
| 88 | 141 | \\ var good = {}; |
| 89 | 142 | \\ if(true) ({}) else if(true) ({}) |
| 90 | 143 | \\ var bad = {}; |
| 91 | 144 | \\} |
| 145 | \\comptime {@export("entry", entry);} | |
| 92 | 146 | , ".tmp_source.zig:5:5: error: invalid token: 'var'"); |
| 93 | 147 | |
| 94 | 148 | cases.add("implicit semicolon - if-else-if expression", |
| 95 | \\export fn entry() { | |
| 149 | \\extern fn entry() { | |
| 96 | 150 | \\ _ = if(true) {} else if(true) {}; |
| 97 | 151 | \\ var good = {}; |
| 98 | 152 | \\ _ = if(true) {} else if(true) {} |
| 99 | 153 | \\ var bad = {}; |
| 100 | 154 | \\} |
| 155 | \\comptime {@export("entry", entry);} | |
| 101 | 156 | , ".tmp_source.zig:5:5: error: invalid token: 'var'"); |
| 102 | 157 | |
| 103 | 158 | cases.add("implicit semicolon - if-else-if-else statement", |
| 104 | \\export fn entry() { | |
| 159 | \\extern fn entry() { | |
| 105 | 160 | \\ if(true) {} else if(true) {} else {} |
| 106 | 161 | \\ var good = {}; |
| 107 | 162 | \\ if(true) ({}) else if(true) ({}) else ({}) |
| 108 | 163 | \\ var bad = {}; |
| 109 | 164 | \\} |
| 165 | \\comptime {@export("entry", entry);} | |
| 110 | 166 | , ".tmp_source.zig:5:5: error: invalid token: 'var'"); |
| 111 | 167 | |
| 112 | 168 | cases.add("implicit semicolon - if-else-if-else expression", |
| 113 | \\export fn entry() { | |
| 169 | \\extern fn entry() { | |
| 114 | 170 | \\ _ = if(true) {} else if(true) {} else {}; |
| 115 | 171 | \\ var good = {}; |
| 116 | 172 | \\ _ = if(true) {} else if(true) {} else {} |
| 117 | 173 | \\ var bad = {}; |
| 118 | 174 | \\} |
| 175 | \\comptime {@export("entry", entry);} | |
| 119 | 176 | , ".tmp_source.zig:5:5: error: invalid token: 'var'"); |
| 120 | 177 | |
| 121 | 178 | cases.add("implicit semicolon - test statement", |
| 122 | \\export fn entry() { | |
| 179 | \\extern fn entry() { | |
| 123 | 180 | \\ if (foo()) |_| {} |
| 124 | 181 | \\ var good = {}; |
| 125 | 182 | \\ if (foo()) |_| ({}) |
| 126 | 183 | \\ var bad = {}; |
| 127 | 184 | \\} |
| 185 | \\comptime {@export("entry", entry);} | |
| 128 | 186 | , ".tmp_source.zig:5:5: error: invalid token: 'var'"); |
| 129 | 187 | |
| 130 | 188 | cases.add("implicit semicolon - test expression", |
| 131 | \\export fn entry() { | |
| 189 | \\extern fn entry() { | |
| 132 | 190 | \\ _ = if (foo()) |_| {}; |
| 133 | 191 | \\ var good = {}; |
| 134 | 192 | \\ _ = if (foo()) |_| {} |
| 135 | 193 | \\ var bad = {}; |
| 136 | 194 | \\} |
| 195 | \\comptime {@export("entry", entry);} | |
| 137 | 196 | , ".tmp_source.zig:5:5: error: invalid token: 'var'"); |
| 138 | 197 | |
| 139 | 198 | cases.add("implicit semicolon - while statement", |
| 140 | \\export fn entry() { | |
| 199 | \\extern fn entry() { | |
| 141 | 200 | \\ while(true) {} |
| 142 | 201 | \\ var good = {}; |
| 143 | 202 | \\ while(true) ({}) |
| 144 | 203 | \\ var bad = {}; |
| 145 | 204 | \\} |
| 205 | \\comptime {@export("entry", entry);} | |
| 146 | 206 | , ".tmp_source.zig:5:5: error: invalid token: 'var'"); |
| 147 | 207 | |
| 148 | 208 | cases.add("implicit semicolon - while expression", |
| 149 | \\export fn entry() { | |
| 209 | \\extern fn entry() { | |
| 150 | 210 | \\ _ = while(true) {}; |
| 151 | 211 | \\ var good = {}; |
| 152 | 212 | \\ _ = while(true) {} |
| 153 | 213 | \\ var bad = {}; |
| 154 | 214 | \\} |
| 215 | \\comptime {@export("entry", entry);} | |
| 155 | 216 | , ".tmp_source.zig:5:5: error: invalid token: 'var'"); |
| 156 | 217 | |
| 157 | 218 | cases.add("implicit semicolon - while-continue statement", |
| 158 | \\export fn entry() { | |
| 219 | \\extern fn entry() { | |
| 159 | 220 | \\ while(true):({}) {} |
| 160 | 221 | \\ var good = {}; |
| 161 | 222 | \\ while(true):({}) ({}) |
| 162 | 223 | \\ var bad = {}; |
| 163 | 224 | \\} |
| 225 | \\comptime {@export("entry", entry);} | |
| 164 | 226 | , ".tmp_source.zig:5:5: error: invalid token: 'var'"); |
| 165 | 227 | |
| 166 | 228 | cases.add("implicit semicolon - while-continue expression", |
| 167 | \\export fn entry() { | |
| 229 | \\extern fn entry() { | |
| 168 | 230 | \\ _ = while(true):({}) {}; |
| 169 | 231 | \\ var good = {}; |
| 170 | 232 | \\ _ = while(true):({}) {} |
| 171 | 233 | \\ var bad = {}; |
| 172 | 234 | \\} |
| 235 | \\comptime {@export("entry", entry);} | |
| 173 | 236 | , ".tmp_source.zig:5:5: error: invalid token: 'var'"); |
| 174 | 237 | |
| 175 | 238 | cases.add("implicit semicolon - for statement", |
| 176 | \\export fn entry() { | |
| 239 | \\extern fn entry() { | |
| 177 | 240 | \\ for(foo()) {} |
| 178 | 241 | \\ var good = {}; |
| 179 | 242 | \\ for(foo()) ({}) |
| 180 | 243 | \\ var bad = {}; |
| 181 | 244 | \\} |
| 245 | \\comptime {@export("entry", entry);} | |
| 182 | 246 | , ".tmp_source.zig:5:5: error: invalid token: 'var'"); |
| 183 | 247 | |
| 184 | 248 | cases.add("implicit semicolon - for expression", |
| 185 | \\export fn entry() { | |
| 249 | \\extern fn entry() { | |
| 186 | 250 | \\ _ = for(foo()) {}; |
| 187 | 251 | \\ var good = {}; |
| 188 | 252 | \\ _ = for(foo()) {} |
| 189 | 253 | \\ var bad = {}; |
| 190 | 254 | \\} |
| 255 | \\comptime {@export("entry", entry);} | |
| 191 | 256 | , ".tmp_source.zig:5:5: error: invalid token: 'var'"); |
| 192 | 257 | |
| 193 | 258 | cases.add("multiple function definitions", |
| 194 | 259 | \\fn a() {} |
| 195 | 260 | \\fn a() {} |
| 196 | \\export fn entry() { a(); } | |
| 261 | \\comptime {@export("entry", entry);} | |
| 262 | \\extern fn entry() { a(); } | |
| 197 | 263 | , ".tmp_source.zig:2:1: error: redefinition of 'a'"); |
| 198 | 264 | |
| 199 | 265 | cases.add("unreachable with return", |
| 200 | 266 | \\fn a() -> noreturn {return;} |
| 201 | \\export fn entry() { a(); } | |
| 267 | \\comptime {@export("entry", entry);} | |
| 268 | \\extern fn entry() { a(); } | |
| 202 | 269 | , ".tmp_source.zig:1:21: error: expected type 'noreturn', found 'void'"); |
| 203 | 270 | |
| 204 | 271 | cases.add("control reaches end of non-void function", |
| 205 | 272 | \\fn a() -> i32 {} |
| 206 | \\export fn entry() { _ = a(); } | |
| 273 | \\comptime {@export("entry", entry);} | |
| 274 | \\extern fn entry() { _ = a(); } | |
| 207 | 275 | , ".tmp_source.zig:1:15: error: expected type 'i32', found 'void'"); |
| 208 | 276 | |
| 209 | 277 | cases.add("undefined function call", |
| 210 | \\export fn a() { | |
| 278 | \\extern fn a() { | |
| 211 | 279 | \\ b(); |
| 212 | 280 | \\} |
| 281 | \\comptime {@export("a", a);} | |
| 213 | 282 | , ".tmp_source.zig:2:5: error: use of undeclared identifier 'b'"); |
| 214 | 283 | |
| 215 | 284 | cases.add("wrong number of arguments", |
| 216 | \\export fn a() { | |
| 285 | \\extern fn a() { | |
| 217 | 286 | \\ b(1); |
| 218 | 287 | \\} |
| 219 | 288 | \\fn b(a: i32, b: i32, c: i32) { } |
| 289 | \\comptime {@export("a", a);} | |
| 220 | 290 | , ".tmp_source.zig:2:6: error: expected 3 arguments, found 1"); |
| 221 | 291 | |
| 222 | 292 | cases.add("invalid type", |
| 223 | 293 | \\fn a() -> bogus {} |
| 224 | \\export fn entry() { _ = a(); } | |
| 294 | \\comptime {@export("entry", entry);} | |
| 295 | \\extern fn entry() { _ = a(); } | |
| 225 | 296 | , ".tmp_source.zig:1:11: error: use of undeclared identifier 'bogus'"); |
| 226 | 297 | |
| 227 | 298 | cases.add("pointer to unreachable", |
| 228 | 299 | \\fn a() -> &noreturn {} |
| 229 | \\export fn entry() { _ = a(); } | |
| 300 | \\comptime {@export("entry", entry);} | |
| 301 | \\extern fn entry() { _ = a(); } | |
| 230 | 302 | , ".tmp_source.zig:1:12: error: pointer to unreachable not allowed"); |
| 231 | 303 | |
| 232 | 304 | cases.add("unreachable code", |
| 233 | \\export fn a() { | |
| 305 | \\extern fn a() { | |
| 234 | 306 | \\ return; |
| 235 | 307 | \\ b(); |
| 236 | 308 | \\} |
| 237 | 309 | \\ |
| 238 | 310 | \\fn b() {} |
| 311 | \\comptime {@export("a", a);} | |
| 239 | 312 | , ".tmp_source.zig:3:5: error: unreachable code"); |
| 240 | 313 | |
| 241 | 314 | cases.add("bad import", |
| 242 | 315 | \\const bogus = @import("bogus-does-not-exist.zig"); |
| 243 | \\export fn entry() { bogus.bogo(); } | |
| 316 | \\comptime {@export("entry", entry);} | |
| 317 | \\extern fn entry() { bogus.bogo(); } | |
| 244 | 318 | , ".tmp_source.zig:1:15: error: unable to find 'bogus-does-not-exist.zig'"); |
| 245 | 319 | |
| 246 | 320 | cases.add("undeclared identifier", |
| 247 | \\export fn a() { | |
| 321 | \\extern fn a() { | |
| 248 | 322 | \\ b + |
| 249 | 323 | \\ c |
| 250 | 324 | \\} |
| 325 | \\comptime {@export("a", a);} | |
| 251 | 326 | , |
| 252 | 327 | ".tmp_source.zig:2:5: error: use of undeclared identifier 'b'", |
| 253 | 328 | ".tmp_source.zig:3:5: error: use of undeclared identifier 'c'"); |
| ... | ... | @@ -255,99 +330,114 @@ pub fn addCases(cases: &tests.CompileErrorContext) { |
| 255 | 330 | cases.add("parameter redeclaration", |
| 256 | 331 | \\fn f(a : i32, a : i32) { |
| 257 | 332 | \\} |
| 258 | \\export fn entry() { f(1, 2); } | |
| 333 | \\comptime {@export("entry", entry);} | |
| 334 | \\extern fn entry() { f(1, 2); } | |
| 259 | 335 | , ".tmp_source.zig:1:15: error: redeclaration of variable 'a'"); |
| 260 | 336 | |
| 261 | 337 | cases.add("local variable redeclaration", |
| 262 | \\export fn f() { | |
| 338 | \\extern fn f() { | |
| 263 | 339 | \\ const a : i32 = 0; |
| 264 | 340 | \\ const a = 0; |
| 265 | 341 | \\} |
| 342 | \\comptime {@export("f", f);} | |
| 266 | 343 | , ".tmp_source.zig:3:5: error: redeclaration of variable 'a'"); |
| 267 | 344 | |
| 268 | 345 | cases.add("local variable redeclares parameter", |
| 269 | 346 | \\fn f(a : i32) { |
| 270 | 347 | \\ const a = 0; |
| 271 | 348 | \\} |
| 272 | \\export fn entry() { f(1); } | |
| 349 | \\comptime {@export("entry", entry);} | |
| 350 | \\extern fn entry() { f(1); } | |
| 273 | 351 | , ".tmp_source.zig:2:5: error: redeclaration of variable 'a'"); |
| 274 | 352 | |
| 275 | 353 | cases.add("variable has wrong type", |
| 276 | \\export fn f() -> i32 { | |
| 354 | \\extern fn f() -> i32 { | |
| 277 | 355 | \\ const a = c"a"; |
| 278 | 356 | \\ a |
| 279 | 357 | \\} |
| 358 | \\comptime {@export("f", f);} | |
| 280 | 359 | , ".tmp_source.zig:3:5: error: expected type 'i32', found '&const u8'"); |
| 281 | 360 | |
| 282 | 361 | cases.add("if condition is bool, not int", |
| 283 | \\export fn f() { | |
| 362 | \\extern fn f() { | |
| 284 | 363 | \\ if (0) {} |
| 285 | 364 | \\} |
| 365 | \\comptime {@export("f", f);} | |
| 286 | 366 | , ".tmp_source.zig:2:9: error: integer value 0 cannot be implicitly casted to type 'bool'"); |
| 287 | 367 | |
| 288 | 368 | cases.add("assign unreachable", |
| 289 | \\export fn f() { | |
| 369 | \\extern fn f() { | |
| 290 | 370 | \\ const a = return; |
| 291 | 371 | \\} |
| 372 | \\comptime {@export("f", f);} | |
| 292 | 373 | , ".tmp_source.zig:2:5: error: unreachable code"); |
| 293 | 374 | |
| 294 | 375 | cases.add("unreachable variable", |
| 295 | \\export fn f() { | |
| 376 | \\extern fn f() { | |
| 296 | 377 | \\ const a: noreturn = {}; |
| 297 | 378 | \\} |
| 379 | \\comptime {@export("f", f);} | |
| 298 | 380 | , ".tmp_source.zig:2:14: error: variable of type 'noreturn' not allowed"); |
| 299 | 381 | |
| 300 | 382 | cases.add("unreachable parameter", |
| 301 | 383 | \\fn f(a: noreturn) {} |
| 302 | \\export fn entry() { f(); } | |
| 384 | \\comptime {@export("entry", entry);} | |
| 385 | \\extern fn entry() { f(); } | |
| 303 | 386 | , ".tmp_source.zig:1:9: error: parameter of type 'noreturn' not allowed"); |
| 304 | 387 | |
| 305 | 388 | cases.add("bad assignment target", |
| 306 | \\export fn f() { | |
| 389 | \\extern fn f() { | |
| 307 | 390 | \\ 3 = 3; |
| 308 | 391 | \\} |
| 392 | \\comptime {@export("f", f);} | |
| 309 | 393 | , ".tmp_source.zig:2:7: error: cannot assign to constant"); |
| 310 | 394 | |
| 311 | 395 | cases.add("assign to constant variable", |
| 312 | \\export fn f() { | |
| 396 | \\extern fn f() { | |
| 313 | 397 | \\ const a = 3; |
| 314 | 398 | \\ a = 4; |
| 315 | 399 | \\} |
| 400 | \\comptime {@export("f", f);} | |
| 316 | 401 | , ".tmp_source.zig:3:7: error: cannot assign to constant"); |
| 317 | 402 | |
| 318 | 403 | cases.add("use of undeclared identifier", |
| 319 | \\export fn f() { | |
| 404 | \\extern fn f() { | |
| 320 | 405 | \\ b = 3; |
| 321 | 406 | \\} |
| 407 | \\comptime {@export("f", f);} | |
| 322 | 408 | , ".tmp_source.zig:2:5: error: use of undeclared identifier 'b'"); |
| 323 | 409 | |
| 324 | 410 | cases.add("const is a statement, not an expression", |
| 325 | \\export fn f() { | |
| 411 | \\extern fn f() { | |
| 326 | 412 | \\ (const a = 0); |
| 327 | 413 | \\} |
| 414 | \\comptime {@export("f", f);} | |
| 328 | 415 | , ".tmp_source.zig:2:6: error: invalid token: 'const'"); |
| 329 | 416 | |
| 330 | 417 | cases.add("array access of undeclared identifier", |
| 331 | \\export fn f() { | |
| 418 | \\extern fn f() { | |
| 332 | 419 | \\ i[i] = i[i]; |
| 333 | 420 | \\} |
| 421 | \\comptime {@export("f", f);} | |
| 334 | 422 | , ".tmp_source.zig:2:5: error: use of undeclared identifier 'i'", |
| 335 | 423 | ".tmp_source.zig:2:12: error: use of undeclared identifier 'i'"); |
| 336 | 424 | |
| 337 | 425 | cases.add("array access of non array", |
| 338 | \\export fn f() { | |
| 426 | \\extern fn f() { | |
| 339 | 427 | \\ var bad : bool = undefined; |
| 340 | 428 | \\ bad[bad] = bad[bad]; |
| 341 | 429 | \\} |
| 430 | \\comptime {@export("f", f);} | |
| 342 | 431 | , ".tmp_source.zig:3:8: error: array access of non-array type 'bool'", |
| 343 | 432 | ".tmp_source.zig:3:19: error: array access of non-array type 'bool'"); |
| 344 | 433 | |
| 345 | 434 | cases.add("array access with non integer index", |
| 346 | \\export fn f() { | |
| 435 | \\extern fn f() { | |
| 347 | 436 | \\ var array = "aoeu"; |
| 348 | 437 | \\ var bad = false; |
| 349 | 438 | \\ array[bad] = array[bad]; |
| 350 | 439 | \\} |
| 440 | \\comptime {@export("f", f);} | |
| 351 | 441 | , ".tmp_source.zig:4:11: error: expected type 'usize', found 'bool'", |
| 352 | 442 | ".tmp_source.zig:4:24: error: expected type 'usize', found 'bool'"); |
| 353 | 443 | |
| ... | ... | @@ -356,7 +446,8 @@ pub fn addCases(cases: &tests.CompileErrorContext) { |
| 356 | 446 | \\fn f() { |
| 357 | 447 | \\ x = 1; |
| 358 | 448 | \\} |
| 359 | \\export fn entry() { f(); } | |
| 449 | \\extern fn entry() { f(); } | |
| 450 | \\comptime {@export("entry", entry);} | |
| 360 | 451 | , ".tmp_source.zig:3:7: error: cannot assign to constant"); |
| 361 | 452 | |
| 362 | 453 | |
| ... | ... | @@ -365,29 +456,33 @@ pub fn addCases(cases: &tests.CompileErrorContext) { |
| 365 | 456 | \\ const x : i32 = if (b) { 1 }; |
| 366 | 457 | \\ const y = if (b) { i32(1) }; |
| 367 | 458 | \\} |
| 368 | \\export fn entry() { f(true); } | |
| 459 | \\extern fn entry() { f(true); } | |
| 460 | \\comptime {@export("entry", entry);} | |
| 369 | 461 | , ".tmp_source.zig:2:30: error: integer value 1 cannot be implicitly casted to type 'void'", |
| 370 | 462 | ".tmp_source.zig:3:15: error: incompatible types: 'i32' and 'void'"); |
| 371 | 463 | |
| 372 | 464 | cases.add("direct struct loop", |
| 373 | 465 | \\const A = struct { a : A, }; |
| 374 | \\export fn entry() -> usize { @sizeOf(A) } | |
| 466 | \\extern fn entry() -> usize { @sizeOf(A) } | |
| 467 | \\comptime {@export("entry", entry);} | |
| 375 | 468 | , ".tmp_source.zig:1:11: error: struct 'A' contains itself"); |
| 376 | 469 | |
| 377 | 470 | cases.add("indirect struct loop", |
| 378 | 471 | \\const A = struct { b : B, }; |
| 379 | 472 | \\const B = struct { c : C, }; |
| 380 | 473 | \\const C = struct { a : A, }; |
| 381 | \\export fn entry() -> usize { @sizeOf(A) } | |
| 474 | \\extern fn entry() -> usize { @sizeOf(A) } | |
| 475 | \\comptime {@export("entry", entry);} | |
| 382 | 476 | , ".tmp_source.zig:1:11: error: struct 'A' contains itself"); |
| 383 | 477 | |
| 384 | 478 | cases.add("invalid struct field", |
| 385 | 479 | \\const A = struct { x : i32, }; |
| 386 | \\export fn f() { | |
| 480 | \\extern fn f() { | |
| 387 | 481 | \\ var a : A = undefined; |
| 388 | 482 | \\ a.foo = 1; |
| 389 | 483 | \\ const y = a.bar; |
| 390 | 484 | \\} |
| 485 | \\comptime {@export("f", f);} | |
| 391 | 486 | , |
| 392 | 487 | ".tmp_source.zig:4:6: error: no member named 'foo' in struct 'A'", |
| 393 | 488 | ".tmp_source.zig:5:16: error: no member named 'bar' in struct 'A'"); |
| ... | ... | @@ -415,7 +510,7 @@ pub fn addCases(cases: &tests.CompileErrorContext) { |
| 415 | 510 | \\ y : i32, |
| 416 | 511 | \\ z : i32, |
| 417 | 512 | \\}; |
| 418 | \\export fn f() { | |
| 513 | \\extern fn f() { | |
| 419 | 514 | \\ const a = A { |
| 420 | 515 | \\ .z = 1, |
| 421 | 516 | \\ .y = 2, |
| ... | ... | @@ -423,6 +518,7 @@ pub fn addCases(cases: &tests.CompileErrorContext) { |
| 423 | 518 | \\ .z = 4, |
| 424 | 519 | \\ }; |
| 425 | 520 | \\} |
| 521 | \\comptime {@export("f", f);} | |
| 426 | 522 | , ".tmp_source.zig:11:9: error: duplicate field"); |
| 427 | 523 | |
| 428 | 524 | cases.add("missing field in struct value expression", |
| ... | ... | @@ -431,7 +527,7 @@ pub fn addCases(cases: &tests.CompileErrorContext) { |
| 431 | 527 | \\ y : i32, |
| 432 | 528 | \\ z : i32, |
| 433 | 529 | \\}; |
| 434 | \\export fn f() { | |
| 530 | \\extern fn f() { | |
| 435 | 531 | \\ // we want the error on the '{' not the 'A' because |
| 436 | 532 | \\ // the A could be a complicated expression |
| 437 | 533 | \\ const a = A { |
| ... | ... | @@ -439,6 +535,7 @@ pub fn addCases(cases: &tests.CompileErrorContext) { |
| 439 | 535 | \\ .y = 2, |
| 440 | 536 | \\ }; |
| 441 | 537 | \\} |
| 538 | \\comptime {@export("f", f);} | |
| 442 | 539 | , ".tmp_source.zig:9:17: error: missing field: 'x'"); |
| 443 | 540 | |
| 444 | 541 | cases.add("invalid field in struct value expression", |
| ... | ... | @@ -447,69 +544,79 @@ pub fn addCases(cases: &tests.CompileErrorContext) { |
| 447 | 544 | \\ y : i32, |
| 448 | 545 | \\ z : i32, |
| 449 | 546 | \\}; |
| 450 | \\export fn f() { | |
| 547 | \\extern fn f() { | |
| 451 | 548 | \\ const a = A { |
| 452 | 549 | \\ .z = 4, |
| 453 | 550 | \\ .y = 2, |
| 454 | 551 | \\ .foo = 42, |
| 455 | 552 | \\ }; |
| 456 | 553 | \\} |
| 554 | \\comptime {@export("f", f);} | |
| 457 | 555 | , ".tmp_source.zig:10:9: error: no member named 'foo' in struct 'A'"); |
| 458 | 556 | |
| 459 | 557 | cases.add("invalid break expression", |
| 460 | \\export fn f() { | |
| 558 | \\extern fn f() { | |
| 461 | 559 | \\ break; |
| 462 | 560 | \\} |
| 561 | \\comptime {@export("f", f);} | |
| 463 | 562 | , ".tmp_source.zig:2:5: error: break expression outside loop"); |
| 464 | 563 | |
| 465 | 564 | cases.add("invalid continue expression", |
| 466 | \\export fn f() { | |
| 565 | \\extern fn f() { | |
| 467 | 566 | \\ continue; |
| 468 | 567 | \\} |
| 568 | \\comptime {@export("f", f);} | |
| 469 | 569 | , ".tmp_source.zig:2:5: error: continue expression outside loop"); |
| 470 | 570 | |
| 471 | 571 | cases.add("invalid maybe type", |
| 472 | \\export fn f() { | |
| 572 | \\extern fn f() { | |
| 473 | 573 | \\ if (true) |x| { } |
| 474 | 574 | \\} |
| 575 | \\comptime {@export("f", f);} | |
| 475 | 576 | , ".tmp_source.zig:2:9: error: expected nullable type, found 'bool'"); |
| 476 | 577 | |
| 477 | 578 | cases.add("cast unreachable", |
| 478 | 579 | \\fn f() -> i32 { |
| 479 | 580 | \\ i32(return 1) |
| 480 | 581 | \\} |
| 481 | \\export fn entry() { _ = f(); } | |
| 582 | \\extern fn entry() { _ = f(); } | |
| 583 | \\comptime {@export("entry", entry);} | |
| 482 | 584 | , ".tmp_source.zig:2:8: error: unreachable code"); |
| 483 | 585 | |
| 484 | 586 | cases.add("invalid builtin fn", |
| 485 | 587 | \\fn f() -> @bogus(foo) { |
| 486 | 588 | \\} |
| 487 | \\export fn entry() { _ = f(); } | |
| 589 | \\extern fn entry() { _ = f(); } | |
| 590 | \\comptime {@export("entry", entry);} | |
| 488 | 591 | , ".tmp_source.zig:1:11: error: invalid builtin function: 'bogus'"); |
| 489 | 592 | |
| 490 | 593 | cases.add("top level decl dependency loop", |
| 491 | 594 | \\const a : @typeOf(b) = 0; |
| 492 | 595 | \\const b : @typeOf(a) = 0; |
| 493 | \\export fn entry() { | |
| 596 | \\extern fn entry() { | |
| 494 | 597 | \\ const c = a + b; |
| 495 | 598 | \\} |
| 599 | \\comptime {@export("entry", entry);} | |
| 496 | 600 | , ".tmp_source.zig:1:1: error: 'a' depends on itself"); |
| 497 | 601 | |
| 498 | 602 | cases.add("noalias on non pointer param", |
| 499 | 603 | \\fn f(noalias x: i32) {} |
| 500 | \\export fn entry() { f(1234); } | |
| 604 | \\extern fn entry() { f(1234); } | |
| 605 | \\comptime {@export("entry", entry);} | |
| 501 | 606 | , ".tmp_source.zig:1:6: error: noalias on non-pointer parameter"); |
| 502 | 607 | |
| 503 | 608 | cases.add("struct init syntax for array", |
| 504 | 609 | \\const foo = []u16{.x = 1024,}; |
| 505 | \\export fn entry() -> usize { @sizeOf(@typeOf(foo)) } | |
| 610 | \\extern fn entry() -> usize { @sizeOf(@typeOf(foo)) } | |
| 611 | \\comptime {@export("entry", entry);} | |
| 506 | 612 | , ".tmp_source.zig:1:18: error: type '[]u16' does not support struct initialization syntax"); |
| 507 | 613 | |
| 508 | 614 | cases.add("type variables must be constant", |
| 509 | 615 | \\var foo = u8; |
| 510 | \\export fn entry() -> foo { | |
| 616 | \\extern fn entry() -> foo { | |
| 511 | 617 | \\ return 1; |
| 512 | 618 | \\} |
| 619 | \\comptime {@export("entry", entry);} | |
| 513 | 620 | , ".tmp_source.zig:1:1: error: variable of type 'type' must be constant"); |
| 514 | 621 | |
| 515 | 622 | |
| ... | ... | @@ -521,9 +628,10 @@ pub fn addCases(cases: &tests.CompileErrorContext) { |
| 521 | 628 | \\ var Bar : i32 = undefined; |
| 522 | 629 | \\} |
| 523 | 630 | \\ |
| 524 | \\export fn entry() { | |
| 631 | \\extern fn entry() { | |
| 525 | 632 | \\ f(1234); |
| 526 | 633 | \\} |
| 634 | \\comptime {@export("entry", entry);} | |
| 527 | 635 | , |
| 528 | 636 | ".tmp_source.zig:4:6: error: redefinition of 'Foo'", |
| 529 | 637 | ".tmp_source.zig:1:1: note: previous definition is here", |
| ... | ... | @@ -545,7 +653,8 @@ pub fn addCases(cases: &tests.CompileErrorContext) { |
| 545 | 653 | \\ } |
| 546 | 654 | \\} |
| 547 | 655 | \\ |
| 548 | \\export fn entry() -> usize { @sizeOf(@typeOf(f)) } | |
| 656 | \\extern fn entry() -> usize { @sizeOf(@typeOf(f)) } | |
| 657 | \\comptime {@export("entry", entry);} | |
| 549 | 658 | , ".tmp_source.zig:8:5: error: enumeration value 'Number.Four' not handled in switch"); |
| 550 | 659 | |
| 551 | 660 | cases.add("switch expression - duplicate enumeration prong", |
| ... | ... | @@ -565,7 +674,8 @@ pub fn addCases(cases: &tests.CompileErrorContext) { |
| 565 | 674 | \\ } |
| 566 | 675 | \\} |
| 567 | 676 | \\ |
| 568 | \\export fn entry() -> usize { @sizeOf(@typeOf(f)) } | |
| 677 | \\extern fn entry() -> usize { @sizeOf(@typeOf(f)) } | |
| 678 | \\comptime {@export("entry", entry);} | |
| 569 | 679 | , ".tmp_source.zig:13:15: error: duplicate switch value", |
| 570 | 680 | ".tmp_source.zig:10:15: note: other value is here"); |
| 571 | 681 | |
| ... | ... | @@ -587,7 +697,8 @@ pub fn addCases(cases: &tests.CompileErrorContext) { |
| 587 | 697 | \\ } |
| 588 | 698 | \\} |
| 589 | 699 | \\ |
| 590 | \\export fn entry() -> usize { @sizeOf(@typeOf(f)) } | |
| 700 | \\extern fn entry() -> usize { @sizeOf(@typeOf(f)) } | |
| 701 | \\comptime {@export("entry", entry);} | |
| 591 | 702 | , ".tmp_source.zig:13:15: error: duplicate switch value", |
| 592 | 703 | ".tmp_source.zig:10:15: note: other value is here"); |
| 593 | 704 | |
| ... | ... | @@ -599,9 +710,10 @@ pub fn addCases(cases: &tests.CompileErrorContext) { |
| 599 | 710 | \\ else => true, |
| 600 | 711 | \\ }; |
| 601 | 712 | \\} |
| 602 | \\export fn entry() { | |
| 713 | \\extern fn entry() { | |
| 603 | 714 | \\ f(1234); |
| 604 | 715 | \\} |
| 716 | \\comptime {@export("entry", entry);} | |
| 605 | 717 | , ".tmp_source.zig:5:9: error: multiple else prongs in switch expression"); |
| 606 | 718 | |
| 607 | 719 | cases.add("switch expression - non exhaustive integer prongs", |
| ... | ... | @@ -610,7 +722,8 @@ pub fn addCases(cases: &tests.CompileErrorContext) { |
| 610 | 722 | \\ 0 => {}, |
| 611 | 723 | \\ } |
| 612 | 724 | \\} |
| 613 | \\export fn entry() -> usize { @sizeOf(@typeOf(foo)) } | |
| 725 | \\extern fn entry() -> usize { @sizeOf(@typeOf(foo)) } | |
| 726 | \\comptime {@export("entry", entry);} | |
| 614 | 727 | , |
| 615 | 728 | ".tmp_source.zig:2:5: error: switch must handle all possibilities"); |
| 616 | 729 | |
| ... | ... | @@ -623,7 +736,8 @@ pub fn addCases(cases: &tests.CompileErrorContext) { |
| 623 | 736 | \\ 206 ... 255 => 3, |
| 624 | 737 | \\ } |
| 625 | 738 | \\} |
| 626 | \\export fn entry() -> usize { @sizeOf(@typeOf(foo)) } | |
| 739 | \\extern fn entry() -> usize { @sizeOf(@typeOf(foo)) } | |
| 740 | \\comptime {@export("entry", entry);} | |
| 627 | 741 | , |
| 628 | 742 | ".tmp_source.zig:6:9: error: duplicate switch value", |
| 629 | 743 | ".tmp_source.zig:5:14: note: previous value is here"); |
| ... | ... | @@ -635,14 +749,16 @@ pub fn addCases(cases: &tests.CompileErrorContext) { |
| 635 | 749 | \\ } |
| 636 | 750 | \\} |
| 637 | 751 | \\const y: u8 = 100; |
| 638 | \\export fn entry() -> usize { @sizeOf(@typeOf(foo)) } | |
| 752 | \\extern fn entry() -> usize { @sizeOf(@typeOf(foo)) } | |
| 753 | \\comptime {@export("entry", entry);} | |
| 639 | 754 | , |
| 640 | 755 | ".tmp_source.zig:2:5: error: else prong required when switching on type '&u8'"); |
| 641 | 756 | |
| 642 | 757 | cases.add("global variable initializer must be constant expression", |
| 643 | 758 | \\extern fn foo() -> i32; |
| 644 | 759 | \\const x = foo(); |
| 645 | \\export fn entry() -> i32 { x } | |
| 760 | \\extern fn entry() -> i32 { x } | |
| 761 | \\comptime {@export("entry", entry);} | |
| 646 | 762 | , ".tmp_source.zig:2:11: error: unable to evaluate constant expression"); |
| 647 | 763 | |
| 648 | 764 | cases.add("array concatenation with wrong type", |
| ... | ... | @@ -650,7 +766,8 @@ pub fn addCases(cases: &tests.CompileErrorContext) { |
| 650 | 766 | \\const derp = usize(1234); |
| 651 | 767 | \\const a = derp ++ "foo"; |
| 652 | 768 | \\ |
| 653 | \\export fn entry() -> usize { @sizeOf(@typeOf(a)) } | |
| 769 | \\extern fn entry() -> usize { @sizeOf(@typeOf(a)) } | |
| 770 | \\comptime {@export("entry", entry);} | |
| 654 | 771 | , ".tmp_source.zig:3:11: error: expected array or C string literal, found 'usize'"); |
| 655 | 772 | |
| 656 | 773 | cases.add("non compile time array concatenation", |
| ... | ... | @@ -658,12 +775,14 @@ pub fn addCases(cases: &tests.CompileErrorContext) { |
| 658 | 775 | \\ s ++ "foo" |
| 659 | 776 | \\} |
| 660 | 777 | \\var s: [10]u8 = undefined; |
| 661 | \\export fn entry() -> usize { @sizeOf(@typeOf(f)) } | |
| 778 | \\extern fn entry() -> usize { @sizeOf(@typeOf(f)) } | |
| 779 | \\comptime {@export("entry", entry);} | |
| 662 | 780 | , ".tmp_source.zig:2:5: error: unable to evaluate constant expression"); |
| 663 | 781 | |
| 664 | 782 | cases.add("@cImport with bogus include", |
| 665 | 783 | \\const c = @cImport(@cInclude("bogus.h")); |
| 666 | \\export fn entry() -> usize { @sizeOf(@typeOf(c.bogo)) } | |
| 784 | \\extern fn entry() -> usize { @sizeOf(@typeOf(c.bogo)) } | |
| 785 | \\comptime {@export("entry", entry);} | |
| 667 | 786 | , ".tmp_source.zig:1:11: error: C import failed", |
| 668 | 787 | ".h:1:10: note: 'bogus.h' file not found"); |
| 669 | 788 | |
| ... | ... | @@ -671,17 +790,20 @@ pub fn addCases(cases: &tests.CompileErrorContext) { |
| 671 | 790 | \\const x = 3; |
| 672 | 791 | \\const y = &x; |
| 673 | 792 | \\fn foo() -> &const i32 { y } |
| 674 | \\export fn entry() -> usize { @sizeOf(@typeOf(foo)) } | |
| 793 | \\extern fn entry() -> usize { @sizeOf(@typeOf(foo)) } | |
| 794 | \\comptime {@export("entry", entry);} | |
| 675 | 795 | , ".tmp_source.zig:3:26: error: expected type '&const i32', found '&const (integer literal)'"); |
| 676 | 796 | |
| 677 | 797 | cases.add("integer overflow error", |
| 678 | 798 | \\const x : u8 = 300; |
| 679 | \\export fn entry() -> usize { @sizeOf(@typeOf(x)) } | |
| 799 | \\extern fn entry() -> usize { @sizeOf(@typeOf(x)) } | |
| 800 | \\comptime {@export("entry", entry);} | |
| 680 | 801 | , ".tmp_source.zig:1:16: error: integer value 300 cannot be implicitly casted to type 'u8'"); |
| 681 | 802 | |
| 682 | 803 | cases.add("incompatible number literals", |
| 683 | 804 | \\const x = 2 == 2.0; |
| 684 | \\export fn entry() -> usize { @sizeOf(@typeOf(x)) } | |
| 805 | \\extern fn entry() -> usize { @sizeOf(@typeOf(x)) } | |
| 806 | \\comptime {@export("entry", entry);} | |
| 685 | 807 | , ".tmp_source.zig:1:11: error: integer value 2 cannot be implicitly casted to type '(float literal)'"); |
| 686 | 808 | |
| 687 | 809 | cases.add("missing function call param", |
| ... | ... | @@ -707,13 +829,15 @@ pub fn addCases(cases: &tests.CompileErrorContext) { |
| 707 | 829 | \\ const result = members[index](); |
| 708 | 830 | \\} |
| 709 | 831 | \\ |
| 710 | \\export fn entry() -> usize { @sizeOf(@typeOf(f)) } | |
| 832 | \\extern fn entry() -> usize { @sizeOf(@typeOf(f)) } | |
| 833 | \\comptime {@export("entry", entry);} | |
| 711 | 834 | , ".tmp_source.zig:20:34: error: expected 1 arguments, found 0"); |
| 712 | 835 | |
| 713 | 836 | cases.add("missing function name and param name", |
| 714 | 837 | \\fn () {} |
| 715 | 838 | \\fn f(i32) {} |
| 716 | \\export fn entry() -> usize { @sizeOf(@typeOf(f)) } | |
| 839 | \\extern fn entry() -> usize { @sizeOf(@typeOf(f)) } | |
| 840 | \\comptime {@export("entry", entry);} | |
| 717 | 841 | , |
| 718 | 842 | ".tmp_source.zig:1:1: error: missing function name", |
| 719 | 843 | ".tmp_source.zig:2:6: error: missing parameter name"); |
| ... | ... | @@ -723,16 +847,20 @@ pub fn addCases(cases: &tests.CompileErrorContext) { |
| 723 | 847 | \\fn a() -> i32 {0} |
| 724 | 848 | \\fn b() -> i32 {1} |
| 725 | 849 | \\fn c() -> i32 {2} |
| 726 | \\export fn entry() -> usize { @sizeOf(@typeOf(fns)) } | |
| 850 | \\extern fn entry() -> usize { @sizeOf(@typeOf(fns)) } | |
| 851 | \\comptime {@export("entry", entry);} | |
| 727 | 852 | , ".tmp_source.zig:1:21: error: expected type 'fn()', found 'fn() -> i32'"); |
| 728 | 853 | |
| 729 | 854 | cases.add("extern function pointer mismatch", |
| 730 | 855 | \\const fns = [](fn(i32)->i32){ a, b, c }; |
| 731 | 856 | \\pub fn a(x: i32) -> i32 {x + 0} |
| 732 | 857 | \\pub fn b(x: i32) -> i32 {x + 1} |
| 733 | \\export fn c(x: i32) -> i32 {x + 2} | |
| 858 | \\extern fn c(x: i32) -> i32 {x + 2} | |
| 859 | \\ | |
| 860 | \\extern fn entry() -> usize { @sizeOf(@typeOf(fns)) } | |
| 734 | 861 | \\ |
| 735 | \\export fn entry() -> usize { @sizeOf(@typeOf(fns)) } | |
| 862 | \\comptime {@export("entry", entry);} | |
| 863 | \\comptime {@export("c", c);} | |
| 736 | 864 | , ".tmp_source.zig:1:37: error: expected type 'fn(i32) -> i32', found 'extern fn(i32) -> i32'"); |
| 737 | 865 | |
| 738 | 866 | |
| ... | ... | @@ -740,14 +868,16 @@ pub fn addCases(cases: &tests.CompileErrorContext) { |
| 740 | 868 | \\const x : f64 = 1.0; |
| 741 | 869 | \\const y : f32 = x; |
| 742 | 870 | \\ |
| 743 | \\export fn entry() -> usize { @sizeOf(@typeOf(y)) } | |
| 871 | \\extern fn entry() -> usize { @sizeOf(@typeOf(y)) } | |
| 872 | \\comptime {@export("entry", entry);} | |
| 744 | 873 | , ".tmp_source.zig:2:17: error: expected type 'f32', found 'f64'"); |
| 745 | 874 | |
| 746 | 875 | |
| 747 | 876 | cases.add("colliding invalid top level functions", |
| 748 | 877 | \\fn func() -> bogus {} |
| 749 | 878 | \\fn func() -> bogus {} |
| 750 | \\export fn entry() -> usize { @sizeOf(@typeOf(func)) } | |
| 879 | \\extern fn entry() -> usize { @sizeOf(@typeOf(func)) } | |
| 880 | \\comptime {@export("entry", entry);} | |
| 751 | 881 | , |
| 752 | 882 | ".tmp_source.zig:2:1: error: redefinition of 'func'", |
| 753 | 883 | ".tmp_source.zig:1:14: error: use of undeclared identifier 'bogus'"); |
| ... | ... | @@ -755,7 +885,8 @@ pub fn addCases(cases: &tests.CompileErrorContext) { |
| 755 | 885 | |
| 756 | 886 | cases.add("bogus compile var", |
| 757 | 887 | \\const x = @import("builtin").bogus; |
| 758 | \\export fn entry() -> usize { @sizeOf(@typeOf(x)) } | |
| 888 | \\extern fn entry() -> usize { @sizeOf(@typeOf(x)) } | |
| 889 | \\comptime {@export("entry", entry);} | |
| 759 | 890 | , ".tmp_source.zig:1:29: error: no member named 'bogus' in '"); |
| 760 | 891 | |
| 761 | 892 | |
| ... | ... | @@ -766,7 +897,8 @@ pub fn addCases(cases: &tests.CompileErrorContext) { |
| 766 | 897 | \\var global_var: usize = 1; |
| 767 | 898 | \\fn get() -> usize { global_var } |
| 768 | 899 | \\ |
| 769 | \\export fn entry() -> usize { @sizeOf(@typeOf(Foo)) } | |
| 900 | \\extern fn entry() -> usize { @sizeOf(@typeOf(Foo)) } | |
| 901 | \\comptime {@export("entry", entry);} | |
| 770 | 902 | , |
| 771 | 903 | ".tmp_source.zig:5:21: error: unable to evaluate constant expression", |
| 772 | 904 | ".tmp_source.zig:2:12: note: called from here", |
| ... | ... | @@ -779,7 +911,8 @@ pub fn addCases(cases: &tests.CompileErrorContext) { |
| 779 | 911 | \\}; |
| 780 | 912 | \\const x = Foo {.field = 1} + Foo {.field = 2}; |
| 781 | 913 | \\ |
| 782 | \\export fn entry() -> usize { @sizeOf(@typeOf(x)) } | |
| 914 | \\extern fn entry() -> usize { @sizeOf(@typeOf(x)) } | |
| 915 | \\comptime {@export("entry", entry);} | |
| 783 | 916 | , ".tmp_source.zig:4:28: error: invalid operands to binary expression: 'Foo' and 'Foo'"); |
| 784 | 917 | |
| 785 | 918 | |
| ... | ... | @@ -789,10 +922,14 @@ pub fn addCases(cases: &tests.CompileErrorContext) { |
| 789 | 922 | \\const int_x = u32(1) / u32(0); |
| 790 | 923 | \\const float_x = f32(1.0) / f32(0.0); |
| 791 | 924 | \\ |
| 792 | \\export fn entry1() -> usize { @sizeOf(@typeOf(lit_int_x)) } | |
| 793 | \\export fn entry2() -> usize { @sizeOf(@typeOf(lit_float_x)) } | |
| 794 | \\export fn entry3() -> usize { @sizeOf(@typeOf(int_x)) } | |
| 795 | \\export fn entry4() -> usize { @sizeOf(@typeOf(float_x)) } | |
| 925 | \\extern fn entry1() -> usize { @sizeOf(@typeOf(lit_int_x)) } | |
| 926 | \\extern fn entry2() -> usize { @sizeOf(@typeOf(lit_float_x)) } | |
| 927 | \\extern fn entry3() -> usize { @sizeOf(@typeOf(int_x)) } | |
| 928 | \\extern fn entry4() -> usize { @sizeOf(@typeOf(float_x)) } | |
| 929 | \\comptime {@export("entry1", entry1);} | |
| 930 | \\comptime {@export("entry2", entry2);} | |
| 931 | \\comptime {@export("entry3", entry3);} | |
| 932 | \\comptime {@export("entry4", entry4);} | |
| 796 | 933 | , |
| 797 | 934 | ".tmp_source.zig:1:21: error: division by zero is undefined", |
| 798 | 935 | ".tmp_source.zig:2:25: error: division by zero is undefined", |
| ... | ... | @@ -804,14 +941,16 @@ pub fn addCases(cases: &tests.CompileErrorContext) { |
| 804 | 941 | \\const foo = "a |
| 805 | 942 | \\b"; |
| 806 | 943 | \\ |
| 807 | \\export fn entry() -> usize { @sizeOf(@typeOf(foo)) } | |
| 944 | \\extern fn entry() -> usize { @sizeOf(@typeOf(foo)) } | |
| 945 | \\comptime {@export("entry", entry);} | |
| 808 | 946 | , ".tmp_source.zig:1:13: error: newline not allowed in string literal"); |
| 809 | 947 | |
| 810 | 948 | cases.add("invalid comparison for function pointers", |
| 811 | 949 | \\fn foo() {} |
| 812 | 950 | \\const invalid = foo > foo; |
| 813 | 951 | \\ |
| 814 | \\export fn entry() -> usize { @sizeOf(@typeOf(invalid)) } | |
| 952 | \\extern fn entry() -> usize { @sizeOf(@typeOf(invalid)) } | |
| 953 | \\comptime {@export("entry", entry);} | |
| 815 | 954 | , ".tmp_source.zig:2:21: error: operator not allowed for type 'fn()'"); |
| 816 | 955 | |
| 817 | 956 | cases.add("generic function instance with non-constant expression", |
| ... | ... | @@ -820,16 +959,18 @@ pub fn addCases(cases: &tests.CompileErrorContext) { |
| 820 | 959 | \\ return foo(a, b); |
| 821 | 960 | \\} |
| 822 | 961 | \\ |
| 823 | \\export fn entry() -> usize { @sizeOf(@typeOf(test1)) } | |
| 962 | \\extern fn entry() -> usize { @sizeOf(@typeOf(test1)) } | |
| 963 | \\comptime {@export("entry", entry);} | |
| 824 | 964 | , ".tmp_source.zig:3:16: error: unable to evaluate constant expression"); |
| 825 | 965 | |
| 826 | 966 | cases.add("goto jumping into block", |
| 827 | \\export fn f() { | |
| 967 | \\extern fn f() { | |
| 828 | 968 | \\ { |
| 829 | 969 | \\a_label: |
| 830 | 970 | \\ } |
| 831 | 971 | \\ goto a_label; |
| 832 | 972 | \\} |
| 973 | \\comptime {@export("f", f);} | |
| 833 | 974 | , ".tmp_source.zig:5:5: error: no label in scope named 'a_label'"); |
| 834 | 975 | |
| 835 | 976 | cases.add("goto jumping past a defer", |
| ... | ... | @@ -840,20 +981,23 @@ pub fn addCases(cases: &tests.CompileErrorContext) { |
| 840 | 981 | \\} |
| 841 | 982 | \\fn derp(){} |
| 842 | 983 | \\ |
| 843 | \\export fn entry() -> usize { @sizeOf(@typeOf(f)) } | |
| 984 | \\extern fn entry() -> usize { @sizeOf(@typeOf(f)) } | |
| 985 | \\comptime {@export("entry", entry);} | |
| 844 | 986 | , ".tmp_source.zig:2:12: error: no label in scope named 'label'"); |
| 845 | 987 | |
| 846 | 988 | cases.add("assign null to non-nullable pointer", |
| 847 | 989 | \\const a: &u8 = null; |
| 848 | 990 | \\ |
| 849 | \\export fn entry() -> usize { @sizeOf(@typeOf(a)) } | |
| 991 | \\extern fn entry() -> usize { @sizeOf(@typeOf(a)) } | |
| 992 | \\comptime {@export("entry", entry);} | |
| 850 | 993 | , ".tmp_source.zig:1:16: error: expected type '&u8', found '(null)'"); |
| 851 | 994 | |
| 852 | 995 | cases.add("indexing an array of size zero", |
| 853 | 996 | \\const array = []u8{}; |
| 854 | \\export fn foo() { | |
| 997 | \\extern fn foo() { | |
| 855 | 998 | \\ const pointer = &array[0]; |
| 856 | 999 | \\} |
| 1000 | \\comptime {@export("foo", foo);} | |
| 857 | 1001 | , ".tmp_source.zig:3:27: error: index 0 outside array of size 0"); |
| 858 | 1002 | |
| 859 | 1003 | cases.add("compile time division by zero", |
| ... | ... | @@ -862,7 +1006,8 @@ pub fn addCases(cases: &tests.CompileErrorContext) { |
| 862 | 1006 | \\ 1 / x |
| 863 | 1007 | \\} |
| 864 | 1008 | \\ |
| 865 | \\export fn entry() -> usize { @sizeOf(@typeOf(y)) } | |
| 1009 | \\extern fn entry() -> usize { @sizeOf(@typeOf(y)) } | |
| 1010 | \\comptime {@export("entry", entry);} | |
| 866 | 1011 | , |
| 867 | 1012 | ".tmp_source.zig:3:7: error: division by zero is undefined", |
| 868 | 1013 | ".tmp_source.zig:1:14: note: called from here"); |
| ... | ... | @@ -870,7 +1015,8 @@ pub fn addCases(cases: &tests.CompileErrorContext) { |
| 870 | 1015 | cases.add("branch on undefined value", |
| 871 | 1016 | \\const x = if (undefined) true else false; |
| 872 | 1017 | \\ |
| 873 | \\export fn entry() -> usize { @sizeOf(@typeOf(x)) } | |
| 1018 | \\extern fn entry() -> usize { @sizeOf(@typeOf(x)) } | |
| 1019 | \\comptime {@export("entry", entry);} | |
| 874 | 1020 | , ".tmp_source.zig:1:15: error: use of undefined value"); |
| 875 | 1021 | |
| 876 | 1022 | |
| ... | ... | @@ -880,7 +1026,8 @@ pub fn addCases(cases: &tests.CompileErrorContext) { |
| 880 | 1026 | \\ return fibbonaci(x - 1) + fibbonaci(x - 2); |
| 881 | 1027 | \\} |
| 882 | 1028 | \\ |
| 883 | \\export fn entry() -> usize { @sizeOf(@typeOf(seventh_fib_number)) } | |
| 1029 | \\comptime {@export("entry", entry);} | |
| 1030 | \\extern fn entry() -> usize { @sizeOf(@typeOf(seventh_fib_number)) } | |
| 884 | 1031 | , |
| 885 | 1032 | ".tmp_source.zig:3:21: error: evaluation exceeded 1000 backwards branches", |
| 886 | 1033 | ".tmp_source.zig:3:21: note: called from here"); |
| ... | ... | @@ -888,7 +1035,8 @@ pub fn addCases(cases: &tests.CompileErrorContext) { |
| 888 | 1035 | cases.add("@embedFile with bogus file", |
| 889 | 1036 | \\const resource = @embedFile("bogus.txt"); |
| 890 | 1037 | \\ |
| 891 | \\export fn entry() -> usize { @sizeOf(@typeOf(resource)) } | |
| 1038 | \\comptime {@export("entry", entry);} | |
| 1039 | \\extern fn entry() -> usize { @sizeOf(@typeOf(resource)) } | |
| 892 | 1040 | , ".tmp_source.zig:1:29: error: unable to find '", "bogus.txt'"); |
| 893 | 1041 | |
| 894 | 1042 | cases.add("non-const expression in struct literal outside function", |
| ... | ... | @@ -898,7 +1046,8 @@ pub fn addCases(cases: &tests.CompileErrorContext) { |
| 898 | 1046 | \\const a = Foo {.x = get_it()}; |
| 899 | 1047 | \\extern fn get_it() -> i32; |
| 900 | 1048 | \\ |
| 901 | \\export fn entry() -> usize { @sizeOf(@typeOf(a)) } | |
| 1049 | \\comptime {@export("entry", entry);} | |
| 1050 | \\extern fn entry() -> usize { @sizeOf(@typeOf(a)) } | |
| 902 | 1051 | , ".tmp_source.zig:4:21: error: unable to evaluate constant expression"); |
| 903 | 1052 | |
| 904 | 1053 | cases.add("non-const expression function call with struct return value outside function", |
| ... | ... | @@ -912,18 +1061,20 @@ pub fn addCases(cases: &tests.CompileErrorContext) { |
| 912 | 1061 | \\} |
| 913 | 1062 | \\var global_side_effect = false; |
| 914 | 1063 | \\ |
| 915 | \\export fn entry() -> usize { @sizeOf(@typeOf(a)) } | |
| 1064 | \\comptime {@export("entry", entry);} | |
| 1065 | \\extern fn entry() -> usize { @sizeOf(@typeOf(a)) } | |
| 916 | 1066 | , |
| 917 | 1067 | ".tmp_source.zig:6:24: error: unable to evaluate constant expression", |
| 918 | 1068 | ".tmp_source.zig:4:17: note: called from here"); |
| 919 | 1069 | |
| 920 | 1070 | cases.add("undeclared identifier error should mark fn as impure", |
| 921 | \\export fn foo() { | |
| 1071 | \\extern fn foo() { | |
| 922 | 1072 | \\ test_a_thing(); |
| 923 | 1073 | \\} |
| 924 | 1074 | \\fn test_a_thing() { |
| 925 | 1075 | \\ bad_fn_call(); |
| 926 | 1076 | \\} |
| 1077 | \\comptime {@export("foo", foo);} | |
| 927 | 1078 | , ".tmp_source.zig:5:5: error: use of undeclared identifier 'bad_fn_call'"); |
| 928 | 1079 | |
| 929 | 1080 | cases.add("illegal comparison of types", |
| ... | ... | @@ -938,14 +1089,16 @@ pub fn addCases(cases: &tests.CompileErrorContext) { |
| 938 | 1089 | \\ *a == *b |
| 939 | 1090 | \\} |
| 940 | 1091 | \\ |
| 941 | \\export fn entry1() -> usize { @sizeOf(@typeOf(bad_eql_1)) } | |
| 942 | \\export fn entry2() -> usize { @sizeOf(@typeOf(bad_eql_2)) } | |
| 1092 | \\extern fn entry1() -> usize { @sizeOf(@typeOf(bad_eql_1)) } | |
| 1093 | \\extern fn entry2() -> usize { @sizeOf(@typeOf(bad_eql_2)) } | |
| 1094 | \\comptime {@export("entry1", entry1);} | |
| 1095 | \\comptime {@export("entry2", entry2);} | |
| 943 | 1096 | , |
| 944 | 1097 | ".tmp_source.zig:2:7: error: operator not allowed for type '[]u8'", |
| 945 | 1098 | ".tmp_source.zig:9:8: error: operator not allowed for type 'EnumWithData'"); |
| 946 | 1099 | |
| 947 | 1100 | cases.add("non-const switch number literal", |
| 948 | \\export fn foo() { | |
| 1101 | \\extern fn foo() { | |
| 949 | 1102 | \\ const x = switch (bar()) { |
| 950 | 1103 | \\ 1, 2 => 1, |
| 951 | 1104 | \\ 3, 4 => 2, |
| ... | ... | @@ -955,22 +1108,25 @@ pub fn addCases(cases: &tests.CompileErrorContext) { |
| 955 | 1108 | \\fn bar() -> i32 { |
| 956 | 1109 | \\ 2 |
| 957 | 1110 | \\} |
| 1111 | \\comptime {@export("foo", foo);} | |
| 958 | 1112 | , ".tmp_source.zig:2:15: error: unable to infer expression type"); |
| 959 | 1113 | |
| 960 | 1114 | cases.add("atomic orderings of cmpxchg - failure stricter than success", |
| 961 | 1115 | \\const AtomicOrder = @import("builtin").AtomicOrder; |
| 962 | \\export fn f() { | |
| 1116 | \\extern fn f() { | |
| 963 | 1117 | \\ var x: i32 = 1234; |
| 964 | 1118 | \\ while (!@cmpxchg(&x, 1234, 5678, AtomicOrder.Monotonic, AtomicOrder.SeqCst)) {} |
| 965 | 1119 | \\} |
| 1120 | \\comptime {@export("f", f);} | |
| 966 | 1121 | , ".tmp_source.zig:4:72: error: failure atomic ordering must be no stricter than success"); |
| 967 | 1122 | |
| 968 | 1123 | cases.add("atomic orderings of cmpxchg - success Monotonic or stricter", |
| 969 | 1124 | \\const AtomicOrder = @import("builtin").AtomicOrder; |
| 970 | \\export fn f() { | |
| 1125 | \\extern fn f() { | |
| 971 | 1126 | \\ var x: i32 = 1234; |
| 972 | 1127 | \\ while (!@cmpxchg(&x, 1234, 5678, AtomicOrder.Unordered, AtomicOrder.Unordered)) {} |
| 973 | 1128 | \\} |
| 1129 | \\comptime {@export("f", f);} | |
| 974 | 1130 | , ".tmp_source.zig:4:49: error: success atomic ordering must be Monotonic or stricter"); |
| 975 | 1131 | |
| 976 | 1132 | cases.add("negation overflow in function evaluation", |
| ... | ... | @@ -979,7 +1135,8 @@ pub fn addCases(cases: &tests.CompileErrorContext) { |
| 979 | 1135 | \\ -x |
| 980 | 1136 | \\} |
| 981 | 1137 | \\ |
| 982 | \\export fn entry() -> usize { @sizeOf(@typeOf(y)) } | |
| 1138 | \\extern fn entry() -> usize { @sizeOf(@typeOf(y)) } | |
| 1139 | \\comptime {@export("entry", entry);} | |
| 983 | 1140 | , |
| 984 | 1141 | ".tmp_source.zig:3:5: error: negation caused overflow", |
| 985 | 1142 | ".tmp_source.zig:1:14: note: called from here"); |
| ... | ... | @@ -990,7 +1147,8 @@ pub fn addCases(cases: &tests.CompileErrorContext) { |
| 990 | 1147 | \\ a + b |
| 991 | 1148 | \\} |
| 992 | 1149 | \\ |
| 993 | \\export fn entry() -> usize { @sizeOf(@typeOf(y)) } | |
| 1150 | \\extern fn entry() -> usize { @sizeOf(@typeOf(y)) } | |
| 1151 | \\comptime {@export("entry", entry);} | |
| 994 | 1152 | , |
| 995 | 1153 | ".tmp_source.zig:3:7: error: operation caused overflow", |
| 996 | 1154 | ".tmp_source.zig:1:14: note: called from here"); |
| ... | ... | @@ -1002,7 +1160,8 @@ pub fn addCases(cases: &tests.CompileErrorContext) { |
| 1002 | 1160 | \\ a - b |
| 1003 | 1161 | \\} |
| 1004 | 1162 | \\ |
| 1005 | \\export fn entry() -> usize { @sizeOf(@typeOf(y)) } | |
| 1163 | \\extern fn entry() -> usize { @sizeOf(@typeOf(y)) } | |
| 1164 | \\comptime {@export("entry", entry);} | |
| 1006 | 1165 | , |
| 1007 | 1166 | ".tmp_source.zig:3:7: error: operation caused overflow", |
| 1008 | 1167 | ".tmp_source.zig:1:14: note: called from here"); |
| ... | ... | @@ -1013,7 +1172,8 @@ pub fn addCases(cases: &tests.CompileErrorContext) { |
| 1013 | 1172 | \\ a * b |
| 1014 | 1173 | \\} |
| 1015 | 1174 | \\ |
| 1016 | \\export fn entry() -> usize { @sizeOf(@typeOf(y)) } | |
| 1175 | \\extern fn entry() -> usize { @sizeOf(@typeOf(y)) } | |
| 1176 | \\comptime {@export("entry", entry);} | |
| 1017 | 1177 | , |
| 1018 | 1178 | ".tmp_source.zig:3:7: error: operation caused overflow", |
| 1019 | 1179 | ".tmp_source.zig:1:14: note: called from here"); |
| ... | ... | @@ -1024,40 +1184,35 @@ pub fn addCases(cases: &tests.CompileErrorContext) { |
| 1024 | 1184 | \\ @truncate(i8, x) |
| 1025 | 1185 | \\} |
| 1026 | 1186 | \\ |
| 1027 | \\export fn entry() -> usize { @sizeOf(@typeOf(f)) } | |
| 1187 | \\extern fn entry() -> usize { @sizeOf(@typeOf(f)) } | |
| 1188 | \\comptime {@export("entry", entry);} | |
| 1028 | 1189 | , ".tmp_source.zig:3:19: error: expected signed integer type, found 'u32'"); |
| 1029 | 1190 | |
| 1030 | 1191 | cases.add("%return in function with non error return type", |
| 1031 | \\export fn f() { | |
| 1192 | \\extern fn f() { | |
| 1032 | 1193 | \\ %return something(); |
| 1033 | 1194 | \\} |
| 1034 | 1195 | \\fn something() -> %void { } |
| 1196 | \\comptime {@export("f", f);} | |
| 1035 | 1197 | , |
| 1036 | 1198 | ".tmp_source.zig:2:5: error: expected type 'void', found 'error'"); |
| 1037 | 1199 | |
| 1038 | cases.add("wrong return type for main", | |
| 1039 | \\pub fn main() { } | |
| 1040 | , ".tmp_source.zig:1:15: error: expected return type of main to be '%void', instead is 'void'"); | |
| 1041 | ||
| 1042 | cases.add("double ?? on main return value", | |
| 1043 | \\pub fn main() -> ??void { | |
| 1044 | \\} | |
| 1045 | , ".tmp_source.zig:1:18: error: expected return type of main to be '%void', instead is '??void'"); | |
| 1046 | ||
| 1047 | 1200 | cases.add("invalid pointer for var type", |
| 1048 | 1201 | \\extern fn ext() -> usize; |
| 1049 | 1202 | \\var bytes: [ext()]u8 = undefined; |
| 1050 | \\export fn f() { | |
| 1203 | \\extern fn f() { | |
| 1051 | 1204 | \\ for (bytes) |*b, i| { |
| 1052 | 1205 | \\ *b = u8(i); |
| 1053 | 1206 | \\ } |
| 1054 | 1207 | \\} |
| 1208 | \\comptime {@export("f", f);} | |
| 1055 | 1209 | , ".tmp_source.zig:2:13: error: unable to evaluate constant expression"); |
| 1056 | 1210 | |
| 1057 | 1211 | cases.add("export function with comptime parameter", |
| 1058 | \\export fn foo(comptime x: i32, y: i32) -> i32{ | |
| 1212 | \\extern fn foo(comptime x: i32, y: i32) -> i32{ | |
| 1059 | 1213 | \\ x + y |
| 1060 | 1214 | \\} |
| 1215 | \\comptime {@export("foo", foo);} | |
| 1061 | 1216 | , ".tmp_source.zig:1:15: error: comptime parameter not allowed in function with calling convention 'ccc'"); |
| 1062 | 1217 | |
| 1063 | 1218 | cases.add("extern function with comptime parameter", |
| ... | ... | @@ -1065,14 +1220,16 @@ pub fn addCases(cases: &tests.CompileErrorContext) { |
| 1065 | 1220 | \\fn f() -> i32 { |
| 1066 | 1221 | \\ foo(1, 2) |
| 1067 | 1222 | \\} |
| 1068 | \\export fn entry() -> usize { @sizeOf(@typeOf(f)) } | |
| 1223 | \\extern fn entry() -> usize { @sizeOf(@typeOf(f)) } | |
| 1224 | \\comptime {@export("entry", entry);} | |
| 1069 | 1225 | , ".tmp_source.zig:1:15: error: comptime parameter not allowed in function with calling convention 'ccc'"); |
| 1070 | 1226 | |
| 1071 | 1227 | cases.add("convert fixed size array to slice with invalid size", |
| 1072 | \\export fn f() { | |
| 1228 | \\extern fn f() { | |
| 1073 | 1229 | \\ var array: [5]u8 = undefined; |
| 1074 | 1230 | \\ var foo = ([]const u32)(array)[0]; |
| 1075 | 1231 | \\} |
| 1232 | \\comptime {@export("f", f);} | |
| 1076 | 1233 | , ".tmp_source.zig:3:28: error: unable to convert [5]u8 to []const u32: size mismatch"); |
| 1077 | 1234 | |
| 1078 | 1235 | cases.add("non-pure function returns type", |
| ... | ... | @@ -1090,10 +1247,11 @@ pub fn addCases(cases: &tests.CompileErrorContext) { |
| 1090 | 1247 | \\ } |
| 1091 | 1248 | \\} |
| 1092 | 1249 | \\ |
| 1093 | \\export fn function_with_return_type_type() { | |
| 1250 | \\extern fn function_with_return_type_type() { | |
| 1094 | 1251 | \\ var list: List(i32) = undefined; |
| 1095 | 1252 | \\ list.length = 10; |
| 1096 | 1253 | \\} |
| 1254 | \\comptime {@export("function_with_return_type_type", function_with_return_type_type);} | |
| 1097 | 1255 | , ".tmp_source.zig:3:7: error: unable to evaluate constant expression", |
| 1098 | 1256 | ".tmp_source.zig:16:19: note: called from here"); |
| 1099 | 1257 | |
| ... | ... | @@ -1102,7 +1260,8 @@ pub fn addCases(cases: &tests.CompileErrorContext) { |
| 1102 | 1260 | \\fn f(m: []const u8) { |
| 1103 | 1261 | \\ m.copy(u8, self[0..], m); |
| 1104 | 1262 | \\} |
| 1105 | \\export fn entry() -> usize { @sizeOf(@typeOf(f)) } | |
| 1263 | \\extern fn entry() -> usize { @sizeOf(@typeOf(f)) } | |
| 1264 | \\comptime {@export("entry", entry);} | |
| 1106 | 1265 | , ".tmp_source.zig:3:6: error: no member named 'copy' in '[]const u8'"); |
| 1107 | 1266 | |
| 1108 | 1267 | cases.add("wrong number of arguments for method fn call", |
| ... | ... | @@ -1113,21 +1272,24 @@ pub fn addCases(cases: &tests.CompileErrorContext) { |
| 1113 | 1272 | \\ |
| 1114 | 1273 | \\ foo.method(1, 2); |
| 1115 | 1274 | \\} |
| 1116 | \\export fn entry() -> usize { @sizeOf(@typeOf(f)) } | |
| 1275 | \\extern fn entry() -> usize { @sizeOf(@typeOf(f)) } | |
| 1276 | \\comptime {@export("entry", entry);} | |
| 1117 | 1277 | , ".tmp_source.zig:6:15: error: expected 2 arguments, found 3"); |
| 1118 | 1278 | |
| 1119 | 1279 | cases.add("assign through constant pointer", |
| 1120 | \\export fn f() { | |
| 1280 | \\extern fn f() { | |
| 1121 | 1281 | \\ var cstr = c"Hat"; |
| 1122 | 1282 | \\ cstr[0] = 'W'; |
| 1123 | 1283 | \\} |
| 1284 | \\comptime {@export("f", f);} | |
| 1124 | 1285 | , ".tmp_source.zig:3:11: error: cannot assign to constant"); |
| 1125 | 1286 | |
| 1126 | 1287 | cases.add("assign through constant slice", |
| 1127 | \\export fn f() { | |
| 1288 | \\extern fn f() { | |
| 1128 | 1289 | \\ var cstr: []const u8 = "Hat"; |
| 1129 | 1290 | \\ cstr[0] = 'W'; |
| 1130 | 1291 | \\} |
| 1292 | \\comptime {@export("f", f);} | |
| 1131 | 1293 | , ".tmp_source.zig:3:11: error: cannot assign to constant"); |
| 1132 | 1294 | |
| 1133 | 1295 | cases.add("main function with bogus args type", |
| ... | ... | @@ -1138,7 +1300,8 @@ pub fn addCases(cases: &tests.CompileErrorContext) { |
| 1138 | 1300 | \\fn foo(blah: []u8) { |
| 1139 | 1301 | \\ for (blah) { } |
| 1140 | 1302 | \\} |
| 1141 | \\export fn entry() -> usize { @sizeOf(@typeOf(foo)) } | |
| 1303 | \\extern fn entry() -> usize { @sizeOf(@typeOf(foo)) } | |
| 1304 | \\comptime {@export("entry", entry);} | |
| 1142 | 1305 | , ".tmp_source.zig:2:5: error: for loop expression missing element parameter"); |
| 1143 | 1306 | |
| 1144 | 1307 | cases.add("misspelled type with pointer only reference", |
| ... | ... | @@ -1171,7 +1334,8 @@ pub fn addCases(cases: &tests.CompileErrorContext) { |
| 1171 | 1334 | \\ var jd = JsonNode {.kind = JsonType.JSONArray , .jobject = JsonOA.JSONArray {jll} }; |
| 1172 | 1335 | \\} |
| 1173 | 1336 | \\ |
| 1174 | \\export fn entry() -> usize { @sizeOf(@typeOf(foo)) } | |
| 1337 | \\extern fn entry() -> usize { @sizeOf(@typeOf(foo)) } | |
| 1338 | \\comptime {@export("entry", entry);} | |
| 1175 | 1339 | , ".tmp_source.zig:5:16: error: use of undeclared identifier 'JsonList'"); |
| 1176 | 1340 | |
| 1177 | 1341 | cases.add("method call with first arg type primitive", |
| ... | ... | @@ -1185,11 +1349,12 @@ pub fn addCases(cases: &tests.CompileErrorContext) { |
| 1185 | 1349 | \\ } |
| 1186 | 1350 | \\}; |
| 1187 | 1351 | \\ |
| 1188 | \\export fn f() { | |
| 1352 | \\extern fn f() { | |
| 1189 | 1353 | \\ const derp = Foo.init(3); |
| 1190 | 1354 | \\ |
| 1191 | 1355 | \\ derp.init(); |
| 1192 | 1356 | \\} |
| 1357 | \\comptime {@export("f", f);} | |
| 1193 | 1358 | , ".tmp_source.zig:14:5: error: expected type 'i32', found '&const Foo'"); |
| 1194 | 1359 | |
| 1195 | 1360 | cases.add("method call with first arg type wrong container", |
| ... | ... | @@ -1213,10 +1378,11 @@ pub fn addCases(cases: &tests.CompileErrorContext) { |
| 1213 | 1378 | \\ field: i32, |
| 1214 | 1379 | \\}; |
| 1215 | 1380 | \\ |
| 1216 | \\export fn foo() { | |
| 1381 | \\extern fn foo() { | |
| 1217 | 1382 | \\ var x = List.init(&global_allocator); |
| 1218 | 1383 | \\ x.init(); |
| 1219 | 1384 | \\} |
| 1385 | \\comptime {@export("foo", foo);} | |
| 1220 | 1386 | , ".tmp_source.zig:23:5: error: expected type '&Allocator', found '&List'"); |
| 1221 | 1387 | |
| 1222 | 1388 | cases.add("binary not on number literal", |
| ... | ... | @@ -1224,16 +1390,18 @@ pub fn addCases(cases: &tests.CompileErrorContext) { |
| 1224 | 1390 | \\const TINY_QUANTUM_SIZE = 1 << TINY_QUANTUM_SHIFT; |
| 1225 | 1391 | \\var block_aligned_stuff: usize = (4 + TINY_QUANTUM_SIZE) & ~(TINY_QUANTUM_SIZE - 1); |
| 1226 | 1392 | \\ |
| 1227 | \\export fn entry() -> usize { @sizeOf(@typeOf(block_aligned_stuff)) } | |
| 1393 | \\extern fn entry() -> usize { @sizeOf(@typeOf(block_aligned_stuff)) } | |
| 1394 | \\comptime {@export("entry", entry);} | |
| 1228 | 1395 | , ".tmp_source.zig:3:60: error: unable to perform binary not operation on type '(integer literal)'"); |
| 1229 | 1396 | |
| 1230 | 1397 | cases.addCase({ |
| 1231 | 1398 | const tc = cases.create("multiple files with private function error", |
| 1232 | 1399 | \\const foo = @import("foo.zig"); |
| 1233 | 1400 | \\ |
| 1234 | \\export fn callPrivFunction() { | |
| 1401 | \\extern fn callPrivFunction() { | |
| 1235 | 1402 | \\ foo.privateFunction(); |
| 1236 | 1403 | \\} |
| 1404 | \\comptime {@export("callPrivFunction", callPrivFunction);} | |
| 1237 | 1405 | , |
| 1238 | 1406 | ".tmp_source.zig:4:8: error: 'privateFunction' is private", |
| 1239 | 1407 | "foo.zig:1:1: note: declared here"); |
| ... | ... | @@ -1249,17 +1417,19 @@ pub fn addCases(cases: &tests.CompileErrorContext) { |
| 1249 | 1417 | \\const zero: i32 = 0; |
| 1250 | 1418 | \\const a = zero{1}; |
| 1251 | 1419 | \\ |
| 1252 | \\export fn entry() -> usize { @sizeOf(@typeOf(a)) } | |
| 1420 | \\extern fn entry() -> usize { @sizeOf(@typeOf(a)) } | |
| 1421 | \\comptime {@export("entry", entry);} | |
| 1253 | 1422 | , ".tmp_source.zig:2:11: error: expected type, found 'i32'"); |
| 1254 | 1423 | |
| 1255 | 1424 | cases.add("assign to constant field", |
| 1256 | 1425 | \\const Foo = struct { |
| 1257 | 1426 | \\ field: i32, |
| 1258 | 1427 | \\}; |
| 1259 | \\export fn derp() { | |
| 1428 | \\extern fn derp() { | |
| 1260 | 1429 | \\ const f = Foo {.field = 1234,}; |
| 1261 | 1430 | \\ f.field = 0; |
| 1262 | 1431 | \\} |
| 1432 | \\comptime {@export("derp", derp);} | |
| 1263 | 1433 | , ".tmp_source.zig:6:13: error: cannot assign to constant"); |
| 1264 | 1434 | |
| 1265 | 1435 | cases.add("return from defer expression", |
| ... | ... | @@ -1277,7 +1447,8 @@ pub fn addCases(cases: &tests.CompileErrorContext) { |
| 1277 | 1447 | \\ return 0; |
| 1278 | 1448 | \\} |
| 1279 | 1449 | \\ |
| 1280 | \\export fn entry() -> usize { @sizeOf(@typeOf(testTrickyDefer)) } | |
| 1450 | \\extern fn entry() -> usize { @sizeOf(@typeOf(testTrickyDefer)) } | |
| 1451 | \\comptime {@export("entry", entry);} | |
| 1281 | 1452 | , ".tmp_source.zig:4:11: error: cannot return from defer expression"); |
| 1282 | 1453 | |
| 1283 | 1454 | cases.add("attempt to access var args out of bounds", |
| ... | ... | @@ -1289,7 +1460,8 @@ pub fn addCases(cases: &tests.CompileErrorContext) { |
| 1289 | 1460 | \\ add(i32(1234)) |
| 1290 | 1461 | \\} |
| 1291 | 1462 | \\ |
| 1292 | \\export fn entry() -> usize { @sizeOf(@typeOf(foo)) } | |
| 1463 | \\comptime {@export("entry", entry);} | |
| 1464 | \\extern fn entry() -> usize { @sizeOf(@typeOf(foo)) } | |
| 1293 | 1465 | , |
| 1294 | 1466 | ".tmp_source.zig:2:19: error: index 1 outside argument list of size 1", |
| 1295 | 1467 | ".tmp_source.zig:6:8: note: called from here"); |
| ... | ... | @@ -1307,27 +1479,31 @@ pub fn addCases(cases: &tests.CompileErrorContext) { |
| 1307 | 1479 | \\ add(1, 2, 3, 4) |
| 1308 | 1480 | \\} |
| 1309 | 1481 | \\ |
| 1310 | \\export fn entry() -> usize { @sizeOf(@typeOf(bar)) } | |
| 1482 | \\comptime {@export("entry", entry);} | |
| 1483 | \\extern fn entry() -> usize { @sizeOf(@typeOf(bar)) } | |
| 1311 | 1484 | , ".tmp_source.zig:10:9: error: parameter of type '(integer literal)' requires comptime"); |
| 1312 | 1485 | |
| 1313 | 1486 | cases.add("assign too big number to u16", |
| 1314 | \\export fn foo() { | |
| 1487 | \\extern fn foo() { | |
| 1315 | 1488 | \\ var vga_mem: u16 = 0xB8000; |
| 1316 | 1489 | \\} |
| 1490 | \\comptime {@export("foo", foo);} | |
| 1317 | 1491 | , ".tmp_source.zig:2:24: error: integer value 753664 cannot be implicitly casted to type 'u16'"); |
| 1318 | 1492 | |
| 1319 | 1493 | cases.add("global variable alignment non power of 2", |
| 1320 | 1494 | \\const some_data: [100]u8 align(3) = undefined; |
| 1321 | \\export fn entry() -> usize { @sizeOf(@typeOf(some_data)) } | |
| 1495 | \\extern fn entry() -> usize { @sizeOf(@typeOf(some_data)) } | |
| 1496 | \\comptime {@export("entry", entry);} | |
| 1322 | 1497 | , ".tmp_source.zig:1:32: error: alignment value 3 is not a power of 2"); |
| 1323 | 1498 | |
| 1324 | 1499 | cases.add("function alignment non power of 2", |
| 1325 | 1500 | \\extern fn foo() align(3); |
| 1326 | \\export fn entry() { foo() } | |
| 1501 | \\extern fn entry() { foo() } | |
| 1502 | \\comptime {@export("entry", entry);} | |
| 1327 | 1503 | , ".tmp_source.zig:1:23: error: alignment value 3 is not a power of 2"); |
| 1328 | 1504 | |
| 1329 | 1505 | cases.add("compile log", |
| 1330 | \\export fn foo() { | |
| 1506 | \\extern fn foo() { | |
| 1331 | 1507 | \\ comptime bar(12, "hi"); |
| 1332 | 1508 | \\} |
| 1333 | 1509 | \\fn bar(a: i32, b: []const u8) { |
| ... | ... | @@ -1335,6 +1511,7 @@ pub fn addCases(cases: &tests.CompileErrorContext) { |
| 1335 | 1511 | \\ @compileLog("a", a, "b", b); |
| 1336 | 1512 | \\ @compileLog("end"); |
| 1337 | 1513 | \\} |
| 1514 | \\comptime {@export("foo", foo);} | |
| 1338 | 1515 | , |
| 1339 | 1516 | ".tmp_source.zig:5:5: error: found compile log statement", |
| 1340 | 1517 | ".tmp_source.zig:2:17: note: called from here", |
| ... | ... | @@ -1358,7 +1535,8 @@ pub fn addCases(cases: &tests.CompileErrorContext) { |
| 1358 | 1535 | \\ return *x; |
| 1359 | 1536 | \\} |
| 1360 | 1537 | \\ |
| 1361 | \\export fn entry() -> usize { @sizeOf(@typeOf(foo)) } | |
| 1538 | \\extern fn entry() -> usize { @sizeOf(@typeOf(foo)) } | |
| 1539 | \\comptime {@export("entry", entry);} | |
| 1362 | 1540 | , ".tmp_source.zig:8:26: error: expected type '&const u3', found '&align(1:3:6) const u3'"); |
| 1363 | 1541 | |
| 1364 | 1542 | cases.add("referring to a struct that is invalid", |
| ... | ... | @@ -1366,19 +1544,20 @@ pub fn addCases(cases: &tests.CompileErrorContext) { |
| 1366 | 1544 | \\ Type: u8, |
| 1367 | 1545 | \\}; |
| 1368 | 1546 | \\ |
| 1369 | \\export fn foo() { | |
| 1547 | \\extern fn foo() { | |
| 1370 | 1548 | \\ comptime assert(@sizeOf(UsbDeviceRequest) == 0x8); |
| 1371 | 1549 | \\} |
| 1372 | 1550 | \\ |
| 1373 | 1551 | \\fn assert(ok: bool) { |
| 1374 | 1552 | \\ if (!ok) unreachable; |
| 1375 | 1553 | \\} |
| 1554 | \\comptime {@export("foo", foo);} | |
| 1376 | 1555 | , |
| 1377 | 1556 | ".tmp_source.zig:10:14: error: unable to evaluate constant expression", |
| 1378 | 1557 | ".tmp_source.zig:6:20: note: called from here"); |
| 1379 | 1558 | |
| 1380 | 1559 | cases.add("control flow uses comptime var at runtime", |
| 1381 | \\export fn foo() { | |
| 1560 | \\extern fn foo() { | |
| 1382 | 1561 | \\ comptime var i = 0; |
| 1383 | 1562 | \\ while (i < 5) : (i += 1) { |
| 1384 | 1563 | \\ bar(); |
| ... | ... | @@ -1386,53 +1565,61 @@ pub fn addCases(cases: &tests.CompileErrorContext) { |
| 1386 | 1565 | \\} |
| 1387 | 1566 | \\ |
| 1388 | 1567 | \\fn bar() { } |
| 1568 | \\comptime {@export("foo", foo);} | |
| 1389 | 1569 | , |
| 1390 | 1570 | ".tmp_source.zig:3:5: error: control flow attempts to use compile-time variable at runtime", |
| 1391 | 1571 | ".tmp_source.zig:3:24: note: compile-time variable assigned here"); |
| 1392 | 1572 | |
| 1393 | 1573 | cases.add("ignored return value", |
| 1394 | \\export fn foo() { | |
| 1574 | \\extern fn foo() { | |
| 1395 | 1575 | \\ bar(); |
| 1396 | 1576 | \\} |
| 1397 | 1577 | \\fn bar() -> i32 { 0 } |
| 1578 | \\comptime {@export("foo", foo);} | |
| 1398 | 1579 | , ".tmp_source.zig:2:8: error: expression value is ignored"); |
| 1399 | 1580 | |
| 1400 | 1581 | cases.add("ignored assert-err-ok return value", |
| 1401 | \\export fn foo() { | |
| 1582 | \\extern fn foo() { | |
| 1402 | 1583 | \\ %%bar(); |
| 1403 | 1584 | \\} |
| 1404 | 1585 | \\fn bar() -> %i32 { 0 } |
| 1586 | \\comptime {@export("foo", foo);} | |
| 1405 | 1587 | , ".tmp_source.zig:2:5: error: expression value is ignored"); |
| 1406 | 1588 | |
| 1407 | 1589 | cases.add("ignored statement value", |
| 1408 | \\export fn foo() { | |
| 1590 | \\extern fn foo() { | |
| 1409 | 1591 | \\ 1; |
| 1410 | 1592 | \\} |
| 1593 | \\comptime {@export("foo", foo);} | |
| 1411 | 1594 | , ".tmp_source.zig:2:5: error: expression value is ignored"); |
| 1412 | 1595 | |
| 1413 | 1596 | cases.add("ignored comptime statement value", |
| 1414 | \\export fn foo() { | |
| 1597 | \\extern fn foo() { | |
| 1415 | 1598 | \\ comptime {1;} |
| 1416 | 1599 | \\} |
| 1600 | \\comptime {@export("foo", foo);} | |
| 1417 | 1601 | , ".tmp_source.zig:2:15: error: expression value is ignored"); |
| 1418 | 1602 | |
| 1419 | 1603 | cases.add("ignored comptime value", |
| 1420 | \\export fn foo() { | |
| 1604 | \\extern fn foo() { | |
| 1421 | 1605 | \\ comptime 1; |
| 1422 | 1606 | \\} |
| 1607 | \\comptime {@export("foo", foo);} | |
| 1423 | 1608 | , ".tmp_source.zig:2:5: error: expression value is ignored"); |
| 1424 | 1609 | |
| 1425 | 1610 | cases.add("ignored defered statement value", |
| 1426 | \\export fn foo() { | |
| 1611 | \\extern fn foo() { | |
| 1427 | 1612 | \\ defer {1;} |
| 1428 | 1613 | \\} |
| 1614 | \\comptime {@export("foo", foo);} | |
| 1429 | 1615 | , ".tmp_source.zig:2:12: error: expression value is ignored"); |
| 1430 | 1616 | |
| 1431 | 1617 | cases.add("ignored defered statement value", |
| 1432 | \\export fn foo() { | |
| 1618 | \\extern fn foo() { | |
| 1433 | 1619 | \\ defer bar(); |
| 1434 | 1620 | \\} |
| 1435 | 1621 | \\fn bar() -> %i32 { 0 } |
| 1622 | \\comptime {@export("foo", foo);} | |
| 1436 | 1623 | , ".tmp_source.zig:2:14: error: expression value is ignored"); |
| 1437 | 1624 | |
| 1438 | 1625 | cases.add("dereference an array", |
| ... | ... | @@ -1443,7 +1630,8 @@ pub fn addCases(cases: &tests.CompileErrorContext) { |
| 1443 | 1630 | \\ return (*out)[0..1]; |
| 1444 | 1631 | \\} |
| 1445 | 1632 | \\ |
| 1446 | \\export fn entry() -> usize { @sizeOf(@typeOf(pass)) } | |
| 1633 | \\extern fn entry() -> usize { @sizeOf(@typeOf(pass)) } | |
| 1634 | \\comptime {@export("entry", entry);} | |
| 1447 | 1635 | , ".tmp_source.zig:4:5: error: attempt to dereference non pointer type '[10]u8'"); |
| 1448 | 1636 | |
| 1449 | 1637 | cases.add("pass const ptr to mutable ptr fn", |
| ... | ... | @@ -1456,46 +1644,31 @@ pub fn addCases(cases: &tests.CompileErrorContext) { |
| 1456 | 1644 | \\ return true; |
| 1457 | 1645 | \\} |
| 1458 | 1646 | \\ |
| 1459 | \\export fn entry() -> usize { @sizeOf(@typeOf(foo)) } | |
| 1647 | \\extern fn entry() -> usize { @sizeOf(@typeOf(foo)) } | |
| 1648 | \\comptime {@export("entry", entry);} | |
| 1460 | 1649 | , ".tmp_source.zig:4:19: error: expected type '&[]const u8', found '&const []const u8'"); |
| 1461 | 1650 | |
| 1462 | cases.addCase({ | |
| 1463 | const tc = cases.create("export collision", | |
| 1464 | \\const foo = @import("foo.zig"); | |
| 1465 | \\ | |
| 1466 | \\export fn bar() -> usize { | |
| 1467 | \\ return foo.baz; | |
| 1468 | \\} | |
| 1469 | , | |
| 1470 | "foo.zig:1:8: error: exported symbol collision: 'bar'", | |
| 1471 | ".tmp_source.zig:3:8: note: other symbol is here"); | |
| 1472 | ||
| 1473 | tc.addSourceFile("foo.zig", | |
| 1474 | \\export fn bar() {} | |
| 1475 | \\pub const baz = 1234; | |
| 1476 | ); | |
| 1477 | ||
| 1478 | tc | |
| 1479 | }); | |
| 1480 | ||
| 1481 | 1651 | cases.add("pass non-copyable type by value to function", |
| 1482 | 1652 | \\const Point = struct { x: i32, y: i32, }; |
| 1483 | 1653 | \\fn foo(p: Point) { } |
| 1484 | \\export fn entry() -> usize { @sizeOf(@typeOf(foo)) } | |
| 1654 | \\extern fn entry() -> usize { @sizeOf(@typeOf(foo)) } | |
| 1655 | \\comptime {@export("entry", entry);} | |
| 1485 | 1656 | , ".tmp_source.zig:2:11: error: type 'Point' is not copyable; cannot pass by value"); |
| 1486 | 1657 | |
| 1487 | 1658 | cases.add("implicit cast from array to mutable slice", |
| 1488 | 1659 | \\var global_array: [10]i32 = undefined; |
| 1489 | 1660 | \\fn foo(param: []i32) {} |
| 1490 | \\export fn entry() { | |
| 1661 | \\extern fn entry() { | |
| 1491 | 1662 | \\ foo(global_array); |
| 1492 | 1663 | \\} |
| 1664 | \\comptime {@export("entry", entry);} | |
| 1493 | 1665 | , ".tmp_source.zig:4:9: error: expected type '[]i32', found '[10]i32'"); |
| 1494 | 1666 | |
| 1495 | 1667 | cases.add("ptrcast to non-pointer", |
| 1496 | \\export fn entry(a: &i32) -> usize { | |
| 1668 | \\extern fn entry(a: &i32) -> usize { | |
| 1497 | 1669 | \\ return @ptrCast(usize, a); |
| 1498 | 1670 | \\} |
| 1671 | \\comptime {@export("entry", entry);} | |
| 1499 | 1672 | , ".tmp_source.zig:2:21: error: expected pointer, found 'usize'"); |
| 1500 | 1673 | |
| 1501 | 1674 | cases.add("too many error values to cast to small integer", |
| ... | ... | @@ -1504,7 +1677,8 @@ pub fn addCases(cases: &tests.CompileErrorContext) { |
| 1504 | 1677 | \\fn foo(e: error) -> u2 { |
| 1505 | 1678 | \\ return u2(e); |
| 1506 | 1679 | \\} |
| 1507 | \\export fn entry() -> usize { @sizeOf(@typeOf(foo)) } | |
| 1680 | \\extern fn entry() -> usize { @sizeOf(@typeOf(foo)) } | |
| 1681 | \\comptime {@export("entry", entry);} | |
| 1508 | 1682 | , ".tmp_source.zig:4:14: error: too many error values to fit in 'u2'"); |
| 1509 | 1683 | |
| 1510 | 1684 | cases.add("asm at compile time", |
| ... | ... | @@ -1523,41 +1697,46 @@ pub fn addCases(cases: &tests.CompileErrorContext) { |
| 1523 | 1697 | |
| 1524 | 1698 | cases.add("invalid member of builtin enum", |
| 1525 | 1699 | \\const builtin = @import("builtin"); |
| 1526 | \\export fn entry() { | |
| 1700 | \\extern fn entry() { | |
| 1527 | 1701 | \\ const foo = builtin.Arch.x86; |
| 1528 | 1702 | \\} |
| 1703 | \\comptime {@export("entry", entry);} | |
| 1529 | 1704 | , ".tmp_source.zig:3:29: error: container 'Arch' has no member called 'x86'"); |
| 1530 | 1705 | |
| 1531 | 1706 | cases.add("int to ptr of 0 bits", |
| 1532 | \\export fn foo() { | |
| 1707 | \\extern fn foo() { | |
| 1533 | 1708 | \\ var x: usize = 0x1000; |
| 1534 | 1709 | \\ var y: &void = @intToPtr(&void, x); |
| 1535 | 1710 | \\} |
| 1711 | \\comptime {@export("foo", foo);} | |
| 1536 | 1712 | , ".tmp_source.zig:3:31: error: type '&void' has 0 bits and cannot store information"); |
| 1537 | 1713 | |
| 1538 | 1714 | cases.add("@fieldParentPtr - non struct", |
| 1539 | 1715 | \\const Foo = i32; |
| 1540 | \\export fn foo(a: &i32) -> &Foo { | |
| 1716 | \\extern fn foo(a: &i32) -> &Foo { | |
| 1541 | 1717 | \\ return @fieldParentPtr(Foo, "a", a); |
| 1542 | 1718 | \\} |
| 1719 | \\comptime {@export("foo", foo);} | |
| 1543 | 1720 | , ".tmp_source.zig:3:28: error: expected struct type, found 'i32'"); |
| 1544 | 1721 | |
| 1545 | 1722 | cases.add("@fieldParentPtr - bad field name", |
| 1546 | 1723 | \\const Foo = struct { |
| 1547 | 1724 | \\ derp: i32, |
| 1548 | 1725 | \\}; |
| 1549 | \\export fn foo(a: &i32) -> &Foo { | |
| 1726 | \\extern fn foo(a: &i32) -> &Foo { | |
| 1550 | 1727 | \\ return @fieldParentPtr(Foo, "a", a); |
| 1551 | 1728 | \\} |
| 1729 | \\comptime {@export("foo", foo);} | |
| 1552 | 1730 | , ".tmp_source.zig:5:33: error: struct 'Foo' has no field 'a'"); |
| 1553 | 1731 | |
| 1554 | 1732 | cases.add("@fieldParentPtr - field pointer is not pointer", |
| 1555 | 1733 | \\const Foo = struct { |
| 1556 | 1734 | \\ a: i32, |
| 1557 | 1735 | \\}; |
| 1558 | \\export fn foo(a: i32) -> &Foo { | |
| 1736 | \\extern fn foo(a: i32) -> &Foo { | |
| 1559 | 1737 | \\ return @fieldParentPtr(Foo, "a", a); |
| 1560 | 1738 | \\} |
| 1739 | \\comptime {@export("foo", foo);} | |
| 1561 | 1740 | , ".tmp_source.zig:5:38: error: expected pointer, found 'i32'"); |
| 1562 | 1741 | |
| 1563 | 1742 | cases.add("@fieldParentPtr - comptime field ptr not based on struct", |
| ... | ... | @@ -1587,18 +1766,20 @@ pub fn addCases(cases: &tests.CompileErrorContext) { |
| 1587 | 1766 | |
| 1588 | 1767 | cases.add("@offsetOf - non struct", |
| 1589 | 1768 | \\const Foo = i32; |
| 1590 | \\export fn foo() -> usize { | |
| 1769 | \\extern fn foo() -> usize { | |
| 1591 | 1770 | \\ return @offsetOf(Foo, "a"); |
| 1592 | 1771 | \\} |
| 1772 | \\comptime {@export("foo", foo);} | |
| 1593 | 1773 | , ".tmp_source.zig:3:22: error: expected struct type, found 'i32'"); |
| 1594 | 1774 | |
| 1595 | 1775 | cases.add("@offsetOf - bad field name", |
| 1596 | 1776 | \\const Foo = struct { |
| 1597 | 1777 | \\ derp: i32, |
| 1598 | 1778 | \\}; |
| 1599 | \\export fn foo() -> usize { | |
| 1779 | \\extern fn foo() -> usize { | |
| 1600 | 1780 | \\ return @offsetOf(Foo, "a"); |
| 1601 | 1781 | \\} |
| 1782 | \\comptime {@export("foo", foo);} | |
| 1602 | 1783 | , ".tmp_source.zig:5:27: error: struct 'Foo' has no field 'a'"); |
| 1603 | 1784 | |
| 1604 | 1785 | cases.addExe("missing main fn in executable", |
| ... | ... | @@ -1611,38 +1792,22 @@ pub fn addCases(cases: &tests.CompileErrorContext) { |
| 1611 | 1792 | "error: 'main' is private", |
| 1612 | 1793 | ".tmp_source.zig:1:1: note: declared here"); |
| 1613 | 1794 | |
| 1614 | cases.add("@setGlobalSection extern variable", | |
| 1615 | \\extern var foo: i32; | |
| 1616 | \\comptime { | |
| 1617 | \\ @setGlobalSection(foo, ".text2"); | |
| 1618 | \\} | |
| 1619 | , | |
| 1620 | ".tmp_source.zig:3:5: error: cannot set section of external variable 'foo'", | |
| 1621 | ".tmp_source.zig:1:8: note: declared here"); | |
| 1622 | ||
| 1623 | cases.add("@setGlobalSection extern fn", | |
| 1624 | \\extern fn foo(); | |
| 1625 | \\comptime { | |
| 1626 | \\ @setGlobalSection(foo, ".text2"); | |
| 1627 | \\} | |
| 1628 | , | |
| 1629 | ".tmp_source.zig:3:5: error: cannot set section of external function 'foo'", | |
| 1630 | ".tmp_source.zig:1:8: note: declared here"); | |
| 1631 | ||
| 1632 | 1795 | cases.add("returning address of local variable - simple", |
| 1633 | \\export fn foo() -> &i32 { | |
| 1796 | \\extern fn foo() -> &i32 { | |
| 1634 | 1797 | \\ var a: i32 = undefined; |
| 1635 | 1798 | \\ return &a; |
| 1636 | 1799 | \\} |
| 1800 | \\comptime {@export("foo", foo);} | |
| 1637 | 1801 | , |
| 1638 | 1802 | ".tmp_source.zig:3:13: error: function returns address of local variable"); |
| 1639 | 1803 | |
| 1640 | 1804 | cases.add("returning address of local variable - phi", |
| 1641 | \\export fn foo(c: bool) -> &i32 { | |
| 1805 | \\extern fn foo(c: bool) -> &i32 { | |
| 1642 | 1806 | \\ var a: i32 = undefined; |
| 1643 | 1807 | \\ var b: i32 = undefined; |
| 1644 | 1808 | \\ return if (c) &a else &b; |
| 1645 | 1809 | \\} |
| 1810 | \\comptime {@export("foo", foo);} | |
| 1646 | 1811 | , |
| 1647 | 1812 | ".tmp_source.zig:4:12: error: function returns address of local variable"); |
| 1648 | 1813 | |
| ... | ... | @@ -1671,55 +1836,61 @@ pub fn addCases(cases: &tests.CompileErrorContext) { |
| 1671 | 1836 | ".tmp_source.zig:5:9: note: previous definition is here"); |
| 1672 | 1837 | |
| 1673 | 1838 | cases.add("while expected bool, got nullable", |
| 1674 | \\export fn foo() { | |
| 1839 | \\extern fn foo() { | |
| 1675 | 1840 | \\ while (bar()) {} |
| 1676 | 1841 | \\} |
| 1677 | 1842 | \\fn bar() -> ?i32 { 1 } |
| 1843 | \\comptime {@export("foo", foo);} | |
| 1678 | 1844 | , |
| 1679 | 1845 | ".tmp_source.zig:2:15: error: expected type 'bool', found '?i32'"); |
| 1680 | 1846 | |
| 1681 | 1847 | cases.add("while expected bool, got error union", |
| 1682 | \\export fn foo() { | |
| 1848 | \\extern fn foo() { | |
| 1683 | 1849 | \\ while (bar()) {} |
| 1684 | 1850 | \\} |
| 1685 | 1851 | \\fn bar() -> %i32 { 1 } |
| 1852 | \\comptime {@export("foo", foo);} | |
| 1686 | 1853 | , |
| 1687 | 1854 | ".tmp_source.zig:2:15: error: expected type 'bool', found '%i32'"); |
| 1688 | 1855 | |
| 1689 | 1856 | cases.add("while expected nullable, got bool", |
| 1690 | \\export fn foo() { | |
| 1857 | \\extern fn foo() { | |
| 1691 | 1858 | \\ while (bar()) |x| {} |
| 1692 | 1859 | \\} |
| 1693 | 1860 | \\fn bar() -> bool { true } |
| 1861 | \\comptime {@export("foo", foo);} | |
| 1694 | 1862 | , |
| 1695 | 1863 | ".tmp_source.zig:2:15: error: expected nullable type, found 'bool'"); |
| 1696 | 1864 | |
| 1697 | 1865 | cases.add("while expected nullable, got error union", |
| 1698 | \\export fn foo() { | |
| 1866 | \\extern fn foo() { | |
| 1699 | 1867 | \\ while (bar()) |x| {} |
| 1700 | 1868 | \\} |
| 1701 | 1869 | \\fn bar() -> %i32 { 1 } |
| 1870 | \\comptime {@export("foo", foo);} | |
| 1702 | 1871 | , |
| 1703 | 1872 | ".tmp_source.zig:2:15: error: expected nullable type, found '%i32'"); |
| 1704 | 1873 | |
| 1705 | 1874 | cases.add("while expected error union, got bool", |
| 1706 | \\export fn foo() { | |
| 1875 | \\extern fn foo() { | |
| 1707 | 1876 | \\ while (bar()) |x| {} else |err| {} |
| 1708 | 1877 | \\} |
| 1709 | 1878 | \\fn bar() -> bool { true } |
| 1879 | \\comptime {@export("foo", foo);} | |
| 1710 | 1880 | , |
| 1711 | 1881 | ".tmp_source.zig:2:15: error: expected error union type, found 'bool'"); |
| 1712 | 1882 | |
| 1713 | 1883 | cases.add("while expected error union, got nullable", |
| 1714 | \\export fn foo() { | |
| 1884 | \\extern fn foo() { | |
| 1715 | 1885 | \\ while (bar()) |x| {} else |err| {} |
| 1716 | 1886 | \\} |
| 1717 | 1887 | \\fn bar() -> ?i32 { 1 } |
| 1888 | \\comptime {@export("foo", foo);} | |
| 1718 | 1889 | , |
| 1719 | 1890 | ".tmp_source.zig:2:15: error: expected error union type, found '?i32'"); |
| 1720 | 1891 | |
| 1721 | 1892 | cases.add("inline fn calls itself indirectly", |
| 1722 | \\export fn foo() { | |
| 1893 | \\extern fn foo() { | |
| 1723 | 1894 | \\ bar(); |
| 1724 | 1895 | \\} |
| 1725 | 1896 | \\inline fn bar() { |
| ... | ... | @@ -1731,29 +1902,33 @@ pub fn addCases(cases: &tests.CompileErrorContext) { |
| 1731 | 1902 | \\ quux(); |
| 1732 | 1903 | \\} |
| 1733 | 1904 | \\extern fn quux(); |
| 1905 | \\comptime {@export("foo", foo);} | |
| 1734 | 1906 | , |
| 1735 | 1907 | ".tmp_source.zig:4:8: error: unable to inline function"); |
| 1736 | 1908 | |
| 1737 | 1909 | cases.add("save reference to inline function", |
| 1738 | \\export fn foo() { | |
| 1910 | \\extern fn foo() { | |
| 1739 | 1911 | \\ quux(@ptrToInt(bar)); |
| 1740 | 1912 | \\} |
| 1741 | 1913 | \\inline fn bar() { } |
| 1742 | 1914 | \\extern fn quux(usize); |
| 1915 | \\comptime {@export("foo", foo);} | |
| 1743 | 1916 | , |
| 1744 | 1917 | ".tmp_source.zig:4:8: error: unable to inline function"); |
| 1745 | 1918 | |
| 1746 | 1919 | cases.add("signed integer division", |
| 1747 | \\export fn foo(a: i32, b: i32) -> i32 { | |
| 1920 | \\extern fn foo(a: i32, b: i32) -> i32 { | |
| 1748 | 1921 | \\ a / b |
| 1749 | 1922 | \\} |
| 1923 | \\comptime {@export("foo", foo);} | |
| 1750 | 1924 | , |
| 1751 | 1925 | ".tmp_source.zig:2:7: error: division with 'i32' and 'i32': signed integers must use @divTrunc, @divFloor, or @divExact"); |
| 1752 | 1926 | |
| 1753 | 1927 | cases.add("signed integer remainder division", |
| 1754 | \\export fn foo(a: i32, b: i32) -> i32 { | |
| 1928 | \\extern fn foo(a: i32, b: i32) -> i32 { | |
| 1755 | 1929 | \\ a % b |
| 1756 | 1930 | \\} |
| 1931 | \\comptime {@export("foo", foo);} | |
| 1757 | 1932 | , |
| 1758 | 1933 | ".tmp_source.zig:2:7: error: remainder division with 'i32' and 'i32': signed integers and floats must use @rem or @mod"); |
| 1759 | 1934 | |
| ... | ... | @@ -1792,59 +1967,65 @@ pub fn addCases(cases: &tests.CompileErrorContext) { |
| 1792 | 1967 | ".tmp_source.zig:3:20: error: cast from 'u16' to 'u8' truncates bits"); |
| 1793 | 1968 | |
| 1794 | 1969 | cases.add("@setDebugSafety twice for same scope", |
| 1795 | \\export fn foo() { | |
| 1970 | \\extern fn foo() { | |
| 1796 | 1971 | \\ @setDebugSafety(this, false); |
| 1797 | 1972 | \\ @setDebugSafety(this, false); |
| 1798 | 1973 | \\} |
| 1974 | \\comptime {@export("foo", foo);} | |
| 1799 | 1975 | , |
| 1800 | 1976 | ".tmp_source.zig:3:5: error: debug safety set twice for same scope", |
| 1801 | 1977 | ".tmp_source.zig:2:5: note: first set here"); |
| 1802 | 1978 | |
| 1803 | 1979 | cases.add("@setFloatMode twice for same scope", |
| 1804 | \\export fn foo() { | |
| 1980 | \\extern fn foo() { | |
| 1805 | 1981 | \\ @setFloatMode(this, @import("builtin").FloatMode.Optimized); |
| 1806 | 1982 | \\ @setFloatMode(this, @import("builtin").FloatMode.Optimized); |
| 1807 | 1983 | \\} |
| 1984 | \\comptime {@export("foo", foo);} | |
| 1808 | 1985 | , |
| 1809 | 1986 | ".tmp_source.zig:3:5: error: float mode set twice for same scope", |
| 1810 | 1987 | ".tmp_source.zig:2:5: note: first set here"); |
| 1811 | 1988 | |
| 1812 | 1989 | cases.add("array access of type", |
| 1813 | \\export fn foo() { | |
| 1990 | \\extern fn foo() { | |
| 1814 | 1991 | \\ var b: u8[40] = undefined; |
| 1815 | 1992 | \\} |
| 1993 | \\comptime {@export("foo", foo);} | |
| 1816 | 1994 | , |
| 1817 | 1995 | ".tmp_source.zig:2:14: error: array access of non-array type 'type'"); |
| 1818 | 1996 | |
| 1819 | 1997 | cases.add("cannot break out of defer expression", |
| 1820 | \\export fn foo() { | |
| 1998 | \\extern fn foo() { | |
| 1821 | 1999 | \\ while (true) { |
| 1822 | 2000 | \\ defer { |
| 1823 | 2001 | \\ break; |
| 1824 | 2002 | \\ } |
| 1825 | 2003 | \\ } |
| 1826 | 2004 | \\} |
| 2005 | \\comptime {@export("foo", foo);} | |
| 1827 | 2006 | , |
| 1828 | 2007 | ".tmp_source.zig:4:13: error: cannot break out of defer expression"); |
| 1829 | 2008 | |
| 1830 | 2009 | cases.add("cannot continue out of defer expression", |
| 1831 | \\export fn foo() { | |
| 2010 | \\extern fn foo() { | |
| 1832 | 2011 | \\ while (true) { |
| 1833 | 2012 | \\ defer { |
| 1834 | 2013 | \\ continue; |
| 1835 | 2014 | \\ } |
| 1836 | 2015 | \\ } |
| 1837 | 2016 | \\} |
| 2017 | \\comptime {@export("foo", foo);} | |
| 1838 | 2018 | , |
| 1839 | 2019 | ".tmp_source.zig:4:13: error: cannot continue out of defer expression"); |
| 1840 | 2020 | |
| 1841 | 2021 | cases.add("cannot goto out of defer expression", |
| 1842 | \\export fn foo() { | |
| 2022 | \\extern fn foo() { | |
| 1843 | 2023 | \\ defer { |
| 1844 | 2024 | \\ goto label; |
| 1845 | 2025 | \\ }; |
| 1846 | 2026 | \\label: |
| 1847 | 2027 | \\} |
| 2028 | \\comptime {@export("foo", foo);} | |
| 1848 | 2029 | , |
| 1849 | 2030 | ".tmp_source.zig:3:9: error: cannot goto out of defer expression"); |
| 1850 | 2031 | |
| ... | ... | @@ -1878,9 +2059,10 @@ pub fn addCases(cases: &tests.CompileErrorContext) { |
| 1878 | 2059 | \\const bar = baz + foo; |
| 1879 | 2060 | \\const baz = 1; |
| 1880 | 2061 | \\ |
| 1881 | \\export fn entry() -> i32 { | |
| 2062 | \\extern fn entry() -> i32 { | |
| 1882 | 2063 | \\ return bar; |
| 1883 | 2064 | \\} |
| 2065 | \\comptime {@export("entry", entry);} | |
| 1884 | 2066 | , |
| 1885 | 2067 | ".tmp_source.zig:1:13: error: aoeu", |
| 1886 | 2068 | ".tmp_source.zig:3:19: note: referenced here", |
| ... | ... | @@ -1893,9 +2075,10 @@ pub fn addCases(cases: &tests.CompileErrorContext) { |
| 1893 | 2075 | \\ |
| 1894 | 2076 | \\var foo: Foo = undefined; |
| 1895 | 2077 | \\ |
| 1896 | \\export fn entry() -> usize { | |
| 2078 | \\extern fn entry() -> usize { | |
| 1897 | 2079 | \\ return @sizeOf(@typeOf(foo.x)); |
| 1898 | 2080 | \\} |
| 2081 | \\comptime {@export("entry", entry);} | |
| 1899 | 2082 | , |
| 1900 | 2083 | ".tmp_source.zig:1:13: error: struct 'Foo' contains itself"); |
| 1901 | 2084 | |
| ... | ... | @@ -1914,16 +2097,18 @@ pub fn addCases(cases: &tests.CompileErrorContext) { |
| 1914 | 2097 | ".tmp_source.zig:2:15: error: float literal out of range of any type"); |
| 1915 | 2098 | |
| 1916 | 2099 | cases.add("explicit cast float literal to integer when there is a fraction component", |
| 1917 | \\export fn entry() -> i32 { | |
| 2100 | \\extern fn entry() -> i32 { | |
| 1918 | 2101 | \\ i32(12.34) |
| 1919 | 2102 | \\} |
| 2103 | \\comptime {@export("entry", entry);} | |
| 1920 | 2104 | , |
| 1921 | 2105 | ".tmp_source.zig:2:9: error: fractional component prevents float value 12.340000 from being casted to type 'i32'"); |
| 1922 | 2106 | |
| 1923 | 2107 | cases.add("non pointer given to @ptrToInt", |
| 1924 | \\export fn entry(x: i32) -> usize { | |
| 2108 | \\extern fn entry(x: i32) -> usize { | |
| 1925 | 2109 | \\ @ptrToInt(x) |
| 1926 | 2110 | \\} |
| 2111 | \\comptime {@export("entry", entry);} | |
| 1927 | 2112 | , |
| 1928 | 2113 | ".tmp_source.zig:2:15: error: expected pointer, found 'i32'"); |
| 1929 | 2114 | |
| ... | ... | @@ -1942,24 +2127,27 @@ pub fn addCases(cases: &tests.CompileErrorContext) { |
| 1942 | 2127 | ".tmp_source.zig:2:15: error: exact shift shifted out 1 bits"); |
| 1943 | 2128 | |
| 1944 | 2129 | cases.add("shifting without int type or comptime known", |
| 1945 | \\export fn entry(x: u8) -> u8 { | |
| 2130 | \\extern fn entry(x: u8) -> u8 { | |
| 1946 | 2131 | \\ return 0x11 << x; |
| 1947 | 2132 | \\} |
| 2133 | \\comptime {@export("entry", entry);} | |
| 1948 | 2134 | , |
| 1949 | 2135 | ".tmp_source.zig:2:17: error: LHS of shift must be an integer type, or RHS must be compile-time known"); |
| 1950 | 2136 | |
| 1951 | 2137 | cases.add("shifting RHS is log2 of LHS int bit width", |
| 1952 | \\export fn entry(x: u8, y: u8) -> u8 { | |
| 2138 | \\extern fn entry(x: u8, y: u8) -> u8 { | |
| 1953 | 2139 | \\ return x << y; |
| 1954 | 2140 | \\} |
| 2141 | \\comptime {@export("entry", entry);} | |
| 1955 | 2142 | , |
| 1956 | 2143 | ".tmp_source.zig:2:17: error: expected type 'u3', found 'u8'"); |
| 1957 | 2144 | |
| 1958 | 2145 | cases.add("globally shadowing a primitive type", |
| 1959 | 2146 | \\const u16 = @intType(false, 8); |
| 1960 | \\export fn entry() { | |
| 2147 | \\extern fn entry() { | |
| 1961 | 2148 | \\ const a: u16 = 300; |
| 1962 | 2149 | \\} |
| 2150 | \\comptime {@export("entry", entry);} | |
| 1963 | 2151 | , |
| 1964 | 2152 | ".tmp_source.zig:1:1: error: declaration shadows type 'u16'"); |
| 1965 | 2153 | |
| ... | ... | @@ -1969,7 +2157,7 @@ pub fn addCases(cases: &tests.CompileErrorContext) { |
| 1969 | 2157 | \\ b: u32, |
| 1970 | 2158 | \\}; |
| 1971 | 2159 | \\ |
| 1972 | \\export fn entry() { | |
| 2160 | \\extern fn entry() { | |
| 1973 | 2161 | \\ var foo = Foo { .a = 1, .b = 10 }; |
| 1974 | 2162 | \\ bar(&foo.b); |
| 1975 | 2163 | \\} |
| ... | ... | @@ -1977,6 +2165,7 @@ pub fn addCases(cases: &tests.CompileErrorContext) { |
| 1977 | 2165 | \\fn bar(x: &u32) { |
| 1978 | 2166 | \\ *x += 1; |
| 1979 | 2167 | \\} |
| 2168 | \\comptime {@export("entry", entry);} | |
| 1980 | 2169 | , |
| 1981 | 2170 | ".tmp_source.zig:8:13: error: expected type '&u32', found '&align(1) u32'"); |
| 1982 | 2171 | |
| ... | ... | @@ -1986,7 +2175,7 @@ pub fn addCases(cases: &tests.CompileErrorContext) { |
| 1986 | 2175 | \\ b: u32, |
| 1987 | 2176 | \\}; |
| 1988 | 2177 | \\ |
| 1989 | \\export fn entry() { | |
| 2178 | \\extern fn entry() { | |
| 1990 | 2179 | \\ var foo = Foo { .a = 1, .b = 10 }; |
| 1991 | 2180 | \\ foo.b += 1; |
| 1992 | 2181 | \\ bar((&foo.b)[0..1]); |
| ... | ... | @@ -1995,55 +2184,61 @@ pub fn addCases(cases: &tests.CompileErrorContext) { |
| 1995 | 2184 | \\fn bar(x: []u32) { |
| 1996 | 2185 | \\ x[0] += 1; |
| 1997 | 2186 | \\} |
| 2187 | \\comptime {@export("entry", entry);} | |
| 1998 | 2188 | , |
| 1999 | 2189 | ".tmp_source.zig:9:17: error: expected type '[]u32', found '[]align(1) u32'"); |
| 2000 | 2190 | |
| 2001 | 2191 | cases.add("increase pointer alignment in @ptrCast", |
| 2002 | \\export fn entry() -> u32 { | |
| 2192 | \\extern fn entry() -> u32 { | |
| 2003 | 2193 | \\ var bytes: [4]u8 = []u8{0x01, 0x02, 0x03, 0x04}; |
| 2004 | 2194 | \\ const ptr = @ptrCast(&u32, &bytes[0]); |
| 2005 | 2195 | \\ return *ptr; |
| 2006 | 2196 | \\} |
| 2197 | \\comptime {@export("entry", entry);} | |
| 2007 | 2198 | , |
| 2008 | 2199 | ".tmp_source.zig:3:17: error: cast increases pointer alignment", |
| 2009 | 2200 | ".tmp_source.zig:3:38: note: '&u8' has alignment 1", |
| 2010 | 2201 | ".tmp_source.zig:3:27: note: '&u32' has alignment 4"); |
| 2011 | 2202 | |
| 2012 | 2203 | cases.add("increase pointer alignment in slice resize", |
| 2013 | \\export fn entry() -> u32 { | |
| 2204 | \\extern fn entry() -> u32 { | |
| 2014 | 2205 | \\ var bytes = []u8{0x01, 0x02, 0x03, 0x04}; |
| 2015 | 2206 | \\ return ([]u32)(bytes[0..])[0]; |
| 2016 | 2207 | \\} |
| 2208 | \\comptime {@export("entry", entry);} | |
| 2017 | 2209 | , |
| 2018 | 2210 | ".tmp_source.zig:3:19: error: cast increases pointer alignment", |
| 2019 | 2211 | ".tmp_source.zig:3:19: note: '[]u8' has alignment 1", |
| 2020 | 2212 | ".tmp_source.zig:3:19: note: '[]u32' has alignment 4"); |
| 2021 | 2213 | |
| 2022 | 2214 | cases.add("@alignCast expects pointer or slice", |
| 2023 | \\export fn entry() { | |
| 2215 | \\extern fn entry() { | |
| 2024 | 2216 | \\ @alignCast(4, u32(3)) |
| 2025 | 2217 | \\} |
| 2218 | \\comptime {@export("entry", entry);} | |
| 2026 | 2219 | , |
| 2027 | 2220 | ".tmp_source.zig:2:22: error: expected pointer or slice, found 'u32'"); |
| 2028 | 2221 | |
| 2029 | 2222 | cases.add("passing an under-aligned function pointer", |
| 2030 | \\export fn entry() { | |
| 2223 | \\extern fn entry() { | |
| 2031 | 2224 | \\ testImplicitlyDecreaseFnAlign(alignedSmall, 1234); |
| 2032 | 2225 | \\} |
| 2033 | 2226 | \\fn testImplicitlyDecreaseFnAlign(ptr: fn () align(8) -> i32, answer: i32) { |
| 2034 | 2227 | \\ if (ptr() != answer) unreachable; |
| 2035 | 2228 | \\} |
| 2036 | 2229 | \\fn alignedSmall() align(4) -> i32 { 1234 } |
| 2230 | \\comptime {@export("entry", entry);} | |
| 2037 | 2231 | , |
| 2038 | 2232 | ".tmp_source.zig:2:35: error: expected type 'fn() align(8) -> i32', found 'fn() align(4) -> i32'"); |
| 2039 | 2233 | |
| 2040 | 2234 | cases.add("passing a not-aligned-enough pointer to cmpxchg", |
| 2041 | 2235 | \\const AtomicOrder = @import("builtin").AtomicOrder; |
| 2042 | \\export fn entry() -> bool { | |
| 2236 | \\extern fn entry() -> bool { | |
| 2043 | 2237 | \\ var x: i32 align(1) = 1234; |
| 2044 | 2238 | \\ while (!@cmpxchg(&x, 1234, 5678, AtomicOrder.SeqCst, AtomicOrder.SeqCst)) {} |
| 2045 | 2239 | \\ return x == 5678; |
| 2046 | 2240 | \\} |
| 2241 | \\comptime {@export("entry", entry);} | |
| 2047 | 2242 | , |
| 2048 | 2243 | ".tmp_source.zig:4:23: error: expected pointer alignment of at least 4, found 1"); |
| 2049 | 2244 | |
| ... | ... | @@ -2069,17 +2264,18 @@ pub fn addCases(cases: &tests.CompileErrorContext) { |
| 2069 | 2264 | cases.add("wrong pointer implicitly casted to pointer to @OpaqueType()", |
| 2070 | 2265 | \\const Derp = @OpaqueType(); |
| 2071 | 2266 | \\extern fn bar(d: &Derp); |
| 2072 | \\export fn foo() { | |
| 2267 | \\extern fn foo() { | |
| 2073 | 2268 | \\ const x = u8(1); |
| 2074 | 2269 | \\ bar(@ptrCast(&c_void, &x)); |
| 2075 | 2270 | \\} |
| 2271 | \\comptime {@export("foo", foo);} | |
| 2076 | 2272 | , |
| 2077 | 2273 | ".tmp_source.zig:5:9: error: expected type '&Derp', found '&c_void'"); |
| 2078 | 2274 | |
| 2079 | 2275 | cases.add("non-const variables of things that require const variables", |
| 2080 | 2276 | \\const Opaque = @OpaqueType(); |
| 2081 | 2277 | \\ |
| 2082 | \\export fn entry(opaque: &Opaque) { | |
| 2278 | \\extern fn entry(opaque: &Opaque) { | |
| 2083 | 2279 | \\ var m2 = &2; |
| 2084 | 2280 | \\ const y: u32 = *m2; |
| 2085 | 2281 | \\ |
| ... | ... | @@ -2099,6 +2295,7 @@ pub fn addCases(cases: &tests.CompileErrorContext) { |
| 2099 | 2295 | \\const Foo = struct { |
| 2100 | 2296 | \\ fn bar(self: &const Foo) {} |
| 2101 | 2297 | \\}; |
| 2298 | \\comptime {@export("entry", entry);} | |
| 2102 | 2299 | , |
| 2103 | 2300 | ".tmp_source.zig:4:4: error: variable of type '&const (integer literal)' must be const or comptime", |
| 2104 | 2301 | ".tmp_source.zig:7:4: error: variable of type '(undefined)' must be const or comptime", |
| ... | ... | @@ -2113,20 +2310,14 @@ pub fn addCases(cases: &tests.CompileErrorContext) { |
| 2113 | 2310 | ".tmp_source.zig:17:4: error: unreachable code"); |
| 2114 | 2311 | |
| 2115 | 2312 | cases.add("wrong types given to atomic order args in cmpxchg", |
| 2116 | \\export fn entry() { | |
| 2313 | \\extern fn entry() { | |
| 2117 | 2314 | \\ var x: i32 = 1234; |
| 2118 | 2315 | \\ while (!@cmpxchg(&x, 1234, 5678, u32(1234), u32(1234))) {} |
| 2119 | 2316 | \\} |
| 2317 | \\comptime {@export("entry", entry);} | |
| 2120 | 2318 | , |
| 2121 | 2319 | ".tmp_source.zig:3:41: error: expected type 'AtomicOrder', found 'u32'"); |
| 2122 | 2320 | |
| 2123 | cases.add("wrong types given to setGlobalLinkage", | |
| 2124 | \\export fn entry() { | |
| 2125 | \\ @setGlobalLinkage(entry, u32(1234)); | |
| 2126 | \\} | |
| 2127 | , | |
| 2128 | ".tmp_source.zig:2:33: error: expected type 'GlobalLinkage', found 'u32'"); | |
| 2129 | ||
| 2130 | 2321 | cases.add("struct with invalid field", |
| 2131 | 2322 | \\const std = @import("std"); |
| 2132 | 2323 | \\const Allocator = std.mem.Allocator; |
| ... | ... | @@ -2145,12 +2336,13 @@ pub fn addCases(cases: &tests.CompileErrorContext) { |
| 2145 | 2336 | \\ }, |
| 2146 | 2337 | \\}; |
| 2147 | 2338 | \\ |
| 2148 | \\export fn entry() { | |
| 2339 | \\extern fn entry() { | |
| 2149 | 2340 | \\ const a = MdNode.Header { |
| 2150 | 2341 | \\ .text = MdText.init(&std.debug.global_allocator), |
| 2151 | 2342 | \\ .weight = HeaderWeight.H1, |
| 2152 | 2343 | \\ }; |
| 2153 | 2344 | \\} |
| 2345 | \\comptime {@export("entry", entry);} | |
| 2154 | 2346 | , |
| 2155 | 2347 | ".tmp_source.zig:14:17: error: use of undeclared identifier 'HeaderValue'"); |
| 2156 | 2348 | |
| ... | ... | @@ -2162,35 +2354,39 @@ pub fn addCases(cases: &tests.CompileErrorContext) { |
| 2162 | 2354 | ".tmp_source.zig:2:5: error: @setAlignStack outside function"); |
| 2163 | 2355 | |
| 2164 | 2356 | cases.add("@setAlignStack in naked function", |
| 2165 | \\export nakedcc fn entry() { | |
| 2357 | \\nakedcc fn entry() { | |
| 2166 | 2358 | \\ @setAlignStack(16); |
| 2167 | 2359 | \\} |
| 2360 | \\comptime {@export("entry", entry);} | |
| 2168 | 2361 | , |
| 2169 | 2362 | ".tmp_source.zig:2:5: error: @setAlignStack in naked function"); |
| 2170 | 2363 | |
| 2171 | 2364 | cases.add("@setAlignStack in inline function", |
| 2172 | \\export fn entry() { | |
| 2365 | \\extern fn entry() { | |
| 2173 | 2366 | \\ foo(); |
| 2174 | 2367 | \\} |
| 2175 | 2368 | \\inline fn foo() { |
| 2176 | 2369 | \\ @setAlignStack(16); |
| 2177 | 2370 | \\} |
| 2371 | \\comptime {@export("entry", entry);} | |
| 2178 | 2372 | , |
| 2179 | 2373 | ".tmp_source.zig:5:5: error: @setAlignStack in inline function"); |
| 2180 | 2374 | |
| 2181 | 2375 | cases.add("@setAlignStack set twice", |
| 2182 | \\export fn entry() { | |
| 2376 | \\extern fn entry() { | |
| 2183 | 2377 | \\ @setAlignStack(16); |
| 2184 | 2378 | \\ @setAlignStack(16); |
| 2185 | 2379 | \\} |
| 2380 | \\comptime {@export("entry", entry);} | |
| 2186 | 2381 | , |
| 2187 | 2382 | ".tmp_source.zig:3:5: error: alignstack set twice", |
| 2188 | 2383 | ".tmp_source.zig:2:5: note: first set here"); |
| 2189 | 2384 | |
| 2190 | 2385 | cases.add("@setAlignStack too big", |
| 2191 | \\export fn entry() { | |
| 2386 | \\extern fn entry() { | |
| 2192 | 2387 | \\ @setAlignStack(511 + 1); |
| 2193 | 2388 | \\} |
| 2389 | \\comptime {@export("entry", entry);} | |
| 2194 | 2390 | , |
| 2195 | 2391 | ".tmp_source.zig:2:5: error: attempt to @setAlignStack(512); maximum is 256"); |
| 2196 | 2392 | |
| ... | ... | @@ -2221,7 +2417,7 @@ pub fn addCases(cases: &tests.CompileErrorContext) { |
| 2221 | 2417 | \\ LinkLibC, |
| 2222 | 2418 | \\}; |
| 2223 | 2419 | \\ |
| 2224 | \\export fn entry() { | |
| 2420 | \\extern fn entry() { | |
| 2225 | 2421 | \\ const tests = []TestCase { |
| 2226 | 2422 | \\ Free("001"), |
| 2227 | 2423 | \\ Free("002"), |
| ... | ... | @@ -2236,13 +2432,14 @@ pub fn addCases(cases: &tests.CompileErrorContext) { |
| 2236 | 2432 | \\ } |
| 2237 | 2433 | \\ } |
| 2238 | 2434 | \\} |
| 2435 | \\comptime {@export("entry", entry);} | |
| 2239 | 2436 | , |
| 2240 | 2437 | ".tmp_source.zig:37:16: error: cannot store runtime value in compile time variable"); |
| 2241 | 2438 | |
| 2242 | 2439 | cases.add("field access of opaque type", |
| 2243 | 2440 | \\const MyType = @OpaqueType(); |
| 2244 | 2441 | \\ |
| 2245 | \\export fn entry() -> bool { | |
| 2442 | \\extern fn entry() -> bool { | |
| 2246 | 2443 | \\ var x: i32 = 1; |
| 2247 | 2444 | \\ return bar(@ptrCast(&MyType, &x)); |
| 2248 | 2445 | \\} |
| ... | ... | @@ -2250,6 +2447,7 @@ pub fn addCases(cases: &tests.CompileErrorContext) { |
| 2250 | 2447 | \\fn bar(x: &MyType) -> bool { |
| 2251 | 2448 | \\ return x.blah; |
| 2252 | 2449 | \\} |
| 2450 | \\comptime {@export("entry", entry);} | |
| 2253 | 2451 | , |
| 2254 | 2452 | ".tmp_source.zig:9:13: error: type '&MyType' does not support field access"); |
| 2255 | 2453 | |
| ... | ... | @@ -2353,10 +2551,11 @@ pub fn addCases(cases: &tests.CompileErrorContext) { |
| 2353 | 2551 | ".tmp_source.zig:2:26: error: member index 1 out of bounds; 'Foo' has 1 members"); |
| 2354 | 2552 | |
| 2355 | 2553 | cases.add("calling var args extern function, passing array instead of pointer", |
| 2356 | \\export fn entry() { | |
| 2554 | \\extern fn entry() { | |
| 2357 | 2555 | \\ foo("hello"); |
| 2358 | 2556 | \\} |
| 2359 | 2557 | \\pub extern fn foo(format: &const u8, ...); |
| 2558 | \\comptime {@export("entry", entry);} | |
| 2360 | 2559 | , |
| 2361 | 2560 | ".tmp_source.zig:2:9: error: expected type '&const u8', found '[5]u8'"); |
| 2362 | 2561 | |
| ... | ... | @@ -2371,9 +2570,10 @@ pub fn addCases(cases: &tests.CompileErrorContext) { |
| 2371 | 2570 | \\ } |
| 2372 | 2571 | \\} |
| 2373 | 2572 | \\ |
| 2374 | \\export fn entry() { | |
| 2573 | \\extern fn entry() { | |
| 2375 | 2574 | \\ var allocator: ContextAllocator = undefined; |
| 2376 | 2575 | \\} |
| 2576 | \\comptime {@export("entry", entry);} | |
| 2377 | 2577 | , |
| 2378 | 2578 | ".tmp_source.zig:4:25: error: aoeu", |
| 2379 | 2579 | ".tmp_source.zig:1:36: note: called from here", |
| ... | ... | @@ -2388,9 +2588,10 @@ pub fn addCases(cases: &tests.CompileErrorContext) { |
| 2388 | 2588 | \\ Five, |
| 2389 | 2589 | \\}; |
| 2390 | 2590 | \\ |
| 2391 | \\export fn entry() { | |
| 2591 | \\extern fn entry() { | |
| 2392 | 2592 | \\ var x = Small.One; |
| 2393 | 2593 | \\} |
| 2594 | \\comptime {@export("entry", entry);} | |
| 2394 | 2595 | , |
| 2395 | 2596 | ".tmp_source.zig:1:20: error: 'u2' too small to hold all bits; must be at least 'u3'"); |
| 2396 | 2597 | |
| ... | ... | @@ -2401,9 +2602,10 @@ pub fn addCases(cases: &tests.CompileErrorContext) { |
| 2401 | 2602 | \\ Three, |
| 2402 | 2603 | \\}; |
| 2403 | 2604 | \\ |
| 2404 | \\export fn entry() { | |
| 2605 | \\extern fn entry() { | |
| 2405 | 2606 | \\ var x = Small.One; |
| 2406 | 2607 | \\} |
| 2608 | \\comptime {@export("entry", entry);} | |
| 2407 | 2609 | , |
| 2408 | 2610 | ".tmp_source.zig:1:20: error: expected integer, found 'f32'"); |
| 2409 | 2611 | |
| ... | ... | @@ -2415,9 +2617,10 @@ pub fn addCases(cases: &tests.CompileErrorContext) { |
| 2415 | 2617 | \\ Four, |
| 2416 | 2618 | \\}; |
| 2417 | 2619 | \\ |
| 2418 | \\export fn entry() { | |
| 2620 | \\extern fn entry() { | |
| 2419 | 2621 | \\ var x: u2 = Small.Two; |
| 2420 | 2622 | \\} |
| 2623 | \\comptime {@export("entry", entry);} | |
| 2421 | 2624 | , |
| 2422 | 2625 | ".tmp_source.zig:9:22: error: expected type 'u2', found 'Small'"); |
| 2423 | 2626 | |
| ... | ... | @@ -2429,9 +2632,10 @@ pub fn addCases(cases: &tests.CompileErrorContext) { |
| 2429 | 2632 | \\ Four, |
| 2430 | 2633 | \\}; |
| 2431 | 2634 | \\ |
| 2432 | \\export fn entry() { | |
| 2635 | \\extern fn entry() { | |
| 2433 | 2636 | \\ var x = u3(Small.Two); |
| 2434 | 2637 | \\} |
| 2638 | \\comptime {@export("entry", entry);} | |
| 2435 | 2639 | , |
| 2436 | 2640 | ".tmp_source.zig:9:15: error: enum to integer cast to 'u3' instead of its tag type, 'u2'"); |
| 2437 | 2641 | |
| ... | ... | @@ -2443,10 +2647,11 @@ pub fn addCases(cases: &tests.CompileErrorContext) { |
| 2443 | 2647 | \\ Four, |
| 2444 | 2648 | \\}; |
| 2445 | 2649 | \\ |
| 2446 | \\export fn entry() { | |
| 2650 | \\extern fn entry() { | |
| 2447 | 2651 | \\ var y = u3(3); |
| 2448 | 2652 | \\ var x = Small(y); |
| 2449 | 2653 | \\} |
| 2654 | \\comptime {@export("entry", entry);} | |
| 2450 | 2655 | , |
| 2451 | 2656 | ".tmp_source.zig:10:18: error: integer to enum cast from 'u3' instead of its tag type, 'u2'"); |
| 2452 | 2657 | |
| ... | ... | @@ -2458,9 +2663,10 @@ pub fn addCases(cases: &tests.CompileErrorContext) { |
| 2458 | 2663 | \\ Four, |
| 2459 | 2664 | \\}; |
| 2460 | 2665 | \\ |
| 2461 | \\export fn entry() { | |
| 2666 | \\extern fn entry() { | |
| 2462 | 2667 | \\ var y = Small.Two; |
| 2463 | 2668 | \\} |
| 2669 | \\comptime {@export("entry", entry);} | |
| 2464 | 2670 | , |
| 2465 | 2671 | ".tmp_source.zig:1:19: error: expected unsigned integer, found 'i2'"); |
| 2466 | 2672 | |
| ... | ... | @@ -2468,9 +2674,10 @@ pub fn addCases(cases: &tests.CompileErrorContext) { |
| 2468 | 2674 | \\const MultipleChoice = struct { |
| 2469 | 2675 | \\ A: i32 = 20, |
| 2470 | 2676 | \\}; |
| 2471 | \\export fn entry() { | |
| 2677 | \\extern fn entry() { | |
| 2472 | 2678 | \\ var x: MultipleChoice = undefined; |
| 2473 | 2679 | \\} |
| 2680 | \\comptime {@export("entry", entry);} | |
| 2474 | 2681 | , |
| 2475 | 2682 | ".tmp_source.zig:2:14: error: enums, not structs, support field assignment"); |
| 2476 | 2683 | |
| ... | ... | @@ -2478,26 +2685,29 @@ pub fn addCases(cases: &tests.CompileErrorContext) { |
| 2478 | 2685 | \\const MultipleChoice = union { |
| 2479 | 2686 | \\ A: i32 = 20, |
| 2480 | 2687 | \\}; |
| 2481 | \\export fn entry() { | |
| 2688 | \\extern fn entry() { | |
| 2482 | 2689 | \\ var x: MultipleChoice = undefined; |
| 2483 | 2690 | \\} |
| 2691 | \\comptime {@export("entry", entry);} | |
| 2484 | 2692 | , |
| 2485 | 2693 | ".tmp_source.zig:2:14: error: non-enum union field assignment", |
| 2486 | 2694 | ".tmp_source.zig:1:24: note: consider 'union(enum)' here"); |
| 2487 | 2695 | |
| 2488 | 2696 | cases.add("enum with 0 fields", |
| 2489 | 2697 | \\const Foo = enum {}; |
| 2490 | \\export fn entry() -> usize { | |
| 2698 | \\extern fn entry() -> usize { | |
| 2491 | 2699 | \\ return @sizeOf(Foo); |
| 2492 | 2700 | \\} |
| 2701 | \\comptime {@export("entry", entry);} | |
| 2493 | 2702 | , |
| 2494 | 2703 | ".tmp_source.zig:1:13: error: enums must have 1 or more fields"); |
| 2495 | 2704 | |
| 2496 | 2705 | cases.add("union with 0 fields", |
| 2497 | 2706 | \\const Foo = union {}; |
| 2498 | \\export fn entry() -> usize { | |
| 2707 | \\extern fn entry() -> usize { | |
| 2499 | 2708 | \\ return @sizeOf(Foo); |
| 2500 | 2709 | \\} |
| 2710 | \\comptime {@export("entry", entry);} | |
| 2501 | 2711 | , |
| 2502 | 2712 | ".tmp_source.zig:1:13: error: unions must have 1 or more fields"); |
| 2503 | 2713 | |
| ... | ... | @@ -2509,9 +2719,10 @@ pub fn addCases(cases: &tests.CompileErrorContext) { |
| 2509 | 2719 | \\ D = 1000, |
| 2510 | 2720 | \\ E = 60, |
| 2511 | 2721 | \\}; |
| 2512 | \\export fn entry() { | |
| 2722 | \\extern fn entry() { | |
| 2513 | 2723 | \\ var x = MultipleChoice.C; |
| 2514 | 2724 | \\} |
| 2725 | \\comptime {@export("entry", entry);} | |
| 2515 | 2726 | , |
| 2516 | 2727 | ".tmp_source.zig:6:9: error: enum tag value 60 already taken", |
| 2517 | 2728 | ".tmp_source.zig:4:9: note: other occurrence here"); |
| ... | ... | @@ -2526,9 +2737,10 @@ pub fn addCases(cases: &tests.CompileErrorContext) { |
| 2526 | 2737 | \\ A: i32, |
| 2527 | 2738 | \\ B: f64, |
| 2528 | 2739 | \\}; |
| 2529 | \\export fn entry() -> usize { | |
| 2740 | \\extern fn entry() -> usize { | |
| 2530 | 2741 | \\ return @sizeOf(Payload); |
| 2531 | 2742 | \\} |
| 2743 | \\comptime {@export("entry", entry);} | |
| 2532 | 2744 | , |
| 2533 | 2745 | ".tmp_source.zig:6:17: error: enum field missing: 'C'", |
| 2534 | 2746 | ".tmp_source.zig:4:5: note: declared here"); |
| ... | ... | @@ -2537,9 +2749,10 @@ pub fn addCases(cases: &tests.CompileErrorContext) { |
| 2537 | 2749 | \\const Foo = union { |
| 2538 | 2750 | \\ A: i32, |
| 2539 | 2751 | \\}; |
| 2540 | \\export fn entry() { | |
| 2752 | \\extern fn entry() { | |
| 2541 | 2753 | \\ const x = @TagType(Foo); |
| 2542 | 2754 | \\} |
| 2755 | \\comptime {@export("entry", entry);} | |
| 2543 | 2756 | , |
| 2544 | 2757 | ".tmp_source.zig:5:24: error: union 'Foo' has no tag", |
| 2545 | 2758 | ".tmp_source.zig:1:13: note: consider 'union(enum)' here"); |
| ... | ... | @@ -2548,9 +2761,10 @@ pub fn addCases(cases: &tests.CompileErrorContext) { |
| 2548 | 2761 | \\const Foo = union(enum(f32)) { |
| 2549 | 2762 | \\ A: i32, |
| 2550 | 2763 | \\}; |
| 2551 | \\export fn entry() { | |
| 2764 | \\extern fn entry() { | |
| 2552 | 2765 | \\ const x = @TagType(Foo); |
| 2553 | 2766 | \\} |
| 2767 | \\comptime {@export("entry", entry);} | |
| 2554 | 2768 | , |
| 2555 | 2769 | ".tmp_source.zig:1:23: error: expected integer tag type, found 'f32'"); |
| 2556 | 2770 | |
| ... | ... | @@ -2558,9 +2772,10 @@ pub fn addCases(cases: &tests.CompileErrorContext) { |
| 2558 | 2772 | \\const Foo = union(u32) { |
| 2559 | 2773 | \\ A: i32, |
| 2560 | 2774 | \\}; |
| 2561 | \\export fn entry() { | |
| 2775 | \\extern fn entry() { | |
| 2562 | 2776 | \\ const x = @TagType(Foo); |
| 2563 | 2777 | \\} |
| 2778 | \\comptime {@export("entry", entry);} | |
| 2564 | 2779 | , |
| 2565 | 2780 | ".tmp_source.zig:1:18: error: expected enum tag type, found 'u32'"); |
| 2566 | 2781 | |
| ... | ... | @@ -2572,9 +2787,10 @@ pub fn addCases(cases: &tests.CompileErrorContext) { |
| 2572 | 2787 | \\ D = 1000, |
| 2573 | 2788 | \\ E = 60, |
| 2574 | 2789 | \\}; |
| 2575 | \\export fn entry() { | |
| 2790 | \\extern fn entry() { | |
| 2576 | 2791 | \\ var x = MultipleChoice { .C = {} }; |
| 2577 | 2792 | \\} |
| 2793 | \\comptime {@export("entry", entry);} | |
| 2578 | 2794 | , |
| 2579 | 2795 | ".tmp_source.zig:6:9: error: enum tag value 60 already taken", |
| 2580 | 2796 | ".tmp_source.zig:4:9: note: other occurrence here"); |
| ... | ... | @@ -2591,9 +2807,10 @@ pub fn addCases(cases: &tests.CompileErrorContext) { |
| 2591 | 2807 | \\ C: bool, |
| 2592 | 2808 | \\ D: bool, |
| 2593 | 2809 | \\}; |
| 2594 | \\export fn entry() { | |
| 2810 | \\extern fn entry() { | |
| 2595 | 2811 | \\ var a = Payload {.A = 1234}; |
| 2596 | 2812 | \\} |
| 2813 | \\comptime {@export("entry", entry);} | |
| 2597 | 2814 | , |
| 2598 | 2815 | ".tmp_source.zig:10:5: error: enum field not found: 'D'", |
| 2599 | 2816 | ".tmp_source.zig:1:16: note: enum declared here"); |
| ... | ... | @@ -2604,9 +2821,10 @@ pub fn addCases(cases: &tests.CompileErrorContext) { |
| 2604 | 2821 | \\ B, |
| 2605 | 2822 | \\ C, |
| 2606 | 2823 | \\}; |
| 2607 | \\export fn entry() { | |
| 2824 | \\extern fn entry() { | |
| 2608 | 2825 | \\ var b = Letter.B; |
| 2609 | 2826 | \\} |
| 2827 | \\comptime {@export("entry", entry);} | |
| 2610 | 2828 | , |
| 2611 | 2829 | ".tmp_source.zig:2:8: error: structs and unions, not enums, support field types", |
| 2612 | 2830 | ".tmp_source.zig:1:16: note: consider 'union(enum)' here"); |
| ... | ... | @@ -2615,9 +2833,10 @@ pub fn addCases(cases: &tests.CompileErrorContext) { |
| 2615 | 2833 | \\const Letter = struct { |
| 2616 | 2834 | \\ A, |
| 2617 | 2835 | \\}; |
| 2618 | \\export fn entry() { | |
| 2836 | \\extern fn entry() { | |
| 2619 | 2837 | \\ var a = Letter { .A = {} }; |
| 2620 | 2838 | \\} |
| 2839 | \\comptime {@export("entry", entry);} | |
| 2621 | 2840 | , |
| 2622 | 2841 | ".tmp_source.zig:2:5: error: struct field missing type"); |
| 2623 | 2842 | |
| ... | ... | @@ -2625,9 +2844,10 @@ pub fn addCases(cases: &tests.CompileErrorContext) { |
| 2625 | 2844 | \\const Letter = extern union { |
| 2626 | 2845 | \\ A, |
| 2627 | 2846 | \\}; |
| 2628 | \\export fn entry() { | |
| 2847 | \\extern fn entry() { | |
| 2629 | 2848 | \\ var a = Letter { .A = {} }; |
| 2630 | 2849 | \\} |
| 2850 | \\comptime {@export("entry", entry);} | |
| 2631 | 2851 | , |
| 2632 | 2852 | ".tmp_source.zig:2:5: error: union field missing type"); |
| 2633 | 2853 | |
| ... | ... | @@ -2642,9 +2862,10 @@ pub fn addCases(cases: &tests.CompileErrorContext) { |
| 2642 | 2862 | \\ B: f64, |
| 2643 | 2863 | \\ C: bool, |
| 2644 | 2864 | \\}; |
| 2645 | \\export fn entry() { | |
| 2865 | \\extern fn entry() { | |
| 2646 | 2866 | \\ var a = Payload { .A = { 1234 } }; |
| 2647 | 2867 | \\} |
| 2868 | \\comptime {@export("entry", entry);} | |
| 2648 | 2869 | , |
| 2649 | 2870 | ".tmp_source.zig:6:29: error: extern union does not support enum tag type"); |
| 2650 | 2871 | |
| ... | ... | @@ -2659,9 +2880,10 @@ pub fn addCases(cases: &tests.CompileErrorContext) { |
| 2659 | 2880 | \\ B: f64, |
| 2660 | 2881 | \\ C: bool, |
| 2661 | 2882 | \\}; |
| 2662 | \\export fn entry() { | |
| 2883 | \\extern fn entry() { | |
| 2663 | 2884 | \\ var a = Payload { .A = { 1234 } }; |
| 2664 | 2885 | \\} |
| 2886 | \\comptime {@export("entry", entry);} | |
| 2665 | 2887 | , |
| 2666 | 2888 | ".tmp_source.zig:6:29: error: packed union does not support enum tag type"); |
| 2667 | 2889 | |
| ... | ... | @@ -2671,7 +2893,7 @@ pub fn addCases(cases: &tests.CompileErrorContext) { |
| 2671 | 2893 | \\ B: f64, |
| 2672 | 2894 | \\ C: bool, |
| 2673 | 2895 | \\}; |
| 2674 | \\export fn entry() { | |
| 2896 | \\extern fn entry() { | |
| 2675 | 2897 | \\ const a = Payload { .A = { 1234 } }; |
| 2676 | 2898 | \\ foo(a); |
| 2677 | 2899 | \\} |
| ... | ... | @@ -2681,6 +2903,7 @@ pub fn addCases(cases: &tests.CompileErrorContext) { |
| 2681 | 2903 | \\ else => unreachable, |
| 2682 | 2904 | \\ } |
| 2683 | 2905 | \\} |
| 2906 | \\comptime {@export("entry", entry);} | |
| 2684 | 2907 | , |
| 2685 | 2908 | ".tmp_source.zig:11:13: error: switch on union which has no attached enum", |
| 2686 | 2909 | ".tmp_source.zig:1:17: note: consider 'union(enum)' here"); |
| ... | ... | @@ -2690,9 +2913,10 @@ pub fn addCases(cases: &tests.CompileErrorContext) { |
| 2690 | 2913 | \\ A = 10, |
| 2691 | 2914 | \\ B = 11, |
| 2692 | 2915 | \\}; |
| 2693 | \\export fn entry() { | |
| 2916 | \\extern fn entry() { | |
| 2694 | 2917 | \\ var x = Foo(0); |
| 2695 | 2918 | \\} |
| 2919 | \\comptime {@export("entry", entry);} | |
| 2696 | 2920 | , |
| 2697 | 2921 | ".tmp_source.zig:6:16: error: enum 'Foo' has no tag matching integer value 0", |
| 2698 | 2922 | ".tmp_source.zig:1:13: note: 'Foo' declared here"); |
| ... | ... | @@ -2704,9 +2928,10 @@ pub fn addCases(cases: &tests.CompileErrorContext) { |
| 2704 | 2928 | \\ B, |
| 2705 | 2929 | \\ C, |
| 2706 | 2930 | \\}; |
| 2707 | \\export fn entry() { | |
| 2931 | \\extern fn entry() { | |
| 2708 | 2932 | \\ var x: Value = Letter.A; |
| 2709 | 2933 | \\} |
| 2934 | \\comptime {@export("entry", entry);} | |
| 2710 | 2935 | , |
| 2711 | 2936 | ".tmp_source.zig:8:26: error: cast to union 'Value' must initialize 'i32' field 'A'", |
| 2712 | 2937 | ".tmp_source.zig:3:5: note: field 'A' declared here"); |
| ... | ... | @@ -2718,13 +2943,36 @@ pub fn addCases(cases: &tests.CompileErrorContext) { |
| 2718 | 2943 | \\ B, |
| 2719 | 2944 | \\ C, |
| 2720 | 2945 | \\}; |
| 2721 | \\export fn entry() { | |
| 2946 | \\extern fn entry() { | |
| 2722 | 2947 | \\ foo(Letter.A); |
| 2723 | 2948 | \\} |
| 2724 | 2949 | \\fn foo(l: Letter) { |
| 2725 | 2950 | \\ var x: Value = l; |
| 2726 | 2951 | \\} |
| 2952 | \\comptime {@export("entry", entry);} | |
| 2727 | 2953 | , |
| 2728 | 2954 | ".tmp_source.zig:11:20: error: runtime cast to union 'Value' which has non-void fields", |
| 2729 | 2955 | ".tmp_source.zig:3:5: note: field 'A' has type 'i32'"); |
| 2956 | ||
| 2957 | cases.addCase({ | |
| 2958 | const tc = cases.create("export collision", | |
| 2959 | \\const foo = @import("foo.zig"); | |
| 2960 | \\ | |
| 2961 | \\comptime {@export("bar", bar);} | |
| 2962 | \\extern fn bar() -> usize { | |
| 2963 | \\ return foo.baz; | |
| 2964 | \\} | |
| 2965 | , | |
| 2966 | "foo.zig:2:11: error: exported symbol collision: 'bar'", | |
| 2967 | ".tmp_source.zig:3:11: note: other symbol is here"); | |
| 2968 | ||
| 2969 | tc.addSourceFile("foo.zig", | |
| 2970 | \\extern fn bar() {} | |
| 2971 | \\comptime {@export("bar", bar);} | |
| 2972 | \\pub const baz = 1234; | |
| 2973 | ); | |
| 2974 | ||
| 2975 | tc | |
| 2976 | }); | |
| 2977 | ||
| 2730 | 2978 | } |
test/standalone/issue_339/test.zig+4-1| ... | ... | @@ -2,6 +2,9 @@ pub fn panic(msg: []const u8) -> noreturn { @breakpoint(); while (true) {} } |
| 2 | 2 | |
| 3 | 3 | fn bar() -> %void {} |
| 4 | 4 | |
| 5 | export fn foo() { | |
| 5 | comptime { | |
| 6 | @export("foo", foo); | |
| 7 | } | |
| 8 | extern fn foo() { | |
| 6 | 9 | %%bar(); |
| 7 | 10 | } |
test/translate_c.zig+32-32| ... | ... | @@ -26,7 +26,7 @@ pub fn addCases(cases: &tests.TranslateCContext) { |
| 26 | 26 | \\ return a < 0 ? -a : a; |
| 27 | 27 | \\} |
| 28 | 28 | , |
| 29 | \\export fn abs(a: c_int) -> c_int { | |
| 29 | \\pub fn abs(a: c_int) -> c_int { | |
| 30 | 30 | \\ return if (a < 0) -a else a; |
| 31 | 31 | \\} |
| 32 | 32 | ); |
| ... | ... | @@ -325,12 +325,12 @@ pub fn addCases(cases: &tests.TranslateCContext) { |
| 325 | 325 | \\ return a; |
| 326 | 326 | \\} |
| 327 | 327 | , |
| 328 | \\export fn foo1(_arg_a: c_uint) -> c_uint { | |
| 328 | \\pub fn foo1(_arg_a: c_uint) -> c_uint { | |
| 329 | 329 | \\ var a = _arg_a; |
| 330 | 330 | \\ a +%= 1; |
| 331 | 331 | \\ return a; |
| 332 | 332 | \\} |
| 333 | \\export fn foo2(_arg_a: c_int) -> c_int { | |
| 333 | \\pub fn foo2(_arg_a: c_int) -> c_int { | |
| 334 | 334 | \\ var a = _arg_a; |
| 335 | 335 | \\ a += 1; |
| 336 | 336 | \\ return a; |
| ... | ... | @@ -346,7 +346,7 @@ pub fn addCases(cases: &tests.TranslateCContext) { |
| 346 | 346 | \\ return i; |
| 347 | 347 | \\} |
| 348 | 348 | , |
| 349 | \\export fn log2(_arg_a: c_uint) -> c_int { | |
| 349 | \\pub fn log2(_arg_a: c_uint) -> c_int { | |
| 350 | 350 | \\ var a = _arg_a; |
| 351 | 351 | \\ var i: c_int = 0; |
| 352 | 352 | \\ while (a > c_uint(0)) { |
| ... | ... | @@ -367,7 +367,7 @@ pub fn addCases(cases: &tests.TranslateCContext) { |
| 367 | 367 | \\ return a; |
| 368 | 368 | \\} |
| 369 | 369 | , |
| 370 | \\export fn max(a: c_int, b: c_int) -> c_int { | |
| 370 | \\pub fn max(a: c_int, b: c_int) -> c_int { | |
| 371 | 371 | \\ if (a < b) return b; |
| 372 | 372 | \\ if (a < b) return b else return a; |
| 373 | 373 | \\} |
| ... | ... | @@ -382,7 +382,7 @@ pub fn addCases(cases: &tests.TranslateCContext) { |
| 382 | 382 | \\ return a; |
| 383 | 383 | \\} |
| 384 | 384 | , |
| 385 | \\export fn max(a: c_int, b: c_int) -> c_int { | |
| 385 | \\pub fn max(a: c_int, b: c_int) -> c_int { | |
| 386 | 386 | \\ if (a == b) return a; |
| 387 | 387 | \\ if (a != b) return b; |
| 388 | 388 | \\ return a; |
| ... | ... | @@ -407,7 +407,7 @@ pub fn addCases(cases: &tests.TranslateCContext) { |
| 407 | 407 | \\ c = a % b; |
| 408 | 408 | \\} |
| 409 | 409 | , |
| 410 | \\export fn s(a: c_int, b: c_int) -> c_int { | |
| 410 | \\pub fn s(a: c_int, b: c_int) -> c_int { | |
| 411 | 411 | \\ var c: c_int; |
| 412 | 412 | \\ c = (a + b); |
| 413 | 413 | \\ c = (a - b); |
| ... | ... | @@ -415,7 +415,7 @@ pub fn addCases(cases: &tests.TranslateCContext) { |
| 415 | 415 | \\ c = @divTrunc(a, b); |
| 416 | 416 | \\ c = @rem(a, b); |
| 417 | 417 | \\} |
| 418 | \\export fn u(a: c_uint, b: c_uint) -> c_uint { | |
| 418 | \\pub fn u(a: c_uint, b: c_uint) -> c_uint { | |
| 419 | 419 | \\ var c: c_uint; |
| 420 | 420 | \\ c = (a +% b); |
| 421 | 421 | \\ c = (a -% b); |
| ... | ... | @@ -430,7 +430,7 @@ pub fn addCases(cases: &tests.TranslateCContext) { |
| 430 | 430 | \\ return (a & b) ^ (a | b); |
| 431 | 431 | \\} |
| 432 | 432 | , |
| 433 | \\export fn max(a: c_int, b: c_int) -> c_int { | |
| 433 | \\pub fn max(a: c_int, b: c_int) -> c_int { | |
| 434 | 434 | \\ return (a & b) ^ (a | b); |
| 435 | 435 | \\} |
| 436 | 436 | ); |
| ... | ... | @@ -444,7 +444,7 @@ pub fn addCases(cases: &tests.TranslateCContext) { |
| 444 | 444 | \\ return a; |
| 445 | 445 | \\} |
| 446 | 446 | , |
| 447 | \\export fn max(a: c_int, b: c_int) -> c_int { | |
| 447 | \\pub fn max(a: c_int, b: c_int) -> c_int { | |
| 448 | 448 | \\ if ((a < b) or (a == b)) return b; |
| 449 | 449 | \\ if ((a >= b) and (a == b)) return a; |
| 450 | 450 | \\ return a; |
| ... | ... | @@ -458,7 +458,7 @@ pub fn addCases(cases: &tests.TranslateCContext) { |
| 458 | 458 | \\ a = tmp; |
| 459 | 459 | \\} |
| 460 | 460 | , |
| 461 | \\export fn max(_arg_a: c_int) -> c_int { | |
| 461 | \\pub fn max(_arg_a: c_int) -> c_int { | |
| 462 | 462 | \\ var a = _arg_a; |
| 463 | 463 | \\ var tmp: c_int; |
| 464 | 464 | \\ tmp = a; |
| ... | ... | @@ -472,7 +472,7 @@ pub fn addCases(cases: &tests.TranslateCContext) { |
| 472 | 472 | \\ c = b = a; |
| 473 | 473 | \\} |
| 474 | 474 | , |
| 475 | \\export fn max(a: c_int) { | |
| 475 | \\pub fn max(a: c_int) { | |
| 476 | 476 | \\ var b: c_int; |
| 477 | 477 | \\ var c: c_int; |
| 478 | 478 | \\ c = { |
| ... | ... | @@ -493,7 +493,7 @@ pub fn addCases(cases: &tests.TranslateCContext) { |
| 493 | 493 | \\ return i; |
| 494 | 494 | \\} |
| 495 | 495 | , |
| 496 | \\export fn log2(_arg_a: u32) -> c_int { | |
| 496 | \\pub fn log2(_arg_a: u32) -> c_int { | |
| 497 | 497 | \\ var a = _arg_a; |
| 498 | 498 | \\ var i: c_int = 0; |
| 499 | 499 | \\ while (a > c_uint(0)) { |
| ... | ... | @@ -518,7 +518,7 @@ pub fn addCases(cases: &tests.TranslateCContext) { |
| 518 | 518 | \\void foo(void) { bar(); } |
| 519 | 519 | , |
| 520 | 520 | \\pub fn bar() {} |
| 521 | \\export fn foo() { | |
| 521 | \\pub fn foo() { | |
| 522 | 522 | \\ bar(); |
| 523 | 523 | \\} |
| 524 | 524 | ); |
| ... | ... | @@ -534,7 +534,7 @@ pub fn addCases(cases: &tests.TranslateCContext) { |
| 534 | 534 | \\pub const struct_Foo = extern struct { |
| 535 | 535 | \\ field: c_int, |
| 536 | 536 | \\}; |
| 537 | \\export fn read_field(foo: ?&struct_Foo) -> c_int { | |
| 537 | \\pub fn read_field(foo: ?&struct_Foo) -> c_int { | |
| 538 | 538 | \\ return (??foo).field; |
| 539 | 539 | \\} |
| 540 | 540 | ); |
| ... | ... | @@ -544,7 +544,7 @@ pub fn addCases(cases: &tests.TranslateCContext) { |
| 544 | 544 | \\ ;;;;; |
| 545 | 545 | \\} |
| 546 | 546 | , |
| 547 | \\export fn foo() {} | |
| 547 | \\pub fn foo() {} | |
| 548 | 548 | ); |
| 549 | 549 | |
| 550 | 550 | cases.add("undefined array global", |
| ... | ... | @@ -560,7 +560,7 @@ pub fn addCases(cases: &tests.TranslateCContext) { |
| 560 | 560 | \\} |
| 561 | 561 | , |
| 562 | 562 | \\pub var array: [100]c_int = undefined; |
| 563 | \\export fn foo(index: c_int) -> c_int { | |
| 563 | \\pub fn foo(index: c_int) -> c_int { | |
| 564 | 564 | \\ return array[index]; |
| 565 | 565 | \\} |
| 566 | 566 | ); |
| ... | ... | @@ -571,7 +571,7 @@ pub fn addCases(cases: &tests.TranslateCContext) { |
| 571 | 571 | \\ return (int)a; |
| 572 | 572 | \\} |
| 573 | 573 | , |
| 574 | \\export fn float_to_int(a: f32) -> c_int { | |
| 574 | \\pub fn float_to_int(a: f32) -> c_int { | |
| 575 | 575 | \\ return c_int(a); |
| 576 | 576 | \\} |
| 577 | 577 | ); |
| ... | ... | @@ -581,7 +581,7 @@ pub fn addCases(cases: &tests.TranslateCContext) { |
| 581 | 581 | \\ return x; |
| 582 | 582 | \\} |
| 583 | 583 | , |
| 584 | \\export fn foo(x: ?&c_ushort) -> ?&c_void { | |
| 584 | \\pub fn foo(x: ?&c_ushort) -> ?&c_void { | |
| 585 | 585 | \\ return @ptrCast(?&c_void, x); |
| 586 | 586 | \\} |
| 587 | 587 | ); |
| ... | ... | @@ -592,7 +592,7 @@ pub fn addCases(cases: &tests.TranslateCContext) { |
| 592 | 592 | \\ return sizeof(int); |
| 593 | 593 | \\} |
| 594 | 594 | , |
| 595 | \\export fn size_of() -> usize { | |
| 595 | \\pub fn size_of() -> usize { | |
| 596 | 596 | \\ return @sizeOf(c_int); |
| 597 | 597 | \\} |
| 598 | 598 | ); |
| ... | ... | @@ -602,7 +602,7 @@ pub fn addCases(cases: &tests.TranslateCContext) { |
| 602 | 602 | \\ return 0; |
| 603 | 603 | \\} |
| 604 | 604 | , |
| 605 | \\export fn foo() -> ?&c_int { | |
| 605 | \\pub fn foo() -> ?&c_int { | |
| 606 | 606 | \\ return null; |
| 607 | 607 | \\} |
| 608 | 608 | ); |
| ... | ... | @@ -612,7 +612,7 @@ pub fn addCases(cases: &tests.TranslateCContext) { |
| 612 | 612 | \\ return 1, 2; |
| 613 | 613 | \\} |
| 614 | 614 | , |
| 615 | \\export fn foo() -> c_int { | |
| 615 | \\pub fn foo() -> c_int { | |
| 616 | 616 | \\ return { |
| 617 | 617 | \\ _ = 1; |
| 618 | 618 | \\ 2 |
| ... | ... | @@ -625,7 +625,7 @@ pub fn addCases(cases: &tests.TranslateCContext) { |
| 625 | 625 | \\ return (1 << 2) >> 1; |
| 626 | 626 | \\} |
| 627 | 627 | , |
| 628 | \\export fn foo() -> c_int { | |
| 628 | \\pub fn foo() -> c_int { | |
| 629 | 629 | \\ return (1 << @import("std").math.Log2Int(c_int)(2)) >> @import("std").math.Log2Int(c_int)(1); |
| 630 | 630 | \\} |
| 631 | 631 | ); |
| ... | ... | @@ -643,7 +643,7 @@ pub fn addCases(cases: &tests.TranslateCContext) { |
| 643 | 643 | \\ a <<= (a <<= 1); |
| 644 | 644 | \\} |
| 645 | 645 | , |
| 646 | \\export fn foo() { | |
| 646 | \\pub fn foo() { | |
| 647 | 647 | \\ var a: c_int = 0; |
| 648 | 648 | \\ a += { |
| 649 | 649 | \\ const _ref = &a; |
| ... | ... | @@ -701,7 +701,7 @@ pub fn addCases(cases: &tests.TranslateCContext) { |
| 701 | 701 | \\ a <<= (a <<= 1); |
| 702 | 702 | \\} |
| 703 | 703 | , |
| 704 | \\export fn foo() { | |
| 704 | \\pub fn foo() { | |
| 705 | 705 | \\ var a: c_uint = c_uint(0); |
| 706 | 706 | \\ a +%= { |
| 707 | 707 | \\ const _ref = &a; |
| ... | ... | @@ -771,7 +771,7 @@ pub fn addCases(cases: &tests.TranslateCContext) { |
| 771 | 771 | \\ u = u--; |
| 772 | 772 | \\} |
| 773 | 773 | , |
| 774 | \\export fn foo() { | |
| 774 | \\pub fn foo() { | |
| 775 | 775 | \\ var i: c_int = 0; |
| 776 | 776 | \\ var u: c_uint = c_uint(0); |
| 777 | 777 | \\ i += 1; |
| ... | ... | @@ -819,7 +819,7 @@ pub fn addCases(cases: &tests.TranslateCContext) { |
| 819 | 819 | \\ u = --u; |
| 820 | 820 | \\} |
| 821 | 821 | , |
| 822 | \\export fn foo() { | |
| 822 | \\pub fn foo() { | |
| 823 | 823 | \\ var i: c_int = 0; |
| 824 | 824 | \\ var u: c_uint = c_uint(0); |
| 825 | 825 | \\ i += 1; |
| ... | ... | @@ -862,7 +862,7 @@ pub fn addCases(cases: &tests.TranslateCContext) { |
| 862 | 862 | \\ while (b != 0); |
| 863 | 863 | \\} |
| 864 | 864 | , |
| 865 | \\export fn foo() { | |
| 865 | \\pub fn foo() { | |
| 866 | 866 | \\ var a: c_int = 2; |
| 867 | 867 | \\ while (true) { |
| 868 | 868 | \\ a -= 1; |
| ... | ... | @@ -886,9 +886,9 @@ pub fn addCases(cases: &tests.TranslateCContext) { |
| 886 | 886 | \\ baz(); |
| 887 | 887 | \\} |
| 888 | 888 | , |
| 889 | \\export fn foo() {} | |
| 890 | \\export fn baz() {} | |
| 891 | \\export fn bar() { | |
| 889 | \\pub fn foo() {} | |
| 890 | \\pub fn baz() {} | |
| 891 | \\pub fn bar() { | |
| 892 | 892 | \\ var f: ?extern fn() = foo; |
| 893 | 893 | \\ (??f)(); |
| 894 | 894 | \\ (??f)(); |
| ... | ... | @@ -901,7 +901,7 @@ pub fn addCases(cases: &tests.TranslateCContext) { |
| 901 | 901 | \\ *x = 1; |
| 902 | 902 | \\} |
| 903 | 903 | , |
| 904 | \\export fn foo(x: ?&c_int) { | |
| 904 | \\pub fn foo(x: ?&c_int) { | |
| 905 | 905 | \\ (*??x) = 1; |
| 906 | 906 | \\} |
| 907 | 907 | ); |