authorgravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2019-06-26 18:29:19-04:00
committergravatar for noreply@github.comGitHub <noreply@github.com> 2019-06-26 18:29:19-04:00
log01ff0d4d629c3800ebac68edfd91edb570aeaa59
treefc1bdbf059e9bf9e99b212aae3056ed0e87e7e77
parent07c0d484eec327ca3bd1e3ce081c1ced230536a9
parent517bdea7549453d958c31cf2af5dc298ea5508a9
signaturebadge-question-mark Signed by PGP key 4AEE18F83AFDEB23

Merge pull request #2602 from ziglang/copy-elision-3

result location mechanism (part of no-copy semantics)

42 files changed, 4319 insertions(+), 2112 deletions(-)

CMakeLists.txt+1
...@@ -6734,6 +6734,7 @@ add_custom_command(...@@ -6734,6 +6734,7 @@ add_custom_command(
6734 "-Doutput-dir=${CMAKE_BINARY_DIR}"6734 "-Doutput-dir=${CMAKE_BINARY_DIR}"
6735 WORKING_DIRECTORY "${CMAKE_SOURCE_DIR}"6735 WORKING_DIRECTORY "${CMAKE_SOURCE_DIR}"
6736 DEPENDS6736 DEPENDS
6737 zig0
6737 "${CMAKE_SOURCE_DIR}/src-self-hosted/dep_tokenizer.zig"6738 "${CMAKE_SOURCE_DIR}/src-self-hosted/dep_tokenizer.zig"
6738 "${CMAKE_SOURCE_DIR}/src-self-hosted/stage1.zig"6739 "${CMAKE_SOURCE_DIR}/src-self-hosted/stage1.zig"
6739 "${CMAKE_SOURCE_DIR}/src-self-hosted/translate_c.zig"6740 "${CMAKE_SOURCE_DIR}/src-self-hosted/translate_c.zig"
build.zig+2-1
...@@ -74,7 +74,8 @@ pub fn build(b: *Builder) !void {...@@ -74,7 +74,8 @@ pub fn build(b: *Builder) !void {
74 const skip_non_native = b.option(bool, "skip-non-native", "Main test suite skips non-native builds") orelse false;74 const skip_non_native = b.option(bool, "skip-non-native", "Main test suite skips non-native builds") orelse false;
75 const skip_self_hosted = b.option(bool, "skip-self-hosted", "Main test suite skips building self hosted compiler") orelse false;75 const skip_self_hosted = b.option(bool, "skip-self-hosted", "Main test suite skips building self hosted compiler") orelse false;
76 if (!skip_self_hosted) {76 if (!skip_self_hosted) {
77 test_step.dependOn(&exe.step);77 // TODO re-enable this after https://github.com/ziglang/zig/issues/2377
78 //test_step.dependOn(&exe.step);
78 }79 }
79 const verbose_link_exe = b.option(bool, "verbose-link", "Print link command for self hosted compiler") orelse false;80 const verbose_link_exe = b.option(bool, "verbose-link", "Print link command for self hosted compiler") orelse false;
80 exe.setVerboseLink(verbose_link_exe);81 exe.setVerboseLink(verbose_link_exe);
doc/langref.html.in+1-1
...@@ -5096,7 +5096,7 @@ fn gimmeTheBiggerInteger(a: u64, b: u64) u64 {...@@ -5096,7 +5096,7 @@ fn gimmeTheBiggerInteger(a: u64, b: u64) u64 {
5096 <p>5096 <p>
5097 For example, if we were to introduce another function to the above snippet:5097 For example, if we were to introduce another function to the above snippet:
5098 </p>5098 </p>
5099 {#code_begin|test_err|values of type 'type' must be comptime known#}5099 {#code_begin|test_err|cannot store runtime value in type 'type'#}
5100fn max(comptime T: type, a: T, b: T) T {5100fn max(comptime T: type, a: T, b: T) T {
5101 return if (a > b) a else b;5101 return if (a > b) a else b;
5102}5102}
src/all_types.hpp+276-92
...@@ -34,12 +34,17 @@ struct CodeGen;...@@ -34,12 +34,17 @@ struct CodeGen;
34struct ConstExprValue;34struct ConstExprValue;
35struct IrInstruction;35struct IrInstruction;
36struct IrInstructionCast;36struct IrInstructionCast;
37struct IrInstructionAllocaGen;
37struct IrBasicBlock;38struct IrBasicBlock;
38struct ScopeDecls;39struct ScopeDecls;
39struct ZigWindowsSDK;40struct ZigWindowsSDK;
40struct Tld;41struct Tld;
41struct TldExport;42struct TldExport;
42struct IrAnalyze;43struct IrAnalyze;
44struct ResultLoc;
45struct ResultLocPeer;
46struct ResultLocPeerParent;
47struct ResultLocBitCast;
4348
44enum X64CABIClass {49enum X64CABIClass {
45 X64CABIClass_Unknown,50 X64CABIClass_Unknown,
...@@ -198,6 +203,9 @@ enum ConstPtrMut {...@@ -198,6 +203,9 @@ enum ConstPtrMut {
198 // The pointer points to memory that is known only at runtime.203 // The pointer points to memory that is known only at runtime.
199 // For example it may point to the initializer value of a variable.204 // For example it may point to the initializer value of a variable.
200 ConstPtrMutRuntimeVar,205 ConstPtrMutRuntimeVar,
206 // The pointer points to memory for which it must be inferred whether the
207 // value is comptime known or not.
208 ConstPtrMutInfer,
201};209};
202210
203struct ConstPtrValue {211struct ConstPtrValue {
...@@ -289,6 +297,7 @@ struct RuntimeHintSlice {...@@ -289,6 +297,7 @@ struct RuntimeHintSlice {
289struct ConstGlobalRefs {297struct ConstGlobalRefs {
290 LLVMValueRef llvm_value;298 LLVMValueRef llvm_value;
291 LLVMValueRef llvm_global;299 LLVMValueRef llvm_global;
300 uint32_t align;
292};301};
293302
294struct ConstExprValue {303struct ConstExprValue {
...@@ -325,6 +334,10 @@ struct ConstExprValue {...@@ -325,6 +334,10 @@ struct ConstExprValue {
325 RuntimeHintPtr rh_ptr;334 RuntimeHintPtr rh_ptr;
326 RuntimeHintSlice rh_slice;335 RuntimeHintSlice rh_slice;
327 } data;336 } data;
337
338 // uncomment these to find bugs. can't leave them uncommented because of a gcc-9 warning
339 //ConstExprValue(const ConstExprValue &other) = delete; // plz zero initialize with {}
340 //ConstExprValue& operator= (const ConstExprValue &other) = delete; // use copy_const_val
328};341};
329342
330enum ReturnKnowledge {343enum ReturnKnowledge {
...@@ -426,7 +439,7 @@ enum NodeType {...@@ -426,7 +439,7 @@ enum NodeType {
426 NodeTypeVariableDeclaration,439 NodeTypeVariableDeclaration,
427 NodeTypeTestDecl,440 NodeTypeTestDecl,
428 NodeTypeBinOpExpr,441 NodeTypeBinOpExpr,
429 NodeTypeUnwrapErrorExpr,442 NodeTypeCatchExpr,
430 NodeTypeFloatLiteral,443 NodeTypeFloatLiteral,
431 NodeTypeIntLiteral,444 NodeTypeIntLiteral,
432 NodeTypeStringLiteral,445 NodeTypeStringLiteral,
...@@ -1364,7 +1377,7 @@ struct ZigFn {...@@ -1364,7 +1377,7 @@ struct ZigFn {
1364 AstNode *fn_no_inline_set_node;1377 AstNode *fn_no_inline_set_node;
1365 AstNode *fn_static_eval_set_node;1378 AstNode *fn_static_eval_set_node;
13661379
1367 ZigList<IrInstruction *> alloca_list;1380 ZigList<IrInstructionAllocaGen *> alloca_gen_list;
1368 ZigList<ZigVar *> variable_list;1381 ZigList<ZigVar *> variable_list;
13691382
1370 Buf *section_name;1383 Buf *section_name;
...@@ -1999,6 +2012,11 @@ struct ScopeDecls {...@@ -1999,6 +2012,11 @@ struct ScopeDecls {
1999 bool any_imports_failed;2012 bool any_imports_failed;
2000};2013};
20012014
2015enum LVal {
2016 LValNone,
2017 LValPtr,
2018};
2019
2002// This scope comes from a block expression in user code.2020// This scope comes from a block expression in user code.
2003// NodeTypeBlock2021// NodeTypeBlock
2004struct ScopeBlock {2022struct ScopeBlock {
...@@ -2007,12 +2025,14 @@ struct ScopeBlock {...@@ -2007,12 +2025,14 @@ struct ScopeBlock {
2007 Buf *name;2025 Buf *name;
2008 IrBasicBlock *end_block;2026 IrBasicBlock *end_block;
2009 IrInstruction *is_comptime;2027 IrInstruction *is_comptime;
2028 ResultLocPeerParent *peer_parent;
2010 ZigList<IrInstruction *> *incoming_values;2029 ZigList<IrInstruction *> *incoming_values;
2011 ZigList<IrBasicBlock *> *incoming_blocks;2030 ZigList<IrBasicBlock *> *incoming_blocks;
20122031
2013 AstNode *safety_set_node;2032 AstNode *safety_set_node;
2014 AstNode *fast_math_set_node;2033 AstNode *fast_math_set_node;
20152034
2035 LVal lval;
2016 bool safety_off;2036 bool safety_off;
2017 bool fast_math_on;2037 bool fast_math_on;
2018};2038};
...@@ -2056,12 +2076,14 @@ struct ScopeCImport {...@@ -2056,12 +2076,14 @@ struct ScopeCImport {
2056struct ScopeLoop {2076struct ScopeLoop {
2057 Scope base;2077 Scope base;
20582078
2079 LVal lval;
2059 Buf *name;2080 Buf *name;
2060 IrBasicBlock *break_block;2081 IrBasicBlock *break_block;
2061 IrBasicBlock *continue_block;2082 IrBasicBlock *continue_block;
2062 IrInstruction *is_comptime;2083 IrInstruction *is_comptime;
2063 ZigList<IrInstruction *> *incoming_values;2084 ZigList<IrInstruction *> *incoming_values;
2064 ZigList<IrBasicBlock *> *incoming_blocks;2085 ZigList<IrBasicBlock *> *incoming_blocks;
2086 ResultLocPeerParent *peer_parent;
2065};2087};
20662088
2067// This scope blocks certain things from working such as comptime continue2089// This scope blocks certain things from working such as comptime continue
...@@ -2138,6 +2160,8 @@ struct IrBasicBlock {...@@ -2138,6 +2160,8 @@ struct IrBasicBlock {
2138 const char *name_hint;2160 const char *name_hint;
2139 size_t debug_id;2161 size_t debug_id;
2140 size_t ref_count;2162 size_t ref_count;
2163 // index into the basic block list
2164 size_t index;
2141 LLVMBasicBlockRef llvm_block;2165 LLVMBasicBlockRef llvm_block;
2142 LLVMBasicBlockRef llvm_exit_block;2166 LLVMBasicBlockRef llvm_exit_block;
2143 // The instruction that referenced this basic block and caused us to2167 // The instruction that referenced this basic block and caused us to
...@@ -2148,11 +2172,10 @@ struct IrBasicBlock {...@@ -2148,11 +2172,10 @@ struct IrBasicBlock {
2148 // if the branch is comptime. The instruction points to the reason2172 // if the branch is comptime. The instruction points to the reason
2149 // the basic block must be comptime.2173 // the basic block must be comptime.
2150 IrInstruction *must_be_comptime_source_instr;2174 IrInstruction *must_be_comptime_source_instr;
2151};2175 IrInstruction *suspend_instruction_ref;
21522176 bool already_appended;
2153enum LVal {2177 bool suspended;
2154 LValNone,2178 bool in_resume_stack;
2155 LValPtr,
2156};2179};
21572180
2158// These instructions are in transition to having "pass 1" instructions2181// These instructions are in transition to having "pass 1" instructions
...@@ -2185,19 +2208,17 @@ enum IrInstructionId {...@@ -2185,19 +2208,17 @@ enum IrInstructionId {
2185 IrInstructionIdUnionFieldPtr,2208 IrInstructionIdUnionFieldPtr,
2186 IrInstructionIdElemPtr,2209 IrInstructionIdElemPtr,
2187 IrInstructionIdVarPtr,2210 IrInstructionIdVarPtr,
2188 IrInstructionIdCall,2211 IrInstructionIdReturnPtr,
2212 IrInstructionIdCallSrc,
2213 IrInstructionIdCallGen,
2189 IrInstructionIdConst,2214 IrInstructionIdConst,
2190 IrInstructionIdReturn,2215 IrInstructionIdReturn,
2191 IrInstructionIdCast,2216 IrInstructionIdCast,
2192 IrInstructionIdResizeSlice,2217 IrInstructionIdResizeSlice,
2193 IrInstructionIdContainerInitList,2218 IrInstructionIdContainerInitList,
2194 IrInstructionIdContainerInitFields,2219 IrInstructionIdContainerInitFields,
2195 IrInstructionIdStructInit,
2196 IrInstructionIdUnionInit,
2197 IrInstructionIdUnreachable,2220 IrInstructionIdUnreachable,
2198 IrInstructionIdTypeOf,2221 IrInstructionIdTypeOf,
2199 IrInstructionIdToPtrType,
2200 IrInstructionIdPtrTypeChild,
2201 IrInstructionIdSetCold,2222 IrInstructionIdSetCold,
2202 IrInstructionIdSetRuntimeSafety,2223 IrInstructionIdSetRuntimeSafety,
2203 IrInstructionIdSetFloatMode,2224 IrInstructionIdSetFloatMode,
...@@ -2222,6 +2243,7 @@ enum IrInstructionId {...@@ -2222,6 +2243,7 @@ enum IrInstructionId {
2222 IrInstructionIdCDefine,2243 IrInstructionIdCDefine,
2223 IrInstructionIdCUndef,2244 IrInstructionIdCUndef,
2224 IrInstructionIdRef,2245 IrInstructionIdRef,
2246 IrInstructionIdRefGen,
2225 IrInstructionIdCompileErr,2247 IrInstructionIdCompileErr,
2226 IrInstructionIdCompileLog,2248 IrInstructionIdCompileLog,
2227 IrInstructionIdErrName,2249 IrInstructionIdErrName,
...@@ -2240,7 +2262,8 @@ enum IrInstructionId {...@@ -2240,7 +2262,8 @@ enum IrInstructionId {
2240 IrInstructionIdBoolNot,2262 IrInstructionIdBoolNot,
2241 IrInstructionIdMemset,2263 IrInstructionIdMemset,
2242 IrInstructionIdMemcpy,2264 IrInstructionIdMemcpy,
2243 IrInstructionIdSlice,2265 IrInstructionIdSliceSrc,
2266 IrInstructionIdSliceGen,
2244 IrInstructionIdMemberCount,2267 IrInstructionIdMemberCount,
2245 IrInstructionIdMemberType,2268 IrInstructionIdMemberType,
2246 IrInstructionIdMemberName,2269 IrInstructionIdMemberName,
...@@ -2250,9 +2273,10 @@ enum IrInstructionId {...@@ -2250,9 +2273,10 @@ enum IrInstructionId {
2250 IrInstructionIdHandle,2273 IrInstructionIdHandle,
2251 IrInstructionIdAlignOf,2274 IrInstructionIdAlignOf,
2252 IrInstructionIdOverflowOp,2275 IrInstructionIdOverflowOp,
2276 IrInstructionIdTestErrSrc,
2277 IrInstructionIdTestErrGen,
2253 IrInstructionIdMulAdd,2278 IrInstructionIdMulAdd,
2254 IrInstructionIdFloatOp,2279 IrInstructionIdFloatOp,
2255 IrInstructionIdTestErr,
2256 IrInstructionIdUnwrapErrCode,2280 IrInstructionIdUnwrapErrCode,
2257 IrInstructionIdUnwrapErrPayload,2281 IrInstructionIdUnwrapErrPayload,
2258 IrInstructionIdErrWrapCode,2282 IrInstructionIdErrWrapCode,
...@@ -2261,7 +2285,7 @@ enum IrInstructionId {...@@ -2261,7 +2285,7 @@ enum IrInstructionId {
2261 IrInstructionIdTestComptime,2285 IrInstructionIdTestComptime,
2262 IrInstructionIdPtrCastSrc,2286 IrInstructionIdPtrCastSrc,
2263 IrInstructionIdPtrCastGen,2287 IrInstructionIdPtrCastGen,
2264 IrInstructionIdBitCast,2288 IrInstructionIdBitCastSrc,
2265 IrInstructionIdBitCastGen,2289 IrInstructionIdBitCastGen,
2266 IrInstructionIdWidenOrShorten,2290 IrInstructionIdWidenOrShorten,
2267 IrInstructionIdIntToPtr,2291 IrInstructionIdIntToPtr,
...@@ -2285,6 +2309,10 @@ enum IrInstructionId {...@@ -2285,6 +2309,10 @@ enum IrInstructionId {
2285 IrInstructionIdSetEvalBranchQuota,2309 IrInstructionIdSetEvalBranchQuota,
2286 IrInstructionIdPtrType,2310 IrInstructionIdPtrType,
2287 IrInstructionIdAlignCast,2311 IrInstructionIdAlignCast,
2312 IrInstructionIdImplicitCast,
2313 IrInstructionIdResolveResult,
2314 IrInstructionIdResetResult,
2315 IrInstructionIdResultPtr,
2288 IrInstructionIdOpaqueType,2316 IrInstructionIdOpaqueType,
2289 IrInstructionIdSetAlignStack,2317 IrInstructionIdSetAlignStack,
2290 IrInstructionIdArgType,2318 IrInstructionIdArgType,
...@@ -2323,10 +2351,13 @@ enum IrInstructionId {...@@ -2323,10 +2351,13 @@ enum IrInstructionId {
2323 IrInstructionIdAssertNonNull,2351 IrInstructionIdAssertNonNull,
2324 IrInstructionIdHasDecl,2352 IrInstructionIdHasDecl,
2325 IrInstructionIdUndeclaredIdent,2353 IrInstructionIdUndeclaredIdent,
2354 IrInstructionIdAllocaSrc,
2355 IrInstructionIdAllocaGen,
2356 IrInstructionIdEndExpr,
2357 IrInstructionIdPtrOfArrayToSlice,
2326};2358};
23272359
2328struct IrInstruction {2360struct IrInstruction {
2329 IrInstructionId id;
2330 Scope *scope;2361 Scope *scope;
2331 AstNode *source_node;2362 AstNode *source_node;
2332 ConstExprValue value;2363 ConstExprValue value;
...@@ -2340,6 +2371,7 @@ struct IrInstruction {...@@ -2340,6 +2371,7 @@ struct IrInstruction {
2340 // with this child field.2371 // with this child field.
2341 IrInstruction *child;2372 IrInstruction *child;
2342 IrBasicBlock *owner_bb;2373 IrBasicBlock *owner_bb;
2374 IrInstructionId id;
2343 // true if this instruction was generated by zig and not from user code2375 // true if this instruction was generated by zig and not from user code
2344 bool is_gen;2376 bool is_gen;
2345};2377};
...@@ -2350,14 +2382,14 @@ struct IrInstructionDeclVarSrc {...@@ -2350,14 +2382,14 @@ struct IrInstructionDeclVarSrc {
2350 ZigVar *var;2382 ZigVar *var;
2351 IrInstruction *var_type;2383 IrInstruction *var_type;
2352 IrInstruction *align_value;2384 IrInstruction *align_value;
2353 IrInstruction *init_value;2385 IrInstruction *ptr;
2354};2386};
23552387
2356struct IrInstructionDeclVarGen {2388struct IrInstructionDeclVarGen {
2357 IrInstruction base;2389 IrInstruction base;
23582390
2359 ZigVar *var;2391 ZigVar *var;
2360 IrInstruction *init_value;2392 IrInstruction *var_ptr;
2361};2393};
23622394
2363struct IrInstructionCondBr {2395struct IrInstructionCondBr {
...@@ -2367,6 +2399,7 @@ struct IrInstructionCondBr {...@@ -2367,6 +2399,7 @@ struct IrInstructionCondBr {
2367 IrBasicBlock *then_block;2399 IrBasicBlock *then_block;
2368 IrBasicBlock *else_block;2400 IrBasicBlock *else_block;
2369 IrInstruction *is_comptime;2401 IrInstruction *is_comptime;
2402 ResultLoc *result_loc;
2370};2403};
23712404
2372struct IrInstructionBr {2405struct IrInstructionBr {
...@@ -2419,6 +2452,7 @@ struct IrInstructionPhi {...@@ -2419,6 +2452,7 @@ struct IrInstructionPhi {
2419 size_t incoming_count;2452 size_t incoming_count;
2420 IrBasicBlock **incoming_blocks;2453 IrBasicBlock **incoming_blocks;
2421 IrInstruction **incoming_values;2454 IrInstruction **incoming_values;
2455 ResultLocPeerParent *peer_parent;
2422};2456};
24232457
2424enum IrUnOp {2458enum IrUnOp {
...@@ -2434,8 +2468,9 @@ struct IrInstructionUnOp {...@@ -2434,8 +2468,9 @@ struct IrInstructionUnOp {
2434 IrInstruction base;2468 IrInstruction base;
24352469
2436 IrUnOp op_id;2470 IrUnOp op_id;
2437 IrInstruction *value;
2438 LVal lval;2471 LVal lval;
2472 IrInstruction *value;
2473 ResultLoc *result_loc;
2439};2474};
24402475
2441enum IrBinOp {2476enum IrBinOp {
...@@ -2492,7 +2527,7 @@ struct IrInstructionLoadPtrGen {...@@ -2492,7 +2527,7 @@ struct IrInstructionLoadPtrGen {
2492 IrInstruction base;2527 IrInstruction base;
24932528
2494 IrInstruction *ptr;2529 IrInstruction *ptr;
2495 LLVMValueRef tmp_ptr;2530 IrInstruction *result_loc;
2496};2531};
24972532
2498struct IrInstructionStorePtr {2533struct IrInstructionStorePtr {
...@@ -2505,6 +2540,7 @@ struct IrInstructionStorePtr {...@@ -2505,6 +2540,7 @@ struct IrInstructionStorePtr {
2505struct IrInstructionFieldPtr {2540struct IrInstructionFieldPtr {
2506 IrInstruction base;2541 IrInstruction base;
25072542
2543 bool initializing;
2508 IrInstruction *container_ptr;2544 IrInstruction *container_ptr;
2509 Buf *field_name_buffer;2545 Buf *field_name_buffer;
2510 IrInstruction *field_name_expr;2546 IrInstruction *field_name_expr;
...@@ -2521,9 +2557,10 @@ struct IrInstructionStructFieldPtr {...@@ -2521,9 +2557,10 @@ struct IrInstructionStructFieldPtr {
2521struct IrInstructionUnionFieldPtr {2557struct IrInstructionUnionFieldPtr {
2522 IrInstruction base;2558 IrInstruction base;
25232559
2560 bool safety_check_on;
2561 bool initializing;
2524 IrInstruction *union_ptr;2562 IrInstruction *union_ptr;
2525 TypeUnionField *field;2563 TypeUnionField *field;
2526 bool is_const;
2527};2564};
25282565
2529struct IrInstructionElemPtr {2566struct IrInstructionElemPtr {
...@@ -2531,8 +2568,8 @@ struct IrInstructionElemPtr {...@@ -2531,8 +2568,8 @@ struct IrInstructionElemPtr {
25312568
2532 IrInstruction *array_ptr;2569 IrInstruction *array_ptr;
2533 IrInstruction *elem_index;2570 IrInstruction *elem_index;
2571 IrInstruction *init_array_type;
2534 PtrLen ptr_len;2572 PtrLen ptr_len;
2535 bool is_const;
2536 bool safety_check_on;2573 bool safety_check_on;
2537};2574};
25382575
...@@ -2543,14 +2580,21 @@ struct IrInstructionVarPtr {...@@ -2543,14 +2580,21 @@ struct IrInstructionVarPtr {
2543 ScopeFnDef *crossed_fndef_scope;2580 ScopeFnDef *crossed_fndef_scope;
2544};2581};
25452582
2546struct IrInstructionCall {2583// For functions that have a return type for which handle_is_ptr is true, a
2584// result location pointer is the secret first parameter ("sret"). This
2585// instruction returns that pointer.
2586struct IrInstructionReturnPtr {
2587 IrInstruction base;
2588};
2589
2590struct IrInstructionCallSrc {
2547 IrInstruction base;2591 IrInstruction base;
25482592
2549 IrInstruction *fn_ref;2593 IrInstruction *fn_ref;
2550 ZigFn *fn_entry;2594 ZigFn *fn_entry;
2551 size_t arg_count;2595 size_t arg_count;
2552 IrInstruction **args;2596 IrInstruction **args;
2553 LLVMValueRef tmp_ptr;2597 ResultLoc *result_loc;
25542598
2555 IrInstruction *async_allocator;2599 IrInstruction *async_allocator;
2556 IrInstruction *new_stack;2600 IrInstruction *new_stack;
...@@ -2559,6 +2603,21 @@ struct IrInstructionCall {...@@ -2559,6 +2603,21 @@ struct IrInstructionCall {
2559 bool is_comptime;2603 bool is_comptime;
2560};2604};
25612605
2606struct IrInstructionCallGen {
2607 IrInstruction base;
2608
2609 IrInstruction *fn_ref;
2610 ZigFn *fn_entry;
2611 size_t arg_count;
2612 IrInstruction **args;
2613 IrInstruction *result_loc;
2614
2615 IrInstruction *async_allocator;
2616 IrInstruction *new_stack;
2617 FnInline fn_inline;
2618 bool is_async;
2619};
2620
2562struct IrInstructionConst {2621struct IrInstructionConst {
2563 IrInstruction base;2622 IrInstruction base;
2564};2623};
...@@ -2581,7 +2640,6 @@ enum CastOp {...@@ -2581,7 +2640,6 @@ enum CastOp {
2581 CastOpNumLitToConcrete,2640 CastOpNumLitToConcrete,
2582 CastOpErrSet,2641 CastOpErrSet,
2583 CastOpBitCast,2642 CastOpBitCast,
2584 CastOpPtrOfArrayToSlice,
2585};2643};
25862644
2587// TODO get rid of this instruction, replace with instructions for each op code2645// TODO get rid of this instruction, replace with instructions for each op code
...@@ -2591,14 +2649,13 @@ struct IrInstructionCast {...@@ -2591,14 +2649,13 @@ struct IrInstructionCast {
2591 IrInstruction *value;2649 IrInstruction *value;
2592 ZigType *dest_type;2650 ZigType *dest_type;
2593 CastOp cast_op;2651 CastOp cast_op;
2594 LLVMValueRef tmp_ptr;
2595};2652};
25962653
2597struct IrInstructionResizeSlice {2654struct IrInstructionResizeSlice {
2598 IrInstruction base;2655 IrInstruction base;
25992656
2600 IrInstruction *operand;2657 IrInstruction *operand;
2601 LLVMValueRef tmp_ptr;2658 IrInstruction *result_loc;
2602};2659};
26032660
2604struct IrInstructionContainerInitList {2661struct IrInstructionContainerInitList {
...@@ -2607,15 +2664,15 @@ struct IrInstructionContainerInitList {...@@ -2607,15 +2664,15 @@ struct IrInstructionContainerInitList {
2607 IrInstruction *container_type;2664 IrInstruction *container_type;
2608 IrInstruction *elem_type;2665 IrInstruction *elem_type;
2609 size_t item_count;2666 size_t item_count;
2610 IrInstruction **items;2667 IrInstruction **elem_result_loc_list;
2611 LLVMValueRef tmp_ptr;2668 IrInstruction *result_loc;
2612};2669};
26132670
2614struct IrInstructionContainerInitFieldsField {2671struct IrInstructionContainerInitFieldsField {
2615 Buf *name;2672 Buf *name;
2616 IrInstruction *value;
2617 AstNode *source_node;2673 AstNode *source_node;
2618 TypeStructField *type_struct_field;2674 TypeStructField *type_struct_field;
2675 IrInstruction *result_loc;
2619};2676};
26202677
2621struct IrInstructionContainerInitFields {2678struct IrInstructionContainerInitFields {
...@@ -2624,29 +2681,7 @@ struct IrInstructionContainerInitFields {...@@ -2624,29 +2681,7 @@ struct IrInstructionContainerInitFields {
2624 IrInstruction *container_type;2681 IrInstruction *container_type;
2625 size_t field_count;2682 size_t field_count;
2626 IrInstructionContainerInitFieldsField *fields;2683 IrInstructionContainerInitFieldsField *fields;
2627};2684 IrInstruction *result_loc;
2628
2629struct IrInstructionStructInitField {
2630 IrInstruction *value;
2631 TypeStructField *type_struct_field;
2632};
2633
2634struct IrInstructionStructInit {
2635 IrInstruction base;
2636
2637 ZigType *struct_type;
2638 size_t field_count;
2639 IrInstructionStructInitField *fields;
2640 LLVMValueRef tmp_ptr;
2641};
2642
2643struct IrInstructionUnionInit {
2644 IrInstruction base;
2645
2646 ZigType *union_type;
2647 TypeUnionField *field;
2648 IrInstruction *init_value;
2649 LLVMValueRef tmp_ptr;
2650};2685};
26512686
2652struct IrInstructionUnreachable {2687struct IrInstructionUnreachable {
...@@ -2659,18 +2694,6 @@ struct IrInstructionTypeOf {...@@ -2659,18 +2694,6 @@ struct IrInstructionTypeOf {
2659 IrInstruction *value;2694 IrInstruction *value;
2660};2695};
26612696
2662struct IrInstructionToPtrType {
2663 IrInstruction base;
2664
2665 IrInstruction *ptr;
2666};
2667
2668struct IrInstructionPtrTypeChild {
2669 IrInstruction base;
2670
2671 IrInstruction *value;
2672};
2673
2674struct IrInstructionSetCold {2697struct IrInstructionSetCold {
2675 IrInstruction base;2698 IrInstruction base;
26762699
...@@ -2764,8 +2787,9 @@ struct IrInstructionTestNonNull {...@@ -2764,8 +2787,9 @@ struct IrInstructionTestNonNull {
2764struct IrInstructionOptionalUnwrapPtr {2787struct IrInstructionOptionalUnwrapPtr {
2765 IrInstruction base;2788 IrInstruction base;
27662789
2767 IrInstruction *base_ptr;
2768 bool safety_check_on;2790 bool safety_check_on;
2791 bool initializing;
2792 IrInstruction *base_ptr;
2769};2793};
27702794
2771struct IrInstructionCtz {2795struct IrInstructionCtz {
...@@ -2805,11 +2829,17 @@ struct IrInstructionRef {...@@ -2805,11 +2829,17 @@ struct IrInstructionRef {
2805 IrInstruction base;2829 IrInstruction base;
28062830
2807 IrInstruction *value;2831 IrInstruction *value;
2808 LLVMValueRef tmp_ptr;
2809 bool is_const;2832 bool is_const;
2810 bool is_volatile;2833 bool is_volatile;
2811};2834};
28122835
2836struct IrInstructionRefGen {
2837 IrInstruction base;
2838
2839 IrInstruction *operand;
2840 IrInstruction *result_loc;
2841};
2842
2813struct IrInstructionCompileErr {2843struct IrInstructionCompileErr {
2814 IrInstruction base;2844 IrInstruction base;
28152845
...@@ -2861,26 +2891,26 @@ struct IrInstructionEmbedFile {...@@ -2861,26 +2891,26 @@ struct IrInstructionEmbedFile {
2861struct IrInstructionCmpxchgSrc {2891struct IrInstructionCmpxchgSrc {
2862 IrInstruction base;2892 IrInstruction base;
28632893
2894 bool is_weak;
2864 IrInstruction *type_value;2895 IrInstruction *type_value;
2865 IrInstruction *ptr;2896 IrInstruction *ptr;
2866 IrInstruction *cmp_value;2897 IrInstruction *cmp_value;
2867 IrInstruction *new_value;2898 IrInstruction *new_value;
2868 IrInstruction *success_order_value;2899 IrInstruction *success_order_value;
2869 IrInstruction *failure_order_value;2900 IrInstruction *failure_order_value;
28702901 ResultLoc *result_loc;
2871 bool is_weak;
2872};2902};
28732903
2874struct IrInstructionCmpxchgGen {2904struct IrInstructionCmpxchgGen {
2875 IrInstruction base;2905 IrInstruction base;
28762906
2907 bool is_weak;
2908 AtomicOrder success_order;
2909 AtomicOrder failure_order;
2877 IrInstruction *ptr;2910 IrInstruction *ptr;
2878 IrInstruction *cmp_value;2911 IrInstruction *cmp_value;
2879 IrInstruction *new_value;2912 IrInstruction *new_value;
2880 LLVMValueRef tmp_ptr;2913 IrInstruction *result_loc;
2881 AtomicOrder success_order;
2882 AtomicOrder failure_order;
2883 bool is_weak;
2884};2914};
28852915
2886struct IrInstructionFence {2916struct IrInstructionFence {
...@@ -2924,6 +2954,7 @@ struct IrInstructionToBytes {...@@ -2924,6 +2954,7 @@ struct IrInstructionToBytes {
2924 IrInstruction base;2954 IrInstruction base;
29252955
2926 IrInstruction *target;2956 IrInstruction *target;
2957 ResultLoc *result_loc;
2927};2958};
29282959
2929struct IrInstructionFromBytes {2960struct IrInstructionFromBytes {
...@@ -2931,6 +2962,7 @@ struct IrInstructionFromBytes {...@@ -2931,6 +2962,7 @@ struct IrInstructionFromBytes {
29312962
2932 IrInstruction *dest_child_type;2963 IrInstruction *dest_child_type;
2933 IrInstruction *target;2964 IrInstruction *target;
2965 ResultLoc *result_loc;
2934};2966};
29352967
2936struct IrInstructionIntToFloat {2968struct IrInstructionIntToFloat {
...@@ -2989,14 +3021,24 @@ struct IrInstructionMemcpy {...@@ -2989,14 +3021,24 @@ struct IrInstructionMemcpy {
2989 IrInstruction *count;3021 IrInstruction *count;
2990};3022};
29913023
2992struct IrInstructionSlice {3024struct IrInstructionSliceSrc {
2993 IrInstruction base;3025 IrInstruction base;
29943026
3027 bool safety_check_on;
2995 IrInstruction *ptr;3028 IrInstruction *ptr;
2996 IrInstruction *start;3029 IrInstruction *start;
2997 IrInstruction *end;3030 IrInstruction *end;
3031 ResultLoc *result_loc;
3032};
3033
3034struct IrInstructionSliceGen {
3035 IrInstruction base;
3036
2998 bool safety_check_on;3037 bool safety_check_on;
2999 LLVMValueRef tmp_ptr;3038 IrInstruction *ptr;
3039 IrInstruction *start;
3040 IrInstruction *end;
3041 IrInstruction *result_loc;
3000};3042};
30013043
3002struct IrInstructionMemberCount {3044struct IrInstructionMemberCount {
...@@ -3070,44 +3112,54 @@ struct IrInstructionAlignOf {...@@ -3070,44 +3112,54 @@ struct IrInstructionAlignOf {
3070};3112};
30713113
3072// returns true if error, returns false if not error3114// returns true if error, returns false if not error
3073struct IrInstructionTestErr {3115struct IrInstructionTestErrSrc {
3074 IrInstruction base;3116 IrInstruction base;
30753117
3076 IrInstruction *value;3118 bool resolve_err_set;
3119 IrInstruction *base_ptr;
3077};3120};
30783121
3079struct IrInstructionUnwrapErrCode {3122struct IrInstructionTestErrGen {
3080 IrInstruction base;3123 IrInstruction base;
30813124
3082 IrInstruction *err_union;3125 IrInstruction *err_union;
3083};3126};
30843127
3128// Takes an error union pointer, returns a pointer to the error code.
3129struct IrInstructionUnwrapErrCode {
3130 IrInstruction base;
3131
3132 bool initializing;
3133 IrInstruction *err_union_ptr;
3134};
3135
3085struct IrInstructionUnwrapErrPayload {3136struct IrInstructionUnwrapErrPayload {
3086 IrInstruction base;3137 IrInstruction base;
30873138
3088 IrInstruction *value;
3089 bool safety_check_on;3139 bool safety_check_on;
3140 bool initializing;
3141 IrInstruction *value;
3090};3142};
30913143
3092struct IrInstructionOptionalWrap {3144struct IrInstructionOptionalWrap {
3093 IrInstruction base;3145 IrInstruction base;
30943146
3095 IrInstruction *value;3147 IrInstruction *operand;
3096 LLVMValueRef tmp_ptr;3148 IrInstruction *result_loc;
3097};3149};
30983150
3099struct IrInstructionErrWrapPayload {3151struct IrInstructionErrWrapPayload {
3100 IrInstruction base;3152 IrInstruction base;
31013153
3102 IrInstruction *value;3154 IrInstruction *operand;
3103 LLVMValueRef tmp_ptr;3155 IrInstruction *result_loc;
3104};3156};
31053157
3106struct IrInstructionErrWrapCode {3158struct IrInstructionErrWrapCode {
3107 IrInstruction base;3159 IrInstruction base;
31083160
3109 IrInstruction *value;3161 IrInstruction *operand;
3110 LLVMValueRef tmp_ptr;3162 IrInstruction *result_loc;
3111};3163};
31123164
3113struct IrInstructionFnProto {3165struct IrInstructionFnProto {
...@@ -3142,18 +3194,17 @@ struct IrInstructionPtrCastGen {...@@ -3142,18 +3194,17 @@ struct IrInstructionPtrCastGen {
3142 bool safety_check_on;3194 bool safety_check_on;
3143};3195};
31443196
3145struct IrInstructionBitCast {3197struct IrInstructionBitCastSrc {
3146 IrInstruction base;3198 IrInstruction base;
31473199
3148 IrInstruction *dest_type;3200 IrInstruction *operand;
3149 IrInstruction *value;3201 ResultLocBitCast *result_loc_bit_cast;
3150};3202};
31513203
3152struct IrInstructionBitCastGen {3204struct IrInstructionBitCastGen {
3153 IrInstruction base;3205 IrInstruction base;
31543206
3155 IrInstruction *operand;3207 IrInstruction *operand;
3156 LLVMValueRef tmp_ptr;
3157};3208};
31583209
3159struct IrInstructionWidenOrShorten {3210struct IrInstructionWidenOrShorten {
...@@ -3229,8 +3280,8 @@ struct IrInstructionTypeName {...@@ -3229,8 +3280,8 @@ struct IrInstructionTypeName {
3229struct IrInstructionDeclRef {3280struct IrInstructionDeclRef {
3230 IrInstruction base;3281 IrInstruction base;
32313282
3232 Tld *tld;
3233 LVal lval;3283 LVal lval;
3284 Tld *tld;
3234};3285};
32353286
3236struct IrInstructionPanic {3287struct IrInstructionPanic {
...@@ -3526,7 +3577,7 @@ struct IrInstructionVectorToArray {...@@ -3526,7 +3577,7 @@ struct IrInstructionVectorToArray {
3526 IrInstruction base;3577 IrInstruction base;
35273578
3528 IrInstruction *vector;3579 IrInstruction *vector;
3529 LLVMValueRef tmp_ptr;3580 IrInstruction *result_loc;
3530};3581};
35313582
3532struct IrInstructionAssertZero {3583struct IrInstructionAssertZero {
...@@ -3554,6 +3605,139 @@ struct IrInstructionUndeclaredIdent {...@@ -3554,6 +3605,139 @@ struct IrInstructionUndeclaredIdent {
3554 Buf *name;3605 Buf *name;
3555};3606};
35563607
3608struct IrInstructionAllocaSrc {
3609 IrInstruction base;
3610
3611 IrInstruction *align;
3612 IrInstruction *is_comptime;
3613 const char *name_hint;
3614};
3615
3616struct IrInstructionAllocaGen {
3617 IrInstruction base;
3618
3619 uint32_t align;
3620 const char *name_hint;
3621};
3622
3623struct IrInstructionEndExpr {
3624 IrInstruction base;
3625
3626 IrInstruction *value;
3627 ResultLoc *result_loc;
3628};
3629
3630struct IrInstructionImplicitCast {
3631 IrInstruction base;
3632
3633 IrInstruction *dest_type;
3634 IrInstruction *target;
3635 ResultLoc *result_loc;
3636};
3637
3638// This one is for writing through the result pointer.
3639struct IrInstructionResolveResult {
3640 IrInstruction base;
3641
3642 ResultLoc *result_loc;
3643 IrInstruction *ty;
3644};
3645
3646// This one is when you want to read the value of the result.
3647// You have to give the value in case it is comptime.
3648struct IrInstructionResultPtr {
3649 IrInstruction base;
3650
3651 ResultLoc *result_loc;
3652 IrInstruction *result;
3653};
3654
3655struct IrInstructionResetResult {
3656 IrInstruction base;
3657
3658 ResultLoc *result_loc;
3659};
3660
3661struct IrInstructionPtrOfArrayToSlice {
3662 IrInstruction base;
3663
3664 IrInstruction *operand;
3665 IrInstruction *result_loc;
3666};
3667
3668enum ResultLocId {
3669 ResultLocIdInvalid,
3670 ResultLocIdNone,
3671 ResultLocIdVar,
3672 ResultLocIdReturn,
3673 ResultLocIdPeer,
3674 ResultLocIdPeerParent,
3675 ResultLocIdInstruction,
3676 ResultLocIdBitCast,
3677};
3678
3679// Additions to this struct may need to be handled in
3680// ir_reset_result
3681struct ResultLoc {
3682 ResultLocId id;
3683 bool written;
3684 IrInstruction *resolved_loc; // result ptr
3685 IrInstruction *source_instruction;
3686 IrInstruction *gen_instruction; // value to store to the result loc
3687 ZigType *implicit_elem_type;
3688};
3689
3690struct ResultLocNone {
3691 ResultLoc base;
3692};
3693
3694struct ResultLocVar {
3695 ResultLoc base;
3696
3697 ZigVar *var;
3698};
3699
3700struct ResultLocReturn {
3701 ResultLoc base;
3702};
3703
3704struct IrSuspendPosition {
3705 size_t basic_block_index;
3706 size_t instruction_index;
3707};
3708
3709struct ResultLocPeerParent {
3710 ResultLoc base;
3711
3712 bool skipped;
3713 bool done_resuming;
3714 IrBasicBlock *end_bb;
3715 ResultLoc *parent;
3716 ZigList<ResultLocPeer *> peers;
3717 ZigType *resolved_type;
3718 IrInstruction *is_comptime;
3719};
3720
3721struct ResultLocPeer {
3722 ResultLoc base;
3723
3724 ResultLocPeerParent *parent;
3725 IrBasicBlock *next_bb;
3726 IrSuspendPosition suspend_pos;
3727};
3728
3729// The result location is the source instruction
3730struct ResultLocInstruction {
3731 ResultLoc base;
3732};
3733
3734// The source_instruction is the destination type
3735struct ResultLocBitCast {
3736 ResultLoc base;
3737
3738 ResultLoc *parent;
3739};
3740
3557static const size_t slice_ptr_index = 0;3741static const size_t slice_ptr_index = 0;
3558static const size_t slice_len_index = 1;3742static const size_t slice_len_index = 1;
35593743
...@@ -3601,7 +3785,7 @@ struct FnWalkAttrs {...@@ -3601,7 +3785,7 @@ struct FnWalkAttrs {
36013785
3602struct FnWalkCall {3786struct FnWalkCall {
3603 ZigList<LLVMValueRef> *gen_param_values;3787 ZigList<LLVMValueRef> *gen_param_values;
3604 IrInstructionCall *inst;3788 IrInstructionCallGen *inst;
3605 bool is_var_args;3789 bool is_var_args;
3606};3790};
36073791
src/analyze.cpp+9-14
...@@ -2995,7 +2995,7 @@ void scan_decls(CodeGen *g, ScopeDecls *decls_scope, AstNode *node) {...@@ -2995,7 +2995,7 @@ void scan_decls(CodeGen *g, ScopeDecls *decls_scope, AstNode *node) {
2995 case NodeTypeBlock:2995 case NodeTypeBlock:
2996 case NodeTypeGroupedExpr:2996 case NodeTypeGroupedExpr:
2997 case NodeTypeBinOpExpr:2997 case NodeTypeBinOpExpr:
2998 case NodeTypeUnwrapErrorExpr:2998 case NodeTypeCatchExpr:
2999 case NodeTypeFnCallExpr:2999 case NodeTypeFnCallExpr:
3000 case NodeTypeArrayAccessExpr:3000 case NodeTypeArrayAccessExpr:
3001 case NodeTypeSliceExpr:3001 case NodeTypeSliceExpr:
...@@ -4181,6 +4181,7 @@ static uint32_t hash_const_val_ptr(ConstExprValue *const_val) {...@@ -4181,6 +4181,7 @@ static uint32_t hash_const_val_ptr(ConstExprValue *const_val) {
4181 case ConstPtrMutComptimeConst:4181 case ConstPtrMutComptimeConst:
4182 hash_val += (uint32_t)4214318515;4182 hash_val += (uint32_t)4214318515;
4183 break;4183 break;
4184 case ConstPtrMutInfer:
4184 case ConstPtrMutComptimeVar:4185 case ConstPtrMutComptimeVar:
4185 hash_val += (uint32_t)1103195694;4186 hash_val += (uint32_t)1103195694;
4186 break;4187 break;
...@@ -4511,6 +4512,8 @@ bool fn_eval_cacheable(Scope *scope, ZigType *return_type) {...@@ -4511,6 +4512,8 @@ bool fn_eval_cacheable(Scope *scope, ZigType *return_type) {
4511 ScopeVarDecl *var_scope = (ScopeVarDecl *)scope;4512 ScopeVarDecl *var_scope = (ScopeVarDecl *)scope;
4512 if (type_is_invalid(var_scope->var->var_type))4513 if (type_is_invalid(var_scope->var->var_type))
4513 return false;4514 return false;
4515 if (var_scope->var->const_value->special == ConstValSpecialUndef)
4516 return false;
4514 if (can_mutate_comptime_var_state(var_scope->var->const_value))4517 if (can_mutate_comptime_var_state(var_scope->var->const_value))
4515 return false;4518 return false;
4516 } else if (scope->id == ScopeIdFnDef) {4519 } else if (scope->id == ScopeIdFnDef) {
...@@ -4710,7 +4713,7 @@ ReqCompTime type_requires_comptime(CodeGen *g, ZigType *type_entry) {...@@ -4710,7 +4713,7 @@ ReqCompTime type_requires_comptime(CodeGen *g, ZigType *type_entry) {
4710void init_const_str_lit(CodeGen *g, ConstExprValue *const_val, Buf *str) {4713void init_const_str_lit(CodeGen *g, ConstExprValue *const_val, Buf *str) {
4711 auto entry = g->string_literals_table.maybe_get(str);4714 auto entry = g->string_literals_table.maybe_get(str);
4712 if (entry != nullptr) {4715 if (entry != nullptr) {
4713 *const_val = *entry->value;4716 memcpy(const_val, entry->value, sizeof(ConstExprValue));
4714 return;4717 return;
4715 }4718 }
47164719
...@@ -4998,12 +5001,9 @@ void init_const_undefined(CodeGen *g, ConstExprValue *const_val) {...@@ -4998,12 +5001,9 @@ void init_const_undefined(CodeGen *g, ConstExprValue *const_val) {
4998 field_val->type = wanted_type->data.structure.fields[i].type_entry;5001 field_val->type = wanted_type->data.structure.fields[i].type_entry;
4999 assert(field_val->type);5002 assert(field_val->type);
5000 init_const_undefined(g, field_val);5003 init_const_undefined(g, field_val);
5001 ConstParent *parent = get_const_val_parent(g, field_val);5004 field_val->parent.id = ConstParentIdStruct;
5002 if (parent != nullptr) {5005 field_val->parent.data.p_struct.struct_val = const_val;
5003 parent->id = ConstParentIdStruct;5006 field_val->parent.data.p_struct.field_index = i;
5004 parent->data.p_struct.struct_val = const_val;
5005 parent->data.p_struct.field_index = i;
5006 }
5007 }5007 }
5008 } else {5008 } else {
5009 const_val->special = ConstValSpecialUndef;5009 const_val->special = ConstValSpecialUndef;
...@@ -5843,11 +5843,6 @@ void expand_undef_array(CodeGen *g, ConstExprValue *const_val) {...@@ -5843,11 +5843,6 @@ void expand_undef_array(CodeGen *g, ConstExprValue *const_val) {
5843 zig_unreachable();5843 zig_unreachable();
5844}5844}
58455845
5846// Deprecated. Reference the parent field directly.
5847ConstParent *get_const_val_parent(CodeGen *g, ConstExprValue *value) {
5848 return &value->parent;
5849}
5850
5851static const ZigTypeId all_type_ids[] = {5846static const ZigTypeId all_type_ids[] = {
5852 ZigTypeIdMetaType,5847 ZigTypeIdMetaType,
5853 ZigTypeIdVoid,5848 ZigTypeIdVoid,
...@@ -7281,6 +7276,6 @@ void src_assert(bool ok, AstNode *source_node) {...@@ -7281,6 +7276,6 @@ void src_assert(bool ok, AstNode *source_node) {
7281 buf_ptr(source_node->owner->data.structure.root_struct->path),7276 buf_ptr(source_node->owner->data.structure.root_struct->path),
7282 (unsigned)source_node->line + 1, (unsigned)source_node->column + 1);7277 (unsigned)source_node->line + 1, (unsigned)source_node->column + 1);
7283 }7278 }
7284 const char *msg = "assertion failed";7279 const char *msg = "assertion failed. This is a bug in the Zig compiler.";
7285 stage2_panic(msg, strlen(msg));7280 stage2_panic(msg, strlen(msg));
7286}7281}
src/analyze.hpp-1
...@@ -180,7 +180,6 @@ void init_const_undefined(CodeGen *g, ConstExprValue *const_val);...@@ -180,7 +180,6 @@ void init_const_undefined(CodeGen *g, ConstExprValue *const_val);
180ConstExprValue *create_const_vals(size_t count);180ConstExprValue *create_const_vals(size_t count);
181181
182ZigType *make_int_type(CodeGen *g, bool is_signed, uint32_t size_in_bits);182ZigType *make_int_type(CodeGen *g, bool is_signed, uint32_t size_in_bits);
183ConstParent *get_const_val_parent(CodeGen *g, ConstExprValue *value);
184void expand_undef_array(CodeGen *g, ConstExprValue *const_val);183void expand_undef_array(CodeGen *g, ConstExprValue *const_val);
185void update_compile_var(CodeGen *g, Buf *name, ConstExprValue *value);184void update_compile_var(CodeGen *g, Buf *name, ConstExprValue *value);
186185
src/ast_render.cpp+3-3
...@@ -165,8 +165,8 @@ static const char *node_type_str(NodeType node_type) {...@@ -165,8 +165,8 @@ static const char *node_type_str(NodeType node_type) {
165 return "Parens";165 return "Parens";
166 case NodeTypeBinOpExpr:166 case NodeTypeBinOpExpr:
167 return "BinOpExpr";167 return "BinOpExpr";
168 case NodeTypeUnwrapErrorExpr:168 case NodeTypeCatchExpr:
169 return "UnwrapErrorExpr";169 return "CatchExpr";
170 case NodeTypeFnCallExpr:170 case NodeTypeFnCallExpr:
171 return "FnCallExpr";171 return "FnCallExpr";
172 case NodeTypeArrayAccessExpr:172 case NodeTypeArrayAccessExpr:
...@@ -1108,7 +1108,7 @@ static void render_node_extra(AstRender *ar, AstNode *node, bool grouped) {...@@ -1108,7 +1108,7 @@ static void render_node_extra(AstRender *ar, AstNode *node, bool grouped) {
1108 fprintf(ar->f, "]");1108 fprintf(ar->f, "]");
1109 break;1109 break;
1110 }1110 }
1111 case NodeTypeUnwrapErrorExpr:1111 case NodeTypeCatchExpr:
1112 {1112 {
1113 render_node_ungrouped(ar, node->data.unwrap_err_expr.op1);1113 render_node_ungrouped(ar, node->data.unwrap_err_expr.op1);
1114 fprintf(ar->f, " catch ");1114 fprintf(ar->f, " catch ");
src/codegen.cpp+280-325
...@@ -691,7 +691,9 @@ static ZigLLVMDIScope *get_di_scope(CodeGen *g, Scope *scope) {...@@ -691,7 +691,9 @@ static ZigLLVMDIScope *get_di_scope(CodeGen *g, Scope *scope) {
691 is_definition, scope_line, flags, is_optimized, nullptr);691 is_definition, scope_line, flags, is_optimized, nullptr);
692692
693 scope->di_scope = ZigLLVMSubprogramToScope(subprogram);693 scope->di_scope = ZigLLVMSubprogramToScope(subprogram);
694 ZigLLVMFnSetSubprogram(fn_llvm_value(g, fn_table_entry), subprogram);694 if (!g->strip_debug_symbols) {
695 ZigLLVMFnSetSubprogram(fn_llvm_value(g, fn_table_entry), subprogram);
696 }
695 return scope->di_scope;697 return scope->di_scope;
696 }698 }
697 case ScopeIdDecls:699 case ScopeIdDecls:
...@@ -859,9 +861,7 @@ static LLVMValueRef gen_store_untyped(CodeGen *g, LLVMValueRef value, LLVMValueR...@@ -859,9 +861,7 @@ static LLVMValueRef gen_store_untyped(CodeGen *g, LLVMValueRef value, LLVMValueR
859{861{
860 LLVMValueRef instruction = LLVMBuildStore(g->builder, value, ptr);862 LLVMValueRef instruction = LLVMBuildStore(g->builder, value, ptr);
861 if (is_volatile) LLVMSetVolatile(instruction, true);863 if (is_volatile) LLVMSetVolatile(instruction, true);
862 if (alignment == 0) {864 if (alignment != 0) {
863 LLVMSetAlignment(instruction, LLVMABIAlignmentOfType(g->target_data_ref, LLVMTypeOf(value)));
864 } else {
865 LLVMSetAlignment(instruction, alignment);865 LLVMSetAlignment(instruction, alignment);
866 }866 }
867 return instruction;867 return instruction;
...@@ -1339,7 +1339,9 @@ static LLVMValueRef get_add_error_return_trace_addr_fn(CodeGen *g) {...@@ -1339,7 +1339,9 @@ static LLVMValueRef get_add_error_return_trace_addr_fn(CodeGen *g) {
1339 LLVMBuildRetVoid(g->builder);1339 LLVMBuildRetVoid(g->builder);
13401340
1341 LLVMPositionBuilderAtEnd(g->builder, prev_block);1341 LLVMPositionBuilderAtEnd(g->builder, prev_block);
1342 LLVMSetCurrentDebugLocation(g->builder, prev_debug_location);1342 if (!g->strip_debug_symbols) {
1343 LLVMSetCurrentDebugLocation(g->builder, prev_debug_location);
1344 }
13431345
1344 g->add_error_return_trace_addr_fn_val = fn_val;1346 g->add_error_return_trace_addr_fn_val = fn_val;
1345 return fn_val;1347 return fn_val;
...@@ -1470,7 +1472,9 @@ static LLVMValueRef get_merge_err_ret_traces_fn_val(CodeGen *g) {...@@ -1470,7 +1472,9 @@ static LLVMValueRef get_merge_err_ret_traces_fn_val(CodeGen *g) {
1470 LLVMBuildBr(g->builder, loop_block);1472 LLVMBuildBr(g->builder, loop_block);
14711473
1472 LLVMPositionBuilderAtEnd(g->builder, prev_block);1474 LLVMPositionBuilderAtEnd(g->builder, prev_block);
1473 LLVMSetCurrentDebugLocation(g->builder, prev_debug_location);1475 if (!g->strip_debug_symbols) {
1476 LLVMSetCurrentDebugLocation(g->builder, prev_debug_location);
1477 }
14741478
1475 g->merge_err_ret_traces_fn_val = fn_val;1479 g->merge_err_ret_traces_fn_val = fn_val;
1476 return fn_val;1480 return fn_val;
...@@ -1526,7 +1530,9 @@ static LLVMValueRef get_return_err_fn(CodeGen *g) {...@@ -1526,7 +1530,9 @@ static LLVMValueRef get_return_err_fn(CodeGen *g) {
1526 LLVMBuildRetVoid(g->builder);1530 LLVMBuildRetVoid(g->builder);
15271531
1528 LLVMPositionBuilderAtEnd(g->builder, prev_block);1532 LLVMPositionBuilderAtEnd(g->builder, prev_block);
1529 LLVMSetCurrentDebugLocation(g->builder, prev_debug_location);1533 if (!g->strip_debug_symbols) {
1534 LLVMSetCurrentDebugLocation(g->builder, prev_debug_location);
1535 }
15301536
1531 g->return_err_fn = fn_val;1537 g->return_err_fn = fn_val;
1532 return fn_val;1538 return fn_val;
...@@ -1654,7 +1660,9 @@ static LLVMValueRef get_safety_crash_err_fn(CodeGen *g) {...@@ -1654,7 +1660,9 @@ static LLVMValueRef get_safety_crash_err_fn(CodeGen *g) {
1654 gen_panic(g, msg_slice, err_ret_trace_arg);1660 gen_panic(g, msg_slice, err_ret_trace_arg);
16551661
1656 LLVMPositionBuilderAtEnd(g->builder, prev_block);1662 LLVMPositionBuilderAtEnd(g->builder, prev_block);
1657 LLVMSetCurrentDebugLocation(g->builder, prev_debug_location);1663 if (!g->strip_debug_symbols) {
1664 LLVMSetCurrentDebugLocation(g->builder, prev_debug_location);
1665 }
16581666
1659 g->safety_crash_err_fn = fn_val;1667 g->safety_crash_err_fn = fn_val;
1660 return fn_val;1668 return fn_val;
...@@ -2004,6 +2012,7 @@ static LLVMValueRef gen_assign_raw(CodeGen *g, LLVMValueRef ptr, ZigType *ptr_ty...@@ -2004,6 +2012,7 @@ static LLVMValueRef gen_assign_raw(CodeGen *g, LLVMValueRef ptr, ZigType *ptr_ty
2004}2012}
20052013
2006static void gen_var_debug_decl(CodeGen *g, ZigVar *var) {2014static void gen_var_debug_decl(CodeGen *g, ZigVar *var) {
2015 if (g->strip_debug_symbols) return;
2007 assert(var->di_loc_var != nullptr);2016 assert(var->di_loc_var != nullptr);
2008 AstNode *source_node = var->decl_node;2017 AstNode *source_node = var->decl_node;
2009 ZigLLVMDILocation *debug_loc = ZigLLVMGetDebugLoc((unsigned)source_node->line + 1,2018 ZigLLVMDILocation *debug_loc = ZigLLVMGetDebugLoc((unsigned)source_node->line + 1,
...@@ -2016,7 +2025,7 @@ static LLVMValueRef ir_llvm_value(CodeGen *g, IrInstruction *instruction) {...@@ -2016,7 +2025,7 @@ static LLVMValueRef ir_llvm_value(CodeGen *g, IrInstruction *instruction) {
2016 if (!type_has_bits(instruction->value.type))2025 if (!type_has_bits(instruction->value.type))
2017 return nullptr;2026 return nullptr;
2018 if (!instruction->llvm_value) {2027 if (!instruction->llvm_value) {
2019 assert(instruction->value.special != ConstValSpecialRuntime);2028 src_assert(instruction->value.special != ConstValSpecialRuntime, instruction->source_node);
2020 assert(instruction->value.type);2029 assert(instruction->value.type);
2021 render_const_val(g, &instruction->value, "");2030 render_const_val(g, &instruction->value, "");
2022 // we might have to do some pointer casting here due to the way union2031 // we might have to do some pointer casting here due to the way union
...@@ -2025,11 +2034,9 @@ static LLVMValueRef ir_llvm_value(CodeGen *g, IrInstruction *instruction) {...@@ -2025,11 +2034,9 @@ static LLVMValueRef ir_llvm_value(CodeGen *g, IrInstruction *instruction) {
2025 render_const_val_global(g, &instruction->value, "");2034 render_const_val_global(g, &instruction->value, "");
2026 ZigType *ptr_type = get_pointer_to_type(g, instruction->value.type, true);2035 ZigType *ptr_type = get_pointer_to_type(g, instruction->value.type, true);
2027 instruction->llvm_value = LLVMBuildBitCast(g->builder, instruction->value.global_refs->llvm_global, get_llvm_type(g, ptr_type), "");2036 instruction->llvm_value = LLVMBuildBitCast(g->builder, instruction->value.global_refs->llvm_global, get_llvm_type(g, ptr_type), "");
2028 } else if (get_codegen_ptr_type(instruction->value.type) != nullptr) {2037 } else {
2029 instruction->llvm_value = LLVMBuildBitCast(g->builder, instruction->value.global_refs->llvm_value,2038 instruction->llvm_value = LLVMBuildBitCast(g->builder, instruction->value.global_refs->llvm_value,
2030 get_llvm_type(g, instruction->value.type), "");2039 get_llvm_type(g, instruction->value.type), "");
2031 } else {
2032 instruction->llvm_value = instruction->value.global_refs->llvm_value;
2033 }2040 }
2034 assert(instruction->llvm_value);2041 assert(instruction->llvm_value);
2035 }2042 }
...@@ -2310,7 +2317,7 @@ void walk_function_params(CodeGen *g, ZigType *fn_type, FnWalk *fn_walk) {...@@ -2310,7 +2317,7 @@ void walk_function_params(CodeGen *g, ZigType *fn_type, FnWalk *fn_walk) {
2310 return;2317 return;
2311 }2318 }
2312 if (fn_walk->id == FnWalkIdCall) {2319 if (fn_walk->id == FnWalkIdCall) {
2313 IrInstructionCall *instruction = fn_walk->data.call.inst;2320 IrInstructionCallGen *instruction = fn_walk->data.call.inst;
2314 bool is_var_args = fn_walk->data.call.is_var_args;2321 bool is_var_args = fn_walk->data.call.is_var_args;
2315 for (size_t call_i = 0; call_i < instruction->arg_count; call_i += 1) {2322 for (size_t call_i = 0; call_i < instruction->arg_count; call_i += 1) {
2316 IrInstruction *param_instruction = instruction->args[call_i];2323 IrInstruction *param_instruction = instruction->args[call_i];
...@@ -2404,17 +2411,33 @@ static LLVMValueRef ir_render_save_err_ret_addr(CodeGen *g, IrExecutable *execut...@@ -2404,17 +2411,33 @@ static LLVMValueRef ir_render_save_err_ret_addr(CodeGen *g, IrExecutable *execut
2404}2411}
24052412
2406static LLVMValueRef ir_render_return(CodeGen *g, IrExecutable *executable, IrInstructionReturn *return_instruction) {2413static LLVMValueRef ir_render_return(CodeGen *g, IrExecutable *executable, IrInstructionReturn *return_instruction) {
2407 LLVMValueRef value = ir_llvm_value(g, return_instruction->value);
2408 ZigType *return_type = return_instruction->value->value.type;
2409
2410 if (want_first_arg_sret(g, &g->cur_fn->type_entry->data.fn.fn_type_id)) {2414 if (want_first_arg_sret(g, &g->cur_fn->type_entry->data.fn.fn_type_id)) {
2415 if (return_instruction->value == nullptr) {
2416 LLVMBuildRetVoid(g->builder);
2417 return nullptr;
2418 }
2411 assert(g->cur_ret_ptr);2419 assert(g->cur_ret_ptr);
2420 src_assert(return_instruction->value->value.special != ConstValSpecialRuntime,
2421 return_instruction->base.source_node);
2422 LLVMValueRef value = ir_llvm_value(g, return_instruction->value);
2423 ZigType *return_type = return_instruction->value->value.type;
2412 gen_assign_raw(g, g->cur_ret_ptr, get_pointer_to_type(g, return_type, false), value);2424 gen_assign_raw(g, g->cur_ret_ptr, get_pointer_to_type(g, return_type, false), value);
2413 LLVMBuildRetVoid(g->builder);2425 LLVMBuildRetVoid(g->builder);
2414 } else if (handle_is_ptr(return_type)) {2426 } else if (g->cur_fn->type_entry->data.fn.fn_type_id.cc != CallingConventionAsync &&
2415 LLVMValueRef by_val_value = gen_load_untyped(g, value, 0, false, "");2427 handle_is_ptr(g->cur_fn->type_entry->data.fn.fn_type_id.return_type))
2416 LLVMBuildRet(g->builder, by_val_value);2428 {
2429 if (return_instruction->value == nullptr) {
2430 LLVMValueRef by_val_value = gen_load_untyped(g, g->cur_ret_ptr, 0, false, "");
2431 LLVMBuildRet(g->builder, by_val_value);
2432 } else {
2433 LLVMValueRef value = ir_llvm_value(g, return_instruction->value);
2434 LLVMValueRef by_val_value = gen_load_untyped(g, value, 0, false, "");
2435 LLVMBuildRet(g->builder, by_val_value);
2436 }
2437 } else if (return_instruction->value == nullptr) {
2438 LLVMBuildRetVoid(g->builder);
2417 } else {2439 } else {
2440 LLVMValueRef value = ir_llvm_value(g, return_instruction->value);
2418 LLVMBuildRet(g->builder, value);2441 LLVMBuildRet(g->builder, value);
2419 }2442 }
2420 return nullptr;2443 return nullptr;
...@@ -2952,7 +2975,7 @@ static LLVMValueRef ir_render_resize_slice(CodeGen *g, IrExecutable *executable,...@@ -2952,7 +2975,7 @@ static LLVMValueRef ir_render_resize_slice(CodeGen *g, IrExecutable *executable,
2952 LLVMValueRef expr_val = ir_llvm_value(g, instruction->operand);2975 LLVMValueRef expr_val = ir_llvm_value(g, instruction->operand);
2953 assert(expr_val);2976 assert(expr_val);
29542977
2955 assert(instruction->tmp_ptr);2978 LLVMValueRef result_loc = ir_llvm_value(g, instruction->result_loc);
2956 assert(wanted_type->id == ZigTypeIdStruct);2979 assert(wanted_type->id == ZigTypeIdStruct);
2957 assert(wanted_type->data.structure.is_slice);2980 assert(wanted_type->data.structure.is_slice);
2958 assert(actual_type->id == ZigTypeIdStruct);2981 assert(actual_type->id == ZigTypeIdStruct);
...@@ -2973,7 +2996,7 @@ static LLVMValueRef ir_render_resize_slice(CodeGen *g, IrExecutable *executable,...@@ -2973,7 +2996,7 @@ static LLVMValueRef ir_render_resize_slice(CodeGen *g, IrExecutable *executable,
2973 LLVMValueRef src_ptr = gen_load_untyped(g, src_ptr_ptr, 0, false, "");2996 LLVMValueRef src_ptr = gen_load_untyped(g, src_ptr_ptr, 0, false, "");
2974 LLVMValueRef src_ptr_casted = LLVMBuildBitCast(g->builder, src_ptr,2997 LLVMValueRef src_ptr_casted = LLVMBuildBitCast(g->builder, src_ptr,
2975 get_llvm_type(g, wanted_type->data.structure.fields[0].type_entry), "");2998 get_llvm_type(g, wanted_type->data.structure.fields[0].type_entry), "");
2976 LLVMValueRef dest_ptr_ptr = LLVMBuildStructGEP(g->builder, instruction->tmp_ptr,2999 LLVMValueRef dest_ptr_ptr = LLVMBuildStructGEP(g->builder, result_loc,
2977 (unsigned)wanted_ptr_index, "");3000 (unsigned)wanted_ptr_index, "");
2978 gen_store_untyped(g, src_ptr_casted, dest_ptr_ptr, 0, false);3001 gen_store_untyped(g, src_ptr_casted, dest_ptr_ptr, 0, false);
29793002
...@@ -3006,12 +3029,10 @@ static LLVMValueRef ir_render_resize_slice(CodeGen *g, IrExecutable *executable,...@@ -3006,12 +3029,10 @@ static LLVMValueRef ir_render_resize_slice(CodeGen *g, IrExecutable *executable,
3006 zig_unreachable();3029 zig_unreachable();
3007 }3030 }
30083031
3009 LLVMValueRef dest_len_ptr = LLVMBuildStructGEP(g->builder, instruction->tmp_ptr,3032 LLVMValueRef dest_len_ptr = LLVMBuildStructGEP(g->builder, result_loc, (unsigned)wanted_len_index, "");
3010 (unsigned)wanted_len_index, "");
3011 gen_store_untyped(g, new_len, dest_len_ptr, 0, false);3033 gen_store_untyped(g, new_len, dest_len_ptr, 0, false);
30123034
30133035 return result_loc;
3014 return instruction->tmp_ptr;
3015}3036}
30163037
3017static LLVMValueRef ir_render_cast(CodeGen *g, IrExecutable *executable,3038static LLVMValueRef ir_render_cast(CodeGen *g, IrExecutable *executable,
...@@ -3081,33 +3102,39 @@ static LLVMValueRef ir_render_cast(CodeGen *g, IrExecutable *executable,...@@ -3081,33 +3102,39 @@ static LLVMValueRef ir_render_cast(CodeGen *g, IrExecutable *executable,
3081 return expr_val;3102 return expr_val;
3082 case CastOpBitCast:3103 case CastOpBitCast:
3083 return LLVMBuildBitCast(g->builder, expr_val, get_llvm_type(g, wanted_type), "");3104 return LLVMBuildBitCast(g->builder, expr_val, get_llvm_type(g, wanted_type), "");
3084 case CastOpPtrOfArrayToSlice: {
3085 assert(cast_instruction->tmp_ptr);
3086 assert(actual_type->id == ZigTypeIdPointer);
3087 ZigType *array_type = actual_type->data.pointer.child_type;
3088 assert(array_type->id == ZigTypeIdArray);
3089
3090 LLVMValueRef ptr_field_ptr = LLVMBuildStructGEP(g->builder, cast_instruction->tmp_ptr,
3091 slice_ptr_index, "");
3092 LLVMValueRef indices[] = {
3093 LLVMConstNull(g->builtin_types.entry_usize->llvm_type),
3094 LLVMConstInt(g->builtin_types.entry_usize->llvm_type, 0, false),
3095 };
3096 LLVMValueRef slice_start_ptr = LLVMBuildInBoundsGEP(g->builder, expr_val, indices, 2, "");
3097 gen_store_untyped(g, slice_start_ptr, ptr_field_ptr, 0, false);
3098
3099 LLVMValueRef len_field_ptr = LLVMBuildStructGEP(g->builder, cast_instruction->tmp_ptr,
3100 slice_len_index, "");
3101 LLVMValueRef len_value = LLVMConstInt(g->builtin_types.entry_usize->llvm_type,
3102 array_type->data.array.len, false);
3103 gen_store_untyped(g, len_value, len_field_ptr, 0, false);
3104
3105 return cast_instruction->tmp_ptr;
3106 }
3107 }3105 }
3108 zig_unreachable();3106 zig_unreachable();
3109}3107}
31103108
3109static LLVMValueRef ir_render_ptr_of_array_to_slice(CodeGen *g, IrExecutable *executable,
3110 IrInstructionPtrOfArrayToSlice *instruction)
3111{
3112 ZigType *actual_type = instruction->operand->value.type;
3113 LLVMValueRef expr_val = ir_llvm_value(g, instruction->operand);
3114 assert(expr_val);
3115
3116 LLVMValueRef result_loc = ir_llvm_value(g, instruction->result_loc);
3117
3118 assert(actual_type->id == ZigTypeIdPointer);
3119 ZigType *array_type = actual_type->data.pointer.child_type;
3120 assert(array_type->id == ZigTypeIdArray);
3121
3122 LLVMValueRef ptr_field_ptr = LLVMBuildStructGEP(g->builder, result_loc, slice_ptr_index, "");
3123 LLVMValueRef indices[] = {
3124 LLVMConstNull(g->builtin_types.entry_usize->llvm_type),
3125 LLVMConstInt(g->builtin_types.entry_usize->llvm_type, 0, false),
3126 };
3127 LLVMValueRef slice_start_ptr = LLVMBuildInBoundsGEP(g->builder, expr_val, indices, 2, "");
3128 gen_store_untyped(g, slice_start_ptr, ptr_field_ptr, 0, false);
3129
3130 LLVMValueRef len_field_ptr = LLVMBuildStructGEP(g->builder, result_loc, slice_len_index, "");
3131 LLVMValueRef len_value = LLVMConstInt(g->builtin_types.entry_usize->llvm_type,
3132 array_type->data.array.len, false);
3133 gen_store_untyped(g, len_value, len_field_ptr, 0, false);
3134
3135 return result_loc;
3136}
3137
3111static LLVMValueRef ir_render_ptr_cast(CodeGen *g, IrExecutable *executable,3138static LLVMValueRef ir_render_ptr_cast(CodeGen *g, IrExecutable *executable,
3112 IrInstructionPtrCastGen *instruction)3139 IrInstructionPtrCastGen *instruction)
3113{3140{
...@@ -3154,12 +3181,7 @@ static LLVMValueRef ir_render_bit_cast(CodeGen *g, IrExecutable *executable,...@@ -3154,12 +3181,7 @@ static LLVMValueRef ir_render_bit_cast(CodeGen *g, IrExecutable *executable,
3154 uint32_t alignment = get_abi_alignment(g, actual_type);3181 uint32_t alignment = get_abi_alignment(g, actual_type);
3155 return gen_load_untyped(g, bitcasted_ptr, alignment, false, "");3182 return gen_load_untyped(g, bitcasted_ptr, alignment, false, "");
3156 } else {3183 } else {
3157 assert(instruction->tmp_ptr != nullptr);3184 zig_unreachable();
3158 LLVMTypeRef wanted_ptr_type_ref = LLVMPointerType(get_llvm_type(g, actual_type), 0);
3159 LLVMValueRef bitcasted_ptr = LLVMBuildBitCast(g->builder, instruction->tmp_ptr, wanted_ptr_type_ref, "");
3160 uint32_t alignment = get_abi_alignment(g, wanted_type);
3161 gen_store_untyped(g, value, bitcasted_ptr, alignment, false);
3162 return instruction->tmp_ptr;
3163 }3185 }
3164}3186}
31653187
...@@ -3345,31 +3367,13 @@ static LLVMValueRef ir_render_bool_not(CodeGen *g, IrExecutable *executable, IrI...@@ -3345,31 +3367,13 @@ static LLVMValueRef ir_render_bool_not(CodeGen *g, IrExecutable *executable, IrI
3345 return LLVMBuildICmp(g->builder, LLVMIntEQ, value, zero, "");3367 return LLVMBuildICmp(g->builder, LLVMIntEQ, value, zero, "");
3346}3368}
33473369
3348static LLVMValueRef ir_render_decl_var(CodeGen *g, IrExecutable *executable,3370static LLVMValueRef ir_render_decl_var(CodeGen *g, IrExecutable *executable, IrInstructionDeclVarGen *instruction) {
3349 IrInstructionDeclVarGen *decl_var_instruction)3371 ZigVar *var = instruction->var;
3350{
3351 ZigVar *var = decl_var_instruction->var;
33523372
3353 if (!type_has_bits(var->var_type))3373 if (!type_has_bits(var->var_type))
3354 return nullptr;3374 return nullptr;
33553375
3356 if (var->ref_count == 0 && g->build_mode != BuildModeDebug)3376 var->value_ref = ir_llvm_value(g, instruction->var_ptr);
3357 return nullptr;
3358
3359 IrInstruction *init_value = decl_var_instruction->init_value;
3360
3361 bool have_init_expr = !value_is_all_undef(&init_value->value);
3362
3363 if (have_init_expr) {
3364 ZigType *var_ptr_type = get_pointer_to_type_extra(g, var->var_type, false, false,
3365 PtrLenSingle, var->align_bytes, 0, 0, false);
3366 LLVMValueRef llvm_init_val = ir_llvm_value(g, init_value);
3367 gen_assign_raw(g, var->value_ref, var_ptr_type, llvm_init_val);
3368 } else if (ir_want_runtime_safety(g, &decl_var_instruction->base)) {
3369 uint32_t align_bytes = (var->align_bytes == 0) ? get_abi_alignment(g, var->var_type) : var->align_bytes;
3370 gen_undef_init(g, align_bytes, var->var_type, var->value_ref);
3371 }
3372
3373 gen_var_debug_decl(g, var);3377 gen_var_debug_decl(g, var);
3374 return nullptr;3378 return nullptr;
3375}3379}
...@@ -3401,13 +3405,13 @@ static LLVMValueRef ir_render_load_ptr(CodeGen *g, IrExecutable *executable, IrI...@@ -3401,13 +3405,13 @@ static LLVMValueRef ir_render_load_ptr(CodeGen *g, IrExecutable *executable, IrI
3401 LLVMValueRef shifted_value = LLVMBuildLShr(g->builder, containing_int, shift_amt_val, "");3405 LLVMValueRef shifted_value = LLVMBuildLShr(g->builder, containing_int, shift_amt_val, "");
34023406
3403 if (handle_is_ptr(child_type)) {3407 if (handle_is_ptr(child_type)) {
3404 assert(instruction->tmp_ptr != nullptr);3408 LLVMValueRef result_loc = ir_llvm_value(g, instruction->result_loc);
3405 LLVMTypeRef same_size_int = LLVMIntType(size_in_bits);3409 LLVMTypeRef same_size_int = LLVMIntType(size_in_bits);
3406 LLVMValueRef truncated_int = LLVMBuildTrunc(g->builder, shifted_value, same_size_int, "");3410 LLVMValueRef truncated_int = LLVMBuildTrunc(g->builder, shifted_value, same_size_int, "");
3407 LLVMValueRef bitcasted_ptr = LLVMBuildBitCast(g->builder, instruction->tmp_ptr,3411 LLVMValueRef bitcasted_ptr = LLVMBuildBitCast(g->builder, result_loc,
3408 LLVMPointerType(same_size_int, 0), "");3412 LLVMPointerType(same_size_int, 0), "");
3409 LLVMBuildStore(g->builder, truncated_int, bitcasted_ptr);3413 LLVMBuildStore(g->builder, truncated_int, bitcasted_ptr);
3410 return instruction->tmp_ptr;3414 return result_loc;
3411 }3415 }
34123416
3413 if (child_type->id == ZigTypeIdFloat) {3417 if (child_type->id == ZigTypeIdFloat) {
...@@ -3585,6 +3589,14 @@ static LLVMValueRef ir_render_var_ptr(CodeGen *g, IrExecutable *executable, IrIn...@@ -3585,6 +3589,14 @@ static LLVMValueRef ir_render_var_ptr(CodeGen *g, IrExecutable *executable, IrIn
3585 }3589 }
3586}3590}
35873591
3592static LLVMValueRef ir_render_return_ptr(CodeGen *g, IrExecutable *executable,
3593 IrInstructionReturnPtr *instruction)
3594{
3595 src_assert(g->cur_ret_ptr != nullptr || !type_has_bits(instruction->base.value.type),
3596 instruction->base.source_node);
3597 return g->cur_ret_ptr;
3598}
3599
3588static LLVMValueRef ir_render_elem_ptr(CodeGen *g, IrExecutable *executable, IrInstructionElemPtr *instruction) {3600static LLVMValueRef ir_render_elem_ptr(CodeGen *g, IrExecutable *executable, IrInstructionElemPtr *instruction) {
3589 LLVMValueRef array_ptr_ptr = ir_llvm_value(g, instruction->array_ptr);3601 LLVMValueRef array_ptr_ptr = ir_llvm_value(g, instruction->array_ptr);
3590 ZigType *array_ptr_type = instruction->array_ptr->value.type;3602 ZigType *array_ptr_type = instruction->array_ptr->value.type;
...@@ -3736,7 +3748,7 @@ static void set_call_instr_sret(CodeGen *g, LLVMValueRef call_instr) {...@@ -3736,7 +3748,7 @@ static void set_call_instr_sret(CodeGen *g, LLVMValueRef call_instr) {
3736 LLVMAddCallSiteAttribute(call_instr, 1, sret_attr);3748 LLVMAddCallSiteAttribute(call_instr, 1, sret_attr);
3737}3749}
37383750
3739static LLVMValueRef ir_render_call(CodeGen *g, IrExecutable *executable, IrInstructionCall *instruction) {3751static LLVMValueRef ir_render_call(CodeGen *g, IrExecutable *executable, IrInstructionCallGen *instruction) {
3740 LLVMValueRef fn_val;3752 LLVMValueRef fn_val;
3741 ZigType *fn_type;3753 ZigType *fn_type;
3742 if (instruction->fn_entry) {3754 if (instruction->fn_entry) {
...@@ -3759,8 +3771,9 @@ static LLVMValueRef ir_render_call(CodeGen *g, IrExecutable *executable, IrInstr...@@ -3759,8 +3771,9 @@ static LLVMValueRef ir_render_call(CodeGen *g, IrExecutable *executable, IrInstr
3759 bool prefix_arg_err_ret_stack = get_prefix_arg_err_ret_stack(g, fn_type_id);3771 bool prefix_arg_err_ret_stack = get_prefix_arg_err_ret_stack(g, fn_type_id);
3760 bool is_var_args = fn_type_id->is_var_args;3772 bool is_var_args = fn_type_id->is_var_args;
3761 ZigList<LLVMValueRef> gen_param_values = {};3773 ZigList<LLVMValueRef> gen_param_values = {};
3774 LLVMValueRef result_loc = instruction->result_loc ? ir_llvm_value(g, instruction->result_loc) : nullptr;
3762 if (first_arg_ret) {3775 if (first_arg_ret) {
3763 gen_param_values.append(instruction->tmp_ptr);3776 gen_param_values.append(result_loc);
3764 }3777 }
3765 if (prefix_arg_err_ret_stack) {3778 if (prefix_arg_err_ret_stack) {
3766 gen_param_values.append(get_cur_err_ret_trace_val(g, instruction->base.scope));3779 gen_param_values.append(get_cur_err_ret_trace_val(g, instruction->base.scope));
...@@ -3768,7 +3781,7 @@ static LLVMValueRef ir_render_call(CodeGen *g, IrExecutable *executable, IrInstr...@@ -3768,7 +3781,7 @@ static LLVMValueRef ir_render_call(CodeGen *g, IrExecutable *executable, IrInstr
3768 if (instruction->is_async) {3781 if (instruction->is_async) {
3769 gen_param_values.append(ir_llvm_value(g, instruction->async_allocator));3782 gen_param_values.append(ir_llvm_value(g, instruction->async_allocator));
37703783
3771 LLVMValueRef err_val_ptr = LLVMBuildStructGEP(g->builder, instruction->tmp_ptr, err_union_err_index, "");3784 LLVMValueRef err_val_ptr = LLVMBuildStructGEP(g->builder, result_loc, err_union_err_index, "");
3772 gen_param_values.append(err_val_ptr);3785 gen_param_values.append(err_val_ptr);
3773 }3786 }
3774 FnWalk fn_walk = {};3787 FnWalk fn_walk = {};
...@@ -3811,9 +3824,9 @@ static LLVMValueRef ir_render_call(CodeGen *g, IrExecutable *executable, IrInstr...@@ -3811,9 +3824,9 @@ static LLVMValueRef ir_render_call(CodeGen *g, IrExecutable *executable, IrInstr
38113824
38123825
3813 if (instruction->is_async) {3826 if (instruction->is_async) {
3814 LLVMValueRef payload_ptr = LLVMBuildStructGEP(g->builder, instruction->tmp_ptr, err_union_payload_index, "");3827 LLVMValueRef payload_ptr = LLVMBuildStructGEP(g->builder, result_loc, err_union_payload_index, "");
3815 LLVMBuildStore(g->builder, result, payload_ptr);3828 LLVMBuildStore(g->builder, result, payload_ptr);
3816 return instruction->tmp_ptr;3829 return result_loc;
3817 }3830 }
38183831
3819 if (src_return_type->id == ZigTypeIdUnreachable) {3832 if (src_return_type->id == ZigTypeIdUnreachable) {
...@@ -3822,11 +3835,11 @@ static LLVMValueRef ir_render_call(CodeGen *g, IrExecutable *executable, IrInstr...@@ -3822,11 +3835,11 @@ static LLVMValueRef ir_render_call(CodeGen *g, IrExecutable *executable, IrInstr
3822 return nullptr;3835 return nullptr;
3823 } else if (first_arg_ret) {3836 } else if (first_arg_ret) {
3824 set_call_instr_sret(g, result);3837 set_call_instr_sret(g, result);
3825 return instruction->tmp_ptr;3838 return result_loc;
3826 } else if (handle_is_ptr(src_return_type)) {3839 } else if (handle_is_ptr(src_return_type)) {
3827 auto store_instr = LLVMBuildStore(g->builder, result, instruction->tmp_ptr);3840 LLVMValueRef store_instr = LLVMBuildStore(g->builder, result, result_loc);
3828 LLVMSetAlignment(store_instr, LLVMGetAlignment(instruction->tmp_ptr));3841 LLVMSetAlignment(store_instr, LLVMGetAlignment(result_loc));
3829 return instruction->tmp_ptr;3842 return result_loc;
3830 } else {3843 } else {
3831 return result;3844 return result;
3832 }3845 }
...@@ -3835,6 +3848,9 @@ static LLVMValueRef ir_render_call(CodeGen *g, IrExecutable *executable, IrInstr...@@ -3835,6 +3848,9 @@ static LLVMValueRef ir_render_call(CodeGen *g, IrExecutable *executable, IrInstr
3835static LLVMValueRef ir_render_struct_field_ptr(CodeGen *g, IrExecutable *executable,3848static LLVMValueRef ir_render_struct_field_ptr(CodeGen *g, IrExecutable *executable,
3836 IrInstructionStructFieldPtr *instruction)3849 IrInstructionStructFieldPtr *instruction)
3837{3850{
3851 if (instruction->base.value.special != ConstValSpecialRuntime)
3852 return nullptr;
3853
3838 LLVMValueRef struct_ptr = ir_llvm_value(g, instruction->struct_ptr);3854 LLVMValueRef struct_ptr = ir_llvm_value(g, instruction->struct_ptr);
3839 // not necessarily a pointer. could be ZigTypeIdStruct3855 // not necessarily a pointer. could be ZigTypeIdStruct
3840 ZigType *struct_ptr_type = instruction->struct_ptr->value.type;3856 ZigType *struct_ptr_type = instruction->struct_ptr->value.type;
...@@ -3856,6 +3872,9 @@ static LLVMValueRef ir_render_struct_field_ptr(CodeGen *g, IrExecutable *executa...@@ -3856,6 +3872,9 @@ static LLVMValueRef ir_render_struct_field_ptr(CodeGen *g, IrExecutable *executa
3856static LLVMValueRef ir_render_union_field_ptr(CodeGen *g, IrExecutable *executable,3872static LLVMValueRef ir_render_union_field_ptr(CodeGen *g, IrExecutable *executable,
3857 IrInstructionUnionFieldPtr *instruction)3873 IrInstructionUnionFieldPtr *instruction)
3858{3874{
3875 if (instruction->base.value.special != ConstValSpecialRuntime)
3876 return nullptr;
3877
3859 ZigType *union_ptr_type = instruction->union_ptr->value.type;3878 ZigType *union_ptr_type = instruction->union_ptr->value.type;
3860 assert(union_ptr_type->id == ZigTypeIdPointer);3879 assert(union_ptr_type->id == ZigTypeIdPointer);
3861 ZigType *union_type = union_ptr_type->data.pointer.child_type;3880 ZigType *union_type = union_ptr_type->data.pointer.child_type;
...@@ -3863,8 +3882,20 @@ static LLVMValueRef ir_render_union_field_ptr(CodeGen *g, IrExecutable *executab...@@ -3863,8 +3882,20 @@ static LLVMValueRef ir_render_union_field_ptr(CodeGen *g, IrExecutable *executab
38633882
3864 TypeUnionField *field = instruction->field;3883 TypeUnionField *field = instruction->field;
38653884
3866 if (!type_has_bits(field->type_entry))3885 if (!type_has_bits(field->type_entry)) {
3886 if (union_type->data.unionation.gen_tag_index == SIZE_MAX) {
3887 return nullptr;
3888 }
3889 if (instruction->initializing) {
3890 LLVMValueRef union_ptr = ir_llvm_value(g, instruction->union_ptr);
3891 LLVMValueRef tag_field_ptr = LLVMBuildStructGEP(g->builder, union_ptr,
3892 union_type->data.unionation.gen_tag_index, "");
3893 LLVMValueRef tag_value = bigint_to_llvm_const(get_llvm_type(g, union_type->data.unionation.tag_type),
3894 &field->enum_field->value);
3895 gen_store_untyped(g, tag_value, tag_field_ptr, 0, false);
3896 }
3867 return nullptr;3897 return nullptr;
3898 }
38683899
3869 LLVMValueRef union_ptr = ir_llvm_value(g, instruction->union_ptr);3900 LLVMValueRef union_ptr = ir_llvm_value(g, instruction->union_ptr);
3870 LLVMTypeRef field_type_ref = LLVMPointerType(get_llvm_type(g, field->type_entry), 0);3901 LLVMTypeRef field_type_ref = LLVMPointerType(get_llvm_type(g, field->type_entry), 0);
...@@ -3875,7 +3906,12 @@ static LLVMValueRef ir_render_union_field_ptr(CodeGen *g, IrExecutable *executab...@@ -3875,7 +3906,12 @@ static LLVMValueRef ir_render_union_field_ptr(CodeGen *g, IrExecutable *executab
3875 return bitcasted_union_field_ptr;3906 return bitcasted_union_field_ptr;
3876 }3907 }
38773908
3878 if (ir_want_runtime_safety(g, &instruction->base)) {3909 if (instruction->initializing) {
3910 LLVMValueRef tag_field_ptr = LLVMBuildStructGEP(g->builder, union_ptr, union_type->data.unionation.gen_tag_index, "");
3911 LLVMValueRef tag_value = bigint_to_llvm_const(get_llvm_type(g, union_type->data.unionation.tag_type),
3912 &field->enum_field->value);
3913 gen_store_untyped(g, tag_value, tag_field_ptr, 0, false);
3914 } else if (instruction->safety_check_on && ir_want_runtime_safety(g, &instruction->base)) {
3879 LLVMValueRef tag_field_ptr = LLVMBuildStructGEP(g->builder, union_ptr, union_type->data.unionation.gen_tag_index, "");3915 LLVMValueRef tag_field_ptr = LLVMBuildStructGEP(g->builder, union_ptr, union_type->data.unionation.gen_tag_index, "");
3880 LLVMValueRef tag_value = gen_load_untyped(g, tag_field_ptr, 0, false, "");3916 LLVMValueRef tag_value = gen_load_untyped(g, tag_field_ptr, 0, false, "");
38813917
...@@ -4075,14 +4111,17 @@ static LLVMValueRef ir_render_test_non_null(CodeGen *g, IrExecutable *executable...@@ -4075,14 +4111,17 @@ static LLVMValueRef ir_render_test_non_null(CodeGen *g, IrExecutable *executable
4075static LLVMValueRef ir_render_optional_unwrap_ptr(CodeGen *g, IrExecutable *executable,4111static LLVMValueRef ir_render_optional_unwrap_ptr(CodeGen *g, IrExecutable *executable,
4076 IrInstructionOptionalUnwrapPtr *instruction)4112 IrInstructionOptionalUnwrapPtr *instruction)
4077{4113{
4114 if (instruction->base.value.special != ConstValSpecialRuntime)
4115 return nullptr;
4116
4078 ZigType *ptr_type = instruction->base_ptr->value.type;4117 ZigType *ptr_type = instruction->base_ptr->value.type;
4079 assert(ptr_type->id == ZigTypeIdPointer);4118 assert(ptr_type->id == ZigTypeIdPointer);
4080 ZigType *maybe_type = ptr_type->data.pointer.child_type;4119 ZigType *maybe_type = ptr_type->data.pointer.child_type;
4081 assert(maybe_type->id == ZigTypeIdOptional);4120 assert(maybe_type->id == ZigTypeIdOptional);
4082 ZigType *child_type = maybe_type->data.maybe.child_type;4121 ZigType *child_type = maybe_type->data.maybe.child_type;
4083 LLVMValueRef maybe_ptr = ir_llvm_value(g, instruction->base_ptr);4122 LLVMValueRef base_ptr = ir_llvm_value(g, instruction->base_ptr);
4084 if (ir_want_runtime_safety(g, &instruction->base) && instruction->safety_check_on) {4123 if (instruction->safety_check_on && ir_want_runtime_safety(g, &instruction->base)) {
4085 LLVMValueRef maybe_handle = get_handle_value(g, maybe_ptr, maybe_type, ptr_type);4124 LLVMValueRef maybe_handle = get_handle_value(g, base_ptr, maybe_type, ptr_type);
4086 LLVMValueRef non_null_bit = gen_non_null_bit(g, maybe_type, maybe_handle);4125 LLVMValueRef non_null_bit = gen_non_null_bit(g, maybe_type, maybe_handle);
4087 LLVMBasicBlockRef fail_block = LLVMAppendBasicBlock(g->cur_fn_val, "UnwrapOptionalFail");4126 LLVMBasicBlockRef fail_block = LLVMAppendBasicBlock(g->cur_fn_val, "UnwrapOptionalFail");
4088 LLVMBasicBlockRef ok_block = LLVMAppendBasicBlock(g->cur_fn_val, "UnwrapOptionalOk");4127 LLVMBasicBlockRef ok_block = LLVMAppendBasicBlock(g->cur_fn_val, "UnwrapOptionalOk");
...@@ -4098,10 +4137,16 @@ static LLVMValueRef ir_render_optional_unwrap_ptr(CodeGen *g, IrExecutable *exec...@@ -4098,10 +4137,16 @@ static LLVMValueRef ir_render_optional_unwrap_ptr(CodeGen *g, IrExecutable *exec
4098 } else {4137 } else {
4099 bool is_scalar = !handle_is_ptr(maybe_type);4138 bool is_scalar = !handle_is_ptr(maybe_type);
4100 if (is_scalar) {4139 if (is_scalar) {
4101 return maybe_ptr;4140 return base_ptr;
4102 } else {4141 } else {
4103 LLVMValueRef maybe_struct_ref = get_handle_value(g, maybe_ptr, maybe_type, ptr_type);4142 LLVMValueRef optional_struct_ref = get_handle_value(g, base_ptr, maybe_type, ptr_type);
4104 return LLVMBuildStructGEP(g->builder, maybe_struct_ref, maybe_child_index, "");4143 if (instruction->initializing) {
4144 LLVMValueRef non_null_bit_ptr = LLVMBuildStructGEP(g->builder, optional_struct_ref,
4145 maybe_null_index, "");
4146 LLVMValueRef non_null_bit = LLVMConstInt(LLVMInt1Type(), 1, false);
4147 gen_store_untyped(g, non_null_bit, non_null_bit_ptr, 0, false);
4148 }
4149 return LLVMBuildStructGEP(g->builder, optional_struct_ref, maybe_child_index, "");
4105 }4150 }
4106 }4151 }
4107}4152}
...@@ -4224,17 +4269,17 @@ static LLVMValueRef ir_render_phi(CodeGen *g, IrExecutable *executable, IrInstru...@@ -4224,17 +4269,17 @@ static LLVMValueRef ir_render_phi(CodeGen *g, IrExecutable *executable, IrInstru
4224 return phi;4269 return phi;
4225}4270}
42264271
4227static LLVMValueRef ir_render_ref(CodeGen *g, IrExecutable *executable, IrInstructionRef *instruction) {4272static LLVMValueRef ir_render_ref(CodeGen *g, IrExecutable *executable, IrInstructionRefGen *instruction) {
4228 if (!type_has_bits(instruction->base.value.type)) {4273 if (!type_has_bits(instruction->base.value.type)) {
4229 return nullptr;4274 return nullptr;
4230 }4275 }
4231 LLVMValueRef value = ir_llvm_value(g, instruction->value);4276 LLVMValueRef value = ir_llvm_value(g, instruction->operand);
4232 if (handle_is_ptr(instruction->value->value.type)) {4277 if (handle_is_ptr(instruction->operand->value.type)) {
4233 return value;4278 return value;
4234 } else {4279 } else {
4235 assert(instruction->tmp_ptr);4280 LLVMValueRef result_loc = ir_llvm_value(g, instruction->result_loc);
4236 gen_store_untyped(g, value, instruction->tmp_ptr, 0, false);4281 gen_store_untyped(g, value, result_loc, 0, false);
4237 return instruction->tmp_ptr;4282 return result_loc;
4238 }4283 }
4239}4284}
42404285
...@@ -4350,7 +4395,9 @@ static LLVMValueRef get_enum_tag_name_function(CodeGen *g, ZigType *enum_type) {...@@ -4350,7 +4395,9 @@ static LLVMValueRef get_enum_tag_name_function(CodeGen *g, ZigType *enum_type) {
4350 g->cur_fn = prev_cur_fn;4395 g->cur_fn = prev_cur_fn;
4351 g->cur_fn_val = prev_cur_fn_val;4396 g->cur_fn_val = prev_cur_fn_val;
4352 LLVMPositionBuilderAtEnd(g->builder, prev_block);4397 LLVMPositionBuilderAtEnd(g->builder, prev_block);
4353 LLVMSetCurrentDebugLocation(g->builder, prev_debug_location);4398 if (!g->strip_debug_symbols) {
4399 LLVMSetCurrentDebugLocation(g->builder, prev_debug_location);
4400 }
43544401
4355 enum_type->data.enumeration.name_function = fn_val;4402 enum_type->data.enumeration.name_function = fn_val;
4356 return fn_val;4403 return fn_val;
...@@ -4526,28 +4573,28 @@ static LLVMValueRef ir_render_cmpxchg(CodeGen *g, IrExecutable *executable, IrIn...@@ -4526,28 +4573,28 @@ static LLVMValueRef ir_render_cmpxchg(CodeGen *g, IrExecutable *executable, IrIn
4526 LLVMValueRef result_val = ZigLLVMBuildCmpXchg(g->builder, ptr_val, cmp_val, new_val,4573 LLVMValueRef result_val = ZigLLVMBuildCmpXchg(g->builder, ptr_val, cmp_val, new_val,
4527 success_order, failure_order, instruction->is_weak);4574 success_order, failure_order, instruction->is_weak);
45284575
4529 ZigType *maybe_type = instruction->base.value.type;4576 ZigType *optional_type = instruction->base.value.type;
4530 assert(maybe_type->id == ZigTypeIdOptional);4577 assert(optional_type->id == ZigTypeIdOptional);
4531 ZigType *child_type = maybe_type->data.maybe.child_type;4578 ZigType *child_type = optional_type->data.maybe.child_type;
45324579
4533 if (!handle_is_ptr(maybe_type)) {4580 if (!handle_is_ptr(optional_type)) {
4534 LLVMValueRef payload_val = LLVMBuildExtractValue(g->builder, result_val, 0, "");4581 LLVMValueRef payload_val = LLVMBuildExtractValue(g->builder, result_val, 0, "");
4535 LLVMValueRef success_bit = LLVMBuildExtractValue(g->builder, result_val, 1, "");4582 LLVMValueRef success_bit = LLVMBuildExtractValue(g->builder, result_val, 1, "");
4536 return LLVMBuildSelect(g->builder, success_bit, LLVMConstNull(get_llvm_type(g, child_type)), payload_val, "");4583 return LLVMBuildSelect(g->builder, success_bit, LLVMConstNull(get_llvm_type(g, child_type)), payload_val, "");
4537 }4584 }
45384585
4539 assert(instruction->tmp_ptr != nullptr);4586 LLVMValueRef result_loc = ir_llvm_value(g, instruction->result_loc);
4540 assert(type_has_bits(child_type));4587 assert(type_has_bits(child_type));
45414588
4542 LLVMValueRef payload_val = LLVMBuildExtractValue(g->builder, result_val, 0, "");4589 LLVMValueRef payload_val = LLVMBuildExtractValue(g->builder, result_val, 0, "");
4543 LLVMValueRef val_ptr = LLVMBuildStructGEP(g->builder, instruction->tmp_ptr, maybe_child_index, "");4590 LLVMValueRef val_ptr = LLVMBuildStructGEP(g->builder, result_loc, maybe_child_index, "");
4544 gen_assign_raw(g, val_ptr, get_pointer_to_type(g, child_type, false), payload_val);4591 gen_assign_raw(g, val_ptr, get_pointer_to_type(g, child_type, false), payload_val);
45454592
4546 LLVMValueRef success_bit = LLVMBuildExtractValue(g->builder, result_val, 1, "");4593 LLVMValueRef success_bit = LLVMBuildExtractValue(g->builder, result_val, 1, "");
4547 LLVMValueRef nonnull_bit = LLVMBuildNot(g->builder, success_bit, "");4594 LLVMValueRef nonnull_bit = LLVMBuildNot(g->builder, success_bit, "");
4548 LLVMValueRef maybe_ptr = LLVMBuildStructGEP(g->builder, instruction->tmp_ptr, maybe_null_index, "");4595 LLVMValueRef maybe_ptr = LLVMBuildStructGEP(g->builder, result_loc, maybe_null_index, "");
4549 gen_store_untyped(g, nonnull_bit, maybe_ptr, 0, false);4596 gen_store_untyped(g, nonnull_bit, maybe_ptr, 0, false);
4550 return instruction->tmp_ptr;4597 return result_loc;
4551}4598}
45524599
4553static LLVMValueRef ir_render_fence(CodeGen *g, IrExecutable *executable, IrInstructionFence *instruction) {4600static LLVMValueRef ir_render_fence(CodeGen *g, IrExecutable *executable, IrInstructionFence *instruction) {
...@@ -4619,16 +4666,14 @@ static LLVMValueRef ir_render_memcpy(CodeGen *g, IrExecutable *executable, IrIns...@@ -4619,16 +4666,14 @@ static LLVMValueRef ir_render_memcpy(CodeGen *g, IrExecutable *executable, IrIns
4619 return nullptr;4666 return nullptr;
4620}4667}
46214668
4622static LLVMValueRef ir_render_slice(CodeGen *g, IrExecutable *executable, IrInstructionSlice *instruction) {4669static LLVMValueRef ir_render_slice(CodeGen *g, IrExecutable *executable, IrInstructionSliceGen *instruction) {
4623 assert(instruction->tmp_ptr);
4624
4625 LLVMValueRef array_ptr_ptr = ir_llvm_value(g, instruction->ptr);4670 LLVMValueRef array_ptr_ptr = ir_llvm_value(g, instruction->ptr);
4626 ZigType *array_ptr_type = instruction->ptr->value.type;4671 ZigType *array_ptr_type = instruction->ptr->value.type;
4627 assert(array_ptr_type->id == ZigTypeIdPointer);4672 assert(array_ptr_type->id == ZigTypeIdPointer);
4628 ZigType *array_type = array_ptr_type->data.pointer.child_type;4673 ZigType *array_type = array_ptr_type->data.pointer.child_type;
4629 LLVMValueRef array_ptr = get_handle_value(g, array_ptr_ptr, array_type, array_ptr_type);4674 LLVMValueRef array_ptr = get_handle_value(g, array_ptr_ptr, array_type, array_ptr_type);
46304675
4631 LLVMValueRef tmp_struct_ptr = instruction->tmp_ptr;4676 LLVMValueRef tmp_struct_ptr = ir_llvm_value(g, instruction->result_loc);
46324677
4633 bool want_runtime_safety = instruction->safety_check_on && ir_want_runtime_safety(g, &instruction->base);4678 bool want_runtime_safety = instruction->safety_check_on && ir_want_runtime_safety(g, &instruction->base);
46344679
...@@ -4646,7 +4691,9 @@ static LLVMValueRef ir_render_slice(CodeGen *g, IrExecutable *executable, IrInst...@@ -4646,7 +4691,9 @@ static LLVMValueRef ir_render_slice(CodeGen *g, IrExecutable *executable, IrInst
4646 end_val = LLVMConstInt(g->builtin_types.entry_usize->llvm_type, array_type->data.array.len, false);4691 end_val = LLVMConstInt(g->builtin_types.entry_usize->llvm_type, array_type->data.array.len, false);
4647 }4692 }
4648 if (want_runtime_safety) {4693 if (want_runtime_safety) {
4649 add_bounds_check(g, start_val, LLVMIntEQ, nullptr, LLVMIntULE, end_val);4694 if (instruction->start->value.special == ConstValSpecialRuntime || instruction->end) {
4695 add_bounds_check(g, start_val, LLVMIntEQ, nullptr, LLVMIntULE, end_val);
4696 }
4650 if (instruction->end) {4697 if (instruction->end) {
4651 LLVMValueRef array_end = LLVMConstInt(g->builtin_types.entry_usize->llvm_type,4698 LLVMValueRef array_end = LLVMConstInt(g->builtin_types.entry_usize->llvm_type,
4652 array_type->data.array.len, false);4699 array_type->data.array.len, false);
...@@ -4877,10 +4924,10 @@ static LLVMValueRef ir_render_overflow_op(CodeGen *g, IrExecutable *executable,...@@ -4877,10 +4924,10 @@ static LLVMValueRef ir_render_overflow_op(CodeGen *g, IrExecutable *executable,
4877 return overflow_bit;4924 return overflow_bit;
4878}4925}
48794926
4880static LLVMValueRef ir_render_test_err(CodeGen *g, IrExecutable *executable, IrInstructionTestErr *instruction) {4927static LLVMValueRef ir_render_test_err(CodeGen *g, IrExecutable *executable, IrInstructionTestErrGen *instruction) {
4881 ZigType *err_union_type = instruction->value->value.type;4928 ZigType *err_union_type = instruction->err_union->value.type;
4882 ZigType *payload_type = err_union_type->data.error_union.payload_type;4929 ZigType *payload_type = err_union_type->data.error_union.payload_type;
4883 LLVMValueRef err_union_handle = ir_llvm_value(g, instruction->value);4930 LLVMValueRef err_union_handle = ir_llvm_value(g, instruction->err_union);
48844931
4885 LLVMValueRef err_val;4932 LLVMValueRef err_val;
4886 if (type_has_bits(payload_type)) {4933 if (type_has_bits(payload_type)) {
...@@ -4897,25 +4944,30 @@ static LLVMValueRef ir_render_test_err(CodeGen *g, IrExecutable *executable, IrI...@@ -4897,25 +4944,30 @@ static LLVMValueRef ir_render_test_err(CodeGen *g, IrExecutable *executable, IrI
4897static LLVMValueRef ir_render_unwrap_err_code(CodeGen *g, IrExecutable *executable,4944static LLVMValueRef ir_render_unwrap_err_code(CodeGen *g, IrExecutable *executable,
4898 IrInstructionUnwrapErrCode *instruction)4945 IrInstructionUnwrapErrCode *instruction)
4899{4946{
4900 ZigType *ptr_type = instruction->err_union->value.type;4947 if (instruction->base.value.special != ConstValSpecialRuntime)
4948 return nullptr;
4949
4950 ZigType *ptr_type = instruction->err_union_ptr->value.type;
4901 assert(ptr_type->id == ZigTypeIdPointer);4951 assert(ptr_type->id == ZigTypeIdPointer);
4902 ZigType *err_union_type = ptr_type->data.pointer.child_type;4952 ZigType *err_union_type = ptr_type->data.pointer.child_type;
4903 ZigType *payload_type = err_union_type->data.error_union.payload_type;4953 ZigType *payload_type = err_union_type->data.error_union.payload_type;
4904 LLVMValueRef err_union_ptr = ir_llvm_value(g, instruction->err_union);4954 LLVMValueRef err_union_ptr = ir_llvm_value(g, instruction->err_union_ptr);
4905 LLVMValueRef err_union_handle = get_handle_value(g, err_union_ptr, err_union_type, ptr_type);4955 if (!type_has_bits(payload_type)) {
49064956 return err_union_ptr;
4907 if (type_has_bits(payload_type)) {
4908 LLVMValueRef err_val_ptr = LLVMBuildStructGEP(g->builder, err_union_handle, err_union_err_index, "");
4909 return gen_load_untyped(g, err_val_ptr, 0, false, "");
4910 } else {4957 } else {
4911 return err_union_handle;4958 // TODO assign undef to the payload
4959 LLVMValueRef err_union_handle = get_handle_value(g, err_union_ptr, err_union_type, ptr_type);
4960 return LLVMBuildStructGEP(g->builder, err_union_handle, err_union_err_index, "");
4912 }4961 }
4913}4962}
49144963
4915static LLVMValueRef ir_render_unwrap_err_payload(CodeGen *g, IrExecutable *executable,4964static LLVMValueRef ir_render_unwrap_err_payload(CodeGen *g, IrExecutable *executable,
4916 IrInstructionUnwrapErrPayload *instruction)4965 IrInstructionUnwrapErrPayload *instruction)
4917{4966{
4918 bool want_safety = ir_want_runtime_safety(g, &instruction->base) && instruction->safety_check_on &&4967 if (instruction->base.value.special != ConstValSpecialRuntime)
4968 return nullptr;
4969
4970 bool want_safety = instruction->safety_check_on && ir_want_runtime_safety(g, &instruction->base) &&
4919 g->errors_by_index.length > 1;4971 g->errors_by_index.length > 1;
4920 if (!want_safety && !type_has_bits(instruction->base.value.type))4972 if (!want_safety && !type_has_bits(instruction->base.value.type))
4921 return nullptr;4973 return nullptr;
...@@ -4951,13 +5003,18 @@ static LLVMValueRef ir_render_unwrap_err_payload(CodeGen *g, IrExecutable *execu...@@ -4951,13 +5003,18 @@ static LLVMValueRef ir_render_unwrap_err_payload(CodeGen *g, IrExecutable *execu
4951 }5003 }
49525004
4953 if (type_has_bits(payload_type)) {5005 if (type_has_bits(payload_type)) {
5006 if (instruction->initializing) {
5007 LLVMValueRef err_tag_ptr = LLVMBuildStructGEP(g->builder, err_union_handle, err_union_err_index, "");
5008 LLVMValueRef ok_err_val = LLVMConstNull(get_llvm_type(g, g->err_tag_type));
5009 gen_store_untyped(g, ok_err_val, err_tag_ptr, 0, false);
5010 }
4954 return LLVMBuildStructGEP(g->builder, err_union_handle, err_union_payload_index, "");5011 return LLVMBuildStructGEP(g->builder, err_union_handle, err_union_payload_index, "");
4955 } else {5012 } else {
4956 return nullptr;5013 return nullptr;
4957 }5014 }
4958}5015}
49595016
4960static LLVMValueRef ir_render_maybe_wrap(CodeGen *g, IrExecutable *executable, IrInstructionOptionalWrap *instruction) {5017static LLVMValueRef ir_render_optional_wrap(CodeGen *g, IrExecutable *executable, IrInstructionOptionalWrap *instruction) {
4961 ZigType *wanted_type = instruction->base.value.type;5018 ZigType *wanted_type = instruction->base.value.type;
49625019
4963 assert(wanted_type->id == ZigTypeIdOptional);5020 assert(wanted_type->id == ZigTypeIdOptional);
...@@ -4965,23 +5022,32 @@ static LLVMValueRef ir_render_maybe_wrap(CodeGen *g, IrExecutable *executable, I...@@ -4965,23 +5022,32 @@ static LLVMValueRef ir_render_maybe_wrap(CodeGen *g, IrExecutable *executable, I
4965 ZigType *child_type = wanted_type->data.maybe.child_type;5022 ZigType *child_type = wanted_type->data.maybe.child_type;
49665023
4967 if (!type_has_bits(child_type)) {5024 if (!type_has_bits(child_type)) {
4968 return LLVMConstInt(LLVMInt1Type(), 1, false);5025 LLVMValueRef result = LLVMConstAllOnes(LLVMInt1Type());
5026 if (instruction->result_loc != nullptr) {
5027 LLVMValueRef result_loc = ir_llvm_value(g, instruction->result_loc);
5028 gen_store_untyped(g, result, result_loc, 0, false);
5029 }
5030 return result;
4969 }5031 }
49705032
4971 LLVMValueRef payload_val = ir_llvm_value(g, instruction->value);5033 LLVMValueRef payload_val = ir_llvm_value(g, instruction->operand);
4972 if (!handle_is_ptr(wanted_type)) {5034 if (!handle_is_ptr(wanted_type)) {
5035 if (instruction->result_loc != nullptr) {
5036 LLVMValueRef result_loc = ir_llvm_value(g, instruction->result_loc);
5037 gen_store_untyped(g, payload_val, result_loc, 0, false);
5038 }
4973 return payload_val;5039 return payload_val;
4974 }5040 }
49755041
4976 assert(instruction->tmp_ptr);5042 LLVMValueRef result_loc = ir_llvm_value(g, instruction->result_loc);
49775043
4978 LLVMValueRef val_ptr = LLVMBuildStructGEP(g->builder, instruction->tmp_ptr, maybe_child_index, "");5044 LLVMValueRef val_ptr = LLVMBuildStructGEP(g->builder, result_loc, maybe_child_index, "");
4979 // child_type and instruction->value->value.type may differ by constness5045 // child_type and instruction->value->value.type may differ by constness
4980 gen_assign_raw(g, val_ptr, get_pointer_to_type(g, child_type, false), payload_val);5046 gen_assign_raw(g, val_ptr, get_pointer_to_type(g, child_type, false), payload_val);
4981 LLVMValueRef maybe_ptr = LLVMBuildStructGEP(g->builder, instruction->tmp_ptr, maybe_null_index, "");5047 LLVMValueRef maybe_ptr = LLVMBuildStructGEP(g->builder, result_loc, maybe_null_index, "");
4982 gen_store_untyped(g, LLVMConstAllOnes(LLVMInt1Type()), maybe_ptr, 0, false);5048 gen_store_untyped(g, LLVMConstAllOnes(LLVMInt1Type()), maybe_ptr, 0, false);
49835049
4984 return instruction->tmp_ptr;5050 return result_loc;
4985}5051}
49865052
4987static LLVMValueRef ir_render_err_wrap_code(CodeGen *g, IrExecutable *executable, IrInstructionErrWrapCode *instruction) {5053static LLVMValueRef ir_render_err_wrap_code(CodeGen *g, IrExecutable *executable, IrInstructionErrWrapCode *instruction) {
...@@ -4989,20 +5055,19 @@ static LLVMValueRef ir_render_err_wrap_code(CodeGen *g, IrExecutable *executable...@@ -4989,20 +5055,19 @@ static LLVMValueRef ir_render_err_wrap_code(CodeGen *g, IrExecutable *executable
49895055
4990 assert(wanted_type->id == ZigTypeIdErrorUnion);5056 assert(wanted_type->id == ZigTypeIdErrorUnion);
49915057
4992 ZigType *payload_type = wanted_type->data.error_union.payload_type;5058 LLVMValueRef err_val = ir_llvm_value(g, instruction->operand);
4993 ZigType *err_set_type = wanted_type->data.error_union.err_set_type;
4994
4995 LLVMValueRef err_val = ir_llvm_value(g, instruction->value);
49965059
4997 if (!type_has_bits(payload_type) || !type_has_bits(err_set_type))5060 if (!handle_is_ptr(wanted_type))
4998 return err_val;5061 return err_val;
49995062
5000 assert(instruction->tmp_ptr);5063 LLVMValueRef result_loc = ir_llvm_value(g, instruction->result_loc);
50015064
5002 LLVMValueRef err_tag_ptr = LLVMBuildStructGEP(g->builder, instruction->tmp_ptr, err_union_err_index, "");5065 LLVMValueRef err_tag_ptr = LLVMBuildStructGEP(g->builder, result_loc, err_union_err_index, "");
5003 gen_store_untyped(g, err_val, err_tag_ptr, 0, false);5066 gen_store_untyped(g, err_val, err_tag_ptr, 0, false);
50045067
5005 return instruction->tmp_ptr;5068 // TODO store undef to the payload
5069
5070 return result_loc;
5006}5071}
50075072
5008static LLVMValueRef ir_render_err_wrap_payload(CodeGen *g, IrExecutable *executable, IrInstructionErrWrapPayload *instruction) {5073static LLVMValueRef ir_render_err_wrap_payload(CodeGen *g, IrExecutable *executable, IrInstructionErrWrapPayload *instruction) {
...@@ -5014,7 +5079,7 @@ static LLVMValueRef ir_render_err_wrap_payload(CodeGen *g, IrExecutable *executa...@@ -5014,7 +5079,7 @@ static LLVMValueRef ir_render_err_wrap_payload(CodeGen *g, IrExecutable *executa
5014 ZigType *err_set_type = wanted_type->data.error_union.err_set_type;5079 ZigType *err_set_type = wanted_type->data.error_union.err_set_type;
50155080
5016 if (!type_has_bits(err_set_type)) {5081 if (!type_has_bits(err_set_type)) {
5017 return ir_llvm_value(g, instruction->value);5082 return ir_llvm_value(g, instruction->operand);
5018 }5083 }
50195084
5020 LLVMValueRef ok_err_val = LLVMConstNull(get_llvm_type(g, g->err_tag_type));5085 LLVMValueRef ok_err_val = LLVMConstNull(get_llvm_type(g, g->err_tag_type));
...@@ -5022,17 +5087,18 @@ static LLVMValueRef ir_render_err_wrap_payload(CodeGen *g, IrExecutable *executa...@@ -5022,17 +5087,18 @@ static LLVMValueRef ir_render_err_wrap_payload(CodeGen *g, IrExecutable *executa
5022 if (!type_has_bits(payload_type))5087 if (!type_has_bits(payload_type))
5023 return ok_err_val;5088 return ok_err_val;
50245089
5025 assert(instruction->tmp_ptr);
50265090
5027 LLVMValueRef payload_val = ir_llvm_value(g, instruction->value);5091 LLVMValueRef result_loc = ir_llvm_value(g, instruction->result_loc);
50285092
5029 LLVMValueRef err_tag_ptr = LLVMBuildStructGEP(g->builder, instruction->tmp_ptr, err_union_err_index, "");5093 LLVMValueRef payload_val = ir_llvm_value(g, instruction->operand);
5094
5095 LLVMValueRef err_tag_ptr = LLVMBuildStructGEP(g->builder, result_loc, err_union_err_index, "");
5030 gen_store_untyped(g, ok_err_val, err_tag_ptr, 0, false);5096 gen_store_untyped(g, ok_err_val, err_tag_ptr, 0, false);
50315097
5032 LLVMValueRef payload_ptr = LLVMBuildStructGEP(g->builder, instruction->tmp_ptr, err_union_payload_index, "");5098 LLVMValueRef payload_ptr = LLVMBuildStructGEP(g->builder, result_loc, err_union_payload_index, "");
5033 gen_assign_raw(g, payload_ptr, get_pointer_to_type(g, payload_type, false), payload_val);5099 gen_assign_raw(g, payload_ptr, get_pointer_to_type(g, payload_type, false), payload_val);
50345100
5035 return instruction->tmp_ptr;5101 return result_loc;
5036}5102}
50375103
5038static LLVMValueRef ir_render_union_tag(CodeGen *g, IrExecutable *executable, IrInstructionUnionTag *instruction) {5104static LLVMValueRef ir_render_union_tag(CodeGen *g, IrExecutable *executable, IrInstructionUnionTag *instruction) {
...@@ -5053,90 +5119,6 @@ static LLVMValueRef ir_render_union_tag(CodeGen *g, IrExecutable *executable, Ir...@@ -5053,90 +5119,6 @@ static LLVMValueRef ir_render_union_tag(CodeGen *g, IrExecutable *executable, Ir
5053 return get_handle_value(g, tag_field_ptr, tag_type, ptr_type);5119 return get_handle_value(g, tag_field_ptr, tag_type, ptr_type);
5054}5120}
50555121
5056static LLVMValueRef ir_render_struct_init(CodeGen *g, IrExecutable *executable, IrInstructionStructInit *instruction) {
5057 for (size_t i = 0; i < instruction->field_count; i += 1) {
5058 IrInstructionStructInitField *field = &instruction->fields[i];
5059 TypeStructField *type_struct_field = field->type_struct_field;
5060 if (!type_has_bits(type_struct_field->type_entry))
5061 continue;
5062
5063 LLVMValueRef field_ptr = LLVMBuildStructGEP(g->builder, instruction->tmp_ptr,
5064 (unsigned)type_struct_field->gen_index, "");
5065 LLVMValueRef value = ir_llvm_value(g, field->value);
5066
5067 uint32_t field_align_bytes = get_abi_alignment(g, type_struct_field->type_entry);
5068 uint32_t host_int_bytes = get_host_int_bytes(g, instruction->struct_type, type_struct_field);
5069
5070 ZigType *ptr_type = get_pointer_to_type_extra(g, type_struct_field->type_entry,
5071 false, false, PtrLenSingle, field_align_bytes,
5072 (uint32_t)type_struct_field->bit_offset_in_host, host_int_bytes, false);
5073
5074 gen_assign_raw(g, field_ptr, ptr_type, value);
5075 }
5076 return instruction->tmp_ptr;
5077}
5078
5079static LLVMValueRef ir_render_union_init(CodeGen *g, IrExecutable *executable, IrInstructionUnionInit *instruction) {
5080 TypeUnionField *type_union_field = instruction->field;
5081
5082 if (!type_has_bits(type_union_field->type_entry))
5083 return nullptr;
5084
5085 uint32_t field_align_bytes = get_abi_alignment(g, type_union_field->type_entry);
5086 ZigType *ptr_type = get_pointer_to_type_extra(g, type_union_field->type_entry,
5087 false, false, PtrLenSingle, field_align_bytes,
5088 0, 0, false);
5089
5090 LLVMValueRef uncasted_union_ptr;
5091 // Even if safety is off in this block, if the union type has the safety field, we have to populate it
5092 // correctly. Otherwise safety code somewhere other than here could fail.
5093 ZigType *union_type = instruction->union_type;
5094 if (union_type->data.unionation.gen_tag_index != SIZE_MAX) {
5095 LLVMValueRef tag_field_ptr = LLVMBuildStructGEP(g->builder, instruction->tmp_ptr,
5096 union_type->data.unionation.gen_tag_index, "");
5097
5098 LLVMValueRef tag_value = bigint_to_llvm_const(get_llvm_type(g, union_type->data.unionation.tag_type),
5099 &type_union_field->enum_field->value);
5100 gen_store_untyped(g, tag_value, tag_field_ptr, 0, false);
5101
5102 uncasted_union_ptr = LLVMBuildStructGEP(g->builder, instruction->tmp_ptr,
5103 (unsigned)union_type->data.unionation.gen_union_index, "");
5104 } else {
5105 uncasted_union_ptr = LLVMBuildStructGEP(g->builder, instruction->tmp_ptr, (unsigned)0, "");
5106 }
5107
5108 LLVMValueRef field_ptr = LLVMBuildBitCast(g->builder, uncasted_union_ptr, get_llvm_type(g, ptr_type), "");
5109 LLVMValueRef value = ir_llvm_value(g, instruction->init_value);
5110
5111 gen_assign_raw(g, field_ptr, ptr_type, value);
5112
5113 return instruction->tmp_ptr;
5114}
5115
5116static LLVMValueRef ir_render_container_init_list(CodeGen *g, IrExecutable *executable,
5117 IrInstructionContainerInitList *instruction)
5118{
5119 ZigType *array_type = instruction->base.value.type;
5120 assert(array_type->id == ZigTypeIdArray);
5121 LLVMValueRef tmp_array_ptr = instruction->tmp_ptr;
5122 assert(tmp_array_ptr);
5123
5124 size_t field_count = instruction->item_count;
5125
5126 ZigType *child_type = array_type->data.array.child_type;
5127 for (size_t i = 0; i < field_count; i += 1) {
5128 LLVMValueRef elem_val = ir_llvm_value(g, instruction->items[i]);
5129 LLVMValueRef indices[] = {
5130 LLVMConstNull(g->builtin_types.entry_usize->llvm_type),
5131 LLVMConstInt(g->builtin_types.entry_usize->llvm_type, i, false),
5132 };
5133 LLVMValueRef elem_ptr = LLVMBuildInBoundsGEP(g->builder, tmp_array_ptr, indices, 2, "");
5134 gen_assign_raw(g, elem_ptr, get_pointer_to_type(g, child_type, false), elem_val);
5135 }
5136
5137 return tmp_array_ptr;
5138}
5139
5140static LLVMValueRef ir_render_panic(CodeGen *g, IrExecutable *executable, IrInstructionPanic *instruction) {5122static LLVMValueRef ir_render_panic(CodeGen *g, IrExecutable *executable, IrInstructionPanic *instruction) {
5141 gen_panic(g, ir_llvm_value(g, instruction->msg), get_cur_err_ret_trace_val(g, instruction->base.scope));5123 gen_panic(g, ir_llvm_value(g, instruction->msg), get_cur_err_ret_trace_val(g, instruction->base.scope));
5142 return nullptr;5124 return nullptr;
...@@ -5353,7 +5335,9 @@ static LLVMValueRef get_coro_alloc_helper_fn_val(CodeGen *g, LLVMTypeRef alloc_f...@@ -5353,7 +5335,9 @@ static LLVMValueRef get_coro_alloc_helper_fn_val(CodeGen *g, LLVMTypeRef alloc_f
5353 g->cur_fn = prev_cur_fn;5335 g->cur_fn = prev_cur_fn;
5354 g->cur_fn_val = prev_cur_fn_val;5336 g->cur_fn_val = prev_cur_fn_val;
5355 LLVMPositionBuilderAtEnd(g->builder, prev_block);5337 LLVMPositionBuilderAtEnd(g->builder, prev_block);
5356 LLVMSetCurrentDebugLocation(g->builder, prev_debug_location);5338 if (!g->strip_debug_symbols) {
5339 LLVMSetCurrentDebugLocation(g->builder, prev_debug_location);
5340 }
53575341
5358 g->coro_alloc_helper_fn_val = fn_val;5342 g->coro_alloc_helper_fn_val = fn_val;
5359 return fn_val;5343 return fn_val;
...@@ -5499,12 +5483,12 @@ static LLVMValueRef ir_render_vector_to_array(CodeGen *g, IrExecutable *executab...@@ -5499,12 +5483,12 @@ static LLVMValueRef ir_render_vector_to_array(CodeGen *g, IrExecutable *executab
5499 ZigType *array_type = instruction->base.value.type;5483 ZigType *array_type = instruction->base.value.type;
5500 assert(array_type->id == ZigTypeIdArray);5484 assert(array_type->id == ZigTypeIdArray);
5501 assert(handle_is_ptr(array_type));5485 assert(handle_is_ptr(array_type));
5502 assert(instruction->tmp_ptr);5486 LLVMValueRef result_loc = ir_llvm_value(g, instruction->result_loc);
5503 LLVMValueRef vector = ir_llvm_value(g, instruction->vector);5487 LLVMValueRef vector = ir_llvm_value(g, instruction->vector);
5504 LLVMValueRef casted_ptr = LLVMBuildBitCast(g->builder, instruction->tmp_ptr,5488 LLVMValueRef casted_ptr = LLVMBuildBitCast(g->builder, result_loc,
5505 LLVMPointerType(get_llvm_type(g, instruction->vector->value.type), 0), "");5489 LLVMPointerType(get_llvm_type(g, instruction->vector->value.type), 0), "");
5506 gen_store_untyped(g, vector, casted_ptr, 0, false);5490 gen_store_untyped(g, vector, casted_ptr, get_ptr_align(g, instruction->result_loc->value.type), false);
5507 return instruction->tmp_ptr;5491 return result_loc;
5508}5492}
55095493
5510static LLVMValueRef ir_render_array_to_vector(CodeGen *g, IrExecutable *executable,5494static LLVMValueRef ir_render_array_to_vector(CodeGen *g, IrExecutable *executable,
...@@ -5567,14 +5551,10 @@ static void set_debug_location(CodeGen *g, IrInstruction *instruction) {...@@ -5567,14 +5551,10 @@ static void set_debug_location(CodeGen *g, IrInstruction *instruction) {
5567}5551}
55685552
5569static LLVMValueRef ir_render_instruction(CodeGen *g, IrExecutable *executable, IrInstruction *instruction) {5553static LLVMValueRef ir_render_instruction(CodeGen *g, IrExecutable *executable, IrInstruction *instruction) {
5570 set_debug_location(g, instruction);
5571
5572 switch (instruction->id) {5554 switch (instruction->id) {
5573 case IrInstructionIdInvalid:5555 case IrInstructionIdInvalid:
5574 case IrInstructionIdConst:5556 case IrInstructionIdConst:
5575 case IrInstructionIdTypeOf:5557 case IrInstructionIdTypeOf:
5576 case IrInstructionIdToPtrType:
5577 case IrInstructionIdPtrTypeChild:
5578 case IrInstructionIdFieldPtr:5558 case IrInstructionIdFieldPtr:
5579 case IrInstructionIdSetCold:5559 case IrInstructionIdSetCold:
5580 case IrInstructionIdSetRuntimeSafety:5560 case IrInstructionIdSetRuntimeSafety:
...@@ -5636,10 +5616,22 @@ static LLVMValueRef ir_render_instruction(CodeGen *g, IrExecutable *executable,...@@ -5636,10 +5616,22 @@ static LLVMValueRef ir_render_instruction(CodeGen *g, IrExecutable *executable,
5636 case IrInstructionIdPtrCastSrc:5616 case IrInstructionIdPtrCastSrc:
5637 case IrInstructionIdCmpxchgSrc:5617 case IrInstructionIdCmpxchgSrc:
5638 case IrInstructionIdLoadPtr:5618 case IrInstructionIdLoadPtr:
5639 case IrInstructionIdBitCast:
5640 case IrInstructionIdGlobalAsm:5619 case IrInstructionIdGlobalAsm:
5641 case IrInstructionIdHasDecl:5620 case IrInstructionIdHasDecl:
5642 case IrInstructionIdUndeclaredIdent:5621 case IrInstructionIdUndeclaredIdent:
5622 case IrInstructionIdCallSrc:
5623 case IrInstructionIdAllocaSrc:
5624 case IrInstructionIdEndExpr:
5625 case IrInstructionIdAllocaGen:
5626 case IrInstructionIdImplicitCast:
5627 case IrInstructionIdResolveResult:
5628 case IrInstructionIdResetResult:
5629 case IrInstructionIdResultPtr:
5630 case IrInstructionIdContainerInitList:
5631 case IrInstructionIdSliceSrc:
5632 case IrInstructionIdRef:
5633 case IrInstructionIdBitCastSrc:
5634 case IrInstructionIdTestErrSrc:
5643 zig_unreachable();5635 zig_unreachable();
56445636
5645 case IrInstructionIdDeclVarGen:5637 case IrInstructionIdDeclVarGen:
...@@ -5664,10 +5656,12 @@ static LLVMValueRef ir_render_instruction(CodeGen *g, IrExecutable *executable,...@@ -5664,10 +5656,12 @@ static LLVMValueRef ir_render_instruction(CodeGen *g, IrExecutable *executable,
5664 return ir_render_store_ptr(g, executable, (IrInstructionStorePtr *)instruction);5656 return ir_render_store_ptr(g, executable, (IrInstructionStorePtr *)instruction);
5665 case IrInstructionIdVarPtr:5657 case IrInstructionIdVarPtr:
5666 return ir_render_var_ptr(g, executable, (IrInstructionVarPtr *)instruction);5658 return ir_render_var_ptr(g, executable, (IrInstructionVarPtr *)instruction);
5659 case IrInstructionIdReturnPtr:
5660 return ir_render_return_ptr(g, executable, (IrInstructionReturnPtr *)instruction);
5667 case IrInstructionIdElemPtr:5661 case IrInstructionIdElemPtr:
5668 return ir_render_elem_ptr(g, executable, (IrInstructionElemPtr *)instruction);5662 return ir_render_elem_ptr(g, executable, (IrInstructionElemPtr *)instruction);
5669 case IrInstructionIdCall:5663 case IrInstructionIdCallGen:
5670 return ir_render_call(g, executable, (IrInstructionCall *)instruction);5664 return ir_render_call(g, executable, (IrInstructionCallGen *)instruction);
5671 case IrInstructionIdStructFieldPtr:5665 case IrInstructionIdStructFieldPtr:
5672 return ir_render_struct_field_ptr(g, executable, (IrInstructionStructFieldPtr *)instruction);5666 return ir_render_struct_field_ptr(g, executable, (IrInstructionStructFieldPtr *)instruction);
5673 case IrInstructionIdUnionFieldPtr:5667 case IrInstructionIdUnionFieldPtr:
...@@ -5692,8 +5686,8 @@ static LLVMValueRef ir_render_instruction(CodeGen *g, IrExecutable *executable,...@@ -5692,8 +5686,8 @@ static LLVMValueRef ir_render_instruction(CodeGen *g, IrExecutable *executable,
5692 return ir_render_bit_reverse(g, executable, (IrInstructionBitReverse *)instruction);5686 return ir_render_bit_reverse(g, executable, (IrInstructionBitReverse *)instruction);
5693 case IrInstructionIdPhi:5687 case IrInstructionIdPhi:
5694 return ir_render_phi(g, executable, (IrInstructionPhi *)instruction);5688 return ir_render_phi(g, executable, (IrInstructionPhi *)instruction);
5695 case IrInstructionIdRef:5689 case IrInstructionIdRefGen:
5696 return ir_render_ref(g, executable, (IrInstructionRef *)instruction);5690 return ir_render_ref(g, executable, (IrInstructionRefGen *)instruction);
5697 case IrInstructionIdErrName:5691 case IrInstructionIdErrName:
5698 return ir_render_err_name(g, executable, (IrInstructionErrName *)instruction);5692 return ir_render_err_name(g, executable, (IrInstructionErrName *)instruction);
5699 case IrInstructionIdCmpxchgGen:5693 case IrInstructionIdCmpxchgGen:
...@@ -5708,8 +5702,8 @@ static LLVMValueRef ir_render_instruction(CodeGen *g, IrExecutable *executable,...@@ -5708,8 +5702,8 @@ static LLVMValueRef ir_render_instruction(CodeGen *g, IrExecutable *executable,
5708 return ir_render_memset(g, executable, (IrInstructionMemset *)instruction);5702 return ir_render_memset(g, executable, (IrInstructionMemset *)instruction);
5709 case IrInstructionIdMemcpy:5703 case IrInstructionIdMemcpy:
5710 return ir_render_memcpy(g, executable, (IrInstructionMemcpy *)instruction);5704 return ir_render_memcpy(g, executable, (IrInstructionMemcpy *)instruction);
5711 case IrInstructionIdSlice:5705 case IrInstructionIdSliceGen:
5712 return ir_render_slice(g, executable, (IrInstructionSlice *)instruction);5706 return ir_render_slice(g, executable, (IrInstructionSliceGen *)instruction);
5713 case IrInstructionIdBreakpoint:5707 case IrInstructionIdBreakpoint:
5714 return ir_render_breakpoint(g, executable, (IrInstructionBreakpoint *)instruction);5708 return ir_render_breakpoint(g, executable, (IrInstructionBreakpoint *)instruction);
5715 case IrInstructionIdReturnAddress:5709 case IrInstructionIdReturnAddress:
...@@ -5720,24 +5714,20 @@ static LLVMValueRef ir_render_instruction(CodeGen *g, IrExecutable *executable,...@@ -5720,24 +5714,20 @@ static LLVMValueRef ir_render_instruction(CodeGen *g, IrExecutable *executable,
5720 return ir_render_handle(g, executable, (IrInstructionHandle *)instruction);5714 return ir_render_handle(g, executable, (IrInstructionHandle *)instruction);
5721 case IrInstructionIdOverflowOp:5715 case IrInstructionIdOverflowOp:
5722 return ir_render_overflow_op(g, executable, (IrInstructionOverflowOp *)instruction);5716 return ir_render_overflow_op(g, executable, (IrInstructionOverflowOp *)instruction);
5723 case IrInstructionIdTestErr:5717 case IrInstructionIdTestErrGen:
5724 return ir_render_test_err(g, executable, (IrInstructionTestErr *)instruction);5718 return ir_render_test_err(g, executable, (IrInstructionTestErrGen *)instruction);
5725 case IrInstructionIdUnwrapErrCode:5719 case IrInstructionIdUnwrapErrCode:
5726 return ir_render_unwrap_err_code(g, executable, (IrInstructionUnwrapErrCode *)instruction);5720 return ir_render_unwrap_err_code(g, executable, (IrInstructionUnwrapErrCode *)instruction);
5727 case IrInstructionIdUnwrapErrPayload:5721 case IrInstructionIdUnwrapErrPayload:
5728 return ir_render_unwrap_err_payload(g, executable, (IrInstructionUnwrapErrPayload *)instruction);5722 return ir_render_unwrap_err_payload(g, executable, (IrInstructionUnwrapErrPayload *)instruction);
5729 case IrInstructionIdOptionalWrap:5723 case IrInstructionIdOptionalWrap:
5730 return ir_render_maybe_wrap(g, executable, (IrInstructionOptionalWrap *)instruction);5724 return ir_render_optional_wrap(g, executable, (IrInstructionOptionalWrap *)instruction);
5731 case IrInstructionIdErrWrapCode:5725 case IrInstructionIdErrWrapCode:
5732 return ir_render_err_wrap_code(g, executable, (IrInstructionErrWrapCode *)instruction);5726 return ir_render_err_wrap_code(g, executable, (IrInstructionErrWrapCode *)instruction);
5733 case IrInstructionIdErrWrapPayload:5727 case IrInstructionIdErrWrapPayload:
5734 return ir_render_err_wrap_payload(g, executable, (IrInstructionErrWrapPayload *)instruction);5728 return ir_render_err_wrap_payload(g, executable, (IrInstructionErrWrapPayload *)instruction);
5735 case IrInstructionIdUnionTag:5729 case IrInstructionIdUnionTag:
5736 return ir_render_union_tag(g, executable, (IrInstructionUnionTag *)instruction);5730 return ir_render_union_tag(g, executable, (IrInstructionUnionTag *)instruction);
5737 case IrInstructionIdStructInit:
5738 return ir_render_struct_init(g, executable, (IrInstructionStructInit *)instruction);
5739 case IrInstructionIdUnionInit:
5740 return ir_render_union_init(g, executable, (IrInstructionUnionInit *)instruction);
5741 case IrInstructionIdPtrCastGen:5731 case IrInstructionIdPtrCastGen:
5742 return ir_render_ptr_cast(g, executable, (IrInstructionPtrCastGen *)instruction);5732 return ir_render_ptr_cast(g, executable, (IrInstructionPtrCastGen *)instruction);
5743 case IrInstructionIdBitCastGen:5733 case IrInstructionIdBitCastGen:
...@@ -5754,8 +5744,6 @@ static LLVMValueRef ir_render_instruction(CodeGen *g, IrExecutable *executable,...@@ -5754,8 +5744,6 @@ static LLVMValueRef ir_render_instruction(CodeGen *g, IrExecutable *executable,
5754 return ir_render_int_to_err(g, executable, (IrInstructionIntToErr *)instruction);5744 return ir_render_int_to_err(g, executable, (IrInstructionIntToErr *)instruction);
5755 case IrInstructionIdErrToInt:5745 case IrInstructionIdErrToInt:
5756 return ir_render_err_to_int(g, executable, (IrInstructionErrToInt *)instruction);5746 return ir_render_err_to_int(g, executable, (IrInstructionErrToInt *)instruction);
5757 case IrInstructionIdContainerInitList:
5758 return ir_render_container_init_list(g, executable, (IrInstructionContainerInitList *)instruction);
5759 case IrInstructionIdPanic:5747 case IrInstructionIdPanic:
5760 return ir_render_panic(g, executable, (IrInstructionPanic *)instruction);5748 return ir_render_panic(g, executable, (IrInstructionPanic *)instruction);
5761 case IrInstructionIdTagName:5749 case IrInstructionIdTagName:
...@@ -5818,6 +5806,8 @@ static LLVMValueRef ir_render_instruction(CodeGen *g, IrExecutable *executable,...@@ -5818,6 +5806,8 @@ static LLVMValueRef ir_render_instruction(CodeGen *g, IrExecutable *executable,
5818 return ir_render_assert_non_null(g, executable, (IrInstructionAssertNonNull *)instruction);5806 return ir_render_assert_non_null(g, executable, (IrInstructionAssertNonNull *)instruction);
5819 case IrInstructionIdResizeSlice:5807 case IrInstructionIdResizeSlice:
5820 return ir_render_resize_slice(g, executable, (IrInstructionResizeSlice *)instruction);5808 return ir_render_resize_slice(g, executable, (IrInstructionResizeSlice *)instruction);
5809 case IrInstructionIdPtrOfArrayToSlice:
5810 return ir_render_ptr_of_array_to_slice(g, executable, (IrInstructionPtrOfArrayToSlice *)instruction);
5821 }5811 }
5822 zig_unreachable();5812 zig_unreachable();
5823}5813}
...@@ -5829,7 +5819,6 @@ static void ir_render(CodeGen *g, ZigFn *fn_entry) {...@@ -5829,7 +5819,6 @@ static void ir_render(CodeGen *g, ZigFn *fn_entry) {
5829 assert(executable->basic_block_list.length > 0);5819 assert(executable->basic_block_list.length > 0);
5830 for (size_t block_i = 0; block_i < executable->basic_block_list.length; block_i += 1) {5820 for (size_t block_i = 0; block_i < executable->basic_block_list.length; block_i += 1) {
5831 IrBasicBlock *current_block = executable->basic_block_list.at(block_i);5821 IrBasicBlock *current_block = executable->basic_block_list.at(block_i);
5832 //assert(current_block->ref_count > 0);
5833 assert(current_block->llvm_block);5822 assert(current_block->llvm_block);
5834 LLVMPositionBuilderAtEnd(g->builder, current_block->llvm_block);5823 LLVMPositionBuilderAtEnd(g->builder, current_block->llvm_block);
5835 for (size_t instr_i = 0; instr_i < current_block->instruction_list.length; instr_i += 1) {5824 for (size_t instr_i = 0; instr_i < current_block->instruction_list.length; instr_i += 1) {
...@@ -5837,6 +5826,9 @@ static void ir_render(CodeGen *g, ZigFn *fn_entry) {...@@ -5837,6 +5826,9 @@ static void ir_render(CodeGen *g, ZigFn *fn_entry) {
5837 if (instruction->ref_count == 0 && !ir_has_side_effects(instruction))5826 if (instruction->ref_count == 0 && !ir_has_side_effects(instruction))
5838 continue;5827 continue;
58395828
5829 if (!g->strip_debug_symbols) {
5830 set_debug_location(g, instruction);
5831 }
5840 instruction->llvm_value = ir_render_instruction(g, executable, instruction);5832 instruction->llvm_value = ir_render_instruction(g, executable, instruction);
5841 }5833 }
5842 current_block->llvm_exit_block = LLVMGetInsertBlock(g->builder);5834 current_block->llvm_exit_block = LLVMGetInsertBlock(g->builder);
...@@ -6626,7 +6618,8 @@ static void render_const_val_global(CodeGen *g, ConstExprValue *const_val, const...@@ -6626,7 +6618,8 @@ static void render_const_val_global(CodeGen *g, ConstExprValue *const_val, const
6626 LLVMSetLinkage(global_value, LLVMInternalLinkage);6618 LLVMSetLinkage(global_value, LLVMInternalLinkage);
6627 LLVMSetGlobalConstant(global_value, true);6619 LLVMSetGlobalConstant(global_value, true);
6628 LLVMSetUnnamedAddr(global_value, true);6620 LLVMSetUnnamedAddr(global_value, true);
6629 LLVMSetAlignment(global_value, get_abi_alignment(g, const_val->type));6621 LLVMSetAlignment(global_value, (const_val->global_refs->align == 0) ?
6622 get_abi_alignment(g, const_val->type) : const_val->global_refs->align);
66306623
6631 const_val->global_refs->llvm_global = global_value;6624 const_val->global_refs->llvm_global = global_value;
6632 }6625 }
...@@ -6751,7 +6744,7 @@ static void do_code_gen(CodeGen *g) {...@@ -6751,7 +6744,7 @@ static void do_code_gen(CodeGen *g) {
6751 zig_panic("TODO debug info for var with ptr casted value");6744 zig_panic("TODO debug info for var with ptr casted value");
6752 }6745 }
6753 ZigType *var_type = g->builtin_types.entry_f128;6746 ZigType *var_type = g->builtin_types.entry_f128;
6754 ConstExprValue coerced_value;6747 ConstExprValue coerced_value = {};
6755 coerced_value.special = ConstValSpecialStatic;6748 coerced_value.special = ConstValSpecialStatic;
6756 coerced_value.type = var_type;6749 coerced_value.type = var_type;
6757 coerced_value.data.x_f128 = bigfloat_to_f128(&const_val->data.x_bigfloat);6750 coerced_value.data.x_f128 = bigfloat_to_f128(&const_val->data.x_bigfloat);
...@@ -6856,20 +6849,24 @@ static void do_code_gen(CodeGen *g) {...@@ -6856,20 +6849,24 @@ static void do_code_gen(CodeGen *g) {
6856 FnTypeId *fn_type_id = &fn_table_entry->type_entry->data.fn.fn_type_id;6849 FnTypeId *fn_type_id = &fn_table_entry->type_entry->data.fn.fn_type_id;
6857 CallingConvention cc = fn_type_id->cc;6850 CallingConvention cc = fn_type_id->cc;
6858 bool is_c_abi = cc == CallingConventionC;6851 bool is_c_abi = cc == CallingConventionC;
6852 bool want_sret = want_first_arg_sret(g, fn_type_id);
68596853
6860 LLVMValueRef fn = fn_llvm_value(g, fn_table_entry);6854 LLVMValueRef fn = fn_llvm_value(g, fn_table_entry);
6861 g->cur_fn = fn_table_entry;6855 g->cur_fn = fn_table_entry;
6862 g->cur_fn_val = fn;6856 g->cur_fn_val = fn;
6863 ZigType *return_type = fn_type_id->return_type;6857
6864 if (handle_is_ptr(return_type)) {6858 build_all_basic_blocks(g, fn_table_entry);
6859 clear_debug_source_node(g);
6860
6861 if (want_sret) {
6865 g->cur_ret_ptr = LLVMGetParam(fn, 0);6862 g->cur_ret_ptr = LLVMGetParam(fn, 0);
6863 } else if (handle_is_ptr(fn_type_id->return_type)) {
6864 g->cur_ret_ptr = build_alloca(g, fn_type_id->return_type, "result", 0);
6865 // TODO add debug info variable for this
6866 } else {6866 } else {
6867 g->cur_ret_ptr = nullptr;6867 g->cur_ret_ptr = nullptr;
6868 }6868 }
68696869
6870 build_all_basic_blocks(g, fn_table_entry);
6871 clear_debug_source_node(g);
6872
6873 uint32_t err_ret_trace_arg_index = get_err_ret_trace_arg_index(g, fn_table_entry);6870 uint32_t err_ret_trace_arg_index = get_err_ret_trace_arg_index(g, fn_table_entry);
6874 bool have_err_ret_trace_arg = err_ret_trace_arg_index != UINT32_MAX;6871 bool have_err_ret_trace_arg = err_ret_trace_arg_index != UINT32_MAX;
6875 if (have_err_ret_trace_arg) {6872 if (have_err_ret_trace_arg) {
...@@ -6894,68 +6891,28 @@ static void do_code_gen(CodeGen *g) {...@@ -6894,68 +6891,28 @@ static void do_code_gen(CodeGen *g) {
6894 }6891 }
68956892
6896 // allocate temporary stack data6893 // allocate temporary stack data
6897 for (size_t alloca_i = 0; alloca_i < fn_table_entry->alloca_list.length; alloca_i += 1) {6894 for (size_t alloca_i = 0; alloca_i < fn_table_entry->alloca_gen_list.length; alloca_i += 1) {
6898 IrInstruction *instruction = fn_table_entry->alloca_list.at(alloca_i);6895 IrInstructionAllocaGen *instruction = fn_table_entry->alloca_gen_list.at(alloca_i);
6899 LLVMValueRef *slot;6896 ZigType *ptr_type = instruction->base.value.type;
6900 ZigType *slot_type = instruction->value.type;6897 assert(ptr_type->id == ZigTypeIdPointer);
6901 uint32_t alignment_bytes = 0;6898 ZigType *child_type = ptr_type->data.pointer.child_type;
6902 if (instruction->id == IrInstructionIdCast) {6899 if (!type_has_bits(child_type))
6903 IrInstructionCast *cast_instruction = (IrInstructionCast *)instruction;6900 continue;
6904 slot = &cast_instruction->tmp_ptr;6901 if (instruction->base.ref_count == 0)
6905 } else if (instruction->id == IrInstructionIdRef) {6902 continue;
6906 IrInstructionRef *ref_instruction = (IrInstructionRef *)instruction;6903 if (instruction->base.value.special != ConstValSpecialRuntime) {
6907 slot = &ref_instruction->tmp_ptr;6904 if (const_ptr_pointee(nullptr, g, &instruction->base.value, nullptr)->special !=
6908 assert(instruction->value.type->id == ZigTypeIdPointer);6905 ConstValSpecialRuntime)
6909 slot_type = instruction->value.type->data.pointer.child_type;6906 {
6910 } else if (instruction->id == IrInstructionIdContainerInitList) {6907 continue;
6911 IrInstructionContainerInitList *container_init_list_instruction = (IrInstructionContainerInitList *)instruction;6908 }
6912 slot = &container_init_list_instruction->tmp_ptr;
6913 } else if (instruction->id == IrInstructionIdStructInit) {
6914 IrInstructionStructInit *struct_init_instruction = (IrInstructionStructInit *)instruction;
6915 slot = &struct_init_instruction->tmp_ptr;
6916 } else if (instruction->id == IrInstructionIdUnionInit) {
6917 IrInstructionUnionInit *union_init_instruction = (IrInstructionUnionInit *)instruction;
6918 slot = &union_init_instruction->tmp_ptr;
6919 } else if (instruction->id == IrInstructionIdCall) {
6920 IrInstructionCall *call_instruction = (IrInstructionCall *)instruction;
6921 slot = &call_instruction->tmp_ptr;
6922 } else if (instruction->id == IrInstructionIdSlice) {
6923 IrInstructionSlice *slice_instruction = (IrInstructionSlice *)instruction;
6924 slot = &slice_instruction->tmp_ptr;
6925 } else if (instruction->id == IrInstructionIdOptionalWrap) {
6926 IrInstructionOptionalWrap *maybe_wrap_instruction = (IrInstructionOptionalWrap *)instruction;
6927 slot = &maybe_wrap_instruction->tmp_ptr;
6928 } else if (instruction->id == IrInstructionIdErrWrapPayload) {
6929 IrInstructionErrWrapPayload *err_wrap_payload_instruction = (IrInstructionErrWrapPayload *)instruction;
6930 slot = &err_wrap_payload_instruction->tmp_ptr;
6931 } else if (instruction->id == IrInstructionIdErrWrapCode) {
6932 IrInstructionErrWrapCode *err_wrap_code_instruction = (IrInstructionErrWrapCode *)instruction;
6933 slot = &err_wrap_code_instruction->tmp_ptr;
6934 } else if (instruction->id == IrInstructionIdCmpxchgGen) {
6935 IrInstructionCmpxchgGen *cmpxchg_instruction = (IrInstructionCmpxchgGen *)instruction;
6936 slot = &cmpxchg_instruction->tmp_ptr;
6937 } else if (instruction->id == IrInstructionIdResizeSlice) {
6938 IrInstructionResizeSlice *resize_slice_instruction = (IrInstructionResizeSlice *)instruction;
6939 slot = &resize_slice_instruction->tmp_ptr;
6940 } else if (instruction->id == IrInstructionIdLoadPtrGen) {
6941 IrInstructionLoadPtrGen *load_ptr_inst = (IrInstructionLoadPtrGen *)instruction;
6942 slot = &load_ptr_inst->tmp_ptr;
6943 } else if (instruction->id == IrInstructionIdBitCastGen) {
6944 IrInstructionBitCastGen *bit_cast_inst = (IrInstructionBitCastGen *)instruction;
6945 slot = &bit_cast_inst->tmp_ptr;
6946 } else if (instruction->id == IrInstructionIdVectorToArray) {
6947 IrInstructionVectorToArray *vector_to_array_instruction = (IrInstructionVectorToArray *)instruction;
6948 alignment_bytes = get_abi_alignment(g, vector_to_array_instruction->vector->value.type);
6949 slot = &vector_to_array_instruction->tmp_ptr;
6950 } else {
6951 zig_unreachable();
6952 }6909 }
6953 *slot = build_alloca(g, slot_type, "", alignment_bytes);6910 instruction->base.llvm_value = build_alloca(g, child_type, instruction->name_hint,
6911 get_ptr_align(g, ptr_type));
6954 }6912 }
69556913
6956 ZigType *import = get_scope_import(&fn_table_entry->fndef_scope->base);6914 ZigType *import = get_scope_import(&fn_table_entry->fndef_scope->base);
69576915 unsigned gen_i_init = want_sret ? 1 : 0;
6958 unsigned gen_i_init = want_first_arg_sret(g, fn_type_id) ? 1 : 0;
69596916
6960 // create debug variable declarations for variables and allocate all local variables6917 // create debug variable declarations for variables and allocate all local variables
6961 FnWalk fn_walk_var = {};6918 FnWalk fn_walk_var = {};
...@@ -6982,8 +6939,6 @@ static void do_code_gen(CodeGen *g) {...@@ -6982,8 +6939,6 @@ static void do_code_gen(CodeGen *g) {
6982 }6939 }
69836940
6984 if (var->src_arg_index == SIZE_MAX) {6941 if (var->src_arg_index == SIZE_MAX) {
6985 var->value_ref = build_alloca(g, var->var_type, buf_ptr(&var->name), var->align_bytes);
6986
6987 var->di_loc_var = ZigLLVMCreateAutoVariable(g->dbuilder, get_di_scope(g, var->parent_scope),6942 var->di_loc_var = ZigLLVMCreateAutoVariable(g->dbuilder, get_di_scope(g, var->parent_scope),
6988 buf_ptr(&var->name), import->data.structure.root_struct->di_file, (unsigned)(var->decl_node->line + 1),6943 buf_ptr(&var->name), import->data.structure.root_struct->di_file, (unsigned)(var->decl_node->line + 1),
6989 get_llvm_di_type(g, var->var_type), !g->strip_debug_symbols, 0);6944 get_llvm_di_type(g, var->var_type), !g->strip_debug_symbols, 0);
src/ir.cpp+3051-1481
...@@ -38,6 +38,7 @@ struct IrAnalyze {...@@ -38,6 +38,7 @@ struct IrAnalyze {
38 ZigType *explicit_return_type;38 ZigType *explicit_return_type;
39 AstNode *explicit_return_type_source_node;39 AstNode *explicit_return_type_source_node;
40 ZigList<IrInstruction *> src_implicit_return_type_list;40 ZigList<IrInstruction *> src_implicit_return_type_list;
41 ZigList<IrSuspendPosition> resume_stack;
41 IrBasicBlock *const_predecessor_bb;42 IrBasicBlock *const_predecessor_bb;
42};43};
4344
...@@ -157,16 +158,19 @@ enum UndefAllowed {...@@ -157,16 +158,19 @@ enum UndefAllowed {
157};158};
158159
159static IrInstruction *ir_gen_node(IrBuilder *irb, AstNode *node, Scope *scope);160static IrInstruction *ir_gen_node(IrBuilder *irb, AstNode *node, Scope *scope);
160static IrInstruction *ir_gen_node_extra(IrBuilder *irb, AstNode *node, Scope *scope, LVal lval);161static IrInstruction *ir_gen_node_extra(IrBuilder *irb, AstNode *node, Scope *scope, LVal lval,
161static IrInstruction *ir_analyze_instruction(IrAnalyze *ira, IrInstruction *instruction);162 ResultLoc *result_loc);
162static IrInstruction *ir_implicit_cast(IrAnalyze *ira, IrInstruction *value, ZigType *expected_type);163static IrInstruction *ir_implicit_cast(IrAnalyze *ira, IrInstruction *value, ZigType *expected_type);
163static IrInstruction *ir_get_deref(IrAnalyze *ira, IrInstruction *source_instruction, IrInstruction *ptr);164static IrInstruction *ir_get_deref(IrAnalyze *ira, IrInstruction *source_instruction, IrInstruction *ptr,
165 ResultLoc *result_loc);
164static ErrorMsg *exec_add_error_node(CodeGen *codegen, IrExecutable *exec, AstNode *source_node, Buf *msg);166static ErrorMsg *exec_add_error_node(CodeGen *codegen, IrExecutable *exec, AstNode *source_node, Buf *msg);
165static IrInstruction *ir_analyze_container_field_ptr(IrAnalyze *ira, Buf *field_name,167static IrInstruction *ir_analyze_container_field_ptr(IrAnalyze *ira, Buf *field_name,
166 IrInstruction *source_instr, IrInstruction *container_ptr, ZigType *container_type);168 IrInstruction *source_instr, IrInstruction *container_ptr, ZigType *container_type, bool initializing);
169static void ir_assert(bool ok, IrInstruction *source_instruction);
167static IrInstruction *ir_get_var_ptr(IrAnalyze *ira, IrInstruction *instruction, ZigVar *var);170static IrInstruction *ir_get_var_ptr(IrAnalyze *ira, IrInstruction *instruction, ZigVar *var);
168static ZigType *ir_resolve_atomic_operand_type(IrAnalyze *ira, IrInstruction *op);171static ZigType *ir_resolve_atomic_operand_type(IrAnalyze *ira, IrInstruction *op);
169static IrInstruction *ir_lval_wrap(IrBuilder *irb, Scope *scope, IrInstruction *value, LVal lval);172static IrInstruction *ir_lval_wrap(IrBuilder *irb, Scope *scope, IrInstruction *value, LVal lval, ResultLoc *result_loc);
173static IrInstruction *ir_expr_wrap(IrBuilder *irb, Scope *scope, IrInstruction *inst, ResultLoc *result_loc);
170static ZigType *adjust_ptr_align(CodeGen *g, ZigType *ptr_type, uint32_t new_align);174static ZigType *adjust_ptr_align(CodeGen *g, ZigType *ptr_type, uint32_t new_align);
171static ZigType *adjust_slice_align(CodeGen *g, ZigType *slice_type, uint32_t new_align);175static ZigType *adjust_slice_align(CodeGen *g, ZigType *slice_type, uint32_t new_align);
172static Error buf_read_value_bytes(IrAnalyze *ira, CodeGen *codegen, AstNode *source_node, uint8_t *buf, ConstExprValue *val);176static Error buf_read_value_bytes(IrAnalyze *ira, CodeGen *codegen, AstNode *source_node, uint8_t *buf, ConstExprValue *val);
...@@ -178,17 +182,28 @@ static IrInstruction *ir_analyze_ptr_cast(IrAnalyze *ira, IrInstruction *source_...@@ -178,17 +182,28 @@ static IrInstruction *ir_analyze_ptr_cast(IrAnalyze *ira, IrInstruction *source_
178static ConstExprValue *ir_resolve_const(IrAnalyze *ira, IrInstruction *value, UndefAllowed undef_allowed);182static ConstExprValue *ir_resolve_const(IrAnalyze *ira, IrInstruction *value, UndefAllowed undef_allowed);
179static void copy_const_val(ConstExprValue *dest, ConstExprValue *src, bool same_global_refs);183static void copy_const_val(ConstExprValue *dest, ConstExprValue *src, bool same_global_refs);
180static Error resolve_ptr_align(IrAnalyze *ira, ZigType *ty, uint32_t *result_align);184static Error resolve_ptr_align(IrAnalyze *ira, ZigType *ty, uint32_t *result_align);
181static void ir_add_alloca(IrAnalyze *ira, IrInstruction *instruction, ZigType *type_entry);
182static IrInstruction *ir_analyze_int_to_ptr(IrAnalyze *ira, IrInstruction *source_instr, IrInstruction *target,185static IrInstruction *ir_analyze_int_to_ptr(IrAnalyze *ira, IrInstruction *source_instr, IrInstruction *target,
183 ZigType *ptr_type);186 ZigType *ptr_type);
184static IrInstruction *ir_analyze_bit_cast(IrAnalyze *ira, IrInstruction *source_instr, IrInstruction *value,187static IrInstruction *ir_analyze_bit_cast(IrAnalyze *ira, IrInstruction *source_instr, IrInstruction *value,
185 ZigType *dest_type);188 ZigType *dest_type);
189static IrInstruction *ir_resolve_result_raw(IrAnalyze *ira, IrInstruction *suspend_source_instr,
190 ResultLoc *result_loc, ZigType *value_type, IrInstruction *value, bool force_runtime, bool non_null_comptime);
191static IrInstruction *ir_resolve_result(IrAnalyze *ira, IrInstruction *suspend_source_instr,
192 ResultLoc *result_loc, ZigType *value_type, IrInstruction *value, bool force_runtime, bool non_null_comptime);
193static IrInstruction *ir_analyze_unwrap_optional_payload(IrAnalyze *ira, IrInstruction *source_instr,
194 IrInstruction *base_ptr, bool safety_check_on, bool initializing);
195static IrInstruction *ir_analyze_unwrap_error_payload(IrAnalyze *ira, IrInstruction *source_instr,
196 IrInstruction *base_ptr, bool safety_check_on, bool initializing);
197static IrInstruction *ir_analyze_unwrap_err_code(IrAnalyze *ira, IrInstruction *source_instr,
198 IrInstruction *base_ptr, bool initializing);
199static IrInstruction *ir_analyze_store_ptr(IrAnalyze *ira, IrInstruction *source_instr,
200 IrInstruction *ptr, IrInstruction *uncasted_value);
186201
187static ConstExprValue *const_ptr_pointee_unchecked(CodeGen *g, ConstExprValue *const_val) {202static ConstExprValue *const_ptr_pointee_unchecked(CodeGen *g, ConstExprValue *const_val) {
188 assert(get_src_ptr_type(const_val->type) != nullptr);203 assert(get_src_ptr_type(const_val->type) != nullptr);
189 assert(const_val->special == ConstValSpecialStatic);204 assert(const_val->special == ConstValSpecialStatic);
190 ConstExprValue *result;205 ConstExprValue *result;
191 206
192 switch (type_has_one_possible_value(g, const_val->type->data.pointer.child_type)) {207 switch (type_has_one_possible_value(g, const_val->type->data.pointer.child_type)) {
193 case OnePossibleValueInvalid:208 case OnePossibleValueInvalid:
194 zig_unreachable();209 zig_unreachable();
...@@ -200,7 +215,7 @@ static ConstExprValue *const_ptr_pointee_unchecked(CodeGen *g, ConstExprValue *c...@@ -200,7 +215,7 @@ static ConstExprValue *const_ptr_pointee_unchecked(CodeGen *g, ConstExprValue *c
200 case OnePossibleValueNo:215 case OnePossibleValueNo:
201 break;216 break;
202 }217 }
203 218
204 switch (const_val->data.x_ptr.special) {219 switch (const_val->data.x_ptr.special) {
205 case ConstPtrSpecialInvalid:220 case ConstPtrSpecialInvalid:
206 zig_unreachable();221 zig_unreachable();
...@@ -246,6 +261,15 @@ static bool is_opt_err_set(ZigType *ty) {...@@ -246,6 +261,15 @@ static bool is_opt_err_set(ZigType *ty) {
246 (ty->id == ZigTypeIdOptional && ty->data.maybe.child_type->id == ZigTypeIdErrorSet);261 (ty->id == ZigTypeIdOptional && ty->data.maybe.child_type->id == ZigTypeIdErrorSet);
247}262}
248263
264static bool is_slice(ZigType *type) {
265 return type->id == ZigTypeIdStruct && type->data.structure.is_slice;
266}
267
268static bool slice_is_const(ZigType *type) {
269 assert(is_slice(type));
270 return type->data.structure.fields[slice_ptr_index].type_entry->data.pointer.is_const;
271}
272
249// This function returns true when you can change the type of a ConstExprValue and the273// This function returns true when you can change the type of a ConstExprValue and the
250// value remains meaningful.274// value remains meaningful.
251static bool types_have_same_zig_comptime_repr(ZigType *a, ZigType *b) {275static bool types_have_same_zig_comptime_repr(ZigType *a, ZigType *b) {
...@@ -282,8 +306,9 @@ static bool types_have_same_zig_comptime_repr(ZigType *a, ZigType *b) {...@@ -282,8 +306,9 @@ static bool types_have_same_zig_comptime_repr(ZigType *a, ZigType *b) {
282 return a->data.floating.bit_count == b->data.floating.bit_count;306 return a->data.floating.bit_count == b->data.floating.bit_count;
283 case ZigTypeIdInt:307 case ZigTypeIdInt:
284 return a->data.integral.is_signed == b->data.integral.is_signed;308 return a->data.integral.is_signed == b->data.integral.is_signed;
285 case ZigTypeIdArray:
286 case ZigTypeIdStruct:309 case ZigTypeIdStruct:
310 return is_slice(a) && is_slice(b);
311 case ZigTypeIdArray:
287 case ZigTypeIdOptional:312 case ZigTypeIdOptional:
288 case ZigTypeIdErrorUnion:313 case ZigTypeIdErrorUnion:
289 case ZigTypeIdEnum:314 case ZigTypeIdEnum:
...@@ -386,6 +411,7 @@ static IrBasicBlock *ir_create_basic_block(IrBuilder *irb, Scope *scope, const c...@@ -386,6 +411,7 @@ static IrBasicBlock *ir_create_basic_block(IrBuilder *irb, Scope *scope, const c
386 result->scope = scope;411 result->scope = scope;
387 result->name_hint = name_hint;412 result->name_hint = name_hint;
388 result->debug_id = exec_next_debug_id(irb->exec);413 result->debug_id = exec_next_debug_id(irb->exec);
414 result->index = SIZE_MAX; // set later
389 return result;415 return result;
390}416}
391417
...@@ -475,8 +501,16 @@ static constexpr IrInstructionId ir_instruction_id(IrInstructionVarPtr *) {...@@ -475,8 +501,16 @@ static constexpr IrInstructionId ir_instruction_id(IrInstructionVarPtr *) {
475 return IrInstructionIdVarPtr;501 return IrInstructionIdVarPtr;
476}502}
477503
478static constexpr IrInstructionId ir_instruction_id(IrInstructionCall *) {504static constexpr IrInstructionId ir_instruction_id(IrInstructionReturnPtr *) {
479 return IrInstructionIdCall;505 return IrInstructionIdReturnPtr;
506}
507
508static constexpr IrInstructionId ir_instruction_id(IrInstructionCallSrc *) {
509 return IrInstructionIdCallSrc;
510}
511
512static constexpr IrInstructionId ir_instruction_id(IrInstructionCallGen *) {
513 return IrInstructionIdCallGen;
480}514}
481515
482static constexpr IrInstructionId ir_instruction_id(IrInstructionConst *) {516static constexpr IrInstructionId ir_instruction_id(IrInstructionConst *) {
...@@ -511,14 +545,6 @@ static constexpr IrInstructionId ir_instruction_id(IrInstructionTypeOf *) {...@@ -511,14 +545,6 @@ static constexpr IrInstructionId ir_instruction_id(IrInstructionTypeOf *) {
511 return IrInstructionIdTypeOf;545 return IrInstructionIdTypeOf;
512}546}
513547
514static constexpr IrInstructionId ir_instruction_id(IrInstructionToPtrType *) {
515 return IrInstructionIdToPtrType;
516}
517
518static constexpr IrInstructionId ir_instruction_id(IrInstructionPtrTypeChild *) {
519 return IrInstructionIdPtrTypeChild;
520}
521
522static constexpr IrInstructionId ir_instruction_id(IrInstructionSetCold *) {548static constexpr IrInstructionId ir_instruction_id(IrInstructionSetCold *) {
523 return IrInstructionIdSetCold;549 return IrInstructionIdSetCold;
524}550}
...@@ -611,12 +637,8 @@ static constexpr IrInstructionId ir_instruction_id(IrInstructionRef *) {...@@ -611,12 +637,8 @@ static constexpr IrInstructionId ir_instruction_id(IrInstructionRef *) {
611 return IrInstructionIdRef;637 return IrInstructionIdRef;
612}638}
613639
614static constexpr IrInstructionId ir_instruction_id(IrInstructionStructInit *) {640static constexpr IrInstructionId ir_instruction_id(IrInstructionRefGen *) {
615 return IrInstructionIdStructInit;641 return IrInstructionIdRefGen;
616}
617
618static constexpr IrInstructionId ir_instruction_id(IrInstructionUnionInit *) {
619 return IrInstructionIdUnionInit;
620}642}
621643
622static constexpr IrInstructionId ir_instruction_id(IrInstructionCompileErr *) {644static constexpr IrInstructionId ir_instruction_id(IrInstructionCompileErr *) {
...@@ -703,8 +725,12 @@ static constexpr IrInstructionId ir_instruction_id(IrInstructionMemcpy *) {...@@ -703,8 +725,12 @@ static constexpr IrInstructionId ir_instruction_id(IrInstructionMemcpy *) {
703 return IrInstructionIdMemcpy;725 return IrInstructionIdMemcpy;
704}726}
705727
706static constexpr IrInstructionId ir_instruction_id(IrInstructionSlice *) {728static constexpr IrInstructionId ir_instruction_id(IrInstructionSliceSrc *) {
707 return IrInstructionIdSlice;729 return IrInstructionIdSliceSrc;
730}
731
732static constexpr IrInstructionId ir_instruction_id(IrInstructionSliceGen *) {
733 return IrInstructionIdSliceGen;
708}734}
709735
710static constexpr IrInstructionId ir_instruction_id(IrInstructionMemberCount *) {736static constexpr IrInstructionId ir_instruction_id(IrInstructionMemberCount *) {
...@@ -743,8 +769,12 @@ static constexpr IrInstructionId ir_instruction_id(IrInstructionOverflowOp *) {...@@ -743,8 +769,12 @@ static constexpr IrInstructionId ir_instruction_id(IrInstructionOverflowOp *) {
743 return IrInstructionIdOverflowOp;769 return IrInstructionIdOverflowOp;
744}770}
745771
746static constexpr IrInstructionId ir_instruction_id(IrInstructionTestErr *) {772static constexpr IrInstructionId ir_instruction_id(IrInstructionTestErrSrc *) {
747 return IrInstructionIdTestErr;773 return IrInstructionIdTestErrSrc;
774}
775
776static constexpr IrInstructionId ir_instruction_id(IrInstructionTestErrGen *) {
777 return IrInstructionIdTestErrGen;
748}778}
749779
750static constexpr IrInstructionId ir_instruction_id(IrInstructionMulAdd *) {780static constexpr IrInstructionId ir_instruction_id(IrInstructionMulAdd *) {
...@@ -787,8 +817,8 @@ static constexpr IrInstructionId ir_instruction_id(IrInstructionPtrCastGen *) {...@@ -787,8 +817,8 @@ static constexpr IrInstructionId ir_instruction_id(IrInstructionPtrCastGen *) {
787 return IrInstructionIdPtrCastGen;817 return IrInstructionIdPtrCastGen;
788}818}
789819
790static constexpr IrInstructionId ir_instruction_id(IrInstructionBitCast *) {820static constexpr IrInstructionId ir_instruction_id(IrInstructionBitCastSrc *) {
791 return IrInstructionIdBitCast;821 return IrInstructionIdBitCastSrc;
792}822}
793823
794static constexpr IrInstructionId ir_instruction_id(IrInstructionBitCastGen *) {824static constexpr IrInstructionId ir_instruction_id(IrInstructionBitCastGen *) {
...@@ -883,6 +913,26 @@ static constexpr IrInstructionId ir_instruction_id(IrInstructionAlignCast *) {...@@ -883,6 +913,26 @@ static constexpr IrInstructionId ir_instruction_id(IrInstructionAlignCast *) {
883 return IrInstructionIdAlignCast;913 return IrInstructionIdAlignCast;
884}914}
885915
916static constexpr IrInstructionId ir_instruction_id(IrInstructionImplicitCast *) {
917 return IrInstructionIdImplicitCast;
918}
919
920static constexpr IrInstructionId ir_instruction_id(IrInstructionResolveResult *) {
921 return IrInstructionIdResolveResult;
922}
923
924static constexpr IrInstructionId ir_instruction_id(IrInstructionResetResult *) {
925 return IrInstructionIdResetResult;
926}
927
928static constexpr IrInstructionId ir_instruction_id(IrInstructionResultPtr *) {
929 return IrInstructionIdResultPtr;
930}
931
932static constexpr IrInstructionId ir_instruction_id(IrInstructionPtrOfArrayToSlice *) {
933 return IrInstructionIdPtrOfArrayToSlice;
934}
935
886static constexpr IrInstructionId ir_instruction_id(IrInstructionOpaqueType *) {936static constexpr IrInstructionId ir_instruction_id(IrInstructionOpaqueType *) {
887 return IrInstructionIdOpaqueType;937 return IrInstructionIdOpaqueType;
888}938}
...@@ -1023,6 +1073,18 @@ static constexpr IrInstructionId ir_instruction_id(IrInstructionUndeclaredIdent...@@ -1023,6 +1073,18 @@ static constexpr IrInstructionId ir_instruction_id(IrInstructionUndeclaredIdent
1023 return IrInstructionIdUndeclaredIdent;1073 return IrInstructionIdUndeclaredIdent;
1024}1074}
10251075
1076static constexpr IrInstructionId ir_instruction_id(IrInstructionAllocaSrc *) {
1077 return IrInstructionIdAllocaSrc;
1078}
1079
1080static constexpr IrInstructionId ir_instruction_id(IrInstructionAllocaGen *) {
1081 return IrInstructionIdAllocaGen;
1082}
1083
1084static constexpr IrInstructionId ir_instruction_id(IrInstructionEndExpr *) {
1085 return IrInstructionIdEndExpr;
1086}
1087
1026template<typename T>1088template<typename T>
1027static T *ir_create_instruction(IrBuilder *irb, Scope *scope, AstNode *source_node) {1089static T *ir_create_instruction(IrBuilder *irb, Scope *scope, AstNode *source_node) {
1028 T *special_instruction = allocate<T>(1);1090 T *special_instruction = allocate<T>(1);
...@@ -1074,13 +1136,15 @@ static IrInstruction *ir_build_cond_br(IrBuilder *irb, Scope *scope, AstNode *so...@@ -1074,13 +1136,15 @@ static IrInstruction *ir_build_cond_br(IrBuilder *irb, Scope *scope, AstNode *so
1074 return &cond_br_instruction->base;1136 return &cond_br_instruction->base;
1075}1137}
10761138
1077static IrInstruction *ir_build_return(IrBuilder *irb, Scope *scope, AstNode *source_node, IrInstruction *return_value) {1139static IrInstruction *ir_build_return(IrBuilder *irb, Scope *scope, AstNode *source_node,
1140 IrInstruction *return_value)
1141{
1078 IrInstructionReturn *return_instruction = ir_build_instruction<IrInstructionReturn>(irb, scope, source_node);1142 IrInstructionReturn *return_instruction = ir_build_instruction<IrInstructionReturn>(irb, scope, source_node);
1079 return_instruction->base.value.type = irb->codegen->builtin_types.entry_unreachable;1143 return_instruction->base.value.type = irb->codegen->builtin_types.entry_unreachable;
1080 return_instruction->base.value.special = ConstValSpecialStatic;1144 return_instruction->base.value.special = ConstValSpecialStatic;
1081 return_instruction->value = return_value;1145 return_instruction->value = return_value;
10821146
1083 ir_ref_instruction(return_value, irb->current_basic_block);1147 if (return_value != nullptr) ir_ref_instruction(return_value, irb->current_basic_block);
10841148
1085 return &return_instruction->base;1149 return &return_instruction->base;
1086}1150}
...@@ -1258,17 +1322,27 @@ static IrInstruction *ir_build_var_ptr(IrBuilder *irb, Scope *scope, AstNode *so...@@ -1258,17 +1322,27 @@ static IrInstruction *ir_build_var_ptr(IrBuilder *irb, Scope *scope, AstNode *so
1258 return ir_build_var_ptr_x(irb, scope, source_node, var, nullptr);1322 return ir_build_var_ptr_x(irb, scope, source_node, var, nullptr);
1259}1323}
12601324
1261static IrInstruction *ir_build_elem_ptr(IrBuilder *irb, Scope *scope, AstNode *source_node, IrInstruction *array_ptr,1325static IrInstruction *ir_build_return_ptr(IrAnalyze *ira, IrInstruction *source_instruction, ZigType *ty) {
1262 IrInstruction *elem_index, bool safety_check_on, PtrLen ptr_len)1326 IrInstructionReturnPtr *instruction = ir_build_instruction<IrInstructionReturnPtr>(&ira->new_irb,
1327 source_instruction->scope, source_instruction->source_node);
1328 instruction->base.value.type = ty;
1329 return &instruction->base;
1330}
1331
1332static IrInstruction *ir_build_elem_ptr(IrBuilder *irb, Scope *scope, AstNode *source_node,
1333 IrInstruction *array_ptr, IrInstruction *elem_index, bool safety_check_on, PtrLen ptr_len,
1334 IrInstruction *init_array_type)
1263{1335{
1264 IrInstructionElemPtr *instruction = ir_build_instruction<IrInstructionElemPtr>(irb, scope, source_node);1336 IrInstructionElemPtr *instruction = ir_build_instruction<IrInstructionElemPtr>(irb, scope, source_node);
1265 instruction->array_ptr = array_ptr;1337 instruction->array_ptr = array_ptr;
1266 instruction->elem_index = elem_index;1338 instruction->elem_index = elem_index;
1267 instruction->safety_check_on = safety_check_on;1339 instruction->safety_check_on = safety_check_on;
1268 instruction->ptr_len = ptr_len;1340 instruction->ptr_len = ptr_len;
1341 instruction->init_array_type = init_array_type;
12691342
1270 ir_ref_instruction(array_ptr, irb->current_basic_block);1343 ir_ref_instruction(array_ptr, irb->current_basic_block);
1271 ir_ref_instruction(elem_index, irb->current_basic_block);1344 ir_ref_instruction(elem_index, irb->current_basic_block);
1345 if (init_array_type != nullptr) ir_ref_instruction(init_array_type, irb->current_basic_block);
12721346
1273 return &instruction->base;1347 return &instruction->base;
1274}1348}
...@@ -1288,12 +1362,13 @@ static IrInstruction *ir_build_field_ptr_instruction(IrBuilder *irb, Scope *scop...@@ -1288,12 +1362,13 @@ static IrInstruction *ir_build_field_ptr_instruction(IrBuilder *irb, Scope *scop
1288}1362}
12891363
1290static IrInstruction *ir_build_field_ptr(IrBuilder *irb, Scope *scope, AstNode *source_node,1364static IrInstruction *ir_build_field_ptr(IrBuilder *irb, Scope *scope, AstNode *source_node,
1291 IrInstruction *container_ptr, Buf *field_name)1365 IrInstruction *container_ptr, Buf *field_name, bool initializing)
1292{1366{
1293 IrInstructionFieldPtr *instruction = ir_build_instruction<IrInstructionFieldPtr>(irb, scope, source_node);1367 IrInstructionFieldPtr *instruction = ir_build_instruction<IrInstructionFieldPtr>(irb, scope, source_node);
1294 instruction->container_ptr = container_ptr;1368 instruction->container_ptr = container_ptr;
1295 instruction->field_name_buffer = field_name;1369 instruction->field_name_buffer = field_name;
1296 instruction->field_name_expr = nullptr;1370 instruction->field_name_expr = nullptr;
1371 instruction->initializing = initializing;
12971372
1298 ir_ref_instruction(container_ptr, irb->current_basic_block);1373 ir_ref_instruction(container_ptr, irb->current_basic_block);
12991374
...@@ -1313,9 +1388,11 @@ static IrInstruction *ir_build_struct_field_ptr(IrBuilder *irb, Scope *scope, As...@@ -1313,9 +1388,11 @@ static IrInstruction *ir_build_struct_field_ptr(IrBuilder *irb, Scope *scope, As
1313}1388}
13141389
1315static IrInstruction *ir_build_union_field_ptr(IrBuilder *irb, Scope *scope, AstNode *source_node,1390static IrInstruction *ir_build_union_field_ptr(IrBuilder *irb, Scope *scope, AstNode *source_node,
1316 IrInstruction *union_ptr, TypeUnionField *field)1391 IrInstruction *union_ptr, TypeUnionField *field, bool safety_check_on, bool initializing)
1317{1392{
1318 IrInstructionUnionFieldPtr *instruction = ir_build_instruction<IrInstructionUnionFieldPtr>(irb, scope, source_node);1393 IrInstructionUnionFieldPtr *instruction = ir_build_instruction<IrInstructionUnionFieldPtr>(irb, scope, source_node);
1394 instruction->initializing = initializing;
1395 instruction->safety_check_on = safety_check_on;
1319 instruction->union_ptr = union_ptr;1396 instruction->union_ptr = union_ptr;
1320 instruction->field = field;1397 instruction->field = field;
13211398
...@@ -1324,12 +1401,12 @@ static IrInstruction *ir_build_union_field_ptr(IrBuilder *irb, Scope *scope, Ast...@@ -1324,12 +1401,12 @@ static IrInstruction *ir_build_union_field_ptr(IrBuilder *irb, Scope *scope, Ast
1324 return &instruction->base;1401 return &instruction->base;
1325}1402}
13261403
1327static IrInstruction *ir_build_call(IrBuilder *irb, Scope *scope, AstNode *source_node,1404static IrInstruction *ir_build_call_src(IrBuilder *irb, Scope *scope, AstNode *source_node,
1328 ZigFn *fn_entry, IrInstruction *fn_ref, size_t arg_count, IrInstruction **args,1405 ZigFn *fn_entry, IrInstruction *fn_ref, size_t arg_count, IrInstruction **args,
1329 bool is_comptime, FnInline fn_inline, bool is_async, IrInstruction *async_allocator,1406 bool is_comptime, FnInline fn_inline, bool is_async, IrInstruction *async_allocator,
1330 IrInstruction *new_stack)1407 IrInstruction *new_stack, ResultLoc *result_loc)
1331{1408{
1332 IrInstructionCall *call_instruction = ir_build_instruction<IrInstructionCall>(irb, scope, source_node);1409 IrInstructionCallSrc *call_instruction = ir_build_instruction<IrInstructionCallSrc>(irb, scope, source_node);
1333 call_instruction->fn_entry = fn_entry;1410 call_instruction->fn_entry = fn_entry;
1334 call_instruction->fn_ref = fn_ref;1411 call_instruction->fn_ref = fn_ref;
1335 call_instruction->is_comptime = is_comptime;1412 call_instruction->is_comptime = is_comptime;
...@@ -1339,6 +1416,7 @@ static IrInstruction *ir_build_call(IrBuilder *irb, Scope *scope, AstNode *sourc...@@ -1339,6 +1416,7 @@ static IrInstruction *ir_build_call(IrBuilder *irb, Scope *scope, AstNode *sourc
1339 call_instruction->is_async = is_async;1416 call_instruction->is_async = is_async;
1340 call_instruction->async_allocator = async_allocator;1417 call_instruction->async_allocator = async_allocator;
1341 call_instruction->new_stack = new_stack;1418 call_instruction->new_stack = new_stack;
1419 call_instruction->result_loc = result_loc;
13421420
1343 if (fn_ref != nullptr) ir_ref_instruction(fn_ref, irb->current_basic_block);1421 if (fn_ref != nullptr) ir_ref_instruction(fn_ref, irb->current_basic_block);
1344 for (size_t i = 0; i < arg_count; i += 1)1422 for (size_t i = 0; i < arg_count; i += 1)
...@@ -1349,8 +1427,37 @@ static IrInstruction *ir_build_call(IrBuilder *irb, Scope *scope, AstNode *sourc...@@ -1349,8 +1427,37 @@ static IrInstruction *ir_build_call(IrBuilder *irb, Scope *scope, AstNode *sourc
1349 return &call_instruction->base;1427 return &call_instruction->base;
1350}1428}
13511429
1430static IrInstruction *ir_build_call_gen(IrAnalyze *ira, IrInstruction *source_instruction,
1431 ZigFn *fn_entry, IrInstruction *fn_ref, size_t arg_count, IrInstruction **args,
1432 FnInline fn_inline, bool is_async, IrInstruction *async_allocator, IrInstruction *new_stack,
1433 IrInstruction *result_loc, ZigType *return_type)
1434{
1435 IrInstructionCallGen *call_instruction = ir_build_instruction<IrInstructionCallGen>(&ira->new_irb,
1436 source_instruction->scope, source_instruction->source_node);
1437 call_instruction->base.value.type = return_type;
1438 call_instruction->fn_entry = fn_entry;
1439 call_instruction->fn_ref = fn_ref;
1440 call_instruction->fn_inline = fn_inline;
1441 call_instruction->args = args;
1442 call_instruction->arg_count = arg_count;
1443 call_instruction->is_async = is_async;
1444 call_instruction->async_allocator = async_allocator;
1445 call_instruction->new_stack = new_stack;
1446 call_instruction->result_loc = result_loc;
1447
1448 if (fn_ref != nullptr) ir_ref_instruction(fn_ref, ira->new_irb.current_basic_block);
1449 for (size_t i = 0; i < arg_count; i += 1)
1450 ir_ref_instruction(args[i], ira->new_irb.current_basic_block);
1451 if (async_allocator != nullptr) ir_ref_instruction(async_allocator, ira->new_irb.current_basic_block);
1452 if (new_stack != nullptr) ir_ref_instruction(new_stack, ira->new_irb.current_basic_block);
1453 if (result_loc != nullptr) ir_ref_instruction(result_loc, ira->new_irb.current_basic_block);
1454
1455 return &call_instruction->base;
1456}
1457
1352static IrInstruction *ir_build_phi(IrBuilder *irb, Scope *scope, AstNode *source_node,1458static IrInstruction *ir_build_phi(IrBuilder *irb, Scope *scope, AstNode *source_node,
1353 size_t incoming_count, IrBasicBlock **incoming_blocks, IrInstruction **incoming_values)1459 size_t incoming_count, IrBasicBlock **incoming_blocks, IrInstruction **incoming_values,
1460 ResultLocPeerParent *peer_parent)
1354{1461{
1355 assert(incoming_count != 0);1462 assert(incoming_count != 0);
1356 assert(incoming_count != SIZE_MAX);1463 assert(incoming_count != SIZE_MAX);
...@@ -1359,6 +1466,7 @@ static IrInstruction *ir_build_phi(IrBuilder *irb, Scope *scope, AstNode *source...@@ -1359,6 +1466,7 @@ static IrInstruction *ir_build_phi(IrBuilder *irb, Scope *scope, AstNode *source
1359 phi_instruction->incoming_count = incoming_count;1466 phi_instruction->incoming_count = incoming_count;
1360 phi_instruction->incoming_blocks = incoming_blocks;1467 phi_instruction->incoming_blocks = incoming_blocks;
1361 phi_instruction->incoming_values = incoming_values;1468 phi_instruction->incoming_values = incoming_values;
1469 phi_instruction->peer_parent = peer_parent;
13621470
1363 for (size_t i = 0; i < incoming_count; i += 1) {1471 for (size_t i = 0; i < incoming_count; i += 1) {
1364 ir_ref_bb(incoming_blocks[i]);1472 ir_ref_bb(incoming_blocks[i]);
...@@ -1412,12 +1520,13 @@ static IrInstruction *ir_build_ptr_type(IrBuilder *irb, Scope *scope, AstNode *s...@@ -1412,12 +1520,13 @@ static IrInstruction *ir_build_ptr_type(IrBuilder *irb, Scope *scope, AstNode *s
1412}1520}
14131521
1414static IrInstruction *ir_build_un_op_lval(IrBuilder *irb, Scope *scope, AstNode *source_node, IrUnOp op_id,1522static IrInstruction *ir_build_un_op_lval(IrBuilder *irb, Scope *scope, AstNode *source_node, IrUnOp op_id,
1415 IrInstruction *value, LVal lval)1523 IrInstruction *value, LVal lval, ResultLoc *result_loc)
1416{1524{
1417 IrInstructionUnOp *instruction = ir_build_instruction<IrInstructionUnOp>(irb, scope, source_node);1525 IrInstructionUnOp *instruction = ir_build_instruction<IrInstructionUnOp>(irb, scope, source_node);
1418 instruction->op_id = op_id;1526 instruction->op_id = op_id;
1419 instruction->value = value;1527 instruction->value = value;
1420 instruction->lval = lval;1528 instruction->lval = lval;
1529 instruction->result_loc = result_loc;
14211530
1422 ir_ref_instruction(value, irb->current_basic_block);1531 ir_ref_instruction(value, irb->current_basic_block);
14231532
...@@ -1427,72 +1536,49 @@ static IrInstruction *ir_build_un_op_lval(IrBuilder *irb, Scope *scope, AstNode...@@ -1427,72 +1536,49 @@ static IrInstruction *ir_build_un_op_lval(IrBuilder *irb, Scope *scope, AstNode
1427static IrInstruction *ir_build_un_op(IrBuilder *irb, Scope *scope, AstNode *source_node, IrUnOp op_id,1536static IrInstruction *ir_build_un_op(IrBuilder *irb, Scope *scope, AstNode *source_node, IrUnOp op_id,
1428 IrInstruction *value)1537 IrInstruction *value)
1429{1538{
1430 return ir_build_un_op_lval(irb, scope, source_node, op_id, value, LValNone);1539 return ir_build_un_op_lval(irb, scope, source_node, op_id, value, LValNone, nullptr);
1431}1540}
14321541
1433static IrInstruction *ir_build_container_init_list(IrBuilder *irb, Scope *scope, AstNode *source_node,1542static IrInstruction *ir_build_container_init_list(IrBuilder *irb, Scope *scope, AstNode *source_node,
1434 IrInstruction *container_type, IrInstruction *elem_type, size_t item_count, IrInstruction **items)1543 IrInstruction *container_type, size_t item_count, IrInstruction **elem_result_loc_list,
1544 IrInstruction *result_loc)
1435{1545{
1436 IrInstructionContainerInitList *container_init_list_instruction =1546 IrInstructionContainerInitList *container_init_list_instruction =
1437 ir_build_instruction<IrInstructionContainerInitList>(irb, scope, source_node);1547 ir_build_instruction<IrInstructionContainerInitList>(irb, scope, source_node);
1438 container_init_list_instruction->container_type = container_type;1548 container_init_list_instruction->container_type = container_type;
1439 container_init_list_instruction->elem_type = elem_type;
1440 container_init_list_instruction->item_count = item_count;1549 container_init_list_instruction->item_count = item_count;
1441 container_init_list_instruction->items = items;1550 container_init_list_instruction->elem_result_loc_list = elem_result_loc_list;
1551 container_init_list_instruction->result_loc = result_loc;
14421552
1443 if (container_type != nullptr) ir_ref_instruction(container_type, irb->current_basic_block);1553 ir_ref_instruction(container_type, irb->current_basic_block);
1444 if (elem_type != nullptr) ir_ref_instruction(elem_type, irb->current_basic_block);
1445 for (size_t i = 0; i < item_count; i += 1) {1554 for (size_t i = 0; i < item_count; i += 1) {
1446 ir_ref_instruction(items[i], irb->current_basic_block);1555 ir_ref_instruction(elem_result_loc_list[i], irb->current_basic_block);
1447 }1556 }
1557 if (result_loc != nullptr) ir_ref_instruction(result_loc, irb->current_basic_block);
14481558
1449 return &container_init_list_instruction->base;1559 return &container_init_list_instruction->base;
1450}1560}
14511561
1452static IrInstruction *ir_build_container_init_fields(IrBuilder *irb, Scope *scope, AstNode *source_node,1562static IrInstruction *ir_build_container_init_fields(IrBuilder *irb, Scope *scope, AstNode *source_node,
1453 IrInstruction *container_type, size_t field_count, IrInstructionContainerInitFieldsField *fields)1563 IrInstruction *container_type, size_t field_count, IrInstructionContainerInitFieldsField *fields,
1564 IrInstruction *result_loc)
1454{1565{
1455 IrInstructionContainerInitFields *container_init_fields_instruction =1566 IrInstructionContainerInitFields *container_init_fields_instruction =
1456 ir_build_instruction<IrInstructionContainerInitFields>(irb, scope, source_node);1567 ir_build_instruction<IrInstructionContainerInitFields>(irb, scope, source_node);
1457 container_init_fields_instruction->container_type = container_type;1568 container_init_fields_instruction->container_type = container_type;
1458 container_init_fields_instruction->field_count = field_count;1569 container_init_fields_instruction->field_count = field_count;
1459 container_init_fields_instruction->fields = fields;1570 container_init_fields_instruction->fields = fields;
1571 container_init_fields_instruction->result_loc = result_loc;
14601572
1461 ir_ref_instruction(container_type, irb->current_basic_block);1573 ir_ref_instruction(container_type, irb->current_basic_block);
1462 for (size_t i = 0; i < field_count; i += 1) {1574 for (size_t i = 0; i < field_count; i += 1) {
1463 ir_ref_instruction(fields[i].value, irb->current_basic_block);1575 ir_ref_instruction(fields[i].result_loc, irb->current_basic_block);
1464 }1576 }
1577 if (result_loc != nullptr) ir_ref_instruction(result_loc, irb->current_basic_block);
14651578
1466 return &container_init_fields_instruction->base;1579 return &container_init_fields_instruction->base;
1467}1580}
14681581
1469static IrInstruction *ir_build_struct_init(IrBuilder *irb, Scope *scope, AstNode *source_node,
1470 ZigType *struct_type, size_t field_count, IrInstructionStructInitField *fields)
1471{
1472 IrInstructionStructInit *struct_init_instruction = ir_build_instruction<IrInstructionStructInit>(irb, scope, source_node);
1473 struct_init_instruction->struct_type = struct_type;
1474 struct_init_instruction->field_count = field_count;
1475 struct_init_instruction->fields = fields;
1476
1477 for (size_t i = 0; i < field_count; i += 1)
1478 ir_ref_instruction(fields[i].value, irb->current_basic_block);
1479
1480 return &struct_init_instruction->base;
1481}
1482
1483static IrInstruction *ir_build_union_init(IrBuilder *irb, Scope *scope, AstNode *source_node,
1484 ZigType *union_type, TypeUnionField *field, IrInstruction *init_value)
1485{
1486 IrInstructionUnionInit *union_init_instruction = ir_build_instruction<IrInstructionUnionInit>(irb, scope, source_node);
1487 union_init_instruction->union_type = union_type;
1488 union_init_instruction->field = field;
1489 union_init_instruction->init_value = init_value;
1490
1491 ir_ref_instruction(init_value, irb->current_basic_block);
1492
1493 return &union_init_instruction->base;
1494}
1495
1496static IrInstruction *ir_build_unreachable(IrBuilder *irb, Scope *scope, AstNode *source_node) {1582static IrInstruction *ir_build_unreachable(IrBuilder *irb, Scope *scope, AstNode *source_node) {
1497 IrInstructionUnreachable *unreachable_instruction =1583 IrInstructionUnreachable *unreachable_instruction =
1498 ir_build_instruction<IrInstructionUnreachable>(irb, scope, source_node);1584 ir_build_instruction<IrInstructionUnreachable>(irb, scope, source_node);
...@@ -1517,47 +1603,47 @@ static IrInstruction *ir_build_store_ptr(IrBuilder *irb, Scope *scope, AstNode *...@@ -1517,47 +1603,47 @@ static IrInstruction *ir_build_store_ptr(IrBuilder *irb, Scope *scope, AstNode *
1517}1603}
15181604
1519static IrInstruction *ir_build_var_decl_src(IrBuilder *irb, Scope *scope, AstNode *source_node,1605static IrInstruction *ir_build_var_decl_src(IrBuilder *irb, Scope *scope, AstNode *source_node,
1520 ZigVar *var, IrInstruction *var_type, IrInstruction *align_value, IrInstruction *init_value)1606 ZigVar *var, IrInstruction *align_value, IrInstruction *ptr)
1521{1607{
1522 IrInstructionDeclVarSrc *decl_var_instruction = ir_build_instruction<IrInstructionDeclVarSrc>(irb, scope, source_node);1608 IrInstructionDeclVarSrc *decl_var_instruction = ir_build_instruction<IrInstructionDeclVarSrc>(irb, scope, source_node);
1523 decl_var_instruction->base.value.special = ConstValSpecialStatic;1609 decl_var_instruction->base.value.special = ConstValSpecialStatic;
1524 decl_var_instruction->base.value.type = irb->codegen->builtin_types.entry_void;1610 decl_var_instruction->base.value.type = irb->codegen->builtin_types.entry_void;
1525 decl_var_instruction->var = var;1611 decl_var_instruction->var = var;
1526 decl_var_instruction->var_type = var_type;
1527 decl_var_instruction->align_value = align_value;1612 decl_var_instruction->align_value = align_value;
1528 decl_var_instruction->init_value = init_value;1613 decl_var_instruction->ptr = ptr;
15291614
1530 if (var_type != nullptr) ir_ref_instruction(var_type, irb->current_basic_block);
1531 if (align_value != nullptr) ir_ref_instruction(align_value, irb->current_basic_block);1615 if (align_value != nullptr) ir_ref_instruction(align_value, irb->current_basic_block);
1532 ir_ref_instruction(init_value, irb->current_basic_block);1616 ir_ref_instruction(ptr, irb->current_basic_block);
15331617
1534 return &decl_var_instruction->base;1618 return &decl_var_instruction->base;
1535}1619}
15361620
1537static IrInstruction *ir_build_var_decl_gen(IrAnalyze *ira, IrInstruction *source_instruction,1621static IrInstruction *ir_build_var_decl_gen(IrAnalyze *ira, IrInstruction *source_instruction,
1538 ZigVar *var, IrInstruction *init_value)1622 ZigVar *var, IrInstruction *var_ptr)
1539{1623{
1540 IrInstructionDeclVarGen *decl_var_instruction = ir_build_instruction<IrInstructionDeclVarGen>(&ira->new_irb,1624 IrInstructionDeclVarGen *decl_var_instruction = ir_build_instruction<IrInstructionDeclVarGen>(&ira->new_irb,
1541 source_instruction->scope, source_instruction->source_node);1625 source_instruction->scope, source_instruction->source_node);
1542 decl_var_instruction->base.value.special = ConstValSpecialStatic;1626 decl_var_instruction->base.value.special = ConstValSpecialStatic;
1543 decl_var_instruction->base.value.type = ira->codegen->builtin_types.entry_void;1627 decl_var_instruction->base.value.type = ira->codegen->builtin_types.entry_void;
1544 decl_var_instruction->var = var;1628 decl_var_instruction->var = var;
1545 decl_var_instruction->init_value = init_value;1629 decl_var_instruction->var_ptr = var_ptr;
15461630
1547 ir_ref_instruction(init_value, ira->new_irb.current_basic_block);1631 ir_ref_instruction(var_ptr, ira->new_irb.current_basic_block);
15481632
1549 return &decl_var_instruction->base;1633 return &decl_var_instruction->base;
1550}1634}
15511635
1552static IrInstruction *ir_build_resize_slice(IrAnalyze *ira, IrInstruction *source_instruction,1636static IrInstruction *ir_build_resize_slice(IrAnalyze *ira, IrInstruction *source_instruction,
1553 IrInstruction *operand, ZigType *ty)1637 IrInstruction *operand, ZigType *ty, IrInstruction *result_loc)
1554{1638{
1555 IrInstructionResizeSlice *instruction = ir_build_instruction<IrInstructionResizeSlice>(&ira->new_irb,1639 IrInstructionResizeSlice *instruction = ir_build_instruction<IrInstructionResizeSlice>(&ira->new_irb,
1556 source_instruction->scope, source_instruction->source_node);1640 source_instruction->scope, source_instruction->source_node);
1557 instruction->base.value.type = ty;1641 instruction->base.value.type = ty;
1558 instruction->operand = operand;1642 instruction->operand = operand;
1643 instruction->result_loc = result_loc;
15591644
1560 ir_ref_instruction(operand, ira->new_irb.current_basic_block);1645 ir_ref_instruction(operand, ira->new_irb.current_basic_block);
1646 ir_ref_instruction(result_loc, ira->new_irb.current_basic_block);
15611647
1562 return &instruction->base;1648 return &instruction->base;
1563}1649}
...@@ -1598,27 +1684,6 @@ static IrInstruction *ir_build_typeof(IrBuilder *irb, Scope *scope, AstNode *sou...@@ -1598,27 +1684,6 @@ static IrInstruction *ir_build_typeof(IrBuilder *irb, Scope *scope, AstNode *sou
1598 return &instruction->base;1684 return &instruction->base;
1599}1685}
16001686
1601static IrInstruction *ir_build_to_ptr_type(IrBuilder *irb, Scope *scope, AstNode *source_node, IrInstruction *ptr) {
1602 IrInstructionToPtrType *instruction = ir_build_instruction<IrInstructionToPtrType>(irb, scope, source_node);
1603 instruction->ptr = ptr;
1604
1605 ir_ref_instruction(ptr, irb->current_basic_block);
1606
1607 return &instruction->base;
1608}
1609
1610static IrInstruction *ir_build_ptr_type_child(IrBuilder *irb, Scope *scope, AstNode *source_node,
1611 IrInstruction *value)
1612{
1613 IrInstructionPtrTypeChild *instruction = ir_build_instruction<IrInstructionPtrTypeChild>(
1614 irb, scope, source_node);
1615 instruction->value = value;
1616
1617 ir_ref_instruction(value, irb->current_basic_block);
1618
1619 return &instruction->base;
1620}
1621
1622static IrInstruction *ir_build_set_cold(IrBuilder *irb, Scope *scope, AstNode *source_node, IrInstruction *is_cold) {1687static IrInstruction *ir_build_set_cold(IrBuilder *irb, Scope *scope, AstNode *source_node, IrInstruction *is_cold) {
1623 IrInstructionSetCold *instruction = ir_build_instruction<IrInstructionSetCold>(irb, scope, source_node);1688 IrInstructionSetCold *instruction = ir_build_instruction<IrInstructionSetCold>(irb, scope, source_node);
1624 instruction->is_cold = is_cold;1689 instruction->is_cold = is_cold;
...@@ -1744,40 +1809,59 @@ static IrInstruction *ir_build_test_nonnull(IrBuilder *irb, Scope *scope, AstNod...@@ -1744,40 +1809,59 @@ static IrInstruction *ir_build_test_nonnull(IrBuilder *irb, Scope *scope, AstNod
1744}1809}
17451810
1746static IrInstruction *ir_build_optional_unwrap_ptr(IrBuilder *irb, Scope *scope, AstNode *source_node,1811static IrInstruction *ir_build_optional_unwrap_ptr(IrBuilder *irb, Scope *scope, AstNode *source_node,
1747 IrInstruction *base_ptr, bool safety_check_on)1812 IrInstruction *base_ptr, bool safety_check_on, bool initializing)
1748{1813{
1749 IrInstructionOptionalUnwrapPtr *instruction = ir_build_instruction<IrInstructionOptionalUnwrapPtr>(irb, scope, source_node);1814 IrInstructionOptionalUnwrapPtr *instruction = ir_build_instruction<IrInstructionOptionalUnwrapPtr>(irb, scope, source_node);
1750 instruction->base_ptr = base_ptr;1815 instruction->base_ptr = base_ptr;
1751 instruction->safety_check_on = safety_check_on;1816 instruction->safety_check_on = safety_check_on;
1817 instruction->initializing = initializing;
17521818
1753 ir_ref_instruction(base_ptr, irb->current_basic_block);1819 ir_ref_instruction(base_ptr, irb->current_basic_block);
17541820
1755 return &instruction->base;1821 return &instruction->base;
1756}1822}
17571823
1758static IrInstruction *ir_build_maybe_wrap(IrBuilder *irb, Scope *scope, AstNode *source_node, IrInstruction *value) {1824static IrInstruction *ir_build_optional_wrap(IrAnalyze *ira, IrInstruction *source_instruction, ZigType *result_ty,
1759 IrInstructionOptionalWrap *instruction = ir_build_instruction<IrInstructionOptionalWrap>(irb, scope, source_node);1825 IrInstruction *operand, IrInstruction *result_loc)
1760 instruction->value = value;1826{
1827 IrInstructionOptionalWrap *instruction = ir_build_instruction<IrInstructionOptionalWrap>(
1828 &ira->new_irb, source_instruction->scope, source_instruction->source_node);
1829 instruction->base.value.type = result_ty;
1830 instruction->operand = operand;
1831 instruction->result_loc = result_loc;
17611832
1762 ir_ref_instruction(value, irb->current_basic_block);1833 ir_ref_instruction(operand, ira->new_irb.current_basic_block);
1834 if (result_loc != nullptr) ir_ref_instruction(result_loc, ira->new_irb.current_basic_block);
17631835
1764 return &instruction->base;1836 return &instruction->base;
1765}1837}
17661838
1767static IrInstruction *ir_build_err_wrap_payload(IrBuilder *irb, Scope *scope, AstNode *source_node, IrInstruction *value) {1839static IrInstruction *ir_build_err_wrap_payload(IrAnalyze *ira, IrInstruction *source_instruction,
1768 IrInstructionErrWrapPayload *instruction = ir_build_instruction<IrInstructionErrWrapPayload>(irb, scope, source_node);1840 ZigType *result_type, IrInstruction *operand, IrInstruction *result_loc)
1769 instruction->value = value;1841{
1842 IrInstructionErrWrapPayload *instruction = ir_build_instruction<IrInstructionErrWrapPayload>(
1843 &ira->new_irb, source_instruction->scope, source_instruction->source_node);
1844 instruction->base.value.type = result_type;
1845 instruction->operand = operand;
1846 instruction->result_loc = result_loc;
17701847
1771 ir_ref_instruction(value, irb->current_basic_block);1848 ir_ref_instruction(operand, ira->new_irb.current_basic_block);
1849 if (result_loc != nullptr) ir_ref_instruction(result_loc, ira->new_irb.current_basic_block);
17721850
1773 return &instruction->base;1851 return &instruction->base;
1774}1852}
17751853
1776static IrInstruction *ir_build_err_wrap_code(IrBuilder *irb, Scope *scope, AstNode *source_node, IrInstruction *value) {1854static IrInstruction *ir_build_err_wrap_code(IrAnalyze *ira, IrInstruction *source_instruction,
1777 IrInstructionErrWrapCode *instruction = ir_build_instruction<IrInstructionErrWrapCode>(irb, scope, source_node);1855 ZigType *result_type, IrInstruction *operand, IrInstruction *result_loc)
1778 instruction->value = value;1856{
1857 IrInstructionErrWrapCode *instruction = ir_build_instruction<IrInstructionErrWrapCode>(
1858 &ira->new_irb, source_instruction->scope, source_instruction->source_node);
1859 instruction->base.value.type = result_type;
1860 instruction->operand = operand;
1861 instruction->result_loc = result_loc;
17791862
1780 ir_ref_instruction(value, irb->current_basic_block);1863 ir_ref_instruction(operand, ira->new_irb.current_basic_block);
1864 if (result_loc != nullptr) ir_ref_instruction(result_loc, ira->new_irb.current_basic_block);
17811865
1782 return &instruction->base;1866 return &instruction->base;
1783}1867}
...@@ -1934,6 +2018,21 @@ static IrInstruction *ir_build_ref(IrBuilder *irb, Scope *scope, AstNode *source...@@ -1934,6 +2018,21 @@ static IrInstruction *ir_build_ref(IrBuilder *irb, Scope *scope, AstNode *source
1934 return &instruction->base;2018 return &instruction->base;
1935}2019}
19362020
2021static IrInstruction *ir_build_ref_gen(IrAnalyze *ira, IrInstruction *source_instruction, ZigType *result_type,
2022 IrInstruction *operand, IrInstruction *result_loc)
2023{
2024 IrInstructionRefGen *instruction = ir_build_instruction<IrInstructionRefGen>(&ira->new_irb,
2025 source_instruction->scope, source_instruction->source_node);
2026 instruction->base.value.type = result_type;
2027 instruction->operand = operand;
2028 instruction->result_loc = result_loc;
2029
2030 ir_ref_instruction(operand, ira->new_irb.current_basic_block);
2031 if (result_loc != nullptr) ir_ref_instruction(result_loc, ira->new_irb.current_basic_block);
2032
2033 return &instruction->base;
2034}
2035
1937static IrInstruction *ir_build_compile_err(IrBuilder *irb, Scope *scope, AstNode *source_node, IrInstruction *msg) {2036static IrInstruction *ir_build_compile_err(IrBuilder *irb, Scope *scope, AstNode *source_node, IrInstruction *msg) {
1938 IrInstructionCompileErr *instruction = ir_build_instruction<IrInstructionCompileErr>(irb, scope, source_node);2037 IrInstructionCompileErr *instruction = ir_build_instruction<IrInstructionCompileErr>(irb, scope, source_node);
1939 instruction->msg = msg;2038 instruction->msg = msg;
...@@ -2011,8 +2110,7 @@ static IrInstruction *ir_build_embed_file(IrBuilder *irb, Scope *scope, AstNode...@@ -2011,8 +2110,7 @@ static IrInstruction *ir_build_embed_file(IrBuilder *irb, Scope *scope, AstNode
20112110
2012static IrInstruction *ir_build_cmpxchg_src(IrBuilder *irb, Scope *scope, AstNode *source_node,2111static IrInstruction *ir_build_cmpxchg_src(IrBuilder *irb, Scope *scope, AstNode *source_node,
2013 IrInstruction *type_value, IrInstruction *ptr, IrInstruction *cmp_value, IrInstruction *new_value,2112 IrInstruction *type_value, IrInstruction *ptr, IrInstruction *cmp_value, IrInstruction *new_value,
2014 IrInstruction *success_order_value, IrInstruction *failure_order_value,2113 IrInstruction *success_order_value, IrInstruction *failure_order_value, bool is_weak, ResultLoc *result_loc)
2015 bool is_weak)
2016{2114{
2017 IrInstructionCmpxchgSrc *instruction = ir_build_instruction<IrInstructionCmpxchgSrc>(irb, scope, source_node);2115 IrInstructionCmpxchgSrc *instruction = ir_build_instruction<IrInstructionCmpxchgSrc>(irb, scope, source_node);
2018 instruction->type_value = type_value;2116 instruction->type_value = type_value;
...@@ -2022,6 +2120,7 @@ static IrInstruction *ir_build_cmpxchg_src(IrBuilder *irb, Scope *scope, AstNode...@@ -2022,6 +2120,7 @@ static IrInstruction *ir_build_cmpxchg_src(IrBuilder *irb, Scope *scope, AstNode
2022 instruction->success_order_value = success_order_value;2120 instruction->success_order_value = success_order_value;
2023 instruction->failure_order_value = failure_order_value;2121 instruction->failure_order_value = failure_order_value;
2024 instruction->is_weak = is_weak;2122 instruction->is_weak = is_weak;
2123 instruction->result_loc = result_loc;
20252124
2026 ir_ref_instruction(type_value, irb->current_basic_block);2125 ir_ref_instruction(type_value, irb->current_basic_block);
2027 ir_ref_instruction(ptr, irb->current_basic_block);2126 ir_ref_instruction(ptr, irb->current_basic_block);
...@@ -2033,22 +2132,25 @@ static IrInstruction *ir_build_cmpxchg_src(IrBuilder *irb, Scope *scope, AstNode...@@ -2033,22 +2132,25 @@ static IrInstruction *ir_build_cmpxchg_src(IrBuilder *irb, Scope *scope, AstNode
2033 return &instruction->base;2132 return &instruction->base;
2034}2133}
20352134
2036static IrInstruction *ir_build_cmpxchg_gen(IrAnalyze *ira, IrInstruction *source_instruction,2135static IrInstruction *ir_build_cmpxchg_gen(IrAnalyze *ira, IrInstruction *source_instruction, ZigType *result_type,
2037 IrInstruction *ptr, IrInstruction *cmp_value, IrInstruction *new_value,2136 IrInstruction *ptr, IrInstruction *cmp_value, IrInstruction *new_value,
2038 AtomicOrder success_order, AtomicOrder failure_order, bool is_weak)2137 AtomicOrder success_order, AtomicOrder failure_order, bool is_weak, IrInstruction *result_loc)
2039{2138{
2040 IrInstructionCmpxchgGen *instruction = ir_build_instruction<IrInstructionCmpxchgGen>(&ira->new_irb,2139 IrInstructionCmpxchgGen *instruction = ir_build_instruction<IrInstructionCmpxchgGen>(&ira->new_irb,
2041 source_instruction->scope, source_instruction->source_node);2140 source_instruction->scope, source_instruction->source_node);
2141 instruction->base.value.type = result_type;
2042 instruction->ptr = ptr;2142 instruction->ptr = ptr;
2043 instruction->cmp_value = cmp_value;2143 instruction->cmp_value = cmp_value;
2044 instruction->new_value = new_value;2144 instruction->new_value = new_value;
2045 instruction->success_order = success_order;2145 instruction->success_order = success_order;
2046 instruction->failure_order = failure_order;2146 instruction->failure_order = failure_order;
2047 instruction->is_weak = is_weak;2147 instruction->is_weak = is_weak;
2148 instruction->result_loc = result_loc;
20482149
2049 ir_ref_instruction(ptr, ira->new_irb.current_basic_block);2150 ir_ref_instruction(ptr, ira->new_irb.current_basic_block);
2050 ir_ref_instruction(cmp_value, ira->new_irb.current_basic_block);2151 ir_ref_instruction(cmp_value, ira->new_irb.current_basic_block);
2051 ir_ref_instruction(new_value, ira->new_irb.current_basic_block);2152 ir_ref_instruction(new_value, ira->new_irb.current_basic_block);
2153 if (result_loc != nullptr) ir_ref_instruction(result_loc, ira->new_irb.current_basic_block);
20522154
2053 return &instruction->base;2155 return &instruction->base;
2054}2156}
...@@ -2107,19 +2209,25 @@ static IrInstruction *ir_build_err_set_cast(IrBuilder *irb, Scope *scope, AstNod...@@ -2107,19 +2209,25 @@ static IrInstruction *ir_build_err_set_cast(IrBuilder *irb, Scope *scope, AstNod
2107 return &instruction->base;2209 return &instruction->base;
2108}2210}
21092211
2110static IrInstruction *ir_build_to_bytes(IrBuilder *irb, Scope *scope, AstNode *source_node, IrInstruction *target) {2212static IrInstruction *ir_build_to_bytes(IrBuilder *irb, Scope *scope, AstNode *source_node, IrInstruction *target,
2213 ResultLoc *result_loc)
2214{
2111 IrInstructionToBytes *instruction = ir_build_instruction<IrInstructionToBytes>(irb, scope, source_node);2215 IrInstructionToBytes *instruction = ir_build_instruction<IrInstructionToBytes>(irb, scope, source_node);
2112 instruction->target = target;2216 instruction->target = target;
2217 instruction->result_loc = result_loc;
21132218
2114 ir_ref_instruction(target, irb->current_basic_block);2219 ir_ref_instruction(target, irb->current_basic_block);
21152220
2116 return &instruction->base;2221 return &instruction->base;
2117}2222}
21182223
2119static IrInstruction *ir_build_from_bytes(IrBuilder *irb, Scope *scope, AstNode *source_node, IrInstruction *dest_child_type, IrInstruction *target) {2224static IrInstruction *ir_build_from_bytes(IrBuilder *irb, Scope *scope, AstNode *source_node,
2225 IrInstruction *dest_child_type, IrInstruction *target, ResultLoc *result_loc)
2226{
2120 IrInstructionFromBytes *instruction = ir_build_instruction<IrInstructionFromBytes>(irb, scope, source_node);2227 IrInstructionFromBytes *instruction = ir_build_instruction<IrInstructionFromBytes>(irb, scope, source_node);
2121 instruction->dest_child_type = dest_child_type;2228 instruction->dest_child_type = dest_child_type;
2122 instruction->target = target;2229 instruction->target = target;
2230 instruction->result_loc = result_loc;
21232231
2124 ir_ref_instruction(dest_child_type, irb->current_basic_block);2232 ir_ref_instruction(dest_child_type, irb->current_basic_block);
2125 ir_ref_instruction(target, irb->current_basic_block);2233 ir_ref_instruction(target, irb->current_basic_block);
...@@ -2221,14 +2329,15 @@ static IrInstruction *ir_build_memcpy(IrBuilder *irb, Scope *scope, AstNode *sou...@@ -2221,14 +2329,15 @@ static IrInstruction *ir_build_memcpy(IrBuilder *irb, Scope *scope, AstNode *sou
2221 return &instruction->base;2329 return &instruction->base;
2222}2330}
22232331
2224static IrInstruction *ir_build_slice(IrBuilder *irb, Scope *scope, AstNode *source_node,2332static IrInstruction *ir_build_slice_src(IrBuilder *irb, Scope *scope, AstNode *source_node,
2225 IrInstruction *ptr, IrInstruction *start, IrInstruction *end, bool safety_check_on)2333 IrInstruction *ptr, IrInstruction *start, IrInstruction *end, bool safety_check_on, ResultLoc *result_loc)
2226{2334{
2227 IrInstructionSlice *instruction = ir_build_instruction<IrInstructionSlice>(irb, scope, source_node);2335 IrInstructionSliceSrc *instruction = ir_build_instruction<IrInstructionSliceSrc>(irb, scope, source_node);
2228 instruction->ptr = ptr;2336 instruction->ptr = ptr;
2229 instruction->start = start;2337 instruction->start = start;
2230 instruction->end = end;2338 instruction->end = end;
2231 instruction->safety_check_on = safety_check_on;2339 instruction->safety_check_on = safety_check_on;
2340 instruction->result_loc = result_loc;
22322341
2233 ir_ref_instruction(ptr, irb->current_basic_block);2342 ir_ref_instruction(ptr, irb->current_basic_block);
2234 ir_ref_instruction(start, irb->current_basic_block);2343 ir_ref_instruction(start, irb->current_basic_block);
...@@ -2237,6 +2346,26 @@ static IrInstruction *ir_build_slice(IrBuilder *irb, Scope *scope, AstNode *sour...@@ -2237,6 +2346,26 @@ static IrInstruction *ir_build_slice(IrBuilder *irb, Scope *scope, AstNode *sour
2237 return &instruction->base;2346 return &instruction->base;
2238}2347}
22392348
2349static IrInstruction *ir_build_slice_gen(IrAnalyze *ira, IrInstruction *source_instruction, ZigType *slice_type,
2350 IrInstruction *ptr, IrInstruction *start, IrInstruction *end, bool safety_check_on, IrInstruction *result_loc)
2351{
2352 IrInstructionSliceGen *instruction = ir_build_instruction<IrInstructionSliceGen>(
2353 &ira->new_irb, source_instruction->scope, source_instruction->source_node);
2354 instruction->base.value.type = slice_type;
2355 instruction->ptr = ptr;
2356 instruction->start = start;
2357 instruction->end = end;
2358 instruction->safety_check_on = safety_check_on;
2359 instruction->result_loc = result_loc;
2360
2361 ir_ref_instruction(ptr, ira->new_irb.current_basic_block);
2362 ir_ref_instruction(start, ira->new_irb.current_basic_block);
2363 if (end) ir_ref_instruction(end, ira->new_irb.current_basic_block);
2364 ir_ref_instruction(result_loc, ira->new_irb.current_basic_block);
2365
2366 return &instruction->base;
2367}
2368
2240static IrInstruction *ir_build_member_count(IrBuilder *irb, Scope *scope, AstNode *source_node, IrInstruction *container) {2369static IrInstruction *ir_build_member_count(IrBuilder *irb, Scope *scope, AstNode *source_node, IrInstruction *container) {
2241 IrInstructionMemberCount *instruction = ir_build_instruction<IrInstructionMemberCount>(irb, scope, source_node);2370 IrInstructionMemberCount *instruction = ir_build_instruction<IrInstructionMemberCount>(irb, scope, source_node);
2242 instruction->container = container;2371 instruction->container = container;
...@@ -2390,34 +2519,49 @@ static IrInstruction *ir_build_align_of(IrBuilder *irb, Scope *scope, AstNode *s...@@ -2390,34 +2519,49 @@ static IrInstruction *ir_build_align_of(IrBuilder *irb, Scope *scope, AstNode *s
2390 return &instruction->base;2519 return &instruction->base;
2391}2520}
23922521
2393static IrInstruction *ir_build_test_err(IrBuilder *irb, Scope *scope, AstNode *source_node,2522static IrInstruction *ir_build_test_err_src(IrBuilder *irb, Scope *scope, AstNode *source_node,
2394 IrInstruction *value)2523 IrInstruction *base_ptr, bool resolve_err_set)
2395{2524{
2396 IrInstructionTestErr *instruction = ir_build_instruction<IrInstructionTestErr>(irb, scope, source_node);2525 IrInstructionTestErrSrc *instruction = ir_build_instruction<IrInstructionTestErrSrc>(irb, scope, source_node);
2397 instruction->value = value;2526 instruction->base_ptr = base_ptr;
2527 instruction->resolve_err_set = resolve_err_set;
23982528
2399 ir_ref_instruction(value, irb->current_basic_block);2529 ir_ref_instruction(base_ptr, irb->current_basic_block);
24002530
2401 return &instruction->base;2531 return &instruction->base;
2402}2532}
24032533
2404static IrInstruction *ir_build_unwrap_err_code(IrBuilder *irb, Scope *scope, AstNode *source_node,2534static IrInstruction *ir_build_test_err_gen(IrAnalyze *ira, IrInstruction *source_instruction,
2405 IrInstruction *err_union)2535 IrInstruction *err_union)
2406{2536{
2407 IrInstructionUnwrapErrCode *instruction = ir_build_instruction<IrInstructionUnwrapErrCode>(irb, scope, source_node);2537 IrInstructionTestErrGen *instruction = ir_build_instruction<IrInstructionTestErrGen>(
2538 &ira->new_irb, source_instruction->scope, source_instruction->source_node);
2539 instruction->base.value.type = ira->codegen->builtin_types.entry_bool;
2408 instruction->err_union = err_union;2540 instruction->err_union = err_union;
24092541
2410 ir_ref_instruction(err_union, irb->current_basic_block);2542 ir_ref_instruction(err_union, ira->new_irb.current_basic_block);
2543
2544 return &instruction->base;
2545}
2546
2547static IrInstruction *ir_build_unwrap_err_code(IrBuilder *irb, Scope *scope, AstNode *source_node,
2548 IrInstruction *err_union_ptr)
2549{
2550 IrInstructionUnwrapErrCode *instruction = ir_build_instruction<IrInstructionUnwrapErrCode>(irb, scope, source_node);
2551 instruction->err_union_ptr = err_union_ptr;
2552
2553 ir_ref_instruction(err_union_ptr, irb->current_basic_block);
24112554
2412 return &instruction->base;2555 return &instruction->base;
2413}2556}
24142557
2415static IrInstruction *ir_build_unwrap_err_payload(IrBuilder *irb, Scope *scope, AstNode *source_node,2558static IrInstruction *ir_build_unwrap_err_payload(IrBuilder *irb, Scope *scope, AstNode *source_node,
2416 IrInstruction *value, bool safety_check_on)2559 IrInstruction *value, bool safety_check_on, bool initializing)
2417{2560{
2418 IrInstructionUnwrapErrPayload *instruction = ir_build_instruction<IrInstructionUnwrapErrPayload>(irb, scope, source_node);2561 IrInstructionUnwrapErrPayload *instruction = ir_build_instruction<IrInstructionUnwrapErrPayload>(irb, scope, source_node);
2419 instruction->value = value;2562 instruction->value = value;
2420 instruction->safety_check_on = safety_check_on;2563 instruction->safety_check_on = safety_check_on;
2564 instruction->initializing = initializing;
24212565
2422 ir_ref_instruction(value, irb->current_basic_block);2566 ir_ref_instruction(value, irb->current_basic_block);
24232567
...@@ -2487,28 +2631,28 @@ static IrInstruction *ir_build_ptr_cast_gen(IrAnalyze *ira, IrInstruction *sourc...@@ -2487,28 +2631,28 @@ static IrInstruction *ir_build_ptr_cast_gen(IrAnalyze *ira, IrInstruction *sourc
2487}2631}
24882632
2489static IrInstruction *ir_build_load_ptr_gen(IrAnalyze *ira, IrInstruction *source_instruction,2633static IrInstruction *ir_build_load_ptr_gen(IrAnalyze *ira, IrInstruction *source_instruction,
2490 IrInstruction *ptr, ZigType *ty)2634 IrInstruction *ptr, ZigType *ty, IrInstruction *result_loc)
2491{2635{
2492 IrInstructionLoadPtrGen *instruction = ir_build_instruction<IrInstructionLoadPtrGen>(2636 IrInstructionLoadPtrGen *instruction = ir_build_instruction<IrInstructionLoadPtrGen>(
2493 &ira->new_irb, source_instruction->scope, source_instruction->source_node);2637 &ira->new_irb, source_instruction->scope, source_instruction->source_node);
2494 instruction->base.value.type = ty;2638 instruction->base.value.type = ty;
2495 instruction->ptr = ptr;2639 instruction->ptr = ptr;
2640 instruction->result_loc = result_loc;
24962641
2497 ir_ref_instruction(ptr, ira->new_irb.current_basic_block);2642 ir_ref_instruction(ptr, ira->new_irb.current_basic_block);
2643 if (result_loc != nullptr) ir_ref_instruction(result_loc, ira->new_irb.current_basic_block);
24982644
2499 return &instruction->base;2645 return &instruction->base;
2500}2646}
25012647
2502static IrInstruction *ir_build_bit_cast(IrBuilder *irb, Scope *scope, AstNode *source_node,2648static IrInstruction *ir_build_bit_cast_src(IrBuilder *irb, Scope *scope, AstNode *source_node,
2503 IrInstruction *dest_type, IrInstruction *value)2649 IrInstruction *operand, ResultLocBitCast *result_loc_bit_cast)
2504{2650{
2505 IrInstructionBitCast *instruction = ir_build_instruction<IrInstructionBitCast>(2651 IrInstructionBitCastSrc *instruction = ir_build_instruction<IrInstructionBitCastSrc>(irb, scope, source_node);
2506 irb, scope, source_node);2652 instruction->operand = operand;
2507 instruction->dest_type = dest_type;2653 instruction->result_loc_bit_cast = result_loc_bit_cast;
2508 instruction->value = value;
25092654
2510 ir_ref_instruction(dest_type, irb->current_basic_block);2655 ir_ref_instruction(operand, irb->current_basic_block);
2511 ir_ref_instruction(value, irb->current_basic_block);
25122656
2513 return &instruction->base;2657 return &instruction->base;
2514}2658}
...@@ -2660,11 +2804,8 @@ static IrInstruction *ir_build_type_name(IrBuilder *irb, Scope *scope, AstNode *...@@ -2660,11 +2804,8 @@ static IrInstruction *ir_build_type_name(IrBuilder *irb, Scope *scope, AstNode *
2660 return &instruction->base;2804 return &instruction->base;
2661}2805}
26622806
2663static IrInstruction *ir_build_decl_ref(IrBuilder *irb, Scope *scope, AstNode *source_node,2807static IrInstruction *ir_build_decl_ref(IrBuilder *irb, Scope *scope, AstNode *source_node, Tld *tld, LVal lval) {
2664 Tld *tld, LVal lval)2808 IrInstructionDeclRef *instruction = ir_build_instruction<IrInstructionDeclRef>(irb, scope, source_node);
2665{
2666 IrInstructionDeclRef *instruction = ir_build_instruction<IrInstructionDeclRef>(
2667 irb, scope, source_node);
2668 instruction->tld = tld;2809 instruction->tld = tld;
2669 instruction->lval = lval;2810 instruction->lval = lval;
26702811
...@@ -2792,6 +2933,53 @@ static IrInstruction *ir_build_align_cast(IrBuilder *irb, Scope *scope, AstNode...@@ -2792,6 +2933,53 @@ static IrInstruction *ir_build_align_cast(IrBuilder *irb, Scope *scope, AstNode
2792 return &instruction->base;2933 return &instruction->base;
2793}2934}
27942935
2936static IrInstruction *ir_build_implicit_cast(IrBuilder *irb, Scope *scope, AstNode *source_node,
2937 IrInstruction *dest_type, IrInstruction *target, ResultLoc *result_loc)
2938{
2939 IrInstructionImplicitCast *instruction = ir_build_instruction<IrInstructionImplicitCast>(irb, scope, source_node);
2940 instruction->dest_type = dest_type;
2941 instruction->target = target;
2942 instruction->result_loc = result_loc;
2943
2944 ir_ref_instruction(dest_type, irb->current_basic_block);
2945 ir_ref_instruction(target, irb->current_basic_block);
2946
2947 return &instruction->base;
2948}
2949
2950static IrInstruction *ir_build_resolve_result(IrBuilder *irb, Scope *scope, AstNode *source_node,
2951 ResultLoc *result_loc, IrInstruction *ty)
2952{
2953 IrInstructionResolveResult *instruction = ir_build_instruction<IrInstructionResolveResult>(irb, scope, source_node);
2954 instruction->result_loc = result_loc;
2955 instruction->ty = ty;
2956
2957 ir_ref_instruction(ty, irb->current_basic_block);
2958
2959 return &instruction->base;
2960}
2961
2962static IrInstruction *ir_build_reset_result(IrBuilder *irb, Scope *scope, AstNode *source_node,
2963 ResultLoc *result_loc)
2964{
2965 IrInstructionResetResult *instruction = ir_build_instruction<IrInstructionResetResult>(irb, scope, source_node);
2966 instruction->result_loc = result_loc;
2967
2968 return &instruction->base;
2969}
2970
2971static IrInstruction *ir_build_result_ptr(IrBuilder *irb, Scope *scope, AstNode *source_node,
2972 ResultLoc *result_loc, IrInstruction *result)
2973{
2974 IrInstructionResultPtr *instruction = ir_build_instruction<IrInstructionResultPtr>(irb, scope, source_node);
2975 instruction->result_loc = result_loc;
2976 instruction->result = result;
2977
2978 ir_ref_instruction(result, irb->current_basic_block);
2979
2980 return &instruction->base;
2981}
2982
2795static IrInstruction *ir_build_opaque_type(IrBuilder *irb, Scope *scope, AstNode *source_node) {2983static IrInstruction *ir_build_opaque_type(IrBuilder *irb, Scope *scope, AstNode *source_node) {
2796 IrInstructionOpaqueType *instruction = ir_build_instruction<IrInstructionOpaqueType>(irb, scope, source_node);2984 IrInstructionOpaqueType *instruction = ir_build_instruction<IrInstructionOpaqueType>(irb, scope, source_node);
27972985
...@@ -3120,16 +3308,31 @@ static IrInstruction *ir_build_check_runtime_scope(IrBuilder *irb, Scope *scope,...@@ -3120,16 +3308,31 @@ static IrInstruction *ir_build_check_runtime_scope(IrBuilder *irb, Scope *scope,
3120}3308}
31213309
3122static IrInstruction *ir_build_vector_to_array(IrAnalyze *ira, IrInstruction *source_instruction,3310static IrInstruction *ir_build_vector_to_array(IrAnalyze *ira, IrInstruction *source_instruction,
3123 IrInstruction *vector, ZigType *result_type)3311 ZigType *result_type, IrInstruction *vector, IrInstruction *result_loc)
3124{3312{
3125 IrInstructionVectorToArray *instruction = ir_build_instruction<IrInstructionVectorToArray>(&ira->new_irb,3313 IrInstructionVectorToArray *instruction = ir_build_instruction<IrInstructionVectorToArray>(&ira->new_irb,
3126 source_instruction->scope, source_instruction->source_node);3314 source_instruction->scope, source_instruction->source_node);
3127 instruction->base.value.type = result_type;3315 instruction->base.value.type = result_type;
3128 instruction->vector = vector;3316 instruction->vector = vector;
3317 instruction->result_loc = result_loc;
31293318
3130 ir_ref_instruction(vector, ira->new_irb.current_basic_block);3319 ir_ref_instruction(vector, ira->new_irb.current_basic_block);
3320 ir_ref_instruction(result_loc, ira->new_irb.current_basic_block);
3321
3322 return &instruction->base;
3323}
3324
3325static IrInstruction *ir_build_ptr_of_array_to_slice(IrAnalyze *ira, IrInstruction *source_instruction,
3326 ZigType *result_type, IrInstruction *operand, IrInstruction *result_loc)
3327{
3328 IrInstructionPtrOfArrayToSlice *instruction = ir_build_instruction<IrInstructionPtrOfArrayToSlice>(&ira->new_irb,
3329 source_instruction->scope, source_instruction->source_node);
3330 instruction->base.value.type = result_type;
3331 instruction->operand = operand;
3332 instruction->result_loc = result_loc;
31313333
3132 ir_add_alloca(ira, &instruction->base, result_type);3334 ir_ref_instruction(operand, ira->new_irb.current_basic_block);
3335 ir_ref_instruction(result_loc, ira->new_irb.current_basic_block);
31333336
3134 return &instruction->base;3337 return &instruction->base;
3135}3338}
...@@ -3173,6 +3376,45 @@ static IrInstruction *ir_build_assert_non_null(IrAnalyze *ira, IrInstruction *so...@@ -3173,6 +3376,45 @@ static IrInstruction *ir_build_assert_non_null(IrAnalyze *ira, IrInstruction *so
3173 return &instruction->base;3376 return &instruction->base;
3174}3377}
31753378
3379static IrInstruction *ir_build_alloca_src(IrBuilder *irb, Scope *scope, AstNode *source_node,
3380 IrInstruction *align, const char *name_hint, IrInstruction *is_comptime)
3381{
3382 IrInstructionAllocaSrc *instruction = ir_build_instruction<IrInstructionAllocaSrc>(irb, scope, source_node);
3383 instruction->base.is_gen = true;
3384 instruction->align = align;
3385 instruction->name_hint = name_hint;
3386 instruction->is_comptime = is_comptime;
3387
3388 if (align != nullptr) ir_ref_instruction(align, irb->current_basic_block);
3389 if (is_comptime != nullptr) ir_ref_instruction(is_comptime, irb->current_basic_block);
3390
3391 return &instruction->base;
3392}
3393
3394static IrInstructionAllocaGen *ir_create_alloca_gen(IrAnalyze *ira, IrInstruction *source_instruction,
3395 uint32_t align, const char *name_hint)
3396{
3397 IrInstructionAllocaGen *instruction = ir_create_instruction<IrInstructionAllocaGen>(&ira->new_irb,
3398 source_instruction->scope, source_instruction->source_node);
3399 instruction->align = align;
3400 instruction->name_hint = name_hint;
3401
3402 return instruction;
3403}
3404
3405static IrInstruction *ir_build_end_expr(IrBuilder *irb, Scope *scope, AstNode *source_node,
3406 IrInstruction *value, ResultLoc *result_loc)
3407{
3408 IrInstructionEndExpr *instruction = ir_build_instruction<IrInstructionEndExpr>(irb, scope, source_node);
3409 instruction->base.is_gen = true;
3410 instruction->value = value;
3411 instruction->result_loc = result_loc;
3412
3413 ir_ref_instruction(value, irb->current_basic_block);
3414
3415 return &instruction->base;
3416}
3417
3176static void ir_count_defers(IrBuilder *irb, Scope *inner_scope, Scope *outer_scope, size_t *results) {3418static void ir_count_defers(IrBuilder *irb, Scope *inner_scope, Scope *outer_scope, size_t *results) {
3177 results[ReturnKindUnconditional] = 0;3419 results[ReturnKindUnconditional] = 0;
3178 results[ReturnKindError] = 0;3420 results[ReturnKindError] = 0;
...@@ -3273,6 +3515,7 @@ static void ir_set_cursor_at_end(IrBuilder *irb, IrBasicBlock *basic_block) {...@@ -3273,6 +3515,7 @@ static void ir_set_cursor_at_end(IrBuilder *irb, IrBasicBlock *basic_block) {
3273}3515}
32743516
3275static void ir_set_cursor_at_end_and_append_block(IrBuilder *irb, IrBasicBlock *basic_block) {3517static void ir_set_cursor_at_end_and_append_block(IrBuilder *irb, IrBasicBlock *basic_block) {
3518 basic_block->index = irb->exec->basic_block_list.length;
3276 irb->exec->basic_block_list.append(basic_block);3519 irb->exec->basic_block_list.append(basic_block);
3277 ir_set_cursor_at_end(irb, basic_block);3520 ir_set_cursor_at_end(irb, basic_block);
3278}3521}
...@@ -3361,7 +3604,7 @@ static IrInstruction *ir_gen_async_return(IrBuilder *irb, Scope *scope, AstNode...@@ -3361,7 +3604,7 @@ static IrInstruction *ir_gen_async_return(IrBuilder *irb, Scope *scope, AstNode
3361 return ir_build_cond_br(irb, scope, node, is_canceled_bool, irb->exec->coro_final_cleanup_block, irb->exec->coro_early_final, is_comptime);3604 return ir_build_cond_br(irb, scope, node, is_canceled_bool, irb->exec->coro_final_cleanup_block, irb->exec->coro_early_final, is_comptime);
3362}3605}
33633606
3364static IrInstruction *ir_gen_return(IrBuilder *irb, Scope *scope, AstNode *node, LVal lval) {3607static IrInstruction *ir_gen_return(IrBuilder *irb, Scope *scope, AstNode *node, LVal lval, ResultLoc *result_loc) {
3365 assert(node->type == NodeTypeReturnExpr);3608 assert(node->type == NodeTypeReturnExpr);
33663609
3367 ZigFn *fn_entry = exec_fn_entry(irb->exec);3610 ZigFn *fn_entry = exec_fn_entry(irb->exec);
...@@ -3385,12 +3628,16 @@ static IrInstruction *ir_gen_return(IrBuilder *irb, Scope *scope, AstNode *node,...@@ -3385,12 +3628,16 @@ static IrInstruction *ir_gen_return(IrBuilder *irb, Scope *scope, AstNode *node,
3385 switch (node->data.return_expr.kind) {3628 switch (node->data.return_expr.kind) {
3386 case ReturnKindUnconditional:3629 case ReturnKindUnconditional:
3387 {3630 {
3631 ResultLocReturn *result_loc_ret = allocate<ResultLocReturn>(1);
3632 result_loc_ret->base.id = ResultLocIdReturn;
3633 ir_build_reset_result(irb, scope, node, &result_loc_ret->base);
3634
3388 IrInstruction *return_value;3635 IrInstruction *return_value;
3389 if (expr_node) {3636 if (expr_node) {
3390 // Temporarily set this so that if we return a type it gets the name of the function3637 // Temporarily set this so that if we return a type it gets the name of the function
3391 ZigFn *prev_name_fn = irb->exec->name_fn;3638 ZigFn *prev_name_fn = irb->exec->name_fn;
3392 irb->exec->name_fn = exec_fn_entry(irb->exec);3639 irb->exec->name_fn = exec_fn_entry(irb->exec);
3393 return_value = ir_gen_node(irb, expr_node, scope);3640 return_value = ir_gen_node_extra(irb, expr_node, scope, LValNone, &result_loc_ret->base);
3394 irb->exec->name_fn = prev_name_fn;3641 irb->exec->name_fn = prev_name_fn;
3395 if (return_value == irb->codegen->invalid_instruction)3642 if (return_value == irb->codegen->invalid_instruction)
3396 return irb->codegen->invalid_instruction;3643 return irb->codegen->invalid_instruction;
...@@ -3408,7 +3655,9 @@ static IrInstruction *ir_gen_return(IrBuilder *irb, Scope *scope, AstNode *node,...@@ -3408,7 +3655,9 @@ static IrInstruction *ir_gen_return(IrBuilder *irb, Scope *scope, AstNode *node,
3408 ir_gen_defers_for_block(irb, scope, outer_scope, false);3655 ir_gen_defers_for_block(irb, scope, outer_scope, false);
3409 }3656 }
34103657
3411 IrInstruction *is_err = ir_build_test_err(irb, scope, node, return_value);3658 IrInstruction *ret_ptr = ir_build_result_ptr(irb, scope, node, &result_loc_ret->base,
3659 return_value);
3660 IrInstruction *is_err = ir_build_test_err_src(irb, scope, node, ret_ptr, false);
34123661
3413 bool should_inline = ir_should_inline(irb->exec, scope);3662 bool should_inline = ir_should_inline(irb->exec, scope);
3414 IrInstruction *is_comptime;3663 IrInstruction *is_comptime;
...@@ -3437,21 +3686,24 @@ static IrInstruction *ir_gen_return(IrBuilder *irb, Scope *scope, AstNode *node,...@@ -3437,21 +3686,24 @@ static IrInstruction *ir_gen_return(IrBuilder *irb, Scope *scope, AstNode *node,
3437 ir_build_br(irb, scope, node, ret_stmt_block, is_comptime);3686 ir_build_br(irb, scope, node, ret_stmt_block, is_comptime);
34383687
3439 ir_set_cursor_at_end_and_append_block(irb, ret_stmt_block);3688 ir_set_cursor_at_end_and_append_block(irb, ret_stmt_block);
3440 return ir_gen_async_return(irb, scope, node, return_value, false);3689 IrInstruction *result = ir_gen_async_return(irb, scope, node, return_value, false);
3690 result_loc_ret->base.source_instruction = result;
3691 return result;
3441 } else {3692 } else {
3442 // generate unconditional defers3693 // generate unconditional defers
3443 ir_gen_defers_for_block(irb, scope, outer_scope, false);3694 ir_gen_defers_for_block(irb, scope, outer_scope, false);
3444 return ir_gen_async_return(irb, scope, node, return_value, false);3695 IrInstruction *result = ir_gen_async_return(irb, scope, node, return_value, false);
3696 result_loc_ret->base.source_instruction = result;
3697 return result;
3445 }3698 }
3446 }3699 }
3447 case ReturnKindError:3700 case ReturnKindError:
3448 {3701 {
3449 assert(expr_node);3702 assert(expr_node);
3450 IrInstruction *err_union_ptr = ir_gen_node_extra(irb, expr_node, scope, LValPtr);3703 IrInstruction *err_union_ptr = ir_gen_node_extra(irb, expr_node, scope, LValPtr, nullptr);
3451 if (err_union_ptr == irb->codegen->invalid_instruction)3704 if (err_union_ptr == irb->codegen->invalid_instruction)
3452 return irb->codegen->invalid_instruction;3705 return irb->codegen->invalid_instruction;
3453 IrInstruction *err_union_val = ir_build_load_ptr(irb, scope, node, err_union_ptr);3706 IrInstruction *is_err_val = ir_build_test_err_src(irb, scope, node, err_union_ptr, true);
3454 IrInstruction *is_err_val = ir_build_test_err(irb, scope, node, err_union_val);
34553707
3456 IrBasicBlock *return_block = ir_create_basic_block(irb, scope, "ErrRetReturn");3708 IrBasicBlock *return_block = ir_create_basic_block(irb, scope, "ErrRetReturn");
3457 IrBasicBlock *continue_block = ir_create_basic_block(irb, scope, "ErrRetContinue");3709 IrBasicBlock *continue_block = ir_create_basic_block(irb, scope, "ErrRetContinue");
...@@ -3466,19 +3718,27 @@ static IrInstruction *ir_gen_return(IrBuilder *irb, Scope *scope, AstNode *node,...@@ -3466,19 +3718,27 @@ static IrInstruction *ir_gen_return(IrBuilder *irb, Scope *scope, AstNode *node,
34663718
3467 ir_set_cursor_at_end_and_append_block(irb, return_block);3719 ir_set_cursor_at_end_and_append_block(irb, return_block);
3468 if (!ir_gen_defers_for_block(irb, scope, outer_scope, true)) {3720 if (!ir_gen_defers_for_block(irb, scope, outer_scope, true)) {
3469 IrInstruction *err_val = ir_build_unwrap_err_code(irb, scope, node, err_union_ptr);3721 IrInstruction *err_val_ptr = ir_build_unwrap_err_code(irb, scope, node, err_union_ptr);
3722 IrInstruction *err_val = ir_build_load_ptr(irb, scope, node, err_val_ptr);
3723
3724 ResultLocReturn *result_loc_ret = allocate<ResultLocReturn>(1);
3725 result_loc_ret->base.id = ResultLocIdReturn;
3726 ir_build_reset_result(irb, scope, node, &result_loc_ret->base);
3727 ir_build_end_expr(irb, scope, node, err_val, &result_loc_ret->base);
3728
3470 if (irb->codegen->have_err_ret_tracing && !should_inline) {3729 if (irb->codegen->have_err_ret_tracing && !should_inline) {
3471 ir_build_save_err_ret_addr(irb, scope, node);3730 ir_build_save_err_ret_addr(irb, scope, node);
3472 }3731 }
3473 ir_gen_async_return(irb, scope, node, err_val, false);3732 IrInstruction *ret_inst = ir_gen_async_return(irb, scope, node, err_val, false);
3733 result_loc_ret->base.source_instruction = ret_inst;
3474 }3734 }
34753735
3476 ir_set_cursor_at_end_and_append_block(irb, continue_block);3736 ir_set_cursor_at_end_and_append_block(irb, continue_block);
3477 IrInstruction *unwrapped_ptr = ir_build_unwrap_err_payload(irb, scope, node, err_union_ptr, false);3737 IrInstruction *unwrapped_ptr = ir_build_unwrap_err_payload(irb, scope, node, err_union_ptr, false, false);
3478 if (lval == LValPtr)3738 if (lval == LValPtr)
3479 return unwrapped_ptr;3739 return unwrapped_ptr;
3480 else3740 else
3481 return ir_build_load_ptr(irb, scope, node, unwrapped_ptr);3741 return ir_expr_wrap(irb, scope, ir_build_load_ptr(irb, scope, node, unwrapped_ptr), result_loc);
3482 }3742 }
3483 }3743 }
3484 zig_unreachable();3744 zig_unreachable();
...@@ -3562,7 +3822,17 @@ static ZigVar *ir_create_var(IrBuilder *irb, AstNode *node, Scope *scope, Buf *n...@@ -3562,7 +3822,17 @@ static ZigVar *ir_create_var(IrBuilder *irb, AstNode *node, Scope *scope, Buf *n
3562 return var;3822 return var;
3563}3823}
35643824
3565static IrInstruction *ir_gen_block(IrBuilder *irb, Scope *parent_scope, AstNode *block_node) {3825static ResultLocPeer *create_peer_result(ResultLocPeerParent *peer_parent) {
3826 ResultLocPeer *result = allocate<ResultLocPeer>(1);
3827 result->base.id = ResultLocIdPeer;
3828 result->base.source_instruction = peer_parent->base.source_instruction;
3829 result->parent = peer_parent;
3830 return result;
3831}
3832
3833static IrInstruction *ir_gen_block(IrBuilder *irb, Scope *parent_scope, AstNode *block_node, LVal lval,
3834 ResultLoc *result_loc)
3835{
3566 assert(block_node->type == NodeTypeBlock);3836 assert(block_node->type == NodeTypeBlock);
35673837
3568 ZigList<IrInstruction *> incoming_values = {0};3838 ZigList<IrInstruction *> incoming_values = {0};
...@@ -3580,15 +3850,24 @@ static IrInstruction *ir_gen_block(IrBuilder *irb, Scope *parent_scope, AstNode...@@ -3580,15 +3850,24 @@ static IrInstruction *ir_gen_block(IrBuilder *irb, Scope *parent_scope, AstNode
35803850
3581 if (block_node->data.block.statements.length == 0) {3851 if (block_node->data.block.statements.length == 0) {
3582 // {}3852 // {}
3583 return ir_build_const_void(irb, child_scope, block_node);3853 return ir_lval_wrap(irb, parent_scope, ir_build_const_void(irb, child_scope, block_node), lval, result_loc);
3584 }3854 }
35853855
3586 if (block_node->data.block.name != nullptr) {3856 if (block_node->data.block.name != nullptr) {
3857 scope_block->lval = lval;
3587 scope_block->incoming_blocks = &incoming_blocks;3858 scope_block->incoming_blocks = &incoming_blocks;
3588 scope_block->incoming_values = &incoming_values;3859 scope_block->incoming_values = &incoming_values;
3589 scope_block->end_block = ir_create_basic_block(irb, parent_scope, "BlockEnd");3860 scope_block->end_block = ir_create_basic_block(irb, parent_scope, "BlockEnd");
3590 scope_block->is_comptime = ir_build_const_bool(irb, parent_scope, block_node,3861 scope_block->is_comptime = ir_build_const_bool(irb, parent_scope, block_node,
3591 ir_should_inline(irb->exec, parent_scope));3862 ir_should_inline(irb->exec, parent_scope));
3863
3864 scope_block->peer_parent = allocate<ResultLocPeerParent>(1);
3865 scope_block->peer_parent->base.id = ResultLocIdPeerParent;
3866 scope_block->peer_parent->base.source_instruction = scope_block->is_comptime;
3867 scope_block->peer_parent->end_bb = scope_block->end_block;
3868 scope_block->peer_parent->is_comptime = scope_block->is_comptime;
3869 scope_block->peer_parent->parent = result_loc;
3870 ir_build_reset_result(irb, parent_scope, block_node, &scope_block->peer_parent->base);
3592 }3871 }
35933872
3594 bool is_continuation_unreachable = false;3873 bool is_continuation_unreachable = false;
...@@ -3602,6 +3881,8 @@ static IrInstruction *ir_gen_block(IrBuilder *irb, Scope *parent_scope, AstNode...@@ -3602,6 +3881,8 @@ static IrInstruction *ir_gen_block(IrBuilder *irb, Scope *parent_scope, AstNode
3602 // keep the last noreturn statement value around in case we need to return it3881 // keep the last noreturn statement value around in case we need to return it
3603 noreturn_return_value = statement_value;3882 noreturn_return_value = statement_value;
3604 }3883 }
3884 // This logic must be kept in sync with
3885 // [STMT_EXPR_TEST_THING] <--- (search this token)
3605 if (statement_node->type == NodeTypeDefer && statement_value != irb->codegen->invalid_instruction) {3886 if (statement_node->type == NodeTypeDefer && statement_value != irb->codegen->invalid_instruction) {
3606 // defer starts a new scope3887 // defer starts a new scope
3607 child_scope = statement_node->data.defer.child_scope;3888 child_scope = statement_node->data.defer.child_scope;
...@@ -3622,21 +3903,41 @@ static IrInstruction *ir_gen_block(IrBuilder *irb, Scope *parent_scope, AstNode...@@ -3622,21 +3903,41 @@ static IrInstruction *ir_gen_block(IrBuilder *irb, Scope *parent_scope, AstNode
3622 return noreturn_return_value;3903 return noreturn_return_value;
3623 }3904 }
36243905
3906 if (scope_block->peer_parent != nullptr && scope_block->peer_parent->peers.length != 0) {
3907 scope_block->peer_parent->peers.last()->next_bb = scope_block->end_block;
3908 }
3625 ir_set_cursor_at_end_and_append_block(irb, scope_block->end_block);3909 ir_set_cursor_at_end_and_append_block(irb, scope_block->end_block);
3626 return ir_build_phi(irb, parent_scope, block_node, incoming_blocks.length, incoming_blocks.items, incoming_values.items);3910 IrInstruction *phi = ir_build_phi(irb, parent_scope, block_node, incoming_blocks.length,
3911 incoming_blocks.items, incoming_values.items, scope_block->peer_parent);
3912 return ir_expr_wrap(irb, parent_scope, phi, result_loc);
3627 } else {3913 } else {
3628 incoming_blocks.append(irb->current_basic_block);3914 incoming_blocks.append(irb->current_basic_block);
3629 incoming_values.append(ir_mark_gen(ir_build_const_void(irb, parent_scope, block_node)));3915 IrInstruction *else_expr_result = ir_mark_gen(ir_build_const_void(irb, parent_scope, block_node));
3916
3917 if (scope_block->peer_parent != nullptr) {
3918 ResultLocPeer *peer_result = create_peer_result(scope_block->peer_parent);
3919 scope_block->peer_parent->peers.append(peer_result);
3920 ir_build_end_expr(irb, parent_scope, block_node, else_expr_result, &peer_result->base);
3921
3922 if (scope_block->peer_parent->peers.length != 0) {
3923 scope_block->peer_parent->peers.last()->next_bb = scope_block->end_block;
3924 }
3925 }
3926
3927 incoming_values.append(else_expr_result);
3630 }3928 }
36313929
3632 if (block_node->data.block.name != nullptr) {3930 if (block_node->data.block.name != nullptr) {
3633 ir_gen_defers_for_block(irb, child_scope, outer_block_scope, false);3931 ir_gen_defers_for_block(irb, child_scope, outer_block_scope, false);
3634 ir_mark_gen(ir_build_br(irb, parent_scope, block_node, scope_block->end_block, scope_block->is_comptime));3932 ir_mark_gen(ir_build_br(irb, parent_scope, block_node, scope_block->end_block, scope_block->is_comptime));
3635 ir_set_cursor_at_end_and_append_block(irb, scope_block->end_block);3933 ir_set_cursor_at_end_and_append_block(irb, scope_block->end_block);
3636 return ir_build_phi(irb, parent_scope, block_node, incoming_blocks.length, incoming_blocks.items, incoming_values.items);3934 IrInstruction *phi = ir_build_phi(irb, parent_scope, block_node, incoming_blocks.length,
3935 incoming_blocks.items, incoming_values.items, scope_block->peer_parent);
3936 return ir_expr_wrap(irb, parent_scope, phi, result_loc);
3637 } else {3937 } else {
3638 ir_gen_defers_for_block(irb, child_scope, outer_block_scope, false);3938 ir_gen_defers_for_block(irb, child_scope, outer_block_scope, false);
3639 return ir_mark_gen(ir_mark_gen(ir_build_const_void(irb, child_scope, block_node)));3939 IrInstruction *void_inst = ir_mark_gen(ir_build_const_void(irb, child_scope, block_node));
3940 return ir_lval_wrap(irb, parent_scope, void_inst, lval, result_loc);
3640 }3941 }
3641}3942}
36423943
...@@ -3656,7 +3957,7 @@ static IrInstruction *ir_gen_bin_op_id(IrBuilder *irb, Scope *scope, AstNode *no...@@ -3656,7 +3957,7 @@ static IrInstruction *ir_gen_bin_op_id(IrBuilder *irb, Scope *scope, AstNode *no
3656}3957}
36573958
3658static IrInstruction *ir_gen_assign(IrBuilder *irb, Scope *scope, AstNode *node) {3959static IrInstruction *ir_gen_assign(IrBuilder *irb, Scope *scope, AstNode *node) {
3659 IrInstruction *lvalue = ir_gen_node_extra(irb, node->data.bin_op_expr.op1, scope, LValPtr);3960 IrInstruction *lvalue = ir_gen_node_extra(irb, node->data.bin_op_expr.op1, scope, LValPtr, nullptr);
3660 IrInstruction *rvalue = ir_gen_node(irb, node->data.bin_op_expr.op2, scope);3961 IrInstruction *rvalue = ir_gen_node(irb, node->data.bin_op_expr.op2, scope);
36613962
3662 if (lvalue == irb->codegen->invalid_instruction || rvalue == irb->codegen->invalid_instruction)3963 if (lvalue == irb->codegen->invalid_instruction || rvalue == irb->codegen->invalid_instruction)
...@@ -3667,7 +3968,7 @@ static IrInstruction *ir_gen_assign(IrBuilder *irb, Scope *scope, AstNode *node)...@@ -3667,7 +3968,7 @@ static IrInstruction *ir_gen_assign(IrBuilder *irb, Scope *scope, AstNode *node)
3667}3968}
36683969
3669static IrInstruction *ir_gen_assign_op(IrBuilder *irb, Scope *scope, AstNode *node, IrBinOp op_id) {3970static IrInstruction *ir_gen_assign_op(IrBuilder *irb, Scope *scope, AstNode *node, IrBinOp op_id) {
3670 IrInstruction *lvalue = ir_gen_node_extra(irb, node->data.bin_op_expr.op1, scope, LValPtr);3971 IrInstruction *lvalue = ir_gen_node_extra(irb, node->data.bin_op_expr.op1, scope, LValPtr, nullptr);
3671 if (lvalue == irb->codegen->invalid_instruction)3972 if (lvalue == irb->codegen->invalid_instruction)
3672 return lvalue;3973 return lvalue;
3673 IrInstruction *op1 = ir_build_load_ptr(irb, scope, node->data.bin_op_expr.op1, lvalue);3974 IrInstruction *op1 = ir_build_load_ptr(irb, scope, node->data.bin_op_expr.op1, lvalue);
...@@ -3718,7 +4019,7 @@ static IrInstruction *ir_gen_bool_or(IrBuilder *irb, Scope *scope, AstNode *node...@@ -3718,7 +4019,7 @@ static IrInstruction *ir_gen_bool_or(IrBuilder *irb, Scope *scope, AstNode *node
3718 incoming_blocks[0] = post_val1_block;4019 incoming_blocks[0] = post_val1_block;
3719 incoming_blocks[1] = post_val2_block;4020 incoming_blocks[1] = post_val2_block;
37204021
3721 return ir_build_phi(irb, scope, node, 2, incoming_blocks, incoming_values);4022 return ir_build_phi(irb, scope, node, 2, incoming_blocks, incoming_values, nullptr);
3722}4023}
37234024
3724static IrInstruction *ir_gen_bool_and(IrBuilder *irb, Scope *scope, AstNode *node) {4025static IrInstruction *ir_gen_bool_and(IrBuilder *irb, Scope *scope, AstNode *node) {
...@@ -3760,16 +4061,51 @@ static IrInstruction *ir_gen_bool_and(IrBuilder *irb, Scope *scope, AstNode *nod...@@ -3760,16 +4061,51 @@ static IrInstruction *ir_gen_bool_and(IrBuilder *irb, Scope *scope, AstNode *nod
3760 incoming_blocks[0] = post_val1_block;4061 incoming_blocks[0] = post_val1_block;
3761 incoming_blocks[1] = post_val2_block;4062 incoming_blocks[1] = post_val2_block;
37624063
3763 return ir_build_phi(irb, scope, node, 2, incoming_blocks, incoming_values);4064 return ir_build_phi(irb, scope, node, 2, incoming_blocks, incoming_values, nullptr);
4065}
4066
4067static ResultLocPeerParent *ir_build_result_peers(IrBuilder *irb, IrInstruction *cond_br_inst,
4068 IrBasicBlock *end_block, ResultLoc *parent, IrInstruction *is_comptime)
4069{
4070 ResultLocPeerParent *peer_parent = allocate<ResultLocPeerParent>(1);
4071 peer_parent->base.id = ResultLocIdPeerParent;
4072 peer_parent->base.source_instruction = cond_br_inst;
4073 peer_parent->end_bb = end_block;
4074 peer_parent->is_comptime = is_comptime;
4075 peer_parent->parent = parent;
4076
4077 IrInstruction *popped_inst = irb->current_basic_block->instruction_list.pop();
4078 ir_assert(popped_inst == cond_br_inst, cond_br_inst);
4079
4080 ir_build_reset_result(irb, cond_br_inst->scope, cond_br_inst->source_node, &peer_parent->base);
4081 irb->current_basic_block->instruction_list.append(popped_inst);
4082
4083 return peer_parent;
3764}4084}
37654085
3766static IrInstruction *ir_gen_orelse(IrBuilder *irb, Scope *parent_scope, AstNode *node) {4086static ResultLocPeerParent *ir_build_binary_result_peers(IrBuilder *irb, IrInstruction *cond_br_inst,
4087 IrBasicBlock *else_block, IrBasicBlock *end_block, ResultLoc *parent, IrInstruction *is_comptime)
4088{
4089 ResultLocPeerParent *peer_parent = ir_build_result_peers(irb, cond_br_inst, end_block, parent, is_comptime);
4090
4091 peer_parent->peers.append(create_peer_result(peer_parent));
4092 peer_parent->peers.last()->next_bb = else_block;
4093
4094 peer_parent->peers.append(create_peer_result(peer_parent));
4095 peer_parent->peers.last()->next_bb = end_block;
4096
4097 return peer_parent;
4098}
4099
4100static IrInstruction *ir_gen_orelse(IrBuilder *irb, Scope *parent_scope, AstNode *node, LVal lval,
4101 ResultLoc *result_loc)
4102{
3767 assert(node->type == NodeTypeBinOpExpr);4103 assert(node->type == NodeTypeBinOpExpr);
37684104
3769 AstNode *op1_node = node->data.bin_op_expr.op1;4105 AstNode *op1_node = node->data.bin_op_expr.op1;
3770 AstNode *op2_node = node->data.bin_op_expr.op2;4106 AstNode *op2_node = node->data.bin_op_expr.op2;
37714107
3772 IrInstruction *maybe_ptr = ir_gen_node_extra(irb, op1_node, parent_scope, LValPtr);4108 IrInstruction *maybe_ptr = ir_gen_node_extra(irb, op1_node, parent_scope, LValPtr, nullptr);
3773 if (maybe_ptr == irb->codegen->invalid_instruction)4109 if (maybe_ptr == irb->codegen->invalid_instruction)
3774 return irb->codegen->invalid_instruction;4110 return irb->codegen->invalid_instruction;
37754111
...@@ -3786,10 +4122,14 @@ static IrInstruction *ir_gen_orelse(IrBuilder *irb, Scope *parent_scope, AstNode...@@ -3786,10 +4122,14 @@ static IrInstruction *ir_gen_orelse(IrBuilder *irb, Scope *parent_scope, AstNode
3786 IrBasicBlock *ok_block = ir_create_basic_block(irb, parent_scope, "OptionalNonNull");4122 IrBasicBlock *ok_block = ir_create_basic_block(irb, parent_scope, "OptionalNonNull");
3787 IrBasicBlock *null_block = ir_create_basic_block(irb, parent_scope, "OptionalNull");4123 IrBasicBlock *null_block = ir_create_basic_block(irb, parent_scope, "OptionalNull");
3788 IrBasicBlock *end_block = ir_create_basic_block(irb, parent_scope, "OptionalEnd");4124 IrBasicBlock *end_block = ir_create_basic_block(irb, parent_scope, "OptionalEnd");
3789 ir_build_cond_br(irb, parent_scope, node, is_non_null, ok_block, null_block, is_comptime);4125 IrInstruction *cond_br_inst = ir_build_cond_br(irb, parent_scope, node, is_non_null, ok_block, null_block, is_comptime);
4126
4127 ResultLocPeerParent *peer_parent = ir_build_binary_result_peers(irb, cond_br_inst, ok_block, end_block,
4128 result_loc, is_comptime);
37904129
3791 ir_set_cursor_at_end_and_append_block(irb, null_block);4130 ir_set_cursor_at_end_and_append_block(irb, null_block);
3792 IrInstruction *null_result = ir_gen_node(irb, op2_node, parent_scope);4131 IrInstruction *null_result = ir_gen_node_extra(irb, op2_node, parent_scope, LValNone,
4132 &peer_parent->peers.at(0)->base);
3793 if (null_result == irb->codegen->invalid_instruction)4133 if (null_result == irb->codegen->invalid_instruction)
3794 return irb->codegen->invalid_instruction;4134 return irb->codegen->invalid_instruction;
3795 IrBasicBlock *after_null_block = irb->current_basic_block;4135 IrBasicBlock *after_null_block = irb->current_basic_block;
...@@ -3797,8 +4137,9 @@ static IrInstruction *ir_gen_orelse(IrBuilder *irb, Scope *parent_scope, AstNode...@@ -3797,8 +4137,9 @@ static IrInstruction *ir_gen_orelse(IrBuilder *irb, Scope *parent_scope, AstNode
3797 ir_mark_gen(ir_build_br(irb, parent_scope, node, end_block, is_comptime));4137 ir_mark_gen(ir_build_br(irb, parent_scope, node, end_block, is_comptime));
37984138
3799 ir_set_cursor_at_end_and_append_block(irb, ok_block);4139 ir_set_cursor_at_end_and_append_block(irb, ok_block);
3800 IrInstruction *unwrapped_ptr = ir_build_optional_unwrap_ptr(irb, parent_scope, node, maybe_ptr, false);4140 IrInstruction *unwrapped_ptr = ir_build_optional_unwrap_ptr(irb, parent_scope, node, maybe_ptr, false, false);
3801 IrInstruction *unwrapped_payload = ir_build_load_ptr(irb, parent_scope, node, unwrapped_ptr);4141 IrInstruction *unwrapped_payload = ir_build_load_ptr(irb, parent_scope, node, unwrapped_ptr);
4142 ir_build_end_expr(irb, parent_scope, node, unwrapped_payload, &peer_parent->peers.at(1)->base);
3802 IrBasicBlock *after_ok_block = irb->current_basic_block;4143 IrBasicBlock *after_ok_block = irb->current_basic_block;
3803 ir_build_br(irb, parent_scope, node, end_block, is_comptime);4144 ir_build_br(irb, parent_scope, node, end_block, is_comptime);
38044145
...@@ -3809,7 +4150,8 @@ static IrInstruction *ir_gen_orelse(IrBuilder *irb, Scope *parent_scope, AstNode...@@ -3809,7 +4150,8 @@ static IrInstruction *ir_gen_orelse(IrBuilder *irb, Scope *parent_scope, AstNode
3809 IrBasicBlock **incoming_blocks = allocate<IrBasicBlock *>(2);4150 IrBasicBlock **incoming_blocks = allocate<IrBasicBlock *>(2);
3810 incoming_blocks[0] = after_null_block;4151 incoming_blocks[0] = after_null_block;
3811 incoming_blocks[1] = after_ok_block;4152 incoming_blocks[1] = after_ok_block;
3812 return ir_build_phi(irb, parent_scope, node, 2, incoming_blocks, incoming_values);4153 IrInstruction *phi = ir_build_phi(irb, parent_scope, node, 2, incoming_blocks, incoming_values, peer_parent);
4154 return ir_lval_wrap(irb, parent_scope, phi, lval, result_loc);
3813}4155}
38144156
3815static IrInstruction *ir_gen_error_union(IrBuilder *irb, Scope *parent_scope, AstNode *node) {4157static IrInstruction *ir_gen_error_union(IrBuilder *irb, Scope *parent_scope, AstNode *node) {
...@@ -3829,7 +4171,7 @@ static IrInstruction *ir_gen_error_union(IrBuilder *irb, Scope *parent_scope, As...@@ -3829,7 +4171,7 @@ static IrInstruction *ir_gen_error_union(IrBuilder *irb, Scope *parent_scope, As
3829 return ir_build_error_union(irb, parent_scope, node, err_set, payload);4171 return ir_build_error_union(irb, parent_scope, node, err_set, payload);
3830}4172}
38314173
3832static IrInstruction *ir_gen_bin_op(IrBuilder *irb, Scope *scope, AstNode *node) {4174static IrInstruction *ir_gen_bin_op(IrBuilder *irb, Scope *scope, AstNode *node, LVal lval, ResultLoc *result_loc) {
3833 assert(node->type == NodeTypeBinOpExpr);4175 assert(node->type == NodeTypeBinOpExpr);
38344176
3835 BinOpType bin_op_type = node->data.bin_op_expr.bin_op;4177 BinOpType bin_op_type = node->data.bin_op_expr.bin_op;
...@@ -3837,87 +4179,87 @@ static IrInstruction *ir_gen_bin_op(IrBuilder *irb, Scope *scope, AstNode *node)...@@ -3837,87 +4179,87 @@ static IrInstruction *ir_gen_bin_op(IrBuilder *irb, Scope *scope, AstNode *node)
3837 case BinOpTypeInvalid:4179 case BinOpTypeInvalid:
3838 zig_unreachable();4180 zig_unreachable();
3839 case BinOpTypeAssign:4181 case BinOpTypeAssign:
3840 return ir_gen_assign(irb, scope, node);4182 return ir_lval_wrap(irb, scope, ir_gen_assign(irb, scope, node), lval, result_loc);
3841 case BinOpTypeAssignTimes:4183 case BinOpTypeAssignTimes:
3842 return ir_gen_assign_op(irb, scope, node, IrBinOpMult);4184 return ir_lval_wrap(irb, scope, ir_gen_assign_op(irb, scope, node, IrBinOpMult), lval, result_loc);
3843 case BinOpTypeAssignTimesWrap:4185 case BinOpTypeAssignTimesWrap:
3844 return ir_gen_assign_op(irb, scope, node, IrBinOpMultWrap);4186 return ir_lval_wrap(irb, scope, ir_gen_assign_op(irb, scope, node, IrBinOpMultWrap), lval, result_loc);
3845 case BinOpTypeAssignDiv:4187 case BinOpTypeAssignDiv:
3846 return ir_gen_assign_op(irb, scope, node, IrBinOpDivUnspecified);4188 return ir_lval_wrap(irb, scope, ir_gen_assign_op(irb, scope, node, IrBinOpDivUnspecified), lval, result_loc);
3847 case BinOpTypeAssignMod:4189 case BinOpTypeAssignMod:
3848 return ir_gen_assign_op(irb, scope, node, IrBinOpRemUnspecified);4190 return ir_lval_wrap(irb, scope, ir_gen_assign_op(irb, scope, node, IrBinOpRemUnspecified), lval, result_loc);
3849 case BinOpTypeAssignPlus:4191 case BinOpTypeAssignPlus:
3850 return ir_gen_assign_op(irb, scope, node, IrBinOpAdd);4192 return ir_lval_wrap(irb, scope, ir_gen_assign_op(irb, scope, node, IrBinOpAdd), lval, result_loc);
3851 case BinOpTypeAssignPlusWrap:4193 case BinOpTypeAssignPlusWrap:
3852 return ir_gen_assign_op(irb, scope, node, IrBinOpAddWrap);4194 return ir_lval_wrap(irb, scope, ir_gen_assign_op(irb, scope, node, IrBinOpAddWrap), lval, result_loc);
3853 case BinOpTypeAssignMinus:4195 case BinOpTypeAssignMinus:
3854 return ir_gen_assign_op(irb, scope, node, IrBinOpSub);4196 return ir_lval_wrap(irb, scope, ir_gen_assign_op(irb, scope, node, IrBinOpSub), lval, result_loc);
3855 case BinOpTypeAssignMinusWrap:4197 case BinOpTypeAssignMinusWrap:
3856 return ir_gen_assign_op(irb, scope, node, IrBinOpSubWrap);4198 return ir_lval_wrap(irb, scope, ir_gen_assign_op(irb, scope, node, IrBinOpSubWrap), lval, result_loc);
3857 case BinOpTypeAssignBitShiftLeft:4199 case BinOpTypeAssignBitShiftLeft:
3858 return ir_gen_assign_op(irb, scope, node, IrBinOpBitShiftLeftLossy);4200 return ir_lval_wrap(irb, scope, ir_gen_assign_op(irb, scope, node, IrBinOpBitShiftLeftLossy), lval, result_loc);
3859 case BinOpTypeAssignBitShiftRight:4201 case BinOpTypeAssignBitShiftRight:
3860 return ir_gen_assign_op(irb, scope, node, IrBinOpBitShiftRightLossy);4202 return ir_lval_wrap(irb, scope, ir_gen_assign_op(irb, scope, node, IrBinOpBitShiftRightLossy), lval, result_loc);
3861 case BinOpTypeAssignBitAnd:4203 case BinOpTypeAssignBitAnd:
3862 return ir_gen_assign_op(irb, scope, node, IrBinOpBinAnd);4204 return ir_lval_wrap(irb, scope, ir_gen_assign_op(irb, scope, node, IrBinOpBinAnd), lval, result_loc);
3863 case BinOpTypeAssignBitXor:4205 case BinOpTypeAssignBitXor:
3864 return ir_gen_assign_op(irb, scope, node, IrBinOpBinXor);4206 return ir_lval_wrap(irb, scope, ir_gen_assign_op(irb, scope, node, IrBinOpBinXor), lval, result_loc);
3865 case BinOpTypeAssignBitOr:4207 case BinOpTypeAssignBitOr:
3866 return ir_gen_assign_op(irb, scope, node, IrBinOpBinOr);4208 return ir_lval_wrap(irb, scope, ir_gen_assign_op(irb, scope, node, IrBinOpBinOr), lval, result_loc);
3867 case BinOpTypeAssignMergeErrorSets:4209 case BinOpTypeAssignMergeErrorSets:
3868 return ir_gen_assign_op(irb, scope, node, IrBinOpMergeErrorSets);4210 return ir_lval_wrap(irb, scope, ir_gen_assign_op(irb, scope, node, IrBinOpMergeErrorSets), lval, result_loc);
3869 case BinOpTypeBoolOr:4211 case BinOpTypeBoolOr:
3870 return ir_gen_bool_or(irb, scope, node);4212 return ir_lval_wrap(irb, scope, ir_gen_bool_or(irb, scope, node), lval, result_loc);
3871 case BinOpTypeBoolAnd:4213 case BinOpTypeBoolAnd:
3872 return ir_gen_bool_and(irb, scope, node);4214 return ir_lval_wrap(irb, scope, ir_gen_bool_and(irb, scope, node), lval, result_loc);
3873 case BinOpTypeCmpEq:4215 case BinOpTypeCmpEq:
3874 return ir_gen_bin_op_id(irb, scope, node, IrBinOpCmpEq);4216 return ir_lval_wrap(irb, scope, ir_gen_bin_op_id(irb, scope, node, IrBinOpCmpEq), lval, result_loc);
3875 case BinOpTypeCmpNotEq:4217 case BinOpTypeCmpNotEq:
3876 return ir_gen_bin_op_id(irb, scope, node, IrBinOpCmpNotEq);4218 return ir_lval_wrap(irb, scope, ir_gen_bin_op_id(irb, scope, node, IrBinOpCmpNotEq), lval, result_loc);
3877 case BinOpTypeCmpLessThan:4219 case BinOpTypeCmpLessThan:
3878 return ir_gen_bin_op_id(irb, scope, node, IrBinOpCmpLessThan);4220 return ir_lval_wrap(irb, scope, ir_gen_bin_op_id(irb, scope, node, IrBinOpCmpLessThan), lval, result_loc);
3879 case BinOpTypeCmpGreaterThan:4221 case BinOpTypeCmpGreaterThan:
3880 return ir_gen_bin_op_id(irb, scope, node, IrBinOpCmpGreaterThan);4222 return ir_lval_wrap(irb, scope, ir_gen_bin_op_id(irb, scope, node, IrBinOpCmpGreaterThan), lval, result_loc);
3881 case BinOpTypeCmpLessOrEq:4223 case BinOpTypeCmpLessOrEq:
3882 return ir_gen_bin_op_id(irb, scope, node, IrBinOpCmpLessOrEq);4224 return ir_lval_wrap(irb, scope, ir_gen_bin_op_id(irb, scope, node, IrBinOpCmpLessOrEq), lval, result_loc);
3883 case BinOpTypeCmpGreaterOrEq:4225 case BinOpTypeCmpGreaterOrEq:
3884 return ir_gen_bin_op_id(irb, scope, node, IrBinOpCmpGreaterOrEq);4226 return ir_lval_wrap(irb, scope, ir_gen_bin_op_id(irb, scope, node, IrBinOpCmpGreaterOrEq), lval, result_loc);
3885 case BinOpTypeBinOr:4227 case BinOpTypeBinOr:
3886 return ir_gen_bin_op_id(irb, scope, node, IrBinOpBinOr);4228 return ir_lval_wrap(irb, scope, ir_gen_bin_op_id(irb, scope, node, IrBinOpBinOr), lval, result_loc);
3887 case BinOpTypeBinXor:4229 case BinOpTypeBinXor:
3888 return ir_gen_bin_op_id(irb, scope, node, IrBinOpBinXor);4230 return ir_lval_wrap(irb, scope, ir_gen_bin_op_id(irb, scope, node, IrBinOpBinXor), lval, result_loc);
3889 case BinOpTypeBinAnd:4231 case BinOpTypeBinAnd:
3890 return ir_gen_bin_op_id(irb, scope, node, IrBinOpBinAnd);4232 return ir_lval_wrap(irb, scope, ir_gen_bin_op_id(irb, scope, node, IrBinOpBinAnd), lval, result_loc);
3891 case BinOpTypeBitShiftLeft:4233 case BinOpTypeBitShiftLeft:
3892 return ir_gen_bin_op_id(irb, scope, node, IrBinOpBitShiftLeftLossy);4234 return ir_lval_wrap(irb, scope, ir_gen_bin_op_id(irb, scope, node, IrBinOpBitShiftLeftLossy), lval, result_loc);
3893 case BinOpTypeBitShiftRight:4235 case BinOpTypeBitShiftRight:
3894 return ir_gen_bin_op_id(irb, scope, node, IrBinOpBitShiftRightLossy);4236 return ir_lval_wrap(irb, scope, ir_gen_bin_op_id(irb, scope, node, IrBinOpBitShiftRightLossy), lval, result_loc);
3895 case BinOpTypeAdd:4237 case BinOpTypeAdd:
3896 return ir_gen_bin_op_id(irb, scope, node, IrBinOpAdd);4238 return ir_lval_wrap(irb, scope, ir_gen_bin_op_id(irb, scope, node, IrBinOpAdd), lval, result_loc);
3897 case BinOpTypeAddWrap:4239 case BinOpTypeAddWrap:
3898 return ir_gen_bin_op_id(irb, scope, node, IrBinOpAddWrap);4240 return ir_lval_wrap(irb, scope, ir_gen_bin_op_id(irb, scope, node, IrBinOpAddWrap), lval, result_loc);
3899 case BinOpTypeSub:4241 case BinOpTypeSub:
3900 return ir_gen_bin_op_id(irb, scope, node, IrBinOpSub);4242 return ir_lval_wrap(irb, scope, ir_gen_bin_op_id(irb, scope, node, IrBinOpSub), lval, result_loc);
3901 case BinOpTypeSubWrap:4243 case BinOpTypeSubWrap:
3902 return ir_gen_bin_op_id(irb, scope, node, IrBinOpSubWrap);4244 return ir_lval_wrap(irb, scope, ir_gen_bin_op_id(irb, scope, node, IrBinOpSubWrap), lval, result_loc);
3903 case BinOpTypeMult:4245 case BinOpTypeMult:
3904 return ir_gen_bin_op_id(irb, scope, node, IrBinOpMult);4246 return ir_lval_wrap(irb, scope, ir_gen_bin_op_id(irb, scope, node, IrBinOpMult), lval, result_loc);
3905 case BinOpTypeMultWrap:4247 case BinOpTypeMultWrap:
3906 return ir_gen_bin_op_id(irb, scope, node, IrBinOpMultWrap);4248 return ir_lval_wrap(irb, scope, ir_gen_bin_op_id(irb, scope, node, IrBinOpMultWrap), lval, result_loc);
3907 case BinOpTypeDiv:4249 case BinOpTypeDiv:
3908 return ir_gen_bin_op_id(irb, scope, node, IrBinOpDivUnspecified);4250 return ir_lval_wrap(irb, scope, ir_gen_bin_op_id(irb, scope, node, IrBinOpDivUnspecified), lval, result_loc);
3909 case BinOpTypeMod:4251 case BinOpTypeMod:
3910 return ir_gen_bin_op_id(irb, scope, node, IrBinOpRemUnspecified);4252 return ir_lval_wrap(irb, scope, ir_gen_bin_op_id(irb, scope, node, IrBinOpRemUnspecified), lval, result_loc);
3911 case BinOpTypeArrayCat:4253 case BinOpTypeArrayCat:
3912 return ir_gen_bin_op_id(irb, scope, node, IrBinOpArrayCat);4254 return ir_lval_wrap(irb, scope, ir_gen_bin_op_id(irb, scope, node, IrBinOpArrayCat), lval, result_loc);
3913 case BinOpTypeArrayMult:4255 case BinOpTypeArrayMult:
3914 return ir_gen_bin_op_id(irb, scope, node, IrBinOpArrayMult);4256 return ir_lval_wrap(irb, scope, ir_gen_bin_op_id(irb, scope, node, IrBinOpArrayMult), lval, result_loc);
3915 case BinOpTypeMergeErrorSets:4257 case BinOpTypeMergeErrorSets:
3916 return ir_gen_bin_op_id(irb, scope, node, IrBinOpMergeErrorSets);4258 return ir_lval_wrap(irb, scope, ir_gen_bin_op_id(irb, scope, node, IrBinOpMergeErrorSets), lval, result_loc);
3917 case BinOpTypeUnwrapOptional:4259 case BinOpTypeUnwrapOptional:
3918 return ir_gen_orelse(irb, scope, node);4260 return ir_gen_orelse(irb, scope, node, lval, result_loc);
3919 case BinOpTypeErrorUnion:4261 case BinOpTypeErrorUnion:
3920 return ir_gen_error_union(irb, scope, node);4262 return ir_lval_wrap(irb, scope, ir_gen_error_union(irb, scope, node), lval, result_loc);
3921 }4263 }
3922 zig_unreachable();4264 zig_unreachable();
3923}4265}
...@@ -3962,12 +4304,12 @@ static void populate_invalid_variable_in_scope(CodeGen *g, Scope *scope, AstNode...@@ -3962,12 +4304,12 @@ static void populate_invalid_variable_in_scope(CodeGen *g, Scope *scope, AstNode
3962 TldVar *tld_var = allocate<TldVar>(1);4304 TldVar *tld_var = allocate<TldVar>(1);
3963 init_tld(&tld_var->base, TldIdVar, var_name, VisibModPub, node, &scope_decls->base);4305 init_tld(&tld_var->base, TldIdVar, var_name, VisibModPub, node, &scope_decls->base);
3964 tld_var->base.resolution = TldResolutionInvalid;4306 tld_var->base.resolution = TldResolutionInvalid;
3965 tld_var->var = add_variable(g, node, &scope_decls->base, var_name, false, 4307 tld_var->var = add_variable(g, node, &scope_decls->base, var_name, false,
3966 &g->invalid_instruction->value, &tld_var->base, g->builtin_types.entry_invalid);4308 &g->invalid_instruction->value, &tld_var->base, g->builtin_types.entry_invalid);
3967 scope_decls->decl_table.put(var_name, &tld_var->base);4309 scope_decls->decl_table.put(var_name, &tld_var->base);
3968}4310}
39694311
3970static IrInstruction *ir_gen_symbol(IrBuilder *irb, Scope *scope, AstNode *node, LVal lval) {4312static IrInstruction *ir_gen_symbol(IrBuilder *irb, Scope *scope, AstNode *node, LVal lval, ResultLoc *result_loc) {
3971 Error err;4313 Error err;
3972 assert(node->type == NodeTypeSymbol);4314 assert(node->type == NodeTypeSymbol);
39734315
...@@ -4001,7 +4343,7 @@ static IrInstruction *ir_gen_symbol(IrBuilder *irb, Scope *scope, AstNode *node,...@@ -4001,7 +4343,7 @@ static IrInstruction *ir_gen_symbol(IrBuilder *irb, Scope *scope, AstNode *node,
4001 if (lval == LValPtr) {4343 if (lval == LValPtr) {
4002 return ir_build_ref(irb, scope, node, value, false, false);4344 return ir_build_ref(irb, scope, node, value, false, false);
4003 } else {4345 } else {
4004 return value;4346 return ir_expr_wrap(irb, scope, value, result_loc);
4005 }4347 }
4006 }4348 }
40074349
...@@ -4009,15 +4351,22 @@ static IrInstruction *ir_gen_symbol(IrBuilder *irb, Scope *scope, AstNode *node,...@@ -4009,15 +4351,22 @@ static IrInstruction *ir_gen_symbol(IrBuilder *irb, Scope *scope, AstNode *node,
4009 ZigVar *var = find_variable(irb->codegen, scope, variable_name, &crossed_fndef_scope);4351 ZigVar *var = find_variable(irb->codegen, scope, variable_name, &crossed_fndef_scope);
4010 if (var) {4352 if (var) {
4011 IrInstruction *var_ptr = ir_build_var_ptr_x(irb, scope, node, var, crossed_fndef_scope);4353 IrInstruction *var_ptr = ir_build_var_ptr_x(irb, scope, node, var, crossed_fndef_scope);
4012 if (lval == LValPtr)4354 if (lval == LValPtr) {
4013 return var_ptr;4355 return var_ptr;
4014 else4356 } else {
4015 return ir_build_load_ptr(irb, scope, node, var_ptr);4357 return ir_expr_wrap(irb, scope, ir_build_load_ptr(irb, scope, node, var_ptr), result_loc);
4358 }
4016 }4359 }
40174360
4018 Tld *tld = find_decl(irb->codegen, scope, variable_name);4361 Tld *tld = find_decl(irb->codegen, scope, variable_name);
4019 if (tld)4362 if (tld) {
4020 return ir_build_decl_ref(irb, scope, node, tld, lval);4363 IrInstruction *decl_ref = ir_build_decl_ref(irb, scope, node, tld, lval);
4364 if (lval == LValPtr) {
4365 return decl_ref;
4366 } else {
4367 return ir_expr_wrap(irb, scope, decl_ref, result_loc);
4368 }
4369 }
40214370
4022 if (get_container_scope(node->owner)->any_imports_failed) {4371 if (get_container_scope(node->owner)->any_imports_failed) {
4023 // skip the error message since we had a failing import in this file4372 // skip the error message since we had a failing import in this file
...@@ -4028,11 +4377,13 @@ static IrInstruction *ir_gen_symbol(IrBuilder *irb, Scope *scope, AstNode *node,...@@ -4028,11 +4377,13 @@ static IrInstruction *ir_gen_symbol(IrBuilder *irb, Scope *scope, AstNode *node,
4028 return ir_build_undeclared_identifier(irb, scope, node, variable_name);4377 return ir_build_undeclared_identifier(irb, scope, node, variable_name);
4029}4378}
40304379
4031static IrInstruction *ir_gen_array_access(IrBuilder *irb, Scope *scope, AstNode *node, LVal lval) {4380static IrInstruction *ir_gen_array_access(IrBuilder *irb, Scope *scope, AstNode *node, LVal lval,
4381 ResultLoc *result_loc)
4382{
4032 assert(node->type == NodeTypeArrayAccessExpr);4383 assert(node->type == NodeTypeArrayAccessExpr);
40334384
4034 AstNode *array_ref_node = node->data.array_access_expr.array_ref_expr;4385 AstNode *array_ref_node = node->data.array_access_expr.array_ref_expr;
4035 IrInstruction *array_ref_instruction = ir_gen_node_extra(irb, array_ref_node, scope, LValPtr);4386 IrInstruction *array_ref_instruction = ir_gen_node_extra(irb, array_ref_node, scope, LValPtr, nullptr);
4036 if (array_ref_instruction == irb->codegen->invalid_instruction)4387 if (array_ref_instruction == irb->codegen->invalid_instruction)
4037 return array_ref_instruction;4388 return array_ref_instruction;
40384389
...@@ -4042,11 +4393,12 @@ static IrInstruction *ir_gen_array_access(IrBuilder *irb, Scope *scope, AstNode...@@ -4042,11 +4393,12 @@ static IrInstruction *ir_gen_array_access(IrBuilder *irb, Scope *scope, AstNode
4042 return subscript_instruction;4393 return subscript_instruction;
40434394
4044 IrInstruction *ptr_instruction = ir_build_elem_ptr(irb, scope, node, array_ref_instruction,4395 IrInstruction *ptr_instruction = ir_build_elem_ptr(irb, scope, node, array_ref_instruction,
4045 subscript_instruction, true, PtrLenSingle);4396 subscript_instruction, true, PtrLenSingle, nullptr);
4046 if (lval == LValPtr)4397 if (lval == LValPtr)
4047 return ptr_instruction;4398 return ptr_instruction;
40484399
4049 return ir_build_load_ptr(irb, scope, node, ptr_instruction);4400 IrInstruction *load_ptr = ir_build_load_ptr(irb, scope, node, ptr_instruction);
4401 return ir_expr_wrap(irb, scope, load_ptr, result_loc);
4050}4402}
40514403
4052static IrInstruction *ir_gen_field_access(IrBuilder *irb, Scope *scope, AstNode *node) {4404static IrInstruction *ir_gen_field_access(IrBuilder *irb, Scope *scope, AstNode *node) {
...@@ -4055,11 +4407,11 @@ static IrInstruction *ir_gen_field_access(IrBuilder *irb, Scope *scope, AstNode...@@ -4055,11 +4407,11 @@ static IrInstruction *ir_gen_field_access(IrBuilder *irb, Scope *scope, AstNode
4055 AstNode *container_ref_node = node->data.field_access_expr.struct_expr;4407 AstNode *container_ref_node = node->data.field_access_expr.struct_expr;
4056 Buf *field_name = node->data.field_access_expr.field_name;4408 Buf *field_name = node->data.field_access_expr.field_name;
40574409
4058 IrInstruction *container_ref_instruction = ir_gen_node_extra(irb, container_ref_node, scope, LValPtr);4410 IrInstruction *container_ref_instruction = ir_gen_node_extra(irb, container_ref_node, scope, LValPtr, nullptr);
4059 if (container_ref_instruction == irb->codegen->invalid_instruction)4411 if (container_ref_instruction == irb->codegen->invalid_instruction)
4060 return container_ref_instruction;4412 return container_ref_instruction;
40614413
4062 return ir_build_field_ptr(irb, scope, node, container_ref_instruction, field_name);4414 return ir_build_field_ptr(irb, scope, node, container_ref_instruction, field_name, false);
4063}4415}
40644416
4065static IrInstruction *ir_gen_overflow_op(IrBuilder *irb, Scope *scope, AstNode *node, IrOverflowOp op) {4417static IrInstruction *ir_gen_overflow_op(IrBuilder *irb, Scope *scope, AstNode *node, IrOverflowOp op) {
...@@ -4132,7 +4484,9 @@ static IrInstruction *ir_gen_this(IrBuilder *irb, Scope *orig_scope, AstNode *no...@@ -4132,7 +4484,9 @@ static IrInstruction *ir_gen_this(IrBuilder *irb, Scope *orig_scope, AstNode *no
4132 zig_unreachable();4484 zig_unreachable();
4133}4485}
41344486
4135static IrInstruction *ir_gen_builtin_fn_call(IrBuilder *irb, Scope *scope, AstNode *node, LVal lval) {4487static IrInstruction *ir_gen_builtin_fn_call(IrBuilder *irb, Scope *scope, AstNode *node, LVal lval,
4488 ResultLoc *result_loc)
4489{
4136 assert(node->type == NodeTypeFnCallExpr);4490 assert(node->type == NodeTypeFnCallExpr);
41374491
4138 AstNode *fn_ref_expr = node->data.fn_call_expr.fn_ref_expr;4492 AstNode *fn_ref_expr = node->data.fn_call_expr.fn_ref_expr;
...@@ -4168,7 +4522,7 @@ static IrInstruction *ir_gen_builtin_fn_call(IrBuilder *irb, Scope *scope, AstNo...@@ -4168,7 +4522,7 @@ static IrInstruction *ir_gen_builtin_fn_call(IrBuilder *irb, Scope *scope, AstNo
4168 return arg;4522 return arg;
41694523
4170 IrInstruction *type_of = ir_build_typeof(irb, scope, node, arg);4524 IrInstruction *type_of = ir_build_typeof(irb, scope, node, arg);
4171 return ir_lval_wrap(irb, scope, type_of, lval);4525 return ir_lval_wrap(irb, scope, type_of, lval, result_loc);
4172 }4526 }
4173 case BuiltinFnIdSetCold:4527 case BuiltinFnIdSetCold:
4174 {4528 {
...@@ -4178,7 +4532,7 @@ static IrInstruction *ir_gen_builtin_fn_call(IrBuilder *irb, Scope *scope, AstNo...@@ -4178,7 +4532,7 @@ static IrInstruction *ir_gen_builtin_fn_call(IrBuilder *irb, Scope *scope, AstNo
4178 return arg0_value;4532 return arg0_value;
41794533
4180 IrInstruction *set_cold = ir_build_set_cold(irb, scope, node, arg0_value);4534 IrInstruction *set_cold = ir_build_set_cold(irb, scope, node, arg0_value);
4181 return ir_lval_wrap(irb, scope, set_cold, lval);4535 return ir_lval_wrap(irb, scope, set_cold, lval, result_loc);
4182 }4536 }
4183 case BuiltinFnIdSetRuntimeSafety:4537 case BuiltinFnIdSetRuntimeSafety:
4184 {4538 {
...@@ -4188,7 +4542,7 @@ static IrInstruction *ir_gen_builtin_fn_call(IrBuilder *irb, Scope *scope, AstNo...@@ -4188,7 +4542,7 @@ static IrInstruction *ir_gen_builtin_fn_call(IrBuilder *irb, Scope *scope, AstNo
4188 return arg0_value;4542 return arg0_value;
41894543
4190 IrInstruction *set_safety = ir_build_set_runtime_safety(irb, scope, node, arg0_value);4544 IrInstruction *set_safety = ir_build_set_runtime_safety(irb, scope, node, arg0_value);
4191 return ir_lval_wrap(irb, scope, set_safety, lval);4545 return ir_lval_wrap(irb, scope, set_safety, lval, result_loc);
4192 }4546 }
4193 case BuiltinFnIdSetFloatMode:4547 case BuiltinFnIdSetFloatMode:
4194 {4548 {
...@@ -4198,7 +4552,7 @@ static IrInstruction *ir_gen_builtin_fn_call(IrBuilder *irb, Scope *scope, AstNo...@@ -4198,7 +4552,7 @@ static IrInstruction *ir_gen_builtin_fn_call(IrBuilder *irb, Scope *scope, AstNo
4198 return arg0_value;4552 return arg0_value;
41994553
4200 IrInstruction *set_float_mode = ir_build_set_float_mode(irb, scope, node, arg0_value);4554 IrInstruction *set_float_mode = ir_build_set_float_mode(irb, scope, node, arg0_value);
4201 return ir_lval_wrap(irb, scope, set_float_mode, lval);4555 return ir_lval_wrap(irb, scope, set_float_mode, lval, result_loc);
4202 }4556 }
4203 case BuiltinFnIdSizeof:4557 case BuiltinFnIdSizeof:
4204 {4558 {
...@@ -4208,7 +4562,7 @@ static IrInstruction *ir_gen_builtin_fn_call(IrBuilder *irb, Scope *scope, AstNo...@@ -4208,7 +4562,7 @@ static IrInstruction *ir_gen_builtin_fn_call(IrBuilder *irb, Scope *scope, AstNo
4208 return arg0_value;4562 return arg0_value;
42094563
4210 IrInstruction *size_of = ir_build_size_of(irb, scope, node, arg0_value);4564 IrInstruction *size_of = ir_build_size_of(irb, scope, node, arg0_value);
4211 return ir_lval_wrap(irb, scope, size_of, lval);4565 return ir_lval_wrap(irb, scope, size_of, lval, result_loc);
4212 }4566 }
4213 case BuiltinFnIdImport:4567 case BuiltinFnIdImport:
4214 {4568 {
...@@ -4218,12 +4572,12 @@ static IrInstruction *ir_gen_builtin_fn_call(IrBuilder *irb, Scope *scope, AstNo...@@ -4218,12 +4572,12 @@ static IrInstruction *ir_gen_builtin_fn_call(IrBuilder *irb, Scope *scope, AstNo
4218 return arg0_value;4572 return arg0_value;
42194573
4220 IrInstruction *import = ir_build_import(irb, scope, node, arg0_value);4574 IrInstruction *import = ir_build_import(irb, scope, node, arg0_value);
4221 return ir_lval_wrap(irb, scope, import, lval);4575 return ir_lval_wrap(irb, scope, import, lval, result_loc);
4222 }4576 }
4223 case BuiltinFnIdCImport:4577 case BuiltinFnIdCImport:
4224 {4578 {
4225 IrInstruction *c_import = ir_build_c_import(irb, scope, node);4579 IrInstruction *c_import = ir_build_c_import(irb, scope, node);
4226 return ir_lval_wrap(irb, scope, c_import, lval);4580 return ir_lval_wrap(irb, scope, c_import, lval, result_loc);
4227 }4581 }
4228 case BuiltinFnIdCInclude:4582 case BuiltinFnIdCInclude:
4229 {4583 {
...@@ -4238,7 +4592,7 @@ static IrInstruction *ir_gen_builtin_fn_call(IrBuilder *irb, Scope *scope, AstNo...@@ -4238,7 +4592,7 @@ static IrInstruction *ir_gen_builtin_fn_call(IrBuilder *irb, Scope *scope, AstNo
4238 }4592 }
42394593
4240 IrInstruction *c_include = ir_build_c_include(irb, scope, node, arg0_value);4594 IrInstruction *c_include = ir_build_c_include(irb, scope, node, arg0_value);
4241 return ir_lval_wrap(irb, scope, c_include, lval);4595 return ir_lval_wrap(irb, scope, c_include, lval, result_loc);
4242 }4596 }
4243 case BuiltinFnIdCDefine:4597 case BuiltinFnIdCDefine:
4244 {4598 {
...@@ -4258,7 +4612,7 @@ static IrInstruction *ir_gen_builtin_fn_call(IrBuilder *irb, Scope *scope, AstNo...@@ -4258,7 +4612,7 @@ static IrInstruction *ir_gen_builtin_fn_call(IrBuilder *irb, Scope *scope, AstNo
4258 }4612 }
42594613
4260 IrInstruction *c_define = ir_build_c_define(irb, scope, node, arg0_value, arg1_value);4614 IrInstruction *c_define = ir_build_c_define(irb, scope, node, arg0_value, arg1_value);
4261 return ir_lval_wrap(irb, scope, c_define, lval);4615 return ir_lval_wrap(irb, scope, c_define, lval, result_loc);
4262 }4616 }
4263 case BuiltinFnIdCUndef:4617 case BuiltinFnIdCUndef:
4264 {4618 {
...@@ -4273,7 +4627,7 @@ static IrInstruction *ir_gen_builtin_fn_call(IrBuilder *irb, Scope *scope, AstNo...@@ -4273,7 +4627,7 @@ static IrInstruction *ir_gen_builtin_fn_call(IrBuilder *irb, Scope *scope, AstNo
4273 }4627 }
42744628
4275 IrInstruction *c_undef = ir_build_c_undef(irb, scope, node, arg0_value);4629 IrInstruction *c_undef = ir_build_c_undef(irb, scope, node, arg0_value);
4276 return ir_lval_wrap(irb, scope, c_undef, lval);4630 return ir_lval_wrap(irb, scope, c_undef, lval, result_loc);
4277 }4631 }
4278 case BuiltinFnIdCompileErr:4632 case BuiltinFnIdCompileErr:
4279 {4633 {
...@@ -4283,7 +4637,7 @@ static IrInstruction *ir_gen_builtin_fn_call(IrBuilder *irb, Scope *scope, AstNo...@@ -4283,7 +4637,7 @@ static IrInstruction *ir_gen_builtin_fn_call(IrBuilder *irb, Scope *scope, AstNo
4283 return arg0_value;4637 return arg0_value;
42844638
4285 IrInstruction *compile_err = ir_build_compile_err(irb, scope, node, arg0_value);4639 IrInstruction *compile_err = ir_build_compile_err(irb, scope, node, arg0_value);
4286 return ir_lval_wrap(irb, scope, compile_err, lval);4640 return ir_lval_wrap(irb, scope, compile_err, lval, result_loc);
4287 }4641 }
4288 case BuiltinFnIdCompileLog:4642 case BuiltinFnIdCompileLog:
4289 {4643 {
...@@ -4297,7 +4651,7 @@ static IrInstruction *ir_gen_builtin_fn_call(IrBuilder *irb, Scope *scope, AstNo...@@ -4297,7 +4651,7 @@ static IrInstruction *ir_gen_builtin_fn_call(IrBuilder *irb, Scope *scope, AstNo
4297 }4651 }
42984652
4299 IrInstruction *compile_log = ir_build_compile_log(irb, scope, node, actual_param_count, args);4653 IrInstruction *compile_log = ir_build_compile_log(irb, scope, node, actual_param_count, args);
4300 return ir_lval_wrap(irb, scope, compile_log, lval);4654 return ir_lval_wrap(irb, scope, compile_log, lval, result_loc);
4301 }4655 }
4302 case BuiltinFnIdErrName:4656 case BuiltinFnIdErrName:
4303 {4657 {
...@@ -4307,7 +4661,7 @@ static IrInstruction *ir_gen_builtin_fn_call(IrBuilder *irb, Scope *scope, AstNo...@@ -4307,7 +4661,7 @@ static IrInstruction *ir_gen_builtin_fn_call(IrBuilder *irb, Scope *scope, AstNo
4307 return arg0_value;4661 return arg0_value;
43084662
4309 IrInstruction *err_name = ir_build_err_name(irb, scope, node, arg0_value);4663 IrInstruction *err_name = ir_build_err_name(irb, scope, node, arg0_value);
4310 return ir_lval_wrap(irb, scope, err_name, lval);4664 return ir_lval_wrap(irb, scope, err_name, lval, result_loc);
4311 }4665 }
4312 case BuiltinFnIdEmbedFile:4666 case BuiltinFnIdEmbedFile:
4313 {4667 {
...@@ -4317,7 +4671,7 @@ static IrInstruction *ir_gen_builtin_fn_call(IrBuilder *irb, Scope *scope, AstNo...@@ -4317,7 +4671,7 @@ static IrInstruction *ir_gen_builtin_fn_call(IrBuilder *irb, Scope *scope, AstNo
4317 return arg0_value;4671 return arg0_value;
43184672
4319 IrInstruction *embed_file = ir_build_embed_file(irb, scope, node, arg0_value);4673 IrInstruction *embed_file = ir_build_embed_file(irb, scope, node, arg0_value);
4320 return ir_lval_wrap(irb, scope, embed_file, lval);4674 return ir_lval_wrap(irb, scope, embed_file, lval, result_loc);
4321 }4675 }
4322 case BuiltinFnIdCmpxchgWeak:4676 case BuiltinFnIdCmpxchgWeak:
4323 case BuiltinFnIdCmpxchgStrong:4677 case BuiltinFnIdCmpxchgStrong:
...@@ -4353,8 +4707,9 @@ static IrInstruction *ir_gen_builtin_fn_call(IrBuilder *irb, Scope *scope, AstNo...@@ -4353,8 +4707,9 @@ static IrInstruction *ir_gen_builtin_fn_call(IrBuilder *irb, Scope *scope, AstNo
4353 return arg5_value;4707 return arg5_value;
43544708
4355 IrInstruction *cmpxchg = ir_build_cmpxchg_src(irb, scope, node, arg0_value, arg1_value,4709 IrInstruction *cmpxchg = ir_build_cmpxchg_src(irb, scope, node, arg0_value, arg1_value,
4356 arg2_value, arg3_value, arg4_value, arg5_value, (builtin_fn->id == BuiltinFnIdCmpxchgWeak));4710 arg2_value, arg3_value, arg4_value, arg5_value, (builtin_fn->id == BuiltinFnIdCmpxchgWeak),
4357 return ir_lval_wrap(irb, scope, cmpxchg, lval);4711 result_loc);
4712 return ir_lval_wrap(irb, scope, cmpxchg, lval, result_loc);
4358 }4713 }
4359 case BuiltinFnIdFence:4714 case BuiltinFnIdFence:
4360 {4715 {
...@@ -4364,7 +4719,7 @@ static IrInstruction *ir_gen_builtin_fn_call(IrBuilder *irb, Scope *scope, AstNo...@@ -4364,7 +4719,7 @@ static IrInstruction *ir_gen_builtin_fn_call(IrBuilder *irb, Scope *scope, AstNo
4364 return arg0_value;4719 return arg0_value;
43654720
4366 IrInstruction *fence = ir_build_fence(irb, scope, node, arg0_value, AtomicOrderUnordered);4721 IrInstruction *fence = ir_build_fence(irb, scope, node, arg0_value, AtomicOrderUnordered);
4367 return ir_lval_wrap(irb, scope, fence, lval);4722 return ir_lval_wrap(irb, scope, fence, lval, result_loc);
4368 }4723 }
4369 case BuiltinFnIdDivExact:4724 case BuiltinFnIdDivExact:
4370 {4725 {
...@@ -4379,7 +4734,7 @@ static IrInstruction *ir_gen_builtin_fn_call(IrBuilder *irb, Scope *scope, AstNo...@@ -4379,7 +4734,7 @@ static IrInstruction *ir_gen_builtin_fn_call(IrBuilder *irb, Scope *scope, AstNo
4379 return arg1_value;4734 return arg1_value;
43804735
4381 IrInstruction *bin_op = ir_build_bin_op(irb, scope, node, IrBinOpDivExact, arg0_value, arg1_value, true);4736 IrInstruction *bin_op = ir_build_bin_op(irb, scope, node, IrBinOpDivExact, arg0_value, arg1_value, true);
4382 return ir_lval_wrap(irb, scope, bin_op, lval);4737 return ir_lval_wrap(irb, scope, bin_op, lval, result_loc);
4383 }4738 }
4384 case BuiltinFnIdDivTrunc:4739 case BuiltinFnIdDivTrunc:
4385 {4740 {
...@@ -4394,7 +4749,7 @@ static IrInstruction *ir_gen_builtin_fn_call(IrBuilder *irb, Scope *scope, AstNo...@@ -4394,7 +4749,7 @@ static IrInstruction *ir_gen_builtin_fn_call(IrBuilder *irb, Scope *scope, AstNo
4394 return arg1_value;4749 return arg1_value;
43954750
4396 IrInstruction *bin_op = ir_build_bin_op(irb, scope, node, IrBinOpDivTrunc, arg0_value, arg1_value, true);4751 IrInstruction *bin_op = ir_build_bin_op(irb, scope, node, IrBinOpDivTrunc, arg0_value, arg1_value, true);
4397 return ir_lval_wrap(irb, scope, bin_op, lval);4752 return ir_lval_wrap(irb, scope, bin_op, lval, result_loc);
4398 }4753 }
4399 case BuiltinFnIdDivFloor:4754 case BuiltinFnIdDivFloor:
4400 {4755 {
...@@ -4409,7 +4764,7 @@ static IrInstruction *ir_gen_builtin_fn_call(IrBuilder *irb, Scope *scope, AstNo...@@ -4409,7 +4764,7 @@ static IrInstruction *ir_gen_builtin_fn_call(IrBuilder *irb, Scope *scope, AstNo
4409 return arg1_value;4764 return arg1_value;
44104765
4411 IrInstruction *bin_op = ir_build_bin_op(irb, scope, node, IrBinOpDivFloor, arg0_value, arg1_value, true);4766 IrInstruction *bin_op = ir_build_bin_op(irb, scope, node, IrBinOpDivFloor, arg0_value, arg1_value, true);
4412 return ir_lval_wrap(irb, scope, bin_op, lval);4767 return ir_lval_wrap(irb, scope, bin_op, lval, result_loc);
4413 }4768 }
4414 case BuiltinFnIdRem:4769 case BuiltinFnIdRem:
4415 {4770 {
...@@ -4424,7 +4779,7 @@ static IrInstruction *ir_gen_builtin_fn_call(IrBuilder *irb, Scope *scope, AstNo...@@ -4424,7 +4779,7 @@ static IrInstruction *ir_gen_builtin_fn_call(IrBuilder *irb, Scope *scope, AstNo
4424 return arg1_value;4779 return arg1_value;
44254780
4426 IrInstruction *bin_op = ir_build_bin_op(irb, scope, node, IrBinOpRemRem, arg0_value, arg1_value, true);4781 IrInstruction *bin_op = ir_build_bin_op(irb, scope, node, IrBinOpRemRem, arg0_value, arg1_value, true);
4427 return ir_lval_wrap(irb, scope, bin_op, lval);4782 return ir_lval_wrap(irb, scope, bin_op, lval, result_loc);
4428 }4783 }
4429 case BuiltinFnIdMod:4784 case BuiltinFnIdMod:
4430 {4785 {
...@@ -4439,7 +4794,7 @@ static IrInstruction *ir_gen_builtin_fn_call(IrBuilder *irb, Scope *scope, AstNo...@@ -4439,7 +4794,7 @@ static IrInstruction *ir_gen_builtin_fn_call(IrBuilder *irb, Scope *scope, AstNo
4439 return arg1_value;4794 return arg1_value;
44404795
4441 IrInstruction *bin_op = ir_build_bin_op(irb, scope, node, IrBinOpRemMod, arg0_value, arg1_value, true);4796 IrInstruction *bin_op = ir_build_bin_op(irb, scope, node, IrBinOpRemMod, arg0_value, arg1_value, true);
4442 return ir_lval_wrap(irb, scope, bin_op, lval);4797 return ir_lval_wrap(irb, scope, bin_op, lval, result_loc);
4443 }4798 }
4444 case BuiltinFnIdSqrt:4799 case BuiltinFnIdSqrt:
4445 case BuiltinFnIdSin:4800 case BuiltinFnIdSin:
...@@ -4467,7 +4822,7 @@ static IrInstruction *ir_gen_builtin_fn_call(IrBuilder *irb, Scope *scope, AstNo...@@ -4467,7 +4822,7 @@ static IrInstruction *ir_gen_builtin_fn_call(IrBuilder *irb, Scope *scope, AstNo
4467 return arg1_value;4822 return arg1_value;
44684823
4469 IrInstruction *ir_sqrt = ir_build_float_op(irb, scope, node, arg0_value, arg1_value, builtin_fn->id);4824 IrInstruction *ir_sqrt = ir_build_float_op(irb, scope, node, arg0_value, arg1_value, builtin_fn->id);
4470 return ir_lval_wrap(irb, scope, ir_sqrt, lval);4825 return ir_lval_wrap(irb, scope, ir_sqrt, lval, result_loc);
4471 }4826 }
4472 case BuiltinFnIdTruncate:4827 case BuiltinFnIdTruncate:
4473 {4828 {
...@@ -4482,7 +4837,7 @@ static IrInstruction *ir_gen_builtin_fn_call(IrBuilder *irb, Scope *scope, AstNo...@@ -4482,7 +4837,7 @@ static IrInstruction *ir_gen_builtin_fn_call(IrBuilder *irb, Scope *scope, AstNo
4482 return arg1_value;4837 return arg1_value;
44834838
4484 IrInstruction *truncate = ir_build_truncate(irb, scope, node, arg0_value, arg1_value);4839 IrInstruction *truncate = ir_build_truncate(irb, scope, node, arg0_value, arg1_value);
4485 return ir_lval_wrap(irb, scope, truncate, lval);4840 return ir_lval_wrap(irb, scope, truncate, lval, result_loc);
4486 }4841 }
4487 case BuiltinFnIdIntCast:4842 case BuiltinFnIdIntCast:
4488 {4843 {
...@@ -4497,7 +4852,7 @@ static IrInstruction *ir_gen_builtin_fn_call(IrBuilder *irb, Scope *scope, AstNo...@@ -4497,7 +4852,7 @@ static IrInstruction *ir_gen_builtin_fn_call(IrBuilder *irb, Scope *scope, AstNo
4497 return arg1_value;4852 return arg1_value;
44984853
4499 IrInstruction *result = ir_build_int_cast(irb, scope, node, arg0_value, arg1_value);4854 IrInstruction *result = ir_build_int_cast(irb, scope, node, arg0_value, arg1_value);
4500 return ir_lval_wrap(irb, scope, result, lval);4855 return ir_lval_wrap(irb, scope, result, lval, result_loc);
4501 }4856 }
4502 case BuiltinFnIdFloatCast:4857 case BuiltinFnIdFloatCast:
4503 {4858 {
...@@ -4512,7 +4867,7 @@ static IrInstruction *ir_gen_builtin_fn_call(IrBuilder *irb, Scope *scope, AstNo...@@ -4512,7 +4867,7 @@ static IrInstruction *ir_gen_builtin_fn_call(IrBuilder *irb, Scope *scope, AstNo
4512 return arg1_value;4867 return arg1_value;
45134868
4514 IrInstruction *result = ir_build_float_cast(irb, scope, node, arg0_value, arg1_value);4869 IrInstruction *result = ir_build_float_cast(irb, scope, node, arg0_value, arg1_value);
4515 return ir_lval_wrap(irb, scope, result, lval);4870 return ir_lval_wrap(irb, scope, result, lval, result_loc);
4516 }4871 }
4517 case BuiltinFnIdErrSetCast:4872 case BuiltinFnIdErrSetCast:
4518 {4873 {
...@@ -4527,7 +4882,7 @@ static IrInstruction *ir_gen_builtin_fn_call(IrBuilder *irb, Scope *scope, AstNo...@@ -4527,7 +4882,7 @@ static IrInstruction *ir_gen_builtin_fn_call(IrBuilder *irb, Scope *scope, AstNo
4527 return arg1_value;4882 return arg1_value;
45284883
4529 IrInstruction *result = ir_build_err_set_cast(irb, scope, node, arg0_value, arg1_value);4884 IrInstruction *result = ir_build_err_set_cast(irb, scope, node, arg0_value, arg1_value);
4530 return ir_lval_wrap(irb, scope, result, lval);4885 return ir_lval_wrap(irb, scope, result, lval, result_loc);
4531 }4886 }
4532 case BuiltinFnIdFromBytes:4887 case BuiltinFnIdFromBytes:
4533 {4888 {
...@@ -4541,8 +4896,8 @@ static IrInstruction *ir_gen_builtin_fn_call(IrBuilder *irb, Scope *scope, AstNo...@@ -4541,8 +4896,8 @@ static IrInstruction *ir_gen_builtin_fn_call(IrBuilder *irb, Scope *scope, AstNo
4541 if (arg1_value == irb->codegen->invalid_instruction)4896 if (arg1_value == irb->codegen->invalid_instruction)
4542 return arg1_value;4897 return arg1_value;
45434898
4544 IrInstruction *result = ir_build_from_bytes(irb, scope, node, arg0_value, arg1_value);4899 IrInstruction *result = ir_build_from_bytes(irb, scope, node, arg0_value, arg1_value, result_loc);
4545 return ir_lval_wrap(irb, scope, result, lval);4900 return ir_lval_wrap(irb, scope, result, lval, result_loc);
4546 }4901 }
4547 case BuiltinFnIdToBytes:4902 case BuiltinFnIdToBytes:
4548 {4903 {
...@@ -4551,8 +4906,8 @@ static IrInstruction *ir_gen_builtin_fn_call(IrBuilder *irb, Scope *scope, AstNo...@@ -4551,8 +4906,8 @@ static IrInstruction *ir_gen_builtin_fn_call(IrBuilder *irb, Scope *scope, AstNo
4551 if (arg0_value == irb->codegen->invalid_instruction)4906 if (arg0_value == irb->codegen->invalid_instruction)
4552 return arg0_value;4907 return arg0_value;
45534908
4554 IrInstruction *result = ir_build_to_bytes(irb, scope, node, arg0_value);4909 IrInstruction *result = ir_build_to_bytes(irb, scope, node, arg0_value, result_loc);
4555 return ir_lval_wrap(irb, scope, result, lval);4910 return ir_lval_wrap(irb, scope, result, lval, result_loc);
4556 }4911 }
4557 case BuiltinFnIdIntToFloat:4912 case BuiltinFnIdIntToFloat:
4558 {4913 {
...@@ -4567,7 +4922,7 @@ static IrInstruction *ir_gen_builtin_fn_call(IrBuilder *irb, Scope *scope, AstNo...@@ -4567,7 +4922,7 @@ static IrInstruction *ir_gen_builtin_fn_call(IrBuilder *irb, Scope *scope, AstNo
4567 return arg1_value;4922 return arg1_value;
45684923
4569 IrInstruction *result = ir_build_int_to_float(irb, scope, node, arg0_value, arg1_value);4924 IrInstruction *result = ir_build_int_to_float(irb, scope, node, arg0_value, arg1_value);
4570 return ir_lval_wrap(irb, scope, result, lval);4925 return ir_lval_wrap(irb, scope, result, lval, result_loc);
4571 }4926 }
4572 case BuiltinFnIdFloatToInt:4927 case BuiltinFnIdFloatToInt:
4573 {4928 {
...@@ -4582,7 +4937,7 @@ static IrInstruction *ir_gen_builtin_fn_call(IrBuilder *irb, Scope *scope, AstNo...@@ -4582,7 +4937,7 @@ static IrInstruction *ir_gen_builtin_fn_call(IrBuilder *irb, Scope *scope, AstNo
4582 return arg1_value;4937 return arg1_value;
45834938
4584 IrInstruction *result = ir_build_float_to_int(irb, scope, node, arg0_value, arg1_value);4939 IrInstruction *result = ir_build_float_to_int(irb, scope, node, arg0_value, arg1_value);
4585 return ir_lval_wrap(irb, scope, result, lval);4940 return ir_lval_wrap(irb, scope, result, lval, result_loc);
4586 }4941 }
4587 case BuiltinFnIdErrToInt:4942 case BuiltinFnIdErrToInt:
4588 {4943 {
...@@ -4592,7 +4947,7 @@ static IrInstruction *ir_gen_builtin_fn_call(IrBuilder *irb, Scope *scope, AstNo...@@ -4592,7 +4947,7 @@ static IrInstruction *ir_gen_builtin_fn_call(IrBuilder *irb, Scope *scope, AstNo
4592 return arg0_value;4947 return arg0_value;
45934948
4594 IrInstruction *result = ir_build_err_to_int(irb, scope, node, arg0_value);4949 IrInstruction *result = ir_build_err_to_int(irb, scope, node, arg0_value);
4595 return ir_lval_wrap(irb, scope, result, lval);4950 return ir_lval_wrap(irb, scope, result, lval, result_loc);
4596 }4951 }
4597 case BuiltinFnIdIntToErr:4952 case BuiltinFnIdIntToErr:
4598 {4953 {
...@@ -4602,7 +4957,7 @@ static IrInstruction *ir_gen_builtin_fn_call(IrBuilder *irb, Scope *scope, AstNo...@@ -4602,7 +4957,7 @@ static IrInstruction *ir_gen_builtin_fn_call(IrBuilder *irb, Scope *scope, AstNo
4602 return arg0_value;4957 return arg0_value;
46034958
4604 IrInstruction *result = ir_build_int_to_err(irb, scope, node, arg0_value);4959 IrInstruction *result = ir_build_int_to_err(irb, scope, node, arg0_value);
4605 return ir_lval_wrap(irb, scope, result, lval);4960 return ir_lval_wrap(irb, scope, result, lval, result_loc);
4606 }4961 }
4607 case BuiltinFnIdBoolToInt:4962 case BuiltinFnIdBoolToInt:
4608 {4963 {
...@@ -4612,7 +4967,7 @@ static IrInstruction *ir_gen_builtin_fn_call(IrBuilder *irb, Scope *scope, AstNo...@@ -4612,7 +4967,7 @@ static IrInstruction *ir_gen_builtin_fn_call(IrBuilder *irb, Scope *scope, AstNo
4612 return arg0_value;4967 return arg0_value;
46134968
4614 IrInstruction *result = ir_build_bool_to_int(irb, scope, node, arg0_value);4969 IrInstruction *result = ir_build_bool_to_int(irb, scope, node, arg0_value);
4615 return ir_lval_wrap(irb, scope, result, lval);4970 return ir_lval_wrap(irb, scope, result, lval, result_loc);
4616 }4971 }
4617 case BuiltinFnIdIntType:4972 case BuiltinFnIdIntType:
4618 {4973 {
...@@ -4627,7 +4982,7 @@ static IrInstruction *ir_gen_builtin_fn_call(IrBuilder *irb, Scope *scope, AstNo...@@ -4627,7 +4982,7 @@ static IrInstruction *ir_gen_builtin_fn_call(IrBuilder *irb, Scope *scope, AstNo
4627 return arg1_value;4982 return arg1_value;
46284983
4629 IrInstruction *int_type = ir_build_int_type(irb, scope, node, arg0_value, arg1_value);4984 IrInstruction *int_type = ir_build_int_type(irb, scope, node, arg0_value, arg1_value);
4630 return ir_lval_wrap(irb, scope, int_type, lval);4985 return ir_lval_wrap(irb, scope, int_type, lval, result_loc);
4631 }4986 }
4632 case BuiltinFnIdVectorType:4987 case BuiltinFnIdVectorType:
4633 {4988 {
...@@ -4642,7 +4997,7 @@ static IrInstruction *ir_gen_builtin_fn_call(IrBuilder *irb, Scope *scope, AstNo...@@ -4642,7 +4997,7 @@ static IrInstruction *ir_gen_builtin_fn_call(IrBuilder *irb, Scope *scope, AstNo
4642 return arg1_value;4997 return arg1_value;
46434998
4644 IrInstruction *vector_type = ir_build_vector_type(irb, scope, node, arg0_value, arg1_value);4999 IrInstruction *vector_type = ir_build_vector_type(irb, scope, node, arg0_value, arg1_value);
4645 return ir_lval_wrap(irb, scope, vector_type, lval);5000 return ir_lval_wrap(irb, scope, vector_type, lval, result_loc);
4646 }5001 }
4647 case BuiltinFnIdMemcpy:5002 case BuiltinFnIdMemcpy:
4648 {5003 {
...@@ -4662,7 +5017,7 @@ static IrInstruction *ir_gen_builtin_fn_call(IrBuilder *irb, Scope *scope, AstNo...@@ -4662,7 +5017,7 @@ static IrInstruction *ir_gen_builtin_fn_call(IrBuilder *irb, Scope *scope, AstNo
4662 return arg2_value;5017 return arg2_value;
46635018
4664 IrInstruction *ir_memcpy = ir_build_memcpy(irb, scope, node, arg0_value, arg1_value, arg2_value);5019 IrInstruction *ir_memcpy = ir_build_memcpy(irb, scope, node, arg0_value, arg1_value, arg2_value);
4665 return ir_lval_wrap(irb, scope, ir_memcpy, lval);5020 return ir_lval_wrap(irb, scope, ir_memcpy, lval, result_loc);
4666 }5021 }
4667 case BuiltinFnIdMemset:5022 case BuiltinFnIdMemset:
4668 {5023 {
...@@ -4682,7 +5037,7 @@ static IrInstruction *ir_gen_builtin_fn_call(IrBuilder *irb, Scope *scope, AstNo...@@ -4682,7 +5037,7 @@ static IrInstruction *ir_gen_builtin_fn_call(IrBuilder *irb, Scope *scope, AstNo
4682 return arg2_value;5037 return arg2_value;
46835038
4684 IrInstruction *ir_memset = ir_build_memset(irb, scope, node, arg0_value, arg1_value, arg2_value);5039 IrInstruction *ir_memset = ir_build_memset(irb, scope, node, arg0_value, arg1_value, arg2_value);
4685 return ir_lval_wrap(irb, scope, ir_memset, lval);5040 return ir_lval_wrap(irb, scope, ir_memset, lval, result_loc);
4686 }5041 }
4687 case BuiltinFnIdMemberCount:5042 case BuiltinFnIdMemberCount:
4688 {5043 {
...@@ -4692,7 +5047,7 @@ static IrInstruction *ir_gen_builtin_fn_call(IrBuilder *irb, Scope *scope, AstNo...@@ -4692,7 +5047,7 @@ static IrInstruction *ir_gen_builtin_fn_call(IrBuilder *irb, Scope *scope, AstNo
4692 return arg0_value;5047 return arg0_value;
46935048
4694 IrInstruction *member_count = ir_build_member_count(irb, scope, node, arg0_value);5049 IrInstruction *member_count = ir_build_member_count(irb, scope, node, arg0_value);
4695 return ir_lval_wrap(irb, scope, member_count, lval);5050 return ir_lval_wrap(irb, scope, member_count, lval, result_loc);
4696 }5051 }
4697 case BuiltinFnIdMemberType:5052 case BuiltinFnIdMemberType:
4698 {5053 {
...@@ -4708,7 +5063,7 @@ static IrInstruction *ir_gen_builtin_fn_call(IrBuilder *irb, Scope *scope, AstNo...@@ -4708,7 +5063,7 @@ static IrInstruction *ir_gen_builtin_fn_call(IrBuilder *irb, Scope *scope, AstNo
47085063
47095064
4710 IrInstruction *member_type = ir_build_member_type(irb, scope, node, arg0_value, arg1_value);5065 IrInstruction *member_type = ir_build_member_type(irb, scope, node, arg0_value, arg1_value);
4711 return ir_lval_wrap(irb, scope, member_type, lval);5066 return ir_lval_wrap(irb, scope, member_type, lval, result_loc);
4712 }5067 }
4713 case BuiltinFnIdMemberName:5068 case BuiltinFnIdMemberName:
4714 {5069 {
...@@ -4724,12 +5079,12 @@ static IrInstruction *ir_gen_builtin_fn_call(IrBuilder *irb, Scope *scope, AstNo...@@ -4724,12 +5079,12 @@ static IrInstruction *ir_gen_builtin_fn_call(IrBuilder *irb, Scope *scope, AstNo
47245079
47255080
4726 IrInstruction *member_name = ir_build_member_name(irb, scope, node, arg0_value, arg1_value);5081 IrInstruction *member_name = ir_build_member_name(irb, scope, node, arg0_value, arg1_value);
4727 return ir_lval_wrap(irb, scope, member_name, lval);5082 return ir_lval_wrap(irb, scope, member_name, lval, result_loc);
4728 }5083 }
4729 case BuiltinFnIdField:5084 case BuiltinFnIdField:
4730 {5085 {
4731 AstNode *arg0_node = node->data.fn_call_expr.params.at(0);5086 AstNode *arg0_node = node->data.fn_call_expr.params.at(0);
4732 IrInstruction *arg0_value = ir_gen_node_extra(irb, arg0_node, scope, LValPtr);5087 IrInstruction *arg0_value = ir_gen_node_extra(irb, arg0_node, scope, LValPtr, nullptr);
4733 if (arg0_value == irb->codegen->invalid_instruction)5088 if (arg0_value == irb->codegen->invalid_instruction)
4734 return arg0_value;5089 return arg0_value;
47355090
...@@ -4743,7 +5098,8 @@ static IrInstruction *ir_gen_builtin_fn_call(IrBuilder *irb, Scope *scope, AstNo...@@ -4743,7 +5098,8 @@ static IrInstruction *ir_gen_builtin_fn_call(IrBuilder *irb, Scope *scope, AstNo
4743 if (lval == LValPtr)5098 if (lval == LValPtr)
4744 return ptr_instruction;5099 return ptr_instruction;
47455100
4746 return ir_build_load_ptr(irb, scope, node, ptr_instruction);5101 IrInstruction *load_ptr = ir_build_load_ptr(irb, scope, node, ptr_instruction);
5102 return ir_expr_wrap(irb, scope, load_ptr, result_loc);
4747 }5103 }
4748 case BuiltinFnIdTypeInfo:5104 case BuiltinFnIdTypeInfo:
4749 {5105 {
...@@ -4753,14 +5109,14 @@ static IrInstruction *ir_gen_builtin_fn_call(IrBuilder *irb, Scope *scope, AstNo...@@ -4753,14 +5109,14 @@ static IrInstruction *ir_gen_builtin_fn_call(IrBuilder *irb, Scope *scope, AstNo
4753 return arg0_value;5109 return arg0_value;
47545110
4755 IrInstruction *type_info = ir_build_type_info(irb, scope, node, arg0_value);5111 IrInstruction *type_info = ir_build_type_info(irb, scope, node, arg0_value);
4756 return ir_lval_wrap(irb, scope, type_info, lval);5112 return ir_lval_wrap(irb, scope, type_info, lval, result_loc);
4757 }5113 }
4758 case BuiltinFnIdBreakpoint:5114 case BuiltinFnIdBreakpoint:
4759 return ir_lval_wrap(irb, scope, ir_build_breakpoint(irb, scope, node), lval);5115 return ir_lval_wrap(irb, scope, ir_build_breakpoint(irb, scope, node), lval, result_loc);
4760 case BuiltinFnIdReturnAddress:5116 case BuiltinFnIdReturnAddress:
4761 return ir_lval_wrap(irb, scope, ir_build_return_address(irb, scope, node), lval);5117 return ir_lval_wrap(irb, scope, ir_build_return_address(irb, scope, node), lval, result_loc);
4762 case BuiltinFnIdFrameAddress:5118 case BuiltinFnIdFrameAddress:
4763 return ir_lval_wrap(irb, scope, ir_build_frame_address(irb, scope, node), lval);5119 return ir_lval_wrap(irb, scope, ir_build_frame_address(irb, scope, node), lval, result_loc);
4764 case BuiltinFnIdHandle:5120 case BuiltinFnIdHandle:
4765 if (!irb->exec->fn_entry) {5121 if (!irb->exec->fn_entry) {
4766 add_node_error(irb->codegen, node, buf_sprintf("@handle() called outside of function definition"));5122 add_node_error(irb->codegen, node, buf_sprintf("@handle() called outside of function definition"));
...@@ -4770,7 +5126,7 @@ static IrInstruction *ir_gen_builtin_fn_call(IrBuilder *irb, Scope *scope, AstNo...@@ -4770,7 +5126,7 @@ static IrInstruction *ir_gen_builtin_fn_call(IrBuilder *irb, Scope *scope, AstNo
4770 add_node_error(irb->codegen, node, buf_sprintf("@handle() in non-async function"));5126 add_node_error(irb->codegen, node, buf_sprintf("@handle() in non-async function"));
4771 return irb->codegen->invalid_instruction;5127 return irb->codegen->invalid_instruction;
4772 }5128 }
4773 return ir_lval_wrap(irb, scope, ir_build_handle(irb, scope, node), lval);5129 return ir_lval_wrap(irb, scope, ir_build_handle(irb, scope, node), lval, result_loc);
4774 case BuiltinFnIdAlignOf:5130 case BuiltinFnIdAlignOf:
4775 {5131 {
4776 AstNode *arg0_node = node->data.fn_call_expr.params.at(0);5132 AstNode *arg0_node = node->data.fn_call_expr.params.at(0);
...@@ -4779,18 +5135,18 @@ static IrInstruction *ir_gen_builtin_fn_call(IrBuilder *irb, Scope *scope, AstNo...@@ -4779,18 +5135,18 @@ static IrInstruction *ir_gen_builtin_fn_call(IrBuilder *irb, Scope *scope, AstNo
4779 return arg0_value;5135 return arg0_value;
47805136
4781 IrInstruction *align_of = ir_build_align_of(irb, scope, node, arg0_value);5137 IrInstruction *align_of = ir_build_align_of(irb, scope, node, arg0_value);
4782 return ir_lval_wrap(irb, scope, align_of, lval);5138 return ir_lval_wrap(irb, scope, align_of, lval, result_loc);
4783 }5139 }
4784 case BuiltinFnIdAddWithOverflow:5140 case BuiltinFnIdAddWithOverflow:
4785 return ir_lval_wrap(irb, scope, ir_gen_overflow_op(irb, scope, node, IrOverflowOpAdd), lval);5141 return ir_lval_wrap(irb, scope, ir_gen_overflow_op(irb, scope, node, IrOverflowOpAdd), lval, result_loc);
4786 case BuiltinFnIdSubWithOverflow:5142 case BuiltinFnIdSubWithOverflow:
4787 return ir_lval_wrap(irb, scope, ir_gen_overflow_op(irb, scope, node, IrOverflowOpSub), lval);5143 return ir_lval_wrap(irb, scope, ir_gen_overflow_op(irb, scope, node, IrOverflowOpSub), lval, result_loc);
4788 case BuiltinFnIdMulWithOverflow:5144 case BuiltinFnIdMulWithOverflow:
4789 return ir_lval_wrap(irb, scope, ir_gen_overflow_op(irb, scope, node, IrOverflowOpMul), lval);5145 return ir_lval_wrap(irb, scope, ir_gen_overflow_op(irb, scope, node, IrOverflowOpMul), lval, result_loc);
4790 case BuiltinFnIdShlWithOverflow:5146 case BuiltinFnIdShlWithOverflow:
4791 return ir_lval_wrap(irb, scope, ir_gen_overflow_op(irb, scope, node, IrOverflowOpShl), lval);5147 return ir_lval_wrap(irb, scope, ir_gen_overflow_op(irb, scope, node, IrOverflowOpShl), lval, result_loc);
4792 case BuiltinFnIdMulAdd:5148 case BuiltinFnIdMulAdd:
4793 return ir_lval_wrap(irb, scope, ir_gen_mul_add(irb, scope, node), lval);5149 return ir_lval_wrap(irb, scope, ir_gen_mul_add(irb, scope, node), lval, result_loc);
4794 case BuiltinFnIdTypeName:5150 case BuiltinFnIdTypeName:
4795 {5151 {
4796 AstNode *arg0_node = node->data.fn_call_expr.params.at(0);5152 AstNode *arg0_node = node->data.fn_call_expr.params.at(0);
...@@ -4799,7 +5155,7 @@ static IrInstruction *ir_gen_builtin_fn_call(IrBuilder *irb, Scope *scope, AstNo...@@ -4799,7 +5155,7 @@ static IrInstruction *ir_gen_builtin_fn_call(IrBuilder *irb, Scope *scope, AstNo
4799 return arg0_value;5155 return arg0_value;
48005156
4801 IrInstruction *type_name = ir_build_type_name(irb, scope, node, arg0_value);5157 IrInstruction *type_name = ir_build_type_name(irb, scope, node, arg0_value);
4802 return ir_lval_wrap(irb, scope, type_name, lval);5158 return ir_lval_wrap(irb, scope, type_name, lval, result_loc);
4803 }5159 }
4804 case BuiltinFnIdPanic:5160 case BuiltinFnIdPanic:
4805 {5161 {
...@@ -4809,7 +5165,7 @@ static IrInstruction *ir_gen_builtin_fn_call(IrBuilder *irb, Scope *scope, AstNo...@@ -4809,7 +5165,7 @@ static IrInstruction *ir_gen_builtin_fn_call(IrBuilder *irb, Scope *scope, AstNo
4809 return arg0_value;5165 return arg0_value;
48105166
4811 IrInstruction *panic = ir_build_panic(irb, scope, node, arg0_value);5167 IrInstruction *panic = ir_build_panic(irb, scope, node, arg0_value);
4812 return ir_lval_wrap(irb, scope, panic, lval);5168 return ir_lval_wrap(irb, scope, panic, lval, result_loc);
4813 }5169 }
4814 case BuiltinFnIdPtrCast:5170 case BuiltinFnIdPtrCast:
4815 {5171 {
...@@ -4824,22 +5180,31 @@ static IrInstruction *ir_gen_builtin_fn_call(IrBuilder *irb, Scope *scope, AstNo...@@ -4824,22 +5180,31 @@ static IrInstruction *ir_gen_builtin_fn_call(IrBuilder *irb, Scope *scope, AstNo
4824 return arg1_value;5180 return arg1_value;
48255181
4826 IrInstruction *ptr_cast = ir_build_ptr_cast_src(irb, scope, node, arg0_value, arg1_value, true);5182 IrInstruction *ptr_cast = ir_build_ptr_cast_src(irb, scope, node, arg0_value, arg1_value, true);
4827 return ir_lval_wrap(irb, scope, ptr_cast, lval);5183 return ir_lval_wrap(irb, scope, ptr_cast, lval, result_loc);
4828 }5184 }
4829 case BuiltinFnIdBitCast:5185 case BuiltinFnIdBitCast:
4830 {5186 {
4831 AstNode *arg0_node = node->data.fn_call_expr.params.at(0);5187 AstNode *dest_type_node = node->data.fn_call_expr.params.at(0);
4832 IrInstruction *arg0_value = ir_gen_node(irb, arg0_node, scope);5188 IrInstruction *dest_type = ir_gen_node(irb, dest_type_node, scope);
4833 if (arg0_value == irb->codegen->invalid_instruction)5189 if (dest_type == irb->codegen->invalid_instruction)
4834 return arg0_value;5190 return dest_type;
5191
5192 ResultLocBitCast *result_loc_bit_cast = allocate<ResultLocBitCast>(1);
5193 result_loc_bit_cast->base.id = ResultLocIdBitCast;
5194 result_loc_bit_cast->base.source_instruction = dest_type;
5195 ir_ref_instruction(dest_type, irb->current_basic_block);
5196 result_loc_bit_cast->parent = result_loc;
5197
5198 ir_build_reset_result(irb, scope, node, &result_loc_bit_cast->base);
48355199
4836 AstNode *arg1_node = node->data.fn_call_expr.params.at(1);5200 AstNode *arg1_node = node->data.fn_call_expr.params.at(1);
4837 IrInstruction *arg1_value = ir_gen_node(irb, arg1_node, scope);5201 IrInstruction *arg1_value = ir_gen_node_extra(irb, arg1_node, scope, LValNone,
5202 &result_loc_bit_cast->base);
4838 if (arg1_value == irb->codegen->invalid_instruction)5203 if (arg1_value == irb->codegen->invalid_instruction)
4839 return arg1_value;5204 return arg1_value;
48405205
4841 IrInstruction *bit_cast = ir_build_bit_cast(irb, scope, node, arg0_value, arg1_value);5206 IrInstruction *bitcast = ir_build_bit_cast_src(irb, scope, arg1_node, arg1_value, result_loc_bit_cast);
4842 return ir_lval_wrap(irb, scope, bit_cast, lval);5207 return ir_lval_wrap(irb, scope, bitcast, lval, result_loc);
4843 }5208 }
4844 case BuiltinFnIdIntToPtr:5209 case BuiltinFnIdIntToPtr:
4845 {5210 {
...@@ -4854,7 +5219,7 @@ static IrInstruction *ir_gen_builtin_fn_call(IrBuilder *irb, Scope *scope, AstNo...@@ -4854,7 +5219,7 @@ static IrInstruction *ir_gen_builtin_fn_call(IrBuilder *irb, Scope *scope, AstNo
4854 return arg1_value;5219 return arg1_value;
48555220
4856 IrInstruction *int_to_ptr = ir_build_int_to_ptr(irb, scope, node, arg0_value, arg1_value);5221 IrInstruction *int_to_ptr = ir_build_int_to_ptr(irb, scope, node, arg0_value, arg1_value);
4857 return ir_lval_wrap(irb, scope, int_to_ptr, lval);5222 return ir_lval_wrap(irb, scope, int_to_ptr, lval, result_loc);
4858 }5223 }
4859 case BuiltinFnIdPtrToInt:5224 case BuiltinFnIdPtrToInt:
4860 {5225 {
...@@ -4864,7 +5229,7 @@ static IrInstruction *ir_gen_builtin_fn_call(IrBuilder *irb, Scope *scope, AstNo...@@ -4864,7 +5229,7 @@ static IrInstruction *ir_gen_builtin_fn_call(IrBuilder *irb, Scope *scope, AstNo
4864 return arg0_value;5229 return arg0_value;
48655230
4866 IrInstruction *ptr_to_int = ir_build_ptr_to_int(irb, scope, node, arg0_value);5231 IrInstruction *ptr_to_int = ir_build_ptr_to_int(irb, scope, node, arg0_value);
4867 return ir_lval_wrap(irb, scope, ptr_to_int, lval);5232 return ir_lval_wrap(irb, scope, ptr_to_int, lval, result_loc);
4868 }5233 }
4869 case BuiltinFnIdTagName:5234 case BuiltinFnIdTagName:
4870 {5235 {
...@@ -4875,7 +5240,7 @@ static IrInstruction *ir_gen_builtin_fn_call(IrBuilder *irb, Scope *scope, AstNo...@@ -4875,7 +5240,7 @@ static IrInstruction *ir_gen_builtin_fn_call(IrBuilder *irb, Scope *scope, AstNo
48755240
4876 IrInstruction *actual_tag = ir_build_union_tag(irb, scope, node, arg0_value);5241 IrInstruction *actual_tag = ir_build_union_tag(irb, scope, node, arg0_value);
4877 IrInstruction *tag_name = ir_build_tag_name(irb, scope, node, actual_tag);5242 IrInstruction *tag_name = ir_build_tag_name(irb, scope, node, actual_tag);
4878 return ir_lval_wrap(irb, scope, tag_name, lval);5243 return ir_lval_wrap(irb, scope, tag_name, lval, result_loc);
4879 }5244 }
4880 case BuiltinFnIdTagType:5245 case BuiltinFnIdTagType:
4881 {5246 {
...@@ -4885,7 +5250,7 @@ static IrInstruction *ir_gen_builtin_fn_call(IrBuilder *irb, Scope *scope, AstNo...@@ -4885,7 +5250,7 @@ static IrInstruction *ir_gen_builtin_fn_call(IrBuilder *irb, Scope *scope, AstNo
4885 return arg0_value;5250 return arg0_value;
48865251
4887 IrInstruction *tag_type = ir_build_tag_type(irb, scope, node, arg0_value);5252 IrInstruction *tag_type = ir_build_tag_type(irb, scope, node, arg0_value);
4888 return ir_lval_wrap(irb, scope, tag_type, lval);5253 return ir_lval_wrap(irb, scope, tag_type, lval, result_loc);
4889 }5254 }
4890 case BuiltinFnIdFieldParentPtr:5255 case BuiltinFnIdFieldParentPtr:
4891 {5256 {
...@@ -4905,7 +5270,7 @@ static IrInstruction *ir_gen_builtin_fn_call(IrBuilder *irb, Scope *scope, AstNo...@@ -4905,7 +5270,7 @@ static IrInstruction *ir_gen_builtin_fn_call(IrBuilder *irb, Scope *scope, AstNo
4905 return arg2_value;5270 return arg2_value;
49065271
4907 IrInstruction *field_parent_ptr = ir_build_field_parent_ptr(irb, scope, node, arg0_value, arg1_value, arg2_value, nullptr);5272 IrInstruction *field_parent_ptr = ir_build_field_parent_ptr(irb, scope, node, arg0_value, arg1_value, arg2_value, nullptr);
4908 return ir_lval_wrap(irb, scope, field_parent_ptr, lval);5273 return ir_lval_wrap(irb, scope, field_parent_ptr, lval, result_loc);
4909 }5274 }
4910 case BuiltinFnIdByteOffsetOf:5275 case BuiltinFnIdByteOffsetOf:
4911 {5276 {
...@@ -4920,7 +5285,7 @@ static IrInstruction *ir_gen_builtin_fn_call(IrBuilder *irb, Scope *scope, AstNo...@@ -4920,7 +5285,7 @@ static IrInstruction *ir_gen_builtin_fn_call(IrBuilder *irb, Scope *scope, AstNo
4920 return arg1_value;5285 return arg1_value;
49215286
4922 IrInstruction *offset_of = ir_build_byte_offset_of(irb, scope, node, arg0_value, arg1_value);5287 IrInstruction *offset_of = ir_build_byte_offset_of(irb, scope, node, arg0_value, arg1_value);
4923 return ir_lval_wrap(irb, scope, offset_of, lval);5288 return ir_lval_wrap(irb, scope, offset_of, lval, result_loc);
4924 }5289 }
4925 case BuiltinFnIdBitOffsetOf:5290 case BuiltinFnIdBitOffsetOf:
4926 {5291 {
...@@ -4935,7 +5300,7 @@ static IrInstruction *ir_gen_builtin_fn_call(IrBuilder *irb, Scope *scope, AstNo...@@ -4935,7 +5300,7 @@ static IrInstruction *ir_gen_builtin_fn_call(IrBuilder *irb, Scope *scope, AstNo
4935 return arg1_value;5300 return arg1_value;
49365301
4937 IrInstruction *offset_of = ir_build_bit_offset_of(irb, scope, node, arg0_value, arg1_value);5302 IrInstruction *offset_of = ir_build_bit_offset_of(irb, scope, node, arg0_value, arg1_value);
4938 return ir_lval_wrap(irb, scope, offset_of, lval);5303 return ir_lval_wrap(irb, scope, offset_of, lval, result_loc);
4939 }5304 }
4940 case BuiltinFnIdInlineCall:5305 case BuiltinFnIdInlineCall:
4941 case BuiltinFnIdNoInlineCall:5306 case BuiltinFnIdNoInlineCall:
...@@ -4961,8 +5326,9 @@ static IrInstruction *ir_gen_builtin_fn_call(IrBuilder *irb, Scope *scope, AstNo...@@ -4961,8 +5326,9 @@ static IrInstruction *ir_gen_builtin_fn_call(IrBuilder *irb, Scope *scope, AstNo
4961 }5326 }
4962 FnInline fn_inline = (builtin_fn->id == BuiltinFnIdInlineCall) ? FnInlineAlways : FnInlineNever;5327 FnInline fn_inline = (builtin_fn->id == BuiltinFnIdInlineCall) ? FnInlineAlways : FnInlineNever;
49635328
4964 IrInstruction *call = ir_build_call(irb, scope, node, nullptr, fn_ref, arg_count, args, false, fn_inline, false, nullptr, nullptr);5329 IrInstruction *call = ir_build_call_src(irb, scope, node, nullptr, fn_ref, arg_count, args, false,
4965 return ir_lval_wrap(irb, scope, call, lval);5330 fn_inline, false, nullptr, nullptr, result_loc);
5331 return ir_lval_wrap(irb, scope, call, lval, result_loc);
4966 }5332 }
4967 case BuiltinFnIdNewStackCall:5333 case BuiltinFnIdNewStackCall:
4968 {5334 {
...@@ -4991,8 +5357,9 @@ static IrInstruction *ir_gen_builtin_fn_call(IrBuilder *irb, Scope *scope, AstNo...@@ -4991,8 +5357,9 @@ static IrInstruction *ir_gen_builtin_fn_call(IrBuilder *irb, Scope *scope, AstNo
4991 return args[i];5357 return args[i];
4992 }5358 }
49935359
4994 IrInstruction *call = ir_build_call(irb, scope, node, nullptr, fn_ref, arg_count, args, false, FnInlineAuto, false, nullptr, new_stack);5360 IrInstruction *call = ir_build_call_src(irb, scope, node, nullptr, fn_ref, arg_count, args, false,
4995 return ir_lval_wrap(irb, scope, call, lval);5361 FnInlineAuto, false, nullptr, new_stack, result_loc);
5362 return ir_lval_wrap(irb, scope, call, lval, result_loc);
4996 }5363 }
4997 case BuiltinFnIdTypeId:5364 case BuiltinFnIdTypeId:
4998 {5365 {
...@@ -5002,7 +5369,7 @@ static IrInstruction *ir_gen_builtin_fn_call(IrBuilder *irb, Scope *scope, AstNo...@@ -5002,7 +5369,7 @@ static IrInstruction *ir_gen_builtin_fn_call(IrBuilder *irb, Scope *scope, AstNo
5002 return arg0_value;5369 return arg0_value;
50035370
5004 IrInstruction *type_id = ir_build_type_id(irb, scope, node, arg0_value);5371 IrInstruction *type_id = ir_build_type_id(irb, scope, node, arg0_value);
5005 return ir_lval_wrap(irb, scope, type_id, lval);5372 return ir_lval_wrap(irb, scope, type_id, lval, result_loc);
5006 }5373 }
5007 case BuiltinFnIdShlExact:5374 case BuiltinFnIdShlExact:
5008 {5375 {
...@@ -5017,7 +5384,7 @@ static IrInstruction *ir_gen_builtin_fn_call(IrBuilder *irb, Scope *scope, AstNo...@@ -5017,7 +5384,7 @@ static IrInstruction *ir_gen_builtin_fn_call(IrBuilder *irb, Scope *scope, AstNo
5017 return arg1_value;5384 return arg1_value;
50185385
5019 IrInstruction *bin_op = ir_build_bin_op(irb, scope, node, IrBinOpBitShiftLeftExact, arg0_value, arg1_value, true);5386 IrInstruction *bin_op = ir_build_bin_op(irb, scope, node, IrBinOpBitShiftLeftExact, arg0_value, arg1_value, true);
5020 return ir_lval_wrap(irb, scope, bin_op, lval);5387 return ir_lval_wrap(irb, scope, bin_op, lval, result_loc);
5021 }5388 }
5022 case BuiltinFnIdShrExact:5389 case BuiltinFnIdShrExact:
5023 {5390 {
...@@ -5032,7 +5399,7 @@ static IrInstruction *ir_gen_builtin_fn_call(IrBuilder *irb, Scope *scope, AstNo...@@ -5032,7 +5399,7 @@ static IrInstruction *ir_gen_builtin_fn_call(IrBuilder *irb, Scope *scope, AstNo
5032 return arg1_value;5399 return arg1_value;
50335400
5034 IrInstruction *bin_op = ir_build_bin_op(irb, scope, node, IrBinOpBitShiftRightExact, arg0_value, arg1_value, true);5401 IrInstruction *bin_op = ir_build_bin_op(irb, scope, node, IrBinOpBitShiftRightExact, arg0_value, arg1_value, true);
5035 return ir_lval_wrap(irb, scope, bin_op, lval);5402 return ir_lval_wrap(irb, scope, bin_op, lval, result_loc);
5036 }5403 }
5037 case BuiltinFnIdSetEvalBranchQuota:5404 case BuiltinFnIdSetEvalBranchQuota:
5038 {5405 {
...@@ -5042,7 +5409,7 @@ static IrInstruction *ir_gen_builtin_fn_call(IrBuilder *irb, Scope *scope, AstNo...@@ -5042,7 +5409,7 @@ static IrInstruction *ir_gen_builtin_fn_call(IrBuilder *irb, Scope *scope, AstNo
5042 return arg0_value;5409 return arg0_value;
50435410
5044 IrInstruction *set_eval_branch_quota = ir_build_set_eval_branch_quota(irb, scope, node, arg0_value);5411 IrInstruction *set_eval_branch_quota = ir_build_set_eval_branch_quota(irb, scope, node, arg0_value);
5045 return ir_lval_wrap(irb, scope, set_eval_branch_quota, lval);5412 return ir_lval_wrap(irb, scope, set_eval_branch_quota, lval, result_loc);
5046 }5413 }
5047 case BuiltinFnIdAlignCast:5414 case BuiltinFnIdAlignCast:
5048 {5415 {
...@@ -5057,17 +5424,17 @@ static IrInstruction *ir_gen_builtin_fn_call(IrBuilder *irb, Scope *scope, AstNo...@@ -5057,17 +5424,17 @@ static IrInstruction *ir_gen_builtin_fn_call(IrBuilder *irb, Scope *scope, AstNo
5057 return arg1_value;5424 return arg1_value;
50585425
5059 IrInstruction *align_cast = ir_build_align_cast(irb, scope, node, arg0_value, arg1_value);5426 IrInstruction *align_cast = ir_build_align_cast(irb, scope, node, arg0_value, arg1_value);
5060 return ir_lval_wrap(irb, scope, align_cast, lval);5427 return ir_lval_wrap(irb, scope, align_cast, lval, result_loc);
5061 }5428 }
5062 case BuiltinFnIdOpaqueType:5429 case BuiltinFnIdOpaqueType:
5063 {5430 {
5064 IrInstruction *opaque_type = ir_build_opaque_type(irb, scope, node);5431 IrInstruction *opaque_type = ir_build_opaque_type(irb, scope, node);
5065 return ir_lval_wrap(irb, scope, opaque_type, lval);5432 return ir_lval_wrap(irb, scope, opaque_type, lval, result_loc);
5066 }5433 }
5067 case BuiltinFnIdThis:5434 case BuiltinFnIdThis:
5068 {5435 {
5069 IrInstruction *this_inst = ir_gen_this(irb, scope, node);5436 IrInstruction *this_inst = ir_gen_this(irb, scope, node);
5070 return ir_lval_wrap(irb, scope, this_inst, lval);5437 return ir_lval_wrap(irb, scope, this_inst, lval, result_loc);
5071 }5438 }
5072 case BuiltinFnIdSetAlignStack:5439 case BuiltinFnIdSetAlignStack:
5073 {5440 {
...@@ -5077,7 +5444,7 @@ static IrInstruction *ir_gen_builtin_fn_call(IrBuilder *irb, Scope *scope, AstNo...@@ -5077,7 +5444,7 @@ static IrInstruction *ir_gen_builtin_fn_call(IrBuilder *irb, Scope *scope, AstNo
5077 return arg0_value;5444 return arg0_value;
50785445
5079 IrInstruction *set_align_stack = ir_build_set_align_stack(irb, scope, node, arg0_value);5446 IrInstruction *set_align_stack = ir_build_set_align_stack(irb, scope, node, arg0_value);
5080 return ir_lval_wrap(irb, scope, set_align_stack, lval);5447 return ir_lval_wrap(irb, scope, set_align_stack, lval, result_loc);
5081 }5448 }
5082 case BuiltinFnIdArgType:5449 case BuiltinFnIdArgType:
5083 {5450 {
...@@ -5092,7 +5459,7 @@ static IrInstruction *ir_gen_builtin_fn_call(IrBuilder *irb, Scope *scope, AstNo...@@ -5092,7 +5459,7 @@ static IrInstruction *ir_gen_builtin_fn_call(IrBuilder *irb, Scope *scope, AstNo
5092 return arg1_value;5459 return arg1_value;
50935460
5094 IrInstruction *arg_type = ir_build_arg_type(irb, scope, node, arg0_value, arg1_value);5461 IrInstruction *arg_type = ir_build_arg_type(irb, scope, node, arg0_value, arg1_value);
5095 return ir_lval_wrap(irb, scope, arg_type, lval);5462 return ir_lval_wrap(irb, scope, arg_type, lval, result_loc);
5096 }5463 }
5097 case BuiltinFnIdExport:5464 case BuiltinFnIdExport:
5098 {5465 {
...@@ -5112,12 +5479,12 @@ static IrInstruction *ir_gen_builtin_fn_call(IrBuilder *irb, Scope *scope, AstNo...@@ -5112,12 +5479,12 @@ static IrInstruction *ir_gen_builtin_fn_call(IrBuilder *irb, Scope *scope, AstNo
5112 return arg2_value;5479 return arg2_value;
51135480
5114 IrInstruction *ir_export = ir_build_export(irb, scope, node, arg0_value, arg1_value, arg2_value);5481 IrInstruction *ir_export = ir_build_export(irb, scope, node, arg0_value, arg1_value, arg2_value);
5115 return ir_lval_wrap(irb, scope, ir_export, lval);5482 return ir_lval_wrap(irb, scope, ir_export, lval, result_loc);
5116 }5483 }
5117 case BuiltinFnIdErrorReturnTrace:5484 case BuiltinFnIdErrorReturnTrace:
5118 {5485 {
5119 IrInstruction *error_return_trace = ir_build_error_return_trace(irb, scope, node, IrInstructionErrorReturnTrace::Null);5486 IrInstruction *error_return_trace = ir_build_error_return_trace(irb, scope, node, IrInstructionErrorReturnTrace::Null);
5120 return ir_lval_wrap(irb, scope, error_return_trace, lval);5487 return ir_lval_wrap(irb, scope, error_return_trace, lval, result_loc);
5121 }5488 }
5122 case BuiltinFnIdAtomicRmw:5489 case BuiltinFnIdAtomicRmw:
5123 {5490 {
...@@ -5146,10 +5513,11 @@ static IrInstruction *ir_gen_builtin_fn_call(IrBuilder *irb, Scope *scope, AstNo...@@ -5146,10 +5513,11 @@ static IrInstruction *ir_gen_builtin_fn_call(IrBuilder *irb, Scope *scope, AstNo
5146 if (arg4_value == irb->codegen->invalid_instruction)5513 if (arg4_value == irb->codegen->invalid_instruction)
5147 return arg4_value;5514 return arg4_value;
51485515
5149 return ir_build_atomic_rmw(irb, scope, node, arg0_value, arg1_value, arg2_value, arg3_value,5516 IrInstruction *inst = ir_build_atomic_rmw(irb, scope, node, arg0_value, arg1_value, arg2_value, arg3_value,
5150 arg4_value,5517 arg4_value,
5151 // these 2 values don't mean anything since we passed non-null values for other args5518 // these 2 values don't mean anything since we passed non-null values for other args
5152 AtomicRmwOp_xchg, AtomicOrderMonotonic);5519 AtomicRmwOp_xchg, AtomicOrderMonotonic);
5520 return ir_lval_wrap(irb, scope, inst, lval, result_loc);
5153 }5521 }
5154 case BuiltinFnIdAtomicLoad:5522 case BuiltinFnIdAtomicLoad:
5155 {5523 {
...@@ -5168,9 +5536,10 @@ static IrInstruction *ir_gen_builtin_fn_call(IrBuilder *irb, Scope *scope, AstNo...@@ -5168,9 +5536,10 @@ static IrInstruction *ir_gen_builtin_fn_call(IrBuilder *irb, Scope *scope, AstNo
5168 if (arg2_value == irb->codegen->invalid_instruction)5536 if (arg2_value == irb->codegen->invalid_instruction)
5169 return arg2_value;5537 return arg2_value;
51705538
5171 return ir_build_atomic_load(irb, scope, node, arg0_value, arg1_value, arg2_value,5539 IrInstruction *inst = ir_build_atomic_load(irb, scope, node, arg0_value, arg1_value, arg2_value,
5172 // this value does not mean anything since we passed non-null values for other arg5540 // this value does not mean anything since we passed non-null values for other arg
5173 AtomicOrderMonotonic);5541 AtomicOrderMonotonic);
5542 return ir_lval_wrap(irb, scope, inst, lval, result_loc);
5174 }5543 }
5175 case BuiltinFnIdIntToEnum:5544 case BuiltinFnIdIntToEnum:
5176 {5545 {
...@@ -5185,7 +5554,7 @@ static IrInstruction *ir_gen_builtin_fn_call(IrBuilder *irb, Scope *scope, AstNo...@@ -5185,7 +5554,7 @@ static IrInstruction *ir_gen_builtin_fn_call(IrBuilder *irb, Scope *scope, AstNo
5185 return arg1_value;5554 return arg1_value;
51865555
5187 IrInstruction *result = ir_build_int_to_enum(irb, scope, node, arg0_value, arg1_value);5556 IrInstruction *result = ir_build_int_to_enum(irb, scope, node, arg0_value, arg1_value);
5188 return ir_lval_wrap(irb, scope, result, lval);5557 return ir_lval_wrap(irb, scope, result, lval, result_loc);
5189 }5558 }
5190 case BuiltinFnIdEnumToInt:5559 case BuiltinFnIdEnumToInt:
5191 {5560 {
...@@ -5195,7 +5564,7 @@ static IrInstruction *ir_gen_builtin_fn_call(IrBuilder *irb, Scope *scope, AstNo...@@ -5195,7 +5564,7 @@ static IrInstruction *ir_gen_builtin_fn_call(IrBuilder *irb, Scope *scope, AstNo
5195 return arg0_value;5564 return arg0_value;
51965565
5197 IrInstruction *result = ir_build_enum_to_int(irb, scope, node, arg0_value);5566 IrInstruction *result = ir_build_enum_to_int(irb, scope, node, arg0_value);
5198 return ir_lval_wrap(irb, scope, result, lval);5567 return ir_lval_wrap(irb, scope, result, lval, result_loc);
5199 }5568 }
5200 case BuiltinFnIdCtz:5569 case BuiltinFnIdCtz:
5201 case BuiltinFnIdPopCount:5570 case BuiltinFnIdPopCount:
...@@ -5233,7 +5602,7 @@ static IrInstruction *ir_gen_builtin_fn_call(IrBuilder *irb, Scope *scope, AstNo...@@ -5233,7 +5602,7 @@ static IrInstruction *ir_gen_builtin_fn_call(IrBuilder *irb, Scope *scope, AstNo
5233 default:5602 default:
5234 zig_unreachable();5603 zig_unreachable();
5235 }5604 }
5236 return ir_lval_wrap(irb, scope, result, lval);5605 return ir_lval_wrap(irb, scope, result, lval, result_loc);
5237 }5606 }
5238 case BuiltinFnIdHasDecl:5607 case BuiltinFnIdHasDecl:
5239 {5608 {
...@@ -5248,17 +5617,19 @@ static IrInstruction *ir_gen_builtin_fn_call(IrBuilder *irb, Scope *scope, AstNo...@@ -5248,17 +5617,19 @@ static IrInstruction *ir_gen_builtin_fn_call(IrBuilder *irb, Scope *scope, AstNo
5248 return arg1_value;5617 return arg1_value;
52495618
5250 IrInstruction *has_decl = ir_build_has_decl(irb, scope, node, arg0_value, arg1_value);5619 IrInstruction *has_decl = ir_build_has_decl(irb, scope, node, arg0_value, arg1_value);
5251 return ir_lval_wrap(irb, scope, has_decl, lval);5620 return ir_lval_wrap(irb, scope, has_decl, lval, result_loc);
5252 }5621 }
5253 }5622 }
5254 zig_unreachable();5623 zig_unreachable();
5255}5624}
52565625
5257static IrInstruction *ir_gen_fn_call(IrBuilder *irb, Scope *scope, AstNode *node, LVal lval) {5626static IrInstruction *ir_gen_fn_call(IrBuilder *irb, Scope *scope, AstNode *node, LVal lval,
5627 ResultLoc *result_loc)
5628{
5258 assert(node->type == NodeTypeFnCallExpr);5629 assert(node->type == NodeTypeFnCallExpr);
52595630
5260 if (node->data.fn_call_expr.is_builtin)5631 if (node->data.fn_call_expr.is_builtin)
5261 return ir_gen_builtin_fn_call(irb, scope, node, lval);5632 return ir_gen_builtin_fn_call(irb, scope, node, lval, result_loc);
52625633
5263 AstNode *fn_ref_node = node->data.fn_call_expr.fn_ref_expr;5634 AstNode *fn_ref_node = node->data.fn_call_expr.fn_ref_expr;
5264 IrInstruction *fn_ref = ir_gen_node(irb, fn_ref_node, scope);5635 IrInstruction *fn_ref = ir_gen_node(irb, fn_ref_node, scope);
...@@ -5284,12 +5655,14 @@ static IrInstruction *ir_gen_fn_call(IrBuilder *irb, Scope *scope, AstNode *node...@@ -5284,12 +5655,14 @@ static IrInstruction *ir_gen_fn_call(IrBuilder *irb, Scope *scope, AstNode *node
5284 }5655 }
5285 }5656 }
52865657
5287 IrInstruction *fn_call = ir_build_call(irb, scope, node, nullptr, fn_ref, arg_count, args, false, FnInlineAuto,5658 IrInstruction *fn_call = ir_build_call_src(irb, scope, node, nullptr, fn_ref, arg_count, args, false, FnInlineAuto,
5288 is_async, async_allocator, nullptr);5659 is_async, async_allocator, nullptr, result_loc);
5289 return ir_lval_wrap(irb, scope, fn_call, lval);5660 return ir_lval_wrap(irb, scope, fn_call, lval, result_loc);
5290}5661}
52915662
5292static IrInstruction *ir_gen_if_bool_expr(IrBuilder *irb, Scope *scope, AstNode *node) {5663static IrInstruction *ir_gen_if_bool_expr(IrBuilder *irb, Scope *scope, AstNode *node, LVal lval,
5664 ResultLoc *result_loc)
5665{
5293 assert(node->type == NodeTypeIfBoolExpr);5666 assert(node->type == NodeTypeIfBoolExpr);
52945667
5295 IrInstruction *condition = ir_gen_node(irb, node->data.if_bool_expr.condition, scope);5668 IrInstruction *condition = ir_gen_node(irb, node->data.if_bool_expr.condition, scope);
...@@ -5310,12 +5683,16 @@ static IrInstruction *ir_gen_if_bool_expr(IrBuilder *irb, Scope *scope, AstNode...@@ -5310,12 +5683,16 @@ static IrInstruction *ir_gen_if_bool_expr(IrBuilder *irb, Scope *scope, AstNode
5310 IrBasicBlock *else_block = ir_create_basic_block(irb, scope, "Else");5683 IrBasicBlock *else_block = ir_create_basic_block(irb, scope, "Else");
5311 IrBasicBlock *endif_block = ir_create_basic_block(irb, scope, "EndIf");5684 IrBasicBlock *endif_block = ir_create_basic_block(irb, scope, "EndIf");
53125685
5313 ir_build_cond_br(irb, scope, condition->source_node, condition, then_block, else_block, is_comptime);5686 IrInstruction *cond_br_inst = ir_build_cond_br(irb, scope, node, condition,
5687 then_block, else_block, is_comptime);
5688 ResultLocPeerParent *peer_parent = ir_build_binary_result_peers(irb, cond_br_inst, else_block, endif_block,
5689 result_loc, is_comptime);
53145690
5315 ir_set_cursor_at_end_and_append_block(irb, then_block);5691 ir_set_cursor_at_end_and_append_block(irb, then_block);
53165692
5317 Scope *subexpr_scope = create_runtime_scope(irb->codegen, node, scope, is_comptime);5693 Scope *subexpr_scope = create_runtime_scope(irb->codegen, node, scope, is_comptime);
5318 IrInstruction *then_expr_result = ir_gen_node(irb, then_node, subexpr_scope);5694 IrInstruction *then_expr_result = ir_gen_node_extra(irb, then_node, subexpr_scope, lval,
5695 &peer_parent->peers.at(0)->base);
5319 if (then_expr_result == irb->codegen->invalid_instruction)5696 if (then_expr_result == irb->codegen->invalid_instruction)
5320 return irb->codegen->invalid_instruction;5697 return irb->codegen->invalid_instruction;
5321 IrBasicBlock *after_then_block = irb->current_basic_block;5698 IrBasicBlock *after_then_block = irb->current_basic_block;
...@@ -5325,11 +5702,12 @@ static IrInstruction *ir_gen_if_bool_expr(IrBuilder *irb, Scope *scope, AstNode...@@ -5325,11 +5702,12 @@ static IrInstruction *ir_gen_if_bool_expr(IrBuilder *irb, Scope *scope, AstNode
5325 ir_set_cursor_at_end_and_append_block(irb, else_block);5702 ir_set_cursor_at_end_and_append_block(irb, else_block);
5326 IrInstruction *else_expr_result;5703 IrInstruction *else_expr_result;
5327 if (else_node) {5704 if (else_node) {
5328 else_expr_result = ir_gen_node(irb, else_node, subexpr_scope);5705 else_expr_result = ir_gen_node_extra(irb, else_node, subexpr_scope, lval, &peer_parent->peers.at(1)->base);
5329 if (else_expr_result == irb->codegen->invalid_instruction)5706 if (else_expr_result == irb->codegen->invalid_instruction)
5330 return irb->codegen->invalid_instruction;5707 return irb->codegen->invalid_instruction;
5331 } else {5708 } else {
5332 else_expr_result = ir_build_const_void(irb, scope, node);5709 else_expr_result = ir_build_const_void(irb, scope, node);
5710 ir_build_end_expr(irb, scope, node, else_expr_result, &peer_parent->peers.at(1)->base);
5333 }5711 }
5334 IrBasicBlock *after_else_block = irb->current_basic_block;5712 IrBasicBlock *after_else_block = irb->current_basic_block;
5335 if (!instr_is_unreachable(else_expr_result))5713 if (!instr_is_unreachable(else_expr_result))
...@@ -5343,14 +5721,15 @@ static IrInstruction *ir_gen_if_bool_expr(IrBuilder *irb, Scope *scope, AstNode...@@ -5343,14 +5721,15 @@ static IrInstruction *ir_gen_if_bool_expr(IrBuilder *irb, Scope *scope, AstNode
5343 incoming_blocks[0] = after_then_block;5721 incoming_blocks[0] = after_then_block;
5344 incoming_blocks[1] = after_else_block;5722 incoming_blocks[1] = after_else_block;
53455723
5346 return ir_build_phi(irb, scope, node, 2, incoming_blocks, incoming_values);5724 IrInstruction *phi = ir_build_phi(irb, scope, node, 2, incoming_blocks, incoming_values, peer_parent);
5725 return ir_expr_wrap(irb, scope, phi, result_loc);
5347}5726}
53485727
5349static IrInstruction *ir_gen_prefix_op_id_lval(IrBuilder *irb, Scope *scope, AstNode *node, IrUnOp op_id, LVal lval) {5728static IrInstruction *ir_gen_prefix_op_id_lval(IrBuilder *irb, Scope *scope, AstNode *node, IrUnOp op_id, LVal lval) {
5350 assert(node->type == NodeTypePrefixOpExpr);5729 assert(node->type == NodeTypePrefixOpExpr);
5351 AstNode *expr_node = node->data.prefix_op_expr.primary_expr;5730 AstNode *expr_node = node->data.prefix_op_expr.primary_expr;
53525731
5353 IrInstruction *value = ir_gen_node_extra(irb, expr_node, scope, lval);5732 IrInstruction *value = ir_gen_node_extra(irb, expr_node, scope, lval, nullptr);
5354 if (value == irb->codegen->invalid_instruction)5733 if (value == irb->codegen->invalid_instruction)
5355 return value;5734 return value;
53565735
...@@ -5361,15 +5740,34 @@ static IrInstruction *ir_gen_prefix_op_id(IrBuilder *irb, Scope *scope, AstNode...@@ -5361,15 +5740,34 @@ static IrInstruction *ir_gen_prefix_op_id(IrBuilder *irb, Scope *scope, AstNode
5361 return ir_gen_prefix_op_id_lval(irb, scope, node, op_id, LValNone);5740 return ir_gen_prefix_op_id_lval(irb, scope, node, op_id, LValNone);
5362}5741}
53635742
5364static IrInstruction *ir_lval_wrap(IrBuilder *irb, Scope *scope, IrInstruction *value, LVal lval) {5743static IrInstruction *ir_expr_wrap(IrBuilder *irb, Scope *scope, IrInstruction *inst, ResultLoc *result_loc) {
5365 if (lval != LValPtr)5744 ir_build_end_expr(irb, scope, inst->source_node, inst, result_loc);
5745 return inst;
5746}
5747
5748static IrInstruction *ir_lval_wrap(IrBuilder *irb, Scope *scope, IrInstruction *value, LVal lval,
5749 ResultLoc *result_loc)
5750{
5751 // This logic must be kept in sync with
5752 // [STMT_EXPR_TEST_THING] <--- (search this token)
5753 if (value == irb->codegen->invalid_instruction ||
5754 instr_is_unreachable(value) ||
5755 value->source_node->type == NodeTypeDefer ||
5756 value->id == IrInstructionIdDeclVarSrc)
5757 {
5366 return value;5758 return value;
5367 if (value == irb->codegen->invalid_instruction)5759 }
5760
5761 if (lval == LValPtr) {
5762 // We needed a pointer to a value, but we got a value. So we create
5763 // an instruction which just makes a pointer of it.
5764 return ir_build_ref(irb, scope, value->source_node, value, false, false);
5765 } else if (result_loc != nullptr) {
5766 return ir_expr_wrap(irb, scope, value, result_loc);
5767 } else {
5368 return value;5768 return value;
5769 }
53695770
5370 // We needed a pointer to a value, but we got a value. So we create
5371 // an instruction which just makes a const pointer of it.
5372 return ir_build_ref(irb, scope, value->source_node, value, false, false);
5373}5771}
53745772
5375static PtrLen star_token_to_ptr_len(TokenId token_id) {5773static PtrLen star_token_to_ptr_len(TokenId token_id) {
...@@ -5442,21 +5840,22 @@ static IrInstruction *ir_gen_pointer_type(IrBuilder *irb, Scope *scope, AstNode...@@ -5442,21 +5840,22 @@ static IrInstruction *ir_gen_pointer_type(IrBuilder *irb, Scope *scope, AstNode
5442 ptr_len, align_value, bit_offset_start, host_int_bytes, is_allow_zero);5840 ptr_len, align_value, bit_offset_start, host_int_bytes, is_allow_zero);
5443}5841}
54445842
5445static IrInstruction *ir_gen_catch_unreachable(IrBuilder *irb, Scope *scope, AstNode *source_node, AstNode *expr_node,5843static IrInstruction *ir_gen_catch_unreachable(IrBuilder *irb, Scope *scope, AstNode *source_node,
5446 LVal lval)5844 AstNode *expr_node, LVal lval, ResultLoc *result_loc)
5447{5845{
5448 IrInstruction *err_union_ptr = ir_gen_node_extra(irb, expr_node, scope, LValPtr);5846 IrInstruction *err_union_ptr = ir_gen_node_extra(irb, expr_node, scope, LValPtr, nullptr);
5449 if (err_union_ptr == irb->codegen->invalid_instruction)5847 if (err_union_ptr == irb->codegen->invalid_instruction)
5450 return irb->codegen->invalid_instruction;5848 return irb->codegen->invalid_instruction;
54515849
5452 IrInstruction *payload_ptr = ir_build_unwrap_err_payload(irb, scope, source_node, err_union_ptr, true);5850 IrInstruction *payload_ptr = ir_build_unwrap_err_payload(irb, scope, source_node, err_union_ptr, true, false);
5453 if (payload_ptr == irb->codegen->invalid_instruction)5851 if (payload_ptr == irb->codegen->invalid_instruction)
5454 return irb->codegen->invalid_instruction;5852 return irb->codegen->invalid_instruction;
54555853
5456 if (lval == LValPtr)5854 if (lval == LValPtr)
5457 return payload_ptr;5855 return payload_ptr;
54585856
5459 return ir_build_load_ptr(irb, scope, source_node, payload_ptr);5857 IrInstruction *load_ptr = ir_build_load_ptr(irb, scope, source_node, payload_ptr);
5858 return ir_expr_wrap(irb, scope, load_ptr, result_loc);
5460}5859}
54615860
5462static IrInstruction *ir_gen_bool_not(IrBuilder *irb, Scope *scope, AstNode *node) {5861static IrInstruction *ir_gen_bool_not(IrBuilder *irb, Scope *scope, AstNode *node) {
...@@ -5470,7 +5869,9 @@ static IrInstruction *ir_gen_bool_not(IrBuilder *irb, Scope *scope, AstNode *nod...@@ -5470,7 +5869,9 @@ static IrInstruction *ir_gen_bool_not(IrBuilder *irb, Scope *scope, AstNode *nod
5470 return ir_build_bool_not(irb, scope, node, value);5869 return ir_build_bool_not(irb, scope, node, value);
5471}5870}
54725871
5473static IrInstruction *ir_gen_prefix_op_expr(IrBuilder *irb, Scope *scope, AstNode *node, LVal lval) {5872static IrInstruction *ir_gen_prefix_op_expr(IrBuilder *irb, Scope *scope, AstNode *node, LVal lval,
5873 ResultLoc *result_loc)
5874{
5474 assert(node->type == NodeTypePrefixOpExpr);5875 assert(node->type == NodeTypePrefixOpExpr);
54755876
5476 PrefixOp prefix_op = node->data.prefix_op_expr.prefix_op;5877 PrefixOp prefix_op = node->data.prefix_op_expr.prefix_op;
...@@ -5479,24 +5880,26 @@ static IrInstruction *ir_gen_prefix_op_expr(IrBuilder *irb, Scope *scope, AstNod...@@ -5479,24 +5880,26 @@ static IrInstruction *ir_gen_prefix_op_expr(IrBuilder *irb, Scope *scope, AstNod
5479 case PrefixOpInvalid:5880 case PrefixOpInvalid:
5480 zig_unreachable();5881 zig_unreachable();
5481 case PrefixOpBoolNot:5882 case PrefixOpBoolNot:
5482 return ir_lval_wrap(irb, scope, ir_gen_bool_not(irb, scope, node), lval);5883 return ir_lval_wrap(irb, scope, ir_gen_bool_not(irb, scope, node), lval, result_loc);
5483 case PrefixOpBinNot:5884 case PrefixOpBinNot:
5484 return ir_lval_wrap(irb, scope, ir_gen_prefix_op_id(irb, scope, node, IrUnOpBinNot), lval);5885 return ir_lval_wrap(irb, scope, ir_gen_prefix_op_id(irb, scope, node, IrUnOpBinNot), lval, result_loc);
5485 case PrefixOpNegation:5886 case PrefixOpNegation:
5486 return ir_lval_wrap(irb, scope, ir_gen_prefix_op_id(irb, scope, node, IrUnOpNegation), lval);5887 return ir_lval_wrap(irb, scope, ir_gen_prefix_op_id(irb, scope, node, IrUnOpNegation), lval, result_loc);
5487 case PrefixOpNegationWrap:5888 case PrefixOpNegationWrap:
5488 return ir_lval_wrap(irb, scope, ir_gen_prefix_op_id(irb, scope, node, IrUnOpNegationWrap), lval);5889 return ir_lval_wrap(irb, scope, ir_gen_prefix_op_id(irb, scope, node, IrUnOpNegationWrap), lval, result_loc);
5489 case PrefixOpOptional:5890 case PrefixOpOptional:
5490 return ir_lval_wrap(irb, scope, ir_gen_prefix_op_id(irb, scope, node, IrUnOpOptional), lval);5891 return ir_lval_wrap(irb, scope, ir_gen_prefix_op_id(irb, scope, node, IrUnOpOptional), lval, result_loc);
5491 case PrefixOpAddrOf: {5892 case PrefixOpAddrOf: {
5492 AstNode *expr_node = node->data.prefix_op_expr.primary_expr;5893 AstNode *expr_node = node->data.prefix_op_expr.primary_expr;
5493 return ir_lval_wrap(irb, scope, ir_gen_node_extra(irb, expr_node, scope, LValPtr), lval);5894 return ir_lval_wrap(irb, scope, ir_gen_node_extra(irb, expr_node, scope, LValPtr, nullptr), lval, result_loc);
5494 }5895 }
5495 }5896 }
5496 zig_unreachable();5897 zig_unreachable();
5497}5898}
54985899
5499static IrInstruction *ir_gen_container_init_expr(IrBuilder *irb, Scope *scope, AstNode *node) {5900static IrInstruction *ir_gen_container_init_expr(IrBuilder *irb, Scope *scope, AstNode *node, LVal lval,
5901 ResultLoc *parent_result_loc)
5902{
5500 assert(node->type == NodeTypeContainerInitExpr);5903 assert(node->type == NodeTypeContainerInitExpr);
55015904
5502 AstNodeContainerInitExpr *container_init_expr = &node->data.container_init_expr;5905 AstNodeContainerInitExpr *container_init_expr = &node->data.container_init_expr;
...@@ -5514,45 +5917,104 @@ static IrInstruction *ir_gen_container_init_expr(IrBuilder *irb, Scope *scope, A...@@ -5514,45 +5917,104 @@ static IrInstruction *ir_gen_container_init_expr(IrBuilder *irb, Scope *scope, A
5514 return container_type;5917 return container_type;
5515 }5918 }
55165919
5517 if (kind == ContainerInitKindStruct) {5920 switch (kind) {
5518 if (elem_type != nullptr) {5921 case ContainerInitKindStruct: {
5519 add_node_error(irb->codegen, container_init_expr->type,5922 if (elem_type != nullptr) {
5520 buf_sprintf("initializing array with struct syntax"));5923 add_node_error(irb->codegen, container_init_expr->type,
5521 return irb->codegen->invalid_instruction;5924 buf_sprintf("initializing array with struct syntax"));
5522 }5925 return irb->codegen->invalid_instruction;
5926 }
5927
5928 IrInstruction *container_ptr = ir_build_resolve_result(irb, scope, node, parent_result_loc,
5929 container_type);
5930
5931 size_t field_count = container_init_expr->entries.length;
5932 IrInstructionContainerInitFieldsField *fields = allocate<IrInstructionContainerInitFieldsField>(field_count);
5933 for (size_t i = 0; i < field_count; i += 1) {
5934 AstNode *entry_node = container_init_expr->entries.at(i);
5935 assert(entry_node->type == NodeTypeStructValueField);
5936
5937 Buf *name = entry_node->data.struct_val_field.name;
5938 AstNode *expr_node = entry_node->data.struct_val_field.expr;
55235939
5524 size_t field_count = container_init_expr->entries.length;5940 IrInstruction *field_ptr = ir_build_field_ptr(irb, scope, entry_node, container_ptr, name, true);
5525 IrInstructionContainerInitFieldsField *fields = allocate<IrInstructionContainerInitFieldsField>(field_count);5941 ResultLocInstruction *result_loc_inst = allocate<ResultLocInstruction>(1);
5526 for (size_t i = 0; i < field_count; i += 1) {5942 result_loc_inst->base.id = ResultLocIdInstruction;
5527 AstNode *entry_node = container_init_expr->entries.at(i);5943 result_loc_inst->base.source_instruction = field_ptr;
5528 assert(entry_node->type == NodeTypeStructValueField);5944 ir_ref_instruction(field_ptr, irb->current_basic_block);
5945 ir_build_reset_result(irb, scope, expr_node, &result_loc_inst->base);
55295946
5530 Buf *name = entry_node->data.struct_val_field.name;5947 IrInstruction *expr_value = ir_gen_node_extra(irb, expr_node, scope, LValNone,
5531 AstNode *expr_node = entry_node->data.struct_val_field.expr;5948 &result_loc_inst->base);
5532 IrInstruction *expr_value = ir_gen_node(irb, expr_node, scope);5949 if (expr_value == irb->codegen->invalid_instruction)
5533 if (expr_value == irb->codegen->invalid_instruction)5950 return expr_value;
5534 return expr_value;
55355951
5536 fields[i].name = name;5952 fields[i].name = name;
5537 fields[i].value = expr_value;5953 fields[i].source_node = entry_node;
5538 fields[i].source_node = entry_node;5954 fields[i].result_loc = field_ptr;
5955 }
5956 IrInstruction *init_fields = ir_build_container_init_fields(irb, scope, node, container_type,
5957 field_count, fields, container_ptr);
5958
5959 return ir_lval_wrap(irb, scope, init_fields, lval, parent_result_loc);
5539 }5960 }
5540 return ir_build_container_init_fields(irb, scope, node, container_type, field_count, fields);5961 case ContainerInitKindArray: {
5541 } else if (kind == ContainerInitKindArray) {5962 size_t item_count = container_init_expr->entries.length;
5542 size_t item_count = container_init_expr->entries.length;5963
5543 IrInstruction **values = allocate<IrInstruction *>(item_count);5964 if (container_type == nullptr) {
5544 for (size_t i = 0; i < item_count; i += 1) {5965 IrInstruction *item_count_inst = ir_build_const_usize(irb, scope, node, item_count);
5545 AstNode *expr_node = container_init_expr->entries.at(i);5966 container_type = ir_build_array_type(irb, scope, node, item_count_inst, elem_type);
5546 IrInstruction *expr_value = ir_gen_node(irb, expr_node, scope);5967 }
5547 if (expr_value == irb->codegen->invalid_instruction)
5548 return expr_value;
55495968
5550 values[i] = expr_value;5969 IrInstruction *container_ptr = ir_build_resolve_result(irb, scope, node, parent_result_loc,
5970 container_type);
5971
5972 IrInstruction **result_locs = allocate<IrInstruction *>(item_count);
5973 for (size_t i = 0; i < item_count; i += 1) {
5974 AstNode *expr_node = container_init_expr->entries.at(i);
5975
5976 IrInstruction *elem_index = ir_build_const_usize(irb, scope, expr_node, i);
5977 IrInstruction *elem_ptr = ir_build_elem_ptr(irb, scope, expr_node, container_ptr, elem_index,
5978 false, PtrLenSingle, container_type);
5979 ResultLocInstruction *result_loc_inst = allocate<ResultLocInstruction>(1);
5980 result_loc_inst->base.id = ResultLocIdInstruction;
5981 result_loc_inst->base.source_instruction = elem_ptr;
5982 ir_ref_instruction(elem_ptr, irb->current_basic_block);
5983 ir_build_reset_result(irb, scope, expr_node, &result_loc_inst->base);
5984
5985 IrInstruction *expr_value = ir_gen_node_extra(irb, expr_node, scope, LValNone,
5986 &result_loc_inst->base);
5987 if (expr_value == irb->codegen->invalid_instruction)
5988 return expr_value;
5989
5990 result_locs[i] = elem_ptr;
5991 }
5992 IrInstruction *init_list = ir_build_container_init_list(irb, scope, node, container_type,
5993 item_count, result_locs, container_ptr);
5994 return ir_lval_wrap(irb, scope, init_list, lval, parent_result_loc);
5551 }5995 }
5552 return ir_build_container_init_list(irb, scope, node, container_type, elem_type, item_count, values);
5553 } else {
5554 zig_unreachable();
5555 }5996 }
5997 zig_unreachable();
5998}
5999
6000static ResultLocVar *ir_build_var_result_loc(IrBuilder *irb, IrInstruction *alloca, ZigVar *var) {
6001 ResultLocVar *result_loc_var = allocate<ResultLocVar>(1);
6002 result_loc_var->base.id = ResultLocIdVar;
6003 result_loc_var->base.source_instruction = alloca;
6004 result_loc_var->var = var;
6005
6006 ir_build_reset_result(irb, alloca->scope, alloca->source_node, &result_loc_var->base);
6007
6008 return result_loc_var;
6009}
6010
6011static void build_decl_var_and_init(IrBuilder *irb, Scope *scope, AstNode *source_node, ZigVar *var,
6012 IrInstruction *init, const char *name_hint, IrInstruction *is_comptime)
6013{
6014 IrInstruction *alloca = ir_build_alloca_src(irb, scope, source_node, nullptr, name_hint, is_comptime);
6015 ResultLocVar *var_result_loc = ir_build_var_result_loc(irb, alloca, var);
6016 ir_build_end_expr(irb, scope, source_node, init, &var_result_loc->base);
6017 ir_build_var_decl_src(irb, scope, source_node, var, nullptr, alloca);
5556}6018}
55576019
5558static IrInstruction *ir_gen_var_decl(IrBuilder *irb, Scope *scope, AstNode *node) {6020static IrInstruction *ir_gen_var_decl(IrBuilder *irb, Scope *scope, AstNode *node) {
...@@ -5565,9 +6027,12 @@ static IrInstruction *ir_gen_var_decl(IrBuilder *irb, Scope *scope, AstNode *nod...@@ -5565,9 +6027,12 @@ static IrInstruction *ir_gen_var_decl(IrBuilder *irb, Scope *scope, AstNode *nod
5565 return irb->codegen->invalid_instruction;6027 return irb->codegen->invalid_instruction;
5566 }6028 }
55676029
6030 // Used for the type expr and the align expr
6031 Scope *comptime_scope = create_comptime_scope(irb->codegen, node, scope);
6032
5568 IrInstruction *type_instruction;6033 IrInstruction *type_instruction;
5569 if (variable_declaration->type != nullptr) {6034 if (variable_declaration->type != nullptr) {
5570 type_instruction = ir_gen_node(irb, variable_declaration->type, scope);6035 type_instruction = ir_gen_node(irb, variable_declaration->type, comptime_scope);
5571 if (type_instruction == irb->codegen->invalid_instruction)6036 if (type_instruction == irb->codegen->invalid_instruction)
5572 return type_instruction;6037 return type_instruction;
5573 } else {6038 } else {
...@@ -5578,8 +6043,8 @@ static IrInstruction *ir_gen_var_decl(IrBuilder *irb, Scope *scope, AstNode *nod...@@ -5578,8 +6043,8 @@ static IrInstruction *ir_gen_var_decl(IrBuilder *irb, Scope *scope, AstNode *nod
5578 bool is_const = variable_declaration->is_const;6043 bool is_const = variable_declaration->is_const;
5579 bool is_extern = variable_declaration->is_extern;6044 bool is_extern = variable_declaration->is_extern;
55806045
5581 IrInstruction *is_comptime = ir_build_const_bool(irb, scope, node,6046 bool is_comptime_scalar = ir_should_inline(irb->exec, scope) || variable_declaration->is_comptime;
5582 ir_should_inline(irb->exec, scope) || variable_declaration->is_comptime);6047 IrInstruction *is_comptime = ir_build_const_bool(irb, scope, node, is_comptime_scalar);
5583 ZigVar *var = ir_create_var(irb, node, scope, variable_declaration->symbol,6048 ZigVar *var = ir_create_var(irb, node, scope, variable_declaration->symbol,
5584 is_const, is_const, is_shadowable, is_comptime);6049 is_const, is_const, is_shadowable, is_comptime);
5585 // we detect IrInstructionIdDeclVarSrc in gen_block to make sure the next node6050 // we detect IrInstructionIdDeclVarSrc in gen_block to make sure the next node
...@@ -5593,7 +6058,7 @@ static IrInstruction *ir_gen_var_decl(IrBuilder *irb, Scope *scope, AstNode *nod...@@ -5593,7 +6058,7 @@ static IrInstruction *ir_gen_var_decl(IrBuilder *irb, Scope *scope, AstNode *nod
55936058
5594 IrInstruction *align_value = nullptr;6059 IrInstruction *align_value = nullptr;
5595 if (variable_declaration->align_expr != nullptr) {6060 if (variable_declaration->align_expr != nullptr) {
5596 align_value = ir_gen_node(irb, variable_declaration->align_expr, scope);6061 align_value = ir_gen_node(irb, variable_declaration->align_expr, comptime_scope);
5597 if (align_value == irb->codegen->invalid_instruction)6062 if (align_value == irb->codegen->invalid_instruction)
5598 return align_value;6063 return align_value;
5599 }6064 }
...@@ -5606,20 +6071,39 @@ static IrInstruction *ir_gen_var_decl(IrBuilder *irb, Scope *scope, AstNode *nod...@@ -5606,20 +6071,39 @@ static IrInstruction *ir_gen_var_decl(IrBuilder *irb, Scope *scope, AstNode *nod
5606 // Parser should ensure that this never happens6071 // Parser should ensure that this never happens
5607 assert(variable_declaration->threadlocal_tok == nullptr);6072 assert(variable_declaration->threadlocal_tok == nullptr);
56086073
6074 IrInstruction *alloca = ir_build_alloca_src(irb, scope, node, align_value,
6075 buf_ptr(variable_declaration->symbol), is_comptime);
6076
6077 // Create a result location for the initialization expression.
6078 ResultLocVar *result_loc_var = ir_build_var_result_loc(irb, alloca, var);
6079 ResultLoc *init_result_loc = (type_instruction == nullptr) ? &result_loc_var->base : nullptr;
6080
6081 Scope *init_scope = is_comptime_scalar ?
6082 create_comptime_scope(irb->codegen, variable_declaration->expr, scope) : scope;
6083
5609 // Temporarily set the name of the IrExecutable to the VariableDeclaration6084 // Temporarily set the name of the IrExecutable to the VariableDeclaration
5610 // so that the struct or enum from the init expression inherits the name.6085 // so that the struct or enum from the init expression inherits the name.
5611 Buf *old_exec_name = irb->exec->name;6086 Buf *old_exec_name = irb->exec->name;
5612 irb->exec->name = variable_declaration->symbol;6087 irb->exec->name = variable_declaration->symbol;
5613 IrInstruction *init_value = ir_gen_node(irb, variable_declaration->expr, scope);6088 IrInstruction *init_value = ir_gen_node_extra(irb, variable_declaration->expr, init_scope,
6089 LValNone, init_result_loc);
5614 irb->exec->name = old_exec_name;6090 irb->exec->name = old_exec_name;
56156091
5616 if (init_value == irb->codegen->invalid_instruction)6092 if (init_value == irb->codegen->invalid_instruction)
5617 return init_value;6093 return irb->codegen->invalid_instruction;
6094
6095 if (type_instruction != nullptr) {
6096 IrInstruction *implicit_cast = ir_build_implicit_cast(irb, scope, node, type_instruction, init_value,
6097 &result_loc_var->base);
6098 ir_build_end_expr(irb, scope, node, implicit_cast, &result_loc_var->base);
6099 }
56186100
5619 return ir_build_var_decl_src(irb, scope, node, var, type_instruction, align_value, init_value);6101 return ir_build_var_decl_src(irb, scope, node, var, align_value, alloca);
5620}6102}
56216103
5622static IrInstruction *ir_gen_while_expr(IrBuilder *irb, Scope *scope, AstNode *node) {6104static IrInstruction *ir_gen_while_expr(IrBuilder *irb, Scope *scope, AstNode *node, LVal lval,
6105 ResultLoc *result_loc)
6106{
5623 assert(node->type == NodeTypeWhileExpr);6107 assert(node->type == NodeTypeWhileExpr);
56246108
5625 AstNode *continue_expr_node = node->data.while_expr.continue_expr;6109 AstNode *continue_expr_node = node->data.while_expr.continue_expr;
...@@ -5654,25 +6138,33 @@ static IrInstruction *ir_gen_while_expr(IrBuilder *irb, Scope *scope, AstNode *n...@@ -5654,25 +6138,33 @@ static IrInstruction *ir_gen_while_expr(IrBuilder *irb, Scope *scope, AstNode *n
5654 } else {6138 } else {
5655 payload_scope = subexpr_scope;6139 payload_scope = subexpr_scope;
5656 }6140 }
5657 IrInstruction *err_val_ptr = ir_gen_node_extra(irb, node->data.while_expr.condition, subexpr_scope, LValPtr);6141 IrInstruction *err_val_ptr = ir_gen_node_extra(irb, node->data.while_expr.condition, subexpr_scope,
6142 LValPtr, nullptr);
5658 if (err_val_ptr == irb->codegen->invalid_instruction)6143 if (err_val_ptr == irb->codegen->invalid_instruction)
5659 return err_val_ptr;6144 return err_val_ptr;
5660 IrInstruction *err_val = ir_build_load_ptr(irb, scope, node->data.while_expr.condition, err_val_ptr);6145 IrInstruction *is_err = ir_build_test_err_src(irb, scope, node->data.while_expr.condition, err_val_ptr, true);
5661 IrInstruction *is_err = ir_build_test_err(irb, scope, node->data.while_expr.condition, err_val);
5662 IrBasicBlock *after_cond_block = irb->current_basic_block;6146 IrBasicBlock *after_cond_block = irb->current_basic_block;
5663 IrInstruction *void_else_result = else_node ? nullptr : ir_mark_gen(ir_build_const_void(irb, scope, node));6147 IrInstruction *void_else_result = else_node ? nullptr : ir_mark_gen(ir_build_const_void(irb, scope, node));
6148 IrInstruction *cond_br_inst;
5664 if (!instr_is_unreachable(is_err)) {6149 if (!instr_is_unreachable(is_err)) {
5665 ir_mark_gen(ir_build_cond_br(irb, scope, node->data.while_expr.condition, is_err,6150 cond_br_inst = ir_build_cond_br(irb, scope, node->data.while_expr.condition, is_err,
5666 else_block, body_block, is_comptime));6151 else_block, body_block, is_comptime);
6152 cond_br_inst->is_gen = true;
6153 } else {
6154 // for the purposes of the source instruction to ir_build_result_peers
6155 cond_br_inst = irb->current_basic_block->instruction_list.last();
5667 }6156 }
56686157
6158 ResultLocPeerParent *peer_parent = ir_build_result_peers(irb, cond_br_inst, end_block, result_loc,
6159 is_comptime);
6160
5669 ir_set_cursor_at_end_and_append_block(irb, body_block);6161 ir_set_cursor_at_end_and_append_block(irb, body_block);
5670 if (var_symbol) {6162 if (var_symbol) {
5671 IrInstruction *var_ptr_value = ir_build_unwrap_err_payload(irb, payload_scope, symbol_node,6163 IrInstruction *payload_ptr = ir_build_unwrap_err_payload(irb, payload_scope, symbol_node,
5672 err_val_ptr, false);6164 err_val_ptr, false, false);
5673 IrInstruction *var_value = node->data.while_expr.var_is_ptr ?6165 IrInstruction *var_ptr = node->data.while_expr.var_is_ptr ?
5674 var_ptr_value : ir_build_load_ptr(irb, payload_scope, symbol_node, var_ptr_value);6166 ir_build_ref(irb, payload_scope, symbol_node, payload_ptr, true, false) : payload_ptr;
5675 ir_build_var_decl_src(irb, payload_scope, symbol_node, payload_var, nullptr, nullptr, var_value);6167 ir_build_var_decl_src(irb, payload_scope, symbol_node, payload_var, nullptr, var_ptr);
5676 }6168 }
56776169
5678 ZigList<IrInstruction *> incoming_values = {0};6170 ZigList<IrInstruction *> incoming_values = {0};
...@@ -5684,7 +6176,12 @@ static IrInstruction *ir_gen_while_expr(IrBuilder *irb, Scope *scope, AstNode *n...@@ -5684,7 +6176,12 @@ static IrInstruction *ir_gen_while_expr(IrBuilder *irb, Scope *scope, AstNode *n
5684 loop_scope->is_comptime = is_comptime;6176 loop_scope->is_comptime = is_comptime;
5685 loop_scope->incoming_blocks = &incoming_blocks;6177 loop_scope->incoming_blocks = &incoming_blocks;
5686 loop_scope->incoming_values = &incoming_values;6178 loop_scope->incoming_values = &incoming_values;
6179 loop_scope->lval = lval;
6180 loop_scope->peer_parent = peer_parent;
56876181
6182 // Note the body block of the loop is not the place that lval and result_loc are used -
6183 // it's actually in break statements, handled similarly to return statements.
6184 // That is why we set those values in loop_scope above and not in this ir_gen_node call.
5688 IrInstruction *body_result = ir_gen_node(irb, node->data.while_expr.body, &loop_scope->base);6185 IrInstruction *body_result = ir_gen_node(irb, node->data.while_expr.body, &loop_scope->base);
5689 if (body_result == irb->codegen->invalid_instruction)6186 if (body_result == irb->codegen->invalid_instruction)
5690 return body_result;6187 return body_result;
...@@ -5713,10 +6210,15 @@ static IrInstruction *ir_gen_while_expr(IrBuilder *irb, Scope *scope, AstNode *n...@@ -5713,10 +6210,15 @@ static IrInstruction *ir_gen_while_expr(IrBuilder *irb, Scope *scope, AstNode *n
5713 ZigVar *err_var = ir_create_var(irb, err_symbol_node, scope, err_symbol,6210 ZigVar *err_var = ir_create_var(irb, err_symbol_node, scope, err_symbol,
5714 true, false, false, is_comptime);6211 true, false, false, is_comptime);
5715 Scope *err_scope = err_var->child_scope;6212 Scope *err_scope = err_var->child_scope;
5716 IrInstruction *err_var_value = ir_build_unwrap_err_code(irb, err_scope, err_symbol_node, err_val_ptr);6213 IrInstruction *err_ptr = ir_build_unwrap_err_code(irb, err_scope, err_symbol_node, err_val_ptr);
5717 ir_build_var_decl_src(irb, err_scope, symbol_node, err_var, nullptr, nullptr, err_var_value);6214 ir_build_var_decl_src(irb, err_scope, symbol_node, err_var, nullptr, err_ptr);
57186215
5719 IrInstruction *else_result = ir_gen_node(irb, else_node, err_scope);6216 if (peer_parent->peers.length != 0) {
6217 peer_parent->peers.last()->next_bb = else_block;
6218 }
6219 ResultLocPeer *peer_result = create_peer_result(peer_parent);
6220 peer_parent->peers.append(peer_result);
6221 IrInstruction *else_result = ir_gen_node_extra(irb, else_node, err_scope, lval, &peer_result->base);
5720 if (else_result == irb->codegen->invalid_instruction)6222 if (else_result == irb->codegen->invalid_instruction)
5721 return else_result;6223 return else_result;
5722 if (!instr_is_unreachable(else_result))6224 if (!instr_is_unreachable(else_result))
...@@ -5730,8 +6232,13 @@ static IrInstruction *ir_gen_while_expr(IrBuilder *irb, Scope *scope, AstNode *n...@@ -5730,8 +6232,13 @@ static IrInstruction *ir_gen_while_expr(IrBuilder *irb, Scope *scope, AstNode *n
5730 incoming_blocks.append(after_cond_block);6232 incoming_blocks.append(after_cond_block);
5731 incoming_values.append(void_else_result);6233 incoming_values.append(void_else_result);
5732 }6234 }
6235 if (peer_parent->peers.length != 0) {
6236 peer_parent->peers.last()->next_bb = end_block;
6237 }
57336238
5734 return ir_build_phi(irb, scope, node, incoming_blocks.length, incoming_blocks.items, incoming_values.items);6239 IrInstruction *phi = ir_build_phi(irb, scope, node, incoming_blocks.length,
6240 incoming_blocks.items, incoming_values.items, peer_parent);
6241 return ir_expr_wrap(irb, scope, phi, result_loc);
5735 } else if (var_symbol != nullptr) {6242 } else if (var_symbol != nullptr) {
5736 ir_set_cursor_at_end_and_append_block(irb, cond_block);6243 ir_set_cursor_at_end_and_append_block(irb, cond_block);
5737 Scope *subexpr_scope = create_runtime_scope(irb->codegen, node, scope, is_comptime);6244 Scope *subexpr_scope = create_runtime_scope(irb->codegen, node, scope, is_comptime);
...@@ -5741,23 +6248,32 @@ static IrInstruction *ir_gen_while_expr(IrBuilder *irb, Scope *scope, AstNode *n...@@ -5741,23 +6248,32 @@ static IrInstruction *ir_gen_while_expr(IrBuilder *irb, Scope *scope, AstNode *n
5741 ZigVar *payload_var = ir_create_var(irb, symbol_node, subexpr_scope, var_symbol,6248 ZigVar *payload_var = ir_create_var(irb, symbol_node, subexpr_scope, var_symbol,
5742 true, false, false, is_comptime);6249 true, false, false, is_comptime);
5743 Scope *child_scope = payload_var->child_scope;6250 Scope *child_scope = payload_var->child_scope;
5744 IrInstruction *maybe_val_ptr = ir_gen_node_extra(irb, node->data.while_expr.condition, subexpr_scope, LValPtr);6251 IrInstruction *maybe_val_ptr = ir_gen_node_extra(irb, node->data.while_expr.condition, subexpr_scope,
6252 LValPtr, nullptr);
5745 if (maybe_val_ptr == irb->codegen->invalid_instruction)6253 if (maybe_val_ptr == irb->codegen->invalid_instruction)
5746 return maybe_val_ptr;6254 return maybe_val_ptr;
5747 IrInstruction *maybe_val = ir_build_load_ptr(irb, scope, node->data.while_expr.condition, maybe_val_ptr);6255 IrInstruction *maybe_val = ir_build_load_ptr(irb, scope, node->data.while_expr.condition, maybe_val_ptr);
5748 IrInstruction *is_non_null = ir_build_test_nonnull(irb, scope, node->data.while_expr.condition, maybe_val);6256 IrInstruction *is_non_null = ir_build_test_nonnull(irb, scope, node->data.while_expr.condition, maybe_val);
5749 IrBasicBlock *after_cond_block = irb->current_basic_block;6257 IrBasicBlock *after_cond_block = irb->current_basic_block;
5750 IrInstruction *void_else_result = else_node ? nullptr : ir_mark_gen(ir_build_const_void(irb, scope, node));6258 IrInstruction *void_else_result = else_node ? nullptr : ir_mark_gen(ir_build_const_void(irb, scope, node));
6259 IrInstruction *cond_br_inst;
5751 if (!instr_is_unreachable(is_non_null)) {6260 if (!instr_is_unreachable(is_non_null)) {
5752 ir_mark_gen(ir_build_cond_br(irb, scope, node->data.while_expr.condition, is_non_null,6261 cond_br_inst = ir_build_cond_br(irb, scope, node->data.while_expr.condition, is_non_null,
5753 body_block, else_block, is_comptime));6262 body_block, else_block, is_comptime);
6263 cond_br_inst->is_gen = true;
6264 } else {
6265 // for the purposes of the source instruction to ir_build_result_peers
6266 cond_br_inst = irb->current_basic_block->instruction_list.last();
5754 }6267 }
57556268
6269 ResultLocPeerParent *peer_parent = ir_build_result_peers(irb, cond_br_inst, end_block, result_loc,
6270 is_comptime);
6271
5756 ir_set_cursor_at_end_and_append_block(irb, body_block);6272 ir_set_cursor_at_end_and_append_block(irb, body_block);
5757 IrInstruction *var_ptr_value = ir_build_optional_unwrap_ptr(irb, child_scope, symbol_node, maybe_val_ptr, false);6273 IrInstruction *payload_ptr = ir_build_optional_unwrap_ptr(irb, child_scope, symbol_node, maybe_val_ptr, false, false);
5758 IrInstruction *var_value = node->data.while_expr.var_is_ptr ?6274 IrInstruction *var_ptr = node->data.while_expr.var_is_ptr ?
5759 var_ptr_value : ir_build_load_ptr(irb, child_scope, symbol_node, var_ptr_value);6275 ir_build_ref(irb, child_scope, symbol_node, payload_ptr, true, false) : payload_ptr;
5760 ir_build_var_decl_src(irb, child_scope, symbol_node, payload_var, nullptr, nullptr, var_value);6276 ir_build_var_decl_src(irb, child_scope, symbol_node, payload_var, nullptr, var_ptr);
57616277
5762 ZigList<IrInstruction *> incoming_values = {0};6278 ZigList<IrInstruction *> incoming_values = {0};
5763 ZigList<IrBasicBlock *> incoming_blocks = {0};6279 ZigList<IrBasicBlock *> incoming_blocks = {0};
...@@ -5768,7 +6284,12 @@ static IrInstruction *ir_gen_while_expr(IrBuilder *irb, Scope *scope, AstNode *n...@@ -5768,7 +6284,12 @@ static IrInstruction *ir_gen_while_expr(IrBuilder *irb, Scope *scope, AstNode *n
5768 loop_scope->is_comptime = is_comptime;6284 loop_scope->is_comptime = is_comptime;
5769 loop_scope->incoming_blocks = &incoming_blocks;6285 loop_scope->incoming_blocks = &incoming_blocks;
5770 loop_scope->incoming_values = &incoming_values;6286 loop_scope->incoming_values = &incoming_values;
6287 loop_scope->lval = lval;
6288 loop_scope->peer_parent = peer_parent;
57716289
6290 // Note the body block of the loop is not the place that lval and result_loc are used -
6291 // it's actually in break statements, handled similarly to return statements.
6292 // That is why we set those values in loop_scope above and not in this ir_gen_node call.
5772 IrInstruction *body_result = ir_gen_node(irb, node->data.while_expr.body, &loop_scope->base);6293 IrInstruction *body_result = ir_gen_node(irb, node->data.while_expr.body, &loop_scope->base);
5773 if (body_result == irb->codegen->invalid_instruction)6294 if (body_result == irb->codegen->invalid_instruction)
5774 return body_result;6295 return body_result;
...@@ -5793,7 +6314,12 @@ static IrInstruction *ir_gen_while_expr(IrBuilder *irb, Scope *scope, AstNode *n...@@ -5793,7 +6314,12 @@ static IrInstruction *ir_gen_while_expr(IrBuilder *irb, Scope *scope, AstNode *n
5793 if (else_node) {6314 if (else_node) {
5794 ir_set_cursor_at_end_and_append_block(irb, else_block);6315 ir_set_cursor_at_end_and_append_block(irb, else_block);
57956316
5796 else_result = ir_gen_node(irb, else_node, scope);6317 if (peer_parent->peers.length != 0) {
6318 peer_parent->peers.last()->next_bb = else_block;
6319 }
6320 ResultLocPeer *peer_result = create_peer_result(peer_parent);
6321 peer_parent->peers.append(peer_result);
6322 else_result = ir_gen_node_extra(irb, else_node, scope, lval, &peer_result->base);
5797 if (else_result == irb->codegen->invalid_instruction)6323 if (else_result == irb->codegen->invalid_instruction)
5798 return else_result;6324 return else_result;
5799 if (!instr_is_unreachable(else_result))6325 if (!instr_is_unreachable(else_result))
...@@ -5808,8 +6334,13 @@ static IrInstruction *ir_gen_while_expr(IrBuilder *irb, Scope *scope, AstNode *n...@@ -5808,8 +6334,13 @@ static IrInstruction *ir_gen_while_expr(IrBuilder *irb, Scope *scope, AstNode *n
5808 incoming_blocks.append(after_cond_block);6334 incoming_blocks.append(after_cond_block);
5809 incoming_values.append(void_else_result);6335 incoming_values.append(void_else_result);
5810 }6336 }
6337 if (peer_parent->peers.length != 0) {
6338 peer_parent->peers.last()->next_bb = end_block;
6339 }
58116340
5812 return ir_build_phi(irb, scope, node, incoming_blocks.length, incoming_blocks.items, incoming_values.items);6341 IrInstruction *phi = ir_build_phi(irb, scope, node, incoming_blocks.length,
6342 incoming_blocks.items, incoming_values.items, peer_parent);
6343 return ir_expr_wrap(irb, scope, phi, result_loc);
5813 } else {6344 } else {
5814 ir_set_cursor_at_end_and_append_block(irb, cond_block);6345 ir_set_cursor_at_end_and_append_block(irb, cond_block);
5815 IrInstruction *cond_val = ir_gen_node(irb, node->data.while_expr.condition, scope);6346 IrInstruction *cond_val = ir_gen_node(irb, node->data.while_expr.condition, scope);
...@@ -5817,11 +6348,18 @@ static IrInstruction *ir_gen_while_expr(IrBuilder *irb, Scope *scope, AstNode *n...@@ -5817,11 +6348,18 @@ static IrInstruction *ir_gen_while_expr(IrBuilder *irb, Scope *scope, AstNode *n
5817 return cond_val;6348 return cond_val;
5818 IrBasicBlock *after_cond_block = irb->current_basic_block;6349 IrBasicBlock *after_cond_block = irb->current_basic_block;
5819 IrInstruction *void_else_result = else_node ? nullptr : ir_mark_gen(ir_build_const_void(irb, scope, node));6350 IrInstruction *void_else_result = else_node ? nullptr : ir_mark_gen(ir_build_const_void(irb, scope, node));
6351 IrInstruction *cond_br_inst;
5820 if (!instr_is_unreachable(cond_val)) {6352 if (!instr_is_unreachable(cond_val)) {
5821 ir_mark_gen(ir_build_cond_br(irb, scope, node->data.while_expr.condition, cond_val,6353 cond_br_inst = ir_build_cond_br(irb, scope, node->data.while_expr.condition, cond_val,
5822 body_block, else_block, is_comptime));6354 body_block, else_block, is_comptime);
6355 cond_br_inst->is_gen = true;
6356 } else {
6357 // for the purposes of the source instruction to ir_build_result_peers
6358 cond_br_inst = irb->current_basic_block->instruction_list.last();
5823 }6359 }
58246360
6361 ResultLocPeerParent *peer_parent = ir_build_result_peers(irb, cond_br_inst, end_block, result_loc,
6362 is_comptime);
5825 ir_set_cursor_at_end_and_append_block(irb, body_block);6363 ir_set_cursor_at_end_and_append_block(irb, body_block);
58266364
5827 ZigList<IrInstruction *> incoming_values = {0};6365 ZigList<IrInstruction *> incoming_values = {0};
...@@ -5835,7 +6373,12 @@ static IrInstruction *ir_gen_while_expr(IrBuilder *irb, Scope *scope, AstNode *n...@@ -5835,7 +6373,12 @@ static IrInstruction *ir_gen_while_expr(IrBuilder *irb, Scope *scope, AstNode *n
5835 loop_scope->is_comptime = is_comptime;6373 loop_scope->is_comptime = is_comptime;
5836 loop_scope->incoming_blocks = &incoming_blocks;6374 loop_scope->incoming_blocks = &incoming_blocks;
5837 loop_scope->incoming_values = &incoming_values;6375 loop_scope->incoming_values = &incoming_values;
6376 loop_scope->lval = lval;
6377 loop_scope->peer_parent = peer_parent;
58386378
6379 // Note the body block of the loop is not the place that lval and result_loc are used -
6380 // it's actually in break statements, handled similarly to return statements.
6381 // That is why we set those values in loop_scope above and not in this ir_gen_node call.
5839 IrInstruction *body_result = ir_gen_node(irb, node->data.while_expr.body, &loop_scope->base);6382 IrInstruction *body_result = ir_gen_node(irb, node->data.while_expr.body, &loop_scope->base);
5840 if (body_result == irb->codegen->invalid_instruction)6383 if (body_result == irb->codegen->invalid_instruction)
5841 return body_result;6384 return body_result;
...@@ -5860,7 +6403,13 @@ static IrInstruction *ir_gen_while_expr(IrBuilder *irb, Scope *scope, AstNode *n...@@ -5860,7 +6403,13 @@ static IrInstruction *ir_gen_while_expr(IrBuilder *irb, Scope *scope, AstNode *n
5860 if (else_node) {6403 if (else_node) {
5861 ir_set_cursor_at_end_and_append_block(irb, else_block);6404 ir_set_cursor_at_end_and_append_block(irb, else_block);
58626405
5863 else_result = ir_gen_node(irb, else_node, subexpr_scope);6406 if (peer_parent->peers.length != 0) {
6407 peer_parent->peers.last()->next_bb = else_block;
6408 }
6409 ResultLocPeer *peer_result = create_peer_result(peer_parent);
6410 peer_parent->peers.append(peer_result);
6411
6412 else_result = ir_gen_node_extra(irb, else_node, subexpr_scope, lval, &peer_result->base);
5864 if (else_result == irb->codegen->invalid_instruction)6413 if (else_result == irb->codegen->invalid_instruction)
5865 return else_result;6414 return else_result;
5866 if (!instr_is_unreachable(else_result))6415 if (!instr_is_unreachable(else_result))
...@@ -5875,12 +6424,19 @@ static IrInstruction *ir_gen_while_expr(IrBuilder *irb, Scope *scope, AstNode *n...@@ -5875,12 +6424,19 @@ static IrInstruction *ir_gen_while_expr(IrBuilder *irb, Scope *scope, AstNode *n
5875 incoming_blocks.append(after_cond_block);6424 incoming_blocks.append(after_cond_block);
5876 incoming_values.append(void_else_result);6425 incoming_values.append(void_else_result);
5877 }6426 }
6427 if (peer_parent->peers.length != 0) {
6428 peer_parent->peers.last()->next_bb = end_block;
6429 }
58786430
5879 return ir_build_phi(irb, scope, node, incoming_blocks.length, incoming_blocks.items, incoming_values.items);6431 IrInstruction *phi = ir_build_phi(irb, scope, node, incoming_blocks.length,
6432 incoming_blocks.items, incoming_values.items, peer_parent);
6433 return ir_expr_wrap(irb, scope, phi, result_loc);
5880 }6434 }
5881}6435}
58826436
5883static IrInstruction *ir_gen_for_expr(IrBuilder *irb, Scope *parent_scope, AstNode *node) {6437static IrInstruction *ir_gen_for_expr(IrBuilder *irb, Scope *parent_scope, AstNode *node, LVal lval,
6438 ResultLoc *result_loc)
6439{
5884 assert(node->type == NodeTypeForExpr);6440 assert(node->type == NodeTypeForExpr);
58856441
5886 AstNode *array_node = node->data.for_expr.array_expr;6442 AstNode *array_node = node->data.for_expr.array_expr;
...@@ -5895,76 +6451,67 @@ static IrInstruction *ir_gen_for_expr(IrBuilder *irb, Scope *parent_scope, AstNo...@@ -5895,76 +6451,67 @@ static IrInstruction *ir_gen_for_expr(IrBuilder *irb, Scope *parent_scope, AstNo
5895 }6451 }
5896 assert(elem_node->type == NodeTypeSymbol);6452 assert(elem_node->type == NodeTypeSymbol);
58976453
5898 IrInstruction *array_val_ptr = ir_gen_node_extra(irb, array_node, parent_scope, LValPtr);6454 IrInstruction *array_val_ptr = ir_gen_node_extra(irb, array_node, parent_scope, LValPtr, nullptr);
5899 if (array_val_ptr == irb->codegen->invalid_instruction)6455 if (array_val_ptr == irb->codegen->invalid_instruction)
5900 return array_val_ptr;6456 return array_val_ptr;
59016457
5902 IrInstruction *pointer_type = ir_build_to_ptr_type(irb, parent_scope, array_node, array_val_ptr);
5903 IrInstruction *elem_var_type;
5904 if (node->data.for_expr.elem_is_ptr) {
5905 elem_var_type = pointer_type;
5906 } else {
5907 elem_var_type = ir_build_ptr_type_child(irb, parent_scope, elem_node, pointer_type);
5908 }
5909
5910 IrInstruction *is_comptime = ir_build_const_bool(irb, parent_scope, node,6458 IrInstruction *is_comptime = ir_build_const_bool(irb, parent_scope, node,
5911 ir_should_inline(irb->exec, parent_scope) || node->data.for_expr.is_inline);6459 ir_should_inline(irb->exec, parent_scope) || node->data.for_expr.is_inline);
59126460
5913 // TODO make it an error to write to element variable or i variable.
5914 Buf *elem_var_name = elem_node->data.symbol_expr.symbol;
5915 ZigVar *elem_var = ir_create_var(irb, elem_node, parent_scope, elem_var_name, true, false, false, is_comptime);
5916 Scope *child_scope = elem_var->child_scope;
5917
5918 IrInstruction *undefined_value = ir_build_const_undefined(irb, child_scope, elem_node);
5919 ir_build_var_decl_src(irb, child_scope, elem_node, elem_var, elem_var_type, nullptr, undefined_value);
5920 IrInstruction *elem_var_ptr = ir_build_var_ptr(irb, child_scope, node, elem_var);
5921
5922 AstNode *index_var_source_node;6461 AstNode *index_var_source_node;
5923 ZigVar *index_var;6462 ZigVar *index_var;
6463 const char *index_var_name;
5924 if (index_node) {6464 if (index_node) {
5925 index_var_source_node = index_node;6465 index_var_source_node = index_node;
5926 Buf *index_var_name = index_node->data.symbol_expr.symbol;6466 Buf *index_var_name_buf = index_node->data.symbol_expr.symbol;
5927 index_var = ir_create_var(irb, index_node, child_scope, index_var_name, true, false, false, is_comptime);6467 index_var = ir_create_var(irb, index_node, parent_scope, index_var_name_buf, true, false, false, is_comptime);
6468 index_var_name = buf_ptr(index_var_name_buf);
5928 } else {6469 } else {
5929 index_var_source_node = node;6470 index_var_source_node = node;
5930 index_var = ir_create_var(irb, node, child_scope, nullptr, true, false, true, is_comptime);6471 index_var = ir_create_var(irb, node, parent_scope, nullptr, true, false, true, is_comptime);
6472 index_var_name = "i";
5931 }6473 }
5932 child_scope = index_var->child_scope;
59336474
5934 IrInstruction *usize = ir_build_const_type(irb, child_scope, node, irb->codegen->builtin_types.entry_usize);6475 IrInstruction *zero = ir_build_const_usize(irb, parent_scope, node, 0);
5935 IrInstruction *zero = ir_build_const_usize(irb, child_scope, node, 0);6476 build_decl_var_and_init(irb, parent_scope, index_var_source_node, index_var, zero, index_var_name, is_comptime);
5936 IrInstruction *one = ir_build_const_usize(irb, child_scope, node, 1);6477 parent_scope = index_var->child_scope;
5937 ir_build_var_decl_src(irb, child_scope, index_var_source_node, index_var, usize, nullptr, zero);6478
5938 IrInstruction *index_ptr = ir_build_var_ptr(irb, child_scope, node, index_var);6479 IrInstruction *one = ir_build_const_usize(irb, parent_scope, node, 1);
6480 IrInstruction *index_ptr = ir_build_var_ptr(irb, parent_scope, node, index_var);
59396481
59406482
5941 IrBasicBlock *cond_block = ir_create_basic_block(irb, child_scope, "ForCond");6483 IrBasicBlock *cond_block = ir_create_basic_block(irb, parent_scope, "ForCond");
5942 IrBasicBlock *body_block = ir_create_basic_block(irb, child_scope, "ForBody");6484 IrBasicBlock *body_block = ir_create_basic_block(irb, parent_scope, "ForBody");
5943 IrBasicBlock *end_block = ir_create_basic_block(irb, child_scope, "ForEnd");6485 IrBasicBlock *end_block = ir_create_basic_block(irb, parent_scope, "ForEnd");
5944 IrBasicBlock *else_block = else_node ? ir_create_basic_block(irb, child_scope, "ForElse") : end_block;6486 IrBasicBlock *else_block = else_node ? ir_create_basic_block(irb, parent_scope, "ForElse") : end_block;
5945 IrBasicBlock *continue_block = ir_create_basic_block(irb, child_scope, "ForContinue");6487 IrBasicBlock *continue_block = ir_create_basic_block(irb, parent_scope, "ForContinue");
59466488
5947 Buf *len_field_name = buf_create_from_str("len");6489 Buf *len_field_name = buf_create_from_str("len");
5948 IrInstruction *len_ref = ir_build_field_ptr(irb, child_scope, node, array_val_ptr, len_field_name);6490 IrInstruction *len_ref = ir_build_field_ptr(irb, parent_scope, node, array_val_ptr, len_field_name, false);
5949 IrInstruction *len_val = ir_build_load_ptr(irb, child_scope, node, len_ref);6491 IrInstruction *len_val = ir_build_load_ptr(irb, parent_scope, node, len_ref);
5950 ir_build_br(irb, child_scope, node, cond_block, is_comptime);6492 ir_build_br(irb, parent_scope, node, cond_block, is_comptime);
59516493
5952 ir_set_cursor_at_end_and_append_block(irb, cond_block);6494 ir_set_cursor_at_end_and_append_block(irb, cond_block);
5953 IrInstruction *index_val = ir_build_load_ptr(irb, child_scope, node, index_ptr);6495 IrInstruction *index_val = ir_build_load_ptr(irb, parent_scope, node, index_ptr);
5954 IrInstruction *cond = ir_build_bin_op(irb, child_scope, node, IrBinOpCmpLessThan, index_val, len_val, false);6496 IrInstruction *cond = ir_build_bin_op(irb, parent_scope, node, IrBinOpCmpLessThan, index_val, len_val, false);
5955 IrBasicBlock *after_cond_block = irb->current_basic_block;6497 IrBasicBlock *after_cond_block = irb->current_basic_block;
5956 IrInstruction *void_else_value = else_node ? nullptr : ir_mark_gen(ir_build_const_void(irb, parent_scope, node));6498 IrInstruction *void_else_value = else_node ? nullptr : ir_mark_gen(ir_build_const_void(irb, parent_scope, node));
5957 ir_mark_gen(ir_build_cond_br(irb, child_scope, node, cond, body_block, else_block, is_comptime));6499 IrInstruction *cond_br_inst = ir_mark_gen(ir_build_cond_br(irb, parent_scope, node, cond,
6500 body_block, else_block, is_comptime));
6501
6502 ResultLocPeerParent *peer_parent = ir_build_result_peers(irb, cond_br_inst, end_block, result_loc, is_comptime);
59586503
5959 ir_set_cursor_at_end_and_append_block(irb, body_block);6504 ir_set_cursor_at_end_and_append_block(irb, body_block);
5960 IrInstruction *elem_ptr = ir_build_elem_ptr(irb, child_scope, node, array_val_ptr, index_val, false, PtrLenSingle);6505 IrInstruction *elem_ptr = ir_build_elem_ptr(irb, parent_scope, node, array_val_ptr, index_val, false,
5961 IrInstruction *elem_val;6506 PtrLenSingle, nullptr);
5962 if (node->data.for_expr.elem_is_ptr) {6507 // TODO make it an error to write to element variable or i variable.
5963 elem_val = elem_ptr;6508 Buf *elem_var_name = elem_node->data.symbol_expr.symbol;
5964 } else {6509 ZigVar *elem_var = ir_create_var(irb, elem_node, parent_scope, elem_var_name, true, false, false, is_comptime);
5965 elem_val = ir_build_load_ptr(irb, child_scope, node, elem_ptr);6510 Scope *child_scope = elem_var->child_scope;
5966 }6511
5967 ir_mark_gen(ir_build_store_ptr(irb, child_scope, node, elem_var_ptr, elem_val));6512 IrInstruction *var_ptr = node->data.for_expr.elem_is_ptr ?
6513 ir_build_ref(irb, parent_scope, elem_node, elem_ptr, true, false) : elem_ptr;
6514 ir_build_var_decl_src(irb, parent_scope, elem_node, elem_var, nullptr, var_ptr);
59686515
5969 ZigList<IrInstruction *> incoming_values = {0};6516 ZigList<IrInstruction *> incoming_values = {0};
5970 ZigList<IrBasicBlock *> incoming_blocks = {0};6517 ZigList<IrBasicBlock *> incoming_blocks = {0};
...@@ -5974,7 +6521,12 @@ static IrInstruction *ir_gen_for_expr(IrBuilder *irb, Scope *parent_scope, AstNo...@@ -5974,7 +6521,12 @@ static IrInstruction *ir_gen_for_expr(IrBuilder *irb, Scope *parent_scope, AstNo
5974 loop_scope->is_comptime = is_comptime;6521 loop_scope->is_comptime = is_comptime;
5975 loop_scope->incoming_blocks = &incoming_blocks;6522 loop_scope->incoming_blocks = &incoming_blocks;
5976 loop_scope->incoming_values = &incoming_values;6523 loop_scope->incoming_values = &incoming_values;
6524 loop_scope->lval = lval;
6525 loop_scope->peer_parent = peer_parent;
59776526
6527 // Note the body block of the loop is not the place that lval and result_loc are used -
6528 // it's actually in break statements, handled similarly to return statements.
6529 // That is why we set those values in loop_scope above and not in this ir_gen_node call.
5978 IrInstruction *body_result = ir_gen_node(irb, body_node, &loop_scope->base);6530 IrInstruction *body_result = ir_gen_node(irb, body_node, &loop_scope->base);
59796531
5980 if (!instr_is_unreachable(body_result)) {6532 if (!instr_is_unreachable(body_result)) {
...@@ -5991,7 +6543,12 @@ static IrInstruction *ir_gen_for_expr(IrBuilder *irb, Scope *parent_scope, AstNo...@@ -5991,7 +6543,12 @@ static IrInstruction *ir_gen_for_expr(IrBuilder *irb, Scope *parent_scope, AstNo
5991 if (else_node) {6543 if (else_node) {
5992 ir_set_cursor_at_end_and_append_block(irb, else_block);6544 ir_set_cursor_at_end_and_append_block(irb, else_block);
59936545
5994 else_result = ir_gen_node(irb, else_node, parent_scope);6546 if (peer_parent->peers.length != 0) {
6547 peer_parent->peers.last()->next_bb = else_block;
6548 }
6549 ResultLocPeer *peer_result = create_peer_result(peer_parent);
6550 peer_parent->peers.append(peer_result);
6551 else_result = ir_gen_node_extra(irb, else_node, parent_scope, lval, &peer_result->base);
5995 if (else_result == irb->codegen->invalid_instruction)6552 if (else_result == irb->codegen->invalid_instruction)
5996 return else_result;6553 return else_result;
5997 if (!instr_is_unreachable(else_result))6554 if (!instr_is_unreachable(else_result))
...@@ -6007,8 +6564,13 @@ static IrInstruction *ir_gen_for_expr(IrBuilder *irb, Scope *parent_scope, AstNo...@@ -6007,8 +6564,13 @@ static IrInstruction *ir_gen_for_expr(IrBuilder *irb, Scope *parent_scope, AstNo
6007 incoming_blocks.append(after_cond_block);6564 incoming_blocks.append(after_cond_block);
6008 incoming_values.append(void_else_value);6565 incoming_values.append(void_else_value);
6009 }6566 }
6567 if (peer_parent->peers.length != 0) {
6568 peer_parent->peers.last()->next_bb = end_block;
6569 }
60106570
6011 return ir_build_phi(irb, parent_scope, node, incoming_blocks.length, incoming_blocks.items, incoming_values.items);6571 IrInstruction *phi = ir_build_phi(irb, parent_scope, node, incoming_blocks.length,
6572 incoming_blocks.items, incoming_values.items, peer_parent);
6573 return ir_expr_wrap(irb, parent_scope, phi, result_loc);
6012}6574}
60136575
6014static IrInstruction *ir_gen_bool_literal(IrBuilder *irb, Scope *scope, AstNode *node) {6576static IrInstruction *ir_gen_bool_literal(IrBuilder *irb, Scope *scope, AstNode *node) {
...@@ -6293,7 +6855,9 @@ static IrInstruction *ir_gen_asm_expr(IrBuilder *irb, Scope *scope, AstNode *nod...@@ -6293,7 +6855,9 @@ static IrInstruction *ir_gen_asm_expr(IrBuilder *irb, Scope *scope, AstNode *nod
6293 input_list, output_types, output_vars, return_count, is_volatile);6855 input_list, output_types, output_vars, return_count, is_volatile);
6294}6856}
62956857
6296static IrInstruction *ir_gen_if_optional_expr(IrBuilder *irb, Scope *scope, AstNode *node) {6858static IrInstruction *ir_gen_if_optional_expr(IrBuilder *irb, Scope *scope, AstNode *node, LVal lval,
6859 ResultLoc *result_loc)
6860{
6297 assert(node->type == NodeTypeIfOptional);6861 assert(node->type == NodeTypeIfOptional);
62986862
6299 Buf *var_symbol = node->data.test_expr.var_symbol;6863 Buf *var_symbol = node->data.test_expr.var_symbol;
...@@ -6302,7 +6866,7 @@ static IrInstruction *ir_gen_if_optional_expr(IrBuilder *irb, Scope *scope, AstN...@@ -6302,7 +6866,7 @@ static IrInstruction *ir_gen_if_optional_expr(IrBuilder *irb, Scope *scope, AstN
6302 AstNode *else_node = node->data.test_expr.else_node;6866 AstNode *else_node = node->data.test_expr.else_node;
6303 bool var_is_ptr = node->data.test_expr.var_is_ptr;6867 bool var_is_ptr = node->data.test_expr.var_is_ptr;
63046868
6305 IrInstruction *maybe_val_ptr = ir_gen_node_extra(irb, expr_node, scope, LValPtr);6869 IrInstruction *maybe_val_ptr = ir_gen_node_extra(irb, expr_node, scope, LValPtr, nullptr);
6306 if (maybe_val_ptr == irb->codegen->invalid_instruction)6870 if (maybe_val_ptr == irb->codegen->invalid_instruction)
6307 return maybe_val_ptr;6871 return maybe_val_ptr;
63086872
...@@ -6319,27 +6883,31 @@ static IrInstruction *ir_gen_if_optional_expr(IrBuilder *irb, Scope *scope, AstN...@@ -6319,27 +6883,31 @@ static IrInstruction *ir_gen_if_optional_expr(IrBuilder *irb, Scope *scope, AstN
6319 } else {6883 } else {
6320 is_comptime = ir_build_test_comptime(irb, scope, node, is_non_null);6884 is_comptime = ir_build_test_comptime(irb, scope, node, is_non_null);
6321 }6885 }
6322 ir_build_cond_br(irb, scope, node, is_non_null, then_block, else_block, is_comptime);6886 IrInstruction *cond_br_inst = ir_build_cond_br(irb, scope, node, is_non_null,
6887 then_block, else_block, is_comptime);
6888
6889 ResultLocPeerParent *peer_parent = ir_build_binary_result_peers(irb, cond_br_inst, else_block, endif_block,
6890 result_loc, is_comptime);
63236891
6324 ir_set_cursor_at_end_and_append_block(irb, then_block);6892 ir_set_cursor_at_end_and_append_block(irb, then_block);
63256893
6326 Scope *subexpr_scope = create_runtime_scope(irb->codegen, node, scope, is_comptime);6894 Scope *subexpr_scope = create_runtime_scope(irb->codegen, node, scope, is_comptime);
6327 Scope *var_scope;6895 Scope *var_scope;
6328 if (var_symbol) {6896 if (var_symbol) {
6329 IrInstruction *var_type = nullptr;
6330 bool is_shadowable = false;6897 bool is_shadowable = false;
6331 bool is_const = true;6898 bool is_const = true;
6332 ZigVar *var = ir_create_var(irb, node, subexpr_scope,6899 ZigVar *var = ir_create_var(irb, node, subexpr_scope,
6333 var_symbol, is_const, is_const, is_shadowable, is_comptime);6900 var_symbol, is_const, is_const, is_shadowable, is_comptime);
63346901
6335 IrInstruction *var_ptr_value = ir_build_optional_unwrap_ptr(irb, subexpr_scope, node, maybe_val_ptr, false);6902 IrInstruction *payload_ptr = ir_build_optional_unwrap_ptr(irb, subexpr_scope, node, maybe_val_ptr, false, false);
6336 IrInstruction *var_value = var_is_ptr ? var_ptr_value : ir_build_load_ptr(irb, subexpr_scope, node, var_ptr_value);6903 IrInstruction *var_ptr = var_is_ptr ? ir_build_ref(irb, subexpr_scope, node, payload_ptr, true, false) : payload_ptr;
6337 ir_build_var_decl_src(irb, subexpr_scope, node, var, var_type, nullptr, var_value);6904 ir_build_var_decl_src(irb, subexpr_scope, node, var, nullptr, var_ptr);
6338 var_scope = var->child_scope;6905 var_scope = var->child_scope;
6339 } else {6906 } else {
6340 var_scope = subexpr_scope;6907 var_scope = subexpr_scope;
6341 }6908 }
6342 IrInstruction *then_expr_result = ir_gen_node(irb, then_node, var_scope);6909 IrInstruction *then_expr_result = ir_gen_node_extra(irb, then_node, var_scope, lval,
6910 &peer_parent->peers.at(0)->base);
6343 if (then_expr_result == irb->codegen->invalid_instruction)6911 if (then_expr_result == irb->codegen->invalid_instruction)
6344 return then_expr_result;6912 return then_expr_result;
6345 IrBasicBlock *after_then_block = irb->current_basic_block;6913 IrBasicBlock *after_then_block = irb->current_basic_block;
...@@ -6349,11 +6917,12 @@ static IrInstruction *ir_gen_if_optional_expr(IrBuilder *irb, Scope *scope, AstN...@@ -6349,11 +6917,12 @@ static IrInstruction *ir_gen_if_optional_expr(IrBuilder *irb, Scope *scope, AstN
6349 ir_set_cursor_at_end_and_append_block(irb, else_block);6917 ir_set_cursor_at_end_and_append_block(irb, else_block);
6350 IrInstruction *else_expr_result;6918 IrInstruction *else_expr_result;
6351 if (else_node) {6919 if (else_node) {
6352 else_expr_result = ir_gen_node(irb, else_node, subexpr_scope);6920 else_expr_result = ir_gen_node_extra(irb, else_node, subexpr_scope, lval, &peer_parent->peers.at(1)->base);
6353 if (else_expr_result == irb->codegen->invalid_instruction)6921 if (else_expr_result == irb->codegen->invalid_instruction)
6354 return else_expr_result;6922 return else_expr_result;
6355 } else {6923 } else {
6356 else_expr_result = ir_build_const_void(irb, scope, node);6924 else_expr_result = ir_build_const_void(irb, scope, node);
6925 ir_build_end_expr(irb, scope, node, else_expr_result, &peer_parent->peers.at(1)->base);
6357 }6926 }
6358 IrBasicBlock *after_else_block = irb->current_basic_block;6927 IrBasicBlock *after_else_block = irb->current_basic_block;
6359 if (!instr_is_unreachable(else_expr_result))6928 if (!instr_is_unreachable(else_expr_result))
...@@ -6367,10 +6936,13 @@ static IrInstruction *ir_gen_if_optional_expr(IrBuilder *irb, Scope *scope, AstN...@@ -6367,10 +6936,13 @@ static IrInstruction *ir_gen_if_optional_expr(IrBuilder *irb, Scope *scope, AstN
6367 incoming_blocks[0] = after_then_block;6936 incoming_blocks[0] = after_then_block;
6368 incoming_blocks[1] = after_else_block;6937 incoming_blocks[1] = after_else_block;
63696938
6370 return ir_build_phi(irb, scope, node, 2, incoming_blocks, incoming_values);6939 IrInstruction *phi = ir_build_phi(irb, scope, node, 2, incoming_blocks, incoming_values, peer_parent);
6940 return ir_expr_wrap(irb, scope, phi, result_loc);
6371}6941}
63726942
6373static IrInstruction *ir_gen_if_err_expr(IrBuilder *irb, Scope *scope, AstNode *node) {6943static IrInstruction *ir_gen_if_err_expr(IrBuilder *irb, Scope *scope, AstNode *node, LVal lval,
6944 ResultLoc *result_loc)
6945{
6374 assert(node->type == NodeTypeIfErrorExpr);6946 assert(node->type == NodeTypeIfErrorExpr);
63756947
6376 AstNode *target_node = node->data.if_err_expr.target_node;6948 AstNode *target_node = node->data.if_err_expr.target_node;
...@@ -6381,12 +6953,12 @@ static IrInstruction *ir_gen_if_err_expr(IrBuilder *irb, Scope *scope, AstNode *...@@ -6381,12 +6953,12 @@ static IrInstruction *ir_gen_if_err_expr(IrBuilder *irb, Scope *scope, AstNode *
6381 Buf *var_symbol = node->data.if_err_expr.var_symbol;6953 Buf *var_symbol = node->data.if_err_expr.var_symbol;
6382 Buf *err_symbol = node->data.if_err_expr.err_symbol;6954 Buf *err_symbol = node->data.if_err_expr.err_symbol;
63836955
6384 IrInstruction *err_val_ptr = ir_gen_node_extra(irb, target_node, scope, LValPtr);6956 IrInstruction *err_val_ptr = ir_gen_node_extra(irb, target_node, scope, LValPtr, nullptr);
6385 if (err_val_ptr == irb->codegen->invalid_instruction)6957 if (err_val_ptr == irb->codegen->invalid_instruction)
6386 return err_val_ptr;6958 return err_val_ptr;
63876959
6388 IrInstruction *err_val = ir_build_load_ptr(irb, scope, node, err_val_ptr);6960 IrInstruction *err_val = ir_build_load_ptr(irb, scope, node, err_val_ptr);
6389 IrInstruction *is_err = ir_build_test_err(irb, scope, node, err_val);6961 IrInstruction *is_err = ir_build_test_err_src(irb, scope, node, err_val_ptr, true);
63906962
6391 IrBasicBlock *ok_block = ir_create_basic_block(irb, scope, "TryOk");6963 IrBasicBlock *ok_block = ir_create_basic_block(irb, scope, "TryOk");
6392 IrBasicBlock *else_block = ir_create_basic_block(irb, scope, "TryElse");6964 IrBasicBlock *else_block = ir_create_basic_block(irb, scope, "TryElse");
...@@ -6394,27 +6966,31 @@ static IrInstruction *ir_gen_if_err_expr(IrBuilder *irb, Scope *scope, AstNode *...@@ -6394,27 +6966,31 @@ static IrInstruction *ir_gen_if_err_expr(IrBuilder *irb, Scope *scope, AstNode *
63946966
6395 bool force_comptime = ir_should_inline(irb->exec, scope);6967 bool force_comptime = ir_should_inline(irb->exec, scope);
6396 IrInstruction *is_comptime = force_comptime ? ir_build_const_bool(irb, scope, node, true) : ir_build_test_comptime(irb, scope, node, is_err);6968 IrInstruction *is_comptime = force_comptime ? ir_build_const_bool(irb, scope, node, true) : ir_build_test_comptime(irb, scope, node, is_err);
6397 ir_build_cond_br(irb, scope, node, is_err, else_block, ok_block, is_comptime);6969 IrInstruction *cond_br_inst = ir_build_cond_br(irb, scope, node, is_err, else_block, ok_block, is_comptime);
6970
6971 ResultLocPeerParent *peer_parent = ir_build_binary_result_peers(irb, cond_br_inst, else_block, endif_block,
6972 result_loc, is_comptime);
63986973
6399 ir_set_cursor_at_end_and_append_block(irb, ok_block);6974 ir_set_cursor_at_end_and_append_block(irb, ok_block);
64006975
6401 Scope *subexpr_scope = create_runtime_scope(irb->codegen, node, scope, is_comptime);6976 Scope *subexpr_scope = create_runtime_scope(irb->codegen, node, scope, is_comptime);
6402 Scope *var_scope;6977 Scope *var_scope;
6403 if (var_symbol) {6978 if (var_symbol) {
6404 IrInstruction *var_type = nullptr;
6405 bool is_shadowable = false;6979 bool is_shadowable = false;
6406 IrInstruction *var_is_comptime = force_comptime ? ir_build_const_bool(irb, subexpr_scope, node, true) : ir_build_test_comptime(irb, subexpr_scope, node, err_val);6980 IrInstruction *var_is_comptime = force_comptime ? ir_build_const_bool(irb, subexpr_scope, node, true) : ir_build_test_comptime(irb, subexpr_scope, node, err_val);
6407 ZigVar *var = ir_create_var(irb, node, subexpr_scope,6981 ZigVar *var = ir_create_var(irb, node, subexpr_scope,
6408 var_symbol, var_is_const, var_is_const, is_shadowable, var_is_comptime);6982 var_symbol, var_is_const, var_is_const, is_shadowable, var_is_comptime);
64096983
6410 IrInstruction *var_ptr_value = ir_build_unwrap_err_payload(irb, subexpr_scope, node, err_val_ptr, false);6984 IrInstruction *payload_ptr = ir_build_unwrap_err_payload(irb, subexpr_scope, node, err_val_ptr, false, false);
6411 IrInstruction *var_value = var_is_ptr ? var_ptr_value : ir_build_load_ptr(irb, subexpr_scope, node, var_ptr_value);6985 IrInstruction *var_ptr = var_is_ptr ?
6412 ir_build_var_decl_src(irb, subexpr_scope, node, var, var_type, nullptr, var_value);6986 ir_build_ref(irb, subexpr_scope, node, payload_ptr, true, false) : payload_ptr;
6987 ir_build_var_decl_src(irb, subexpr_scope, node, var, nullptr, var_ptr);
6413 var_scope = var->child_scope;6988 var_scope = var->child_scope;
6414 } else {6989 } else {
6415 var_scope = subexpr_scope;6990 var_scope = subexpr_scope;
6416 }6991 }
6417 IrInstruction *then_expr_result = ir_gen_node(irb, then_node, var_scope);6992 IrInstruction *then_expr_result = ir_gen_node_extra(irb, then_node, var_scope, lval,
6993 &peer_parent->peers.at(0)->base);
6418 if (then_expr_result == irb->codegen->invalid_instruction)6994 if (then_expr_result == irb->codegen->invalid_instruction)
6419 return then_expr_result;6995 return then_expr_result;
6420 IrBasicBlock *after_then_block = irb->current_basic_block;6996 IrBasicBlock *after_then_block = irb->current_basic_block;
...@@ -6427,23 +7003,23 @@ static IrInstruction *ir_gen_if_err_expr(IrBuilder *irb, Scope *scope, AstNode *...@@ -6427,23 +7003,23 @@ static IrInstruction *ir_gen_if_err_expr(IrBuilder *irb, Scope *scope, AstNode *
6427 if (else_node) {7003 if (else_node) {
6428 Scope *err_var_scope;7004 Scope *err_var_scope;
6429 if (err_symbol) {7005 if (err_symbol) {
6430 IrInstruction *var_type = nullptr;
6431 bool is_shadowable = false;7006 bool is_shadowable = false;
6432 bool is_const = true;7007 bool is_const = true;
6433 ZigVar *var = ir_create_var(irb, node, subexpr_scope,7008 ZigVar *var = ir_create_var(irb, node, subexpr_scope,
6434 err_symbol, is_const, is_const, is_shadowable, is_comptime);7009 err_symbol, is_const, is_const, is_shadowable, is_comptime);
64357010
6436 IrInstruction *var_value = ir_build_unwrap_err_code(irb, subexpr_scope, node, err_val_ptr);7011 IrInstruction *err_ptr = ir_build_unwrap_err_code(irb, subexpr_scope, node, err_val_ptr);
6437 ir_build_var_decl_src(irb, subexpr_scope, node, var, var_type, nullptr, var_value);7012 ir_build_var_decl_src(irb, subexpr_scope, node, var, nullptr, err_ptr);
6438 err_var_scope = var->child_scope;7013 err_var_scope = var->child_scope;
6439 } else {7014 } else {
6440 err_var_scope = subexpr_scope;7015 err_var_scope = subexpr_scope;
6441 }7016 }
6442 else_expr_result = ir_gen_node(irb, else_node, err_var_scope);7017 else_expr_result = ir_gen_node_extra(irb, else_node, err_var_scope, lval, &peer_parent->peers.at(1)->base);
6443 if (else_expr_result == irb->codegen->invalid_instruction)7018 if (else_expr_result == irb->codegen->invalid_instruction)
6444 return else_expr_result;7019 return else_expr_result;
6445 } else {7020 } else {
6446 else_expr_result = ir_build_const_void(irb, scope, node);7021 else_expr_result = ir_build_const_void(irb, scope, node);
7022 ir_build_end_expr(irb, scope, node, else_expr_result, &peer_parent->peers.at(1)->base);
6447 }7023 }
6448 IrBasicBlock *after_else_block = irb->current_basic_block;7024 IrBasicBlock *after_else_block = irb->current_basic_block;
6449 if (!instr_is_unreachable(else_expr_result))7025 if (!instr_is_unreachable(else_expr_result))
...@@ -6457,14 +7033,15 @@ static IrInstruction *ir_gen_if_err_expr(IrBuilder *irb, Scope *scope, AstNode *...@@ -6457,14 +7033,15 @@ static IrInstruction *ir_gen_if_err_expr(IrBuilder *irb, Scope *scope, AstNode *
6457 incoming_blocks[0] = after_then_block;7033 incoming_blocks[0] = after_then_block;
6458 incoming_blocks[1] = after_else_block;7034 incoming_blocks[1] = after_else_block;
64597035
6460 return ir_build_phi(irb, scope, node, 2, incoming_blocks, incoming_values);7036 IrInstruction *phi = ir_build_phi(irb, scope, node, 2, incoming_blocks, incoming_values, peer_parent);
7037 return ir_expr_wrap(irb, scope, phi, result_loc);
6461}7038}
64627039
6463static bool ir_gen_switch_prong_expr(IrBuilder *irb, Scope *scope, AstNode *switch_node, AstNode *prong_node,7040static bool ir_gen_switch_prong_expr(IrBuilder *irb, Scope *scope, AstNode *switch_node, AstNode *prong_node,
6464 IrBasicBlock *end_block, IrInstruction *is_comptime, IrInstruction *var_is_comptime,7041 IrBasicBlock *end_block, IrInstruction *is_comptime, IrInstruction *var_is_comptime,
6465 IrInstruction *target_value_ptr, IrInstruction **prong_values, size_t prong_values_len,7042 IrInstruction *target_value_ptr, IrInstruction **prong_values, size_t prong_values_len,
6466 ZigList<IrBasicBlock *> *incoming_blocks, ZigList<IrInstruction *> *incoming_values,7043 ZigList<IrBasicBlock *> *incoming_blocks, ZigList<IrInstruction *> *incoming_values,
6467 IrInstructionSwitchElseVar **out_switch_else_var)7044 IrInstructionSwitchElseVar **out_switch_else_var, LVal lval, ResultLoc *result_loc)
6468{7045{
6469 assert(switch_node->type == NodeTypeSwitchExpr);7046 assert(switch_node->type == NodeTypeSwitchExpr);
6470 assert(prong_node->type == NodeTypeSwitchProng);7047 assert(prong_node->type == NodeTypeSwitchProng);
...@@ -6482,28 +7059,27 @@ static bool ir_gen_switch_prong_expr(IrBuilder *irb, Scope *scope, AstNode *swit...@@ -6482,28 +7059,27 @@ static bool ir_gen_switch_prong_expr(IrBuilder *irb, Scope *scope, AstNode *swit
6482 ZigVar *var = ir_create_var(irb, var_symbol_node, scope,7059 ZigVar *var = ir_create_var(irb, var_symbol_node, scope,
6483 var_name, is_const, is_const, is_shadowable, var_is_comptime);7060 var_name, is_const, is_const, is_shadowable, var_is_comptime);
6484 child_scope = var->child_scope;7061 child_scope = var->child_scope;
6485 IrInstruction *var_value;7062 IrInstruction *var_ptr;
6486 if (out_switch_else_var != nullptr) {7063 if (out_switch_else_var != nullptr) {
6487 IrInstructionSwitchElseVar *switch_else_var = ir_build_switch_else_var(irb, scope, var_symbol_node,7064 IrInstructionSwitchElseVar *switch_else_var = ir_build_switch_else_var(irb, scope, var_symbol_node,
6488 target_value_ptr);7065 target_value_ptr);
6489 *out_switch_else_var = switch_else_var;7066 *out_switch_else_var = switch_else_var;
6490 IrInstruction *var_ptr_value = &switch_else_var->base;7067 IrInstruction *payload_ptr = &switch_else_var->base;
6491 var_value = var_is_ptr ? var_ptr_value : ir_build_load_ptr(irb, scope, var_symbol_node, var_ptr_value);7068 var_ptr = var_is_ptr ? ir_build_ref(irb, scope, var_symbol_node, payload_ptr, true, false) : payload_ptr;
6492 } else if (prong_values != nullptr) {7069 } else if (prong_values != nullptr) {
6493 IrInstruction *var_ptr_value = ir_build_switch_var(irb, scope, var_symbol_node, target_value_ptr,7070 IrInstruction *payload_ptr = ir_build_switch_var(irb, scope, var_symbol_node, target_value_ptr,
6494 prong_values, prong_values_len);7071 prong_values, prong_values_len);
6495 var_value = var_is_ptr ? var_ptr_value : ir_build_load_ptr(irb, scope, var_symbol_node, var_ptr_value);7072 var_ptr = var_is_ptr ? ir_build_ref(irb, scope, var_symbol_node, payload_ptr, true, false) : payload_ptr;
6496 } else {7073 } else {
6497 var_value = var_is_ptr ? target_value_ptr : ir_build_load_ptr(irb, scope, var_symbol_node, 7074 var_ptr = var_is_ptr ?
6498target_value_ptr);7075 ir_build_ref(irb, scope, var_symbol_node, target_value_ptr, true, false) : target_value_ptr;
6499 }7076 }
6500 IrInstruction *var_type = nullptr; // infer the type7077 ir_build_var_decl_src(irb, scope, var_symbol_node, var, nullptr, var_ptr);
6501 ir_build_var_decl_src(irb, scope, var_symbol_node, var, var_type, nullptr, var_value);
6502 } else {7078 } else {
6503 child_scope = scope;7079 child_scope = scope;
6504 }7080 }
65057081
6506 IrInstruction *expr_result = ir_gen_node(irb, expr_node, child_scope);7082 IrInstruction *expr_result = ir_gen_node_extra(irb, expr_node, child_scope, lval, result_loc);
6507 if (expr_result == irb->codegen->invalid_instruction)7083 if (expr_result == irb->codegen->invalid_instruction)
6508 return false;7084 return false;
6509 if (!instr_is_unreachable(expr_result))7085 if (!instr_is_unreachable(expr_result))
...@@ -6513,11 +7089,13 @@ target_value_ptr);...@@ -6513,11 +7089,13 @@ target_value_ptr);
6513 return true;7089 return true;
6514}7090}
65157091
6516static IrInstruction *ir_gen_switch_expr(IrBuilder *irb, Scope *scope, AstNode *node) {7092static IrInstruction *ir_gen_switch_expr(IrBuilder *irb, Scope *scope, AstNode *node, LVal lval,
7093 ResultLoc *result_loc)
7094{
6517 assert(node->type == NodeTypeSwitchExpr);7095 assert(node->type == NodeTypeSwitchExpr);
65187096
6519 AstNode *target_node = node->data.switch_expr.expr;7097 AstNode *target_node = node->data.switch_expr.expr;
6520 IrInstruction *target_value_ptr = ir_gen_node_extra(irb, target_node, scope, LValPtr);7098 IrInstruction *target_value_ptr = ir_gen_node_extra(irb, target_node, scope, LValPtr, nullptr);
6521 if (target_value_ptr == irb->codegen->invalid_instruction)7099 if (target_value_ptr == irb->codegen->invalid_instruction)
6522 return target_value_ptr;7100 return target_value_ptr;
6523 IrInstruction *target_value = ir_build_switch_target(irb, scope, node, target_value_ptr);7101 IrInstruction *target_value = ir_build_switch_target(irb, scope, node, target_value_ptr);
...@@ -6544,6 +7122,14 @@ static IrInstruction *ir_gen_switch_expr(IrBuilder *irb, Scope *scope, AstNode *...@@ -6544,6 +7122,14 @@ static IrInstruction *ir_gen_switch_expr(IrBuilder *irb, Scope *scope, AstNode *
65447122
6545 IrInstructionSwitchElseVar *switch_else_var = nullptr;7123 IrInstructionSwitchElseVar *switch_else_var = nullptr;
65467124
7125 ResultLocPeerParent *peer_parent = allocate<ResultLocPeerParent>(1);
7126 peer_parent->base.id = ResultLocIdPeerParent;
7127 peer_parent->end_bb = end_block;
7128 peer_parent->is_comptime = is_comptime;
7129 peer_parent->parent = result_loc;
7130
7131 ir_build_reset_result(irb, scope, node, &peer_parent->base);
7132
6547 // First do the else and the ranges7133 // First do the else and the ranges
6548 Scope *subexpr_scope = create_runtime_scope(irb->codegen, node, scope, is_comptime);7134 Scope *subexpr_scope = create_runtime_scope(irb->codegen, node, scope, is_comptime);
6549 Scope *comptime_scope = create_comptime_scope(irb->codegen, node, scope);7135 Scope *comptime_scope = create_comptime_scope(irb->codegen, node, scope);
...@@ -6552,6 +7138,7 @@ static IrInstruction *ir_gen_switch_expr(IrBuilder *irb, Scope *scope, AstNode *...@@ -6552,6 +7138,7 @@ static IrInstruction *ir_gen_switch_expr(IrBuilder *irb, Scope *scope, AstNode *
6552 AstNode *prong_node = node->data.switch_expr.prongs.at(prong_i);7138 AstNode *prong_node = node->data.switch_expr.prongs.at(prong_i);
6553 size_t prong_item_count = prong_node->data.switch_prong.items.length;7139 size_t prong_item_count = prong_node->data.switch_prong.items.length;
6554 if (prong_item_count == 0) {7140 if (prong_item_count == 0) {
7141 ResultLocPeer *this_peer_result_loc = create_peer_result(peer_parent);
6555 if (else_prong) {7142 if (else_prong) {
6556 ErrorMsg *msg = add_node_error(irb->codegen, prong_node,7143 ErrorMsg *msg = add_node_error(irb->codegen, prong_node,
6557 buf_sprintf("multiple else prongs in switch expression"));7144 buf_sprintf("multiple else prongs in switch expression"));
...@@ -6562,15 +7149,21 @@ static IrInstruction *ir_gen_switch_expr(IrBuilder *irb, Scope *scope, AstNode *...@@ -6562,15 +7149,21 @@ static IrInstruction *ir_gen_switch_expr(IrBuilder *irb, Scope *scope, AstNode *
6562 else_prong = prong_node;7149 else_prong = prong_node;
65637150
6564 IrBasicBlock *prev_block = irb->current_basic_block;7151 IrBasicBlock *prev_block = irb->current_basic_block;
7152 if (peer_parent->peers.length > 0) {
7153 peer_parent->peers.last()->next_bb = else_block;
7154 }
7155 peer_parent->peers.append(this_peer_result_loc);
6565 ir_set_cursor_at_end_and_append_block(irb, else_block);7156 ir_set_cursor_at_end_and_append_block(irb, else_block);
6566 if (!ir_gen_switch_prong_expr(irb, subexpr_scope, node, prong_node, end_block,7157 if (!ir_gen_switch_prong_expr(irb, subexpr_scope, node, prong_node, end_block,
6567 is_comptime, var_is_comptime, target_value_ptr, nullptr, 0, &incoming_blocks, &incoming_values,7158 is_comptime, var_is_comptime, target_value_ptr, nullptr, 0, &incoming_blocks, &incoming_values,
6568 &switch_else_var))7159 &switch_else_var, lval, &this_peer_result_loc->base))
6569 {7160 {
6570 return irb->codegen->invalid_instruction;7161 return irb->codegen->invalid_instruction;
6571 }7162 }
6572 ir_set_cursor_at_end(irb, prev_block);7163 ir_set_cursor_at_end(irb, prev_block);
6573 } else if (prong_node->data.switch_prong.any_items_are_range) {7164 } else if (prong_node->data.switch_prong.any_items_are_range) {
7165 ResultLocPeer *this_peer_result_loc = create_peer_result(peer_parent);
7166
6574 IrInstruction *ok_bit = nullptr;7167 IrInstruction *ok_bit = nullptr;
6575 AstNode *last_item_node = nullptr;7168 AstNode *last_item_node = nullptr;
6576 for (size_t item_i = 0; item_i < prong_item_count; item_i += 1) {7169 for (size_t item_i = 0; item_i < prong_item_count; item_i += 1) {
...@@ -6627,13 +7220,20 @@ static IrInstruction *ir_gen_switch_expr(IrBuilder *irb, Scope *scope, AstNode *...@@ -6627,13 +7220,20 @@ static IrInstruction *ir_gen_switch_expr(IrBuilder *irb, Scope *scope, AstNode *
66277220
6628 assert(ok_bit);7221 assert(ok_bit);
6629 assert(last_item_node);7222 assert(last_item_node);
6630 ir_mark_gen(ir_build_cond_br(irb, scope, last_item_node, ok_bit, range_block_yes,7223 IrInstruction *br_inst = ir_mark_gen(ir_build_cond_br(irb, scope, last_item_node, ok_bit,
6631 range_block_no, is_comptime));7224 range_block_yes, range_block_no, is_comptime));
7225 if (peer_parent->base.source_instruction == nullptr) {
7226 peer_parent->base.source_instruction = br_inst;
7227 }
66327228
7229 if (peer_parent->peers.length > 0) {
7230 peer_parent->peers.last()->next_bb = range_block_yes;
7231 }
7232 peer_parent->peers.append(this_peer_result_loc);
6633 ir_set_cursor_at_end_and_append_block(irb, range_block_yes);7233 ir_set_cursor_at_end_and_append_block(irb, range_block_yes);
6634 if (!ir_gen_switch_prong_expr(irb, subexpr_scope, node, prong_node, end_block,7234 if (!ir_gen_switch_prong_expr(irb, subexpr_scope, node, prong_node, end_block,
6635 is_comptime, var_is_comptime, target_value_ptr, nullptr, 0,7235 is_comptime, var_is_comptime, target_value_ptr, nullptr, 0,
6636 &incoming_blocks, &incoming_values, nullptr))7236 &incoming_blocks, &incoming_values, nullptr, lval, &this_peer_result_loc->base))
6637 {7237 {
6638 return irb->codegen->invalid_instruction;7238 return irb->codegen->invalid_instruction;
6639 }7239 }
...@@ -6651,6 +7251,8 @@ static IrInstruction *ir_gen_switch_expr(IrBuilder *irb, Scope *scope, AstNode *...@@ -6651,6 +7251,8 @@ static IrInstruction *ir_gen_switch_expr(IrBuilder *irb, Scope *scope, AstNode *
6651 if (prong_node->data.switch_prong.any_items_are_range)7251 if (prong_node->data.switch_prong.any_items_are_range)
6652 continue;7252 continue;
66537253
7254 ResultLocPeer *this_peer_result_loc = create_peer_result(peer_parent);
7255
6654 IrBasicBlock *prong_block = ir_create_basic_block(irb, scope, "SwitchProng");7256 IrBasicBlock *prong_block = ir_create_basic_block(irb, scope, "SwitchProng");
6655 IrInstruction **items = allocate<IrInstruction *>(prong_item_count);7257 IrInstruction **items = allocate<IrInstruction *>(prong_item_count);
66567258
...@@ -6674,10 +7276,14 @@ static IrInstruction *ir_gen_switch_expr(IrBuilder *irb, Scope *scope, AstNode *...@@ -6674,10 +7276,14 @@ static IrInstruction *ir_gen_switch_expr(IrBuilder *irb, Scope *scope, AstNode *
6674 }7276 }
66757277
6676 IrBasicBlock *prev_block = irb->current_basic_block;7278 IrBasicBlock *prev_block = irb->current_basic_block;
7279 if (peer_parent->peers.length > 0) {
7280 peer_parent->peers.last()->next_bb = prong_block;
7281 }
7282 peer_parent->peers.append(this_peer_result_loc);
6677 ir_set_cursor_at_end_and_append_block(irb, prong_block);7283 ir_set_cursor_at_end_and_append_block(irb, prong_block);
6678 if (!ir_gen_switch_prong_expr(irb, subexpr_scope, node, prong_node, end_block,7284 if (!ir_gen_switch_prong_expr(irb, subexpr_scope, node, prong_node, end_block,
6679 is_comptime, var_is_comptime, target_value_ptr, items, prong_item_count,7285 is_comptime, var_is_comptime, target_value_ptr, items, prong_item_count,
6680 &incoming_blocks, &incoming_values, nullptr))7286 &incoming_blocks, &incoming_values, nullptr, lval, &this_peer_result_loc->base))
6681 {7287 {
6682 return irb->codegen->invalid_instruction;7288 return irb->codegen->invalid_instruction;
6683 }7289 }
...@@ -6686,38 +7292,57 @@ static IrInstruction *ir_gen_switch_expr(IrBuilder *irb, Scope *scope, AstNode *...@@ -6686,38 +7292,57 @@ static IrInstruction *ir_gen_switch_expr(IrBuilder *irb, Scope *scope, AstNode *
66867292
6687 }7293 }
66887294
6689 IrInstruction *switch_prongs_void = ir_build_check_switch_prongs(irb, scope, node, target_value, check_ranges.items, check_ranges.length,7295 IrInstruction *switch_prongs_void = ir_build_check_switch_prongs(irb, scope, node, target_value,
6690 else_prong != nullptr);7296 check_ranges.items, check_ranges.length, else_prong != nullptr);
66917297
7298 IrInstruction *br_instruction;
6692 if (cases.length == 0) {7299 if (cases.length == 0) {
6693 ir_build_br(irb, scope, node, else_block, is_comptime);7300 br_instruction = ir_build_br(irb, scope, node, else_block, is_comptime);
6694 } else {7301 } else {
6695 IrInstructionSwitchBr *switch_br = ir_build_switch_br(irb, scope, node, target_value, else_block,7302 IrInstructionSwitchBr *switch_br = ir_build_switch_br(irb, scope, node, target_value, else_block,
6696 cases.length, cases.items, is_comptime, switch_prongs_void);7303 cases.length, cases.items, is_comptime, switch_prongs_void);
6697 if (switch_else_var != nullptr) {7304 if (switch_else_var != nullptr) {
6698 switch_else_var->switch_br = switch_br;7305 switch_else_var->switch_br = switch_br;
6699 }7306 }
7307 br_instruction = &switch_br->base;
7308 }
7309 if (peer_parent->base.source_instruction == nullptr) {
7310 peer_parent->base.source_instruction = br_instruction;
7311 }
7312 for (size_t i = 0; i < peer_parent->peers.length; i += 1) {
7313 peer_parent->peers.at(i)->base.source_instruction = peer_parent->base.source_instruction;
6700 }7314 }
67017315
6702 if (!else_prong) {7316 if (!else_prong) {
7317 if (peer_parent->peers.length != 0) {
7318 peer_parent->peers.last()->next_bb = else_block;
7319 }
6703 ir_set_cursor_at_end_and_append_block(irb, else_block);7320 ir_set_cursor_at_end_and_append_block(irb, else_block);
6704 ir_build_unreachable(irb, scope, node);7321 ir_build_unreachable(irb, scope, node);
7322 } else {
7323 if (peer_parent->peers.length != 0) {
7324 peer_parent->peers.last()->next_bb = end_block;
7325 }
6705 }7326 }
67067327
6707 ir_set_cursor_at_end_and_append_block(irb, end_block);7328 ir_set_cursor_at_end_and_append_block(irb, end_block);
6708 assert(incoming_blocks.length == incoming_values.length);7329 assert(incoming_blocks.length == incoming_values.length);
7330 IrInstruction *result_instruction;
6709 if (incoming_blocks.length == 0) {7331 if (incoming_blocks.length == 0) {
6710 return ir_build_const_void(irb, scope, node);7332 result_instruction = ir_build_const_void(irb, scope, node);
6711 } else {7333 } else {
6712 return ir_build_phi(irb, scope, node, incoming_blocks.length, incoming_blocks.items, incoming_values.items);7334 result_instruction = ir_build_phi(irb, scope, node, incoming_blocks.length,
7335 incoming_blocks.items, incoming_values.items, peer_parent);
6713 }7336 }
7337 return ir_expr_wrap(irb, scope, result_instruction, result_loc);
6714}7338}
67157339
6716static IrInstruction *ir_gen_comptime(IrBuilder *irb, Scope *parent_scope, AstNode *node, LVal lval) {7340static IrInstruction *ir_gen_comptime(IrBuilder *irb, Scope *parent_scope, AstNode *node, LVal lval) {
6717 assert(node->type == NodeTypeCompTime);7341 assert(node->type == NodeTypeCompTime);
67187342
6719 Scope *child_scope = create_comptime_scope(irb->codegen, node, parent_scope);7343 Scope *child_scope = create_comptime_scope(irb->codegen, node, parent_scope);
6720 return ir_gen_node_extra(irb, node->data.comptime_expr.expr, child_scope, lval);7344 // purposefully pass null for result_loc and let EndExpr handle it
7345 return ir_gen_node_extra(irb, node->data.comptime_expr.expr, child_scope, lval, nullptr);
6721}7346}
67227347
6723static IrInstruction *ir_gen_return_from_block(IrBuilder *irb, Scope *break_scope, AstNode *node, ScopeBlock *block_scope) {7348static IrInstruction *ir_gen_return_from_block(IrBuilder *irb, Scope *break_scope, AstNode *node, ScopeBlock *block_scope) {
...@@ -6730,7 +7355,11 @@ static IrInstruction *ir_gen_return_from_block(IrBuilder *irb, Scope *break_scop...@@ -6730,7 +7355,11 @@ static IrInstruction *ir_gen_return_from_block(IrBuilder *irb, Scope *break_scop
67307355
6731 IrInstruction *result_value;7356 IrInstruction *result_value;
6732 if (node->data.break_expr.expr) {7357 if (node->data.break_expr.expr) {
6733 result_value = ir_gen_node(irb, node->data.break_expr.expr, break_scope);7358 ResultLocPeer *peer_result = create_peer_result(block_scope->peer_parent);
7359 block_scope->peer_parent->peers.append(peer_result);
7360
7361 result_value = ir_gen_node_extra(irb, node->data.break_expr.expr, break_scope, block_scope->lval,
7362 &peer_result->base);
6734 if (result_value == irb->codegen->invalid_instruction)7363 if (result_value == irb->codegen->invalid_instruction)
6735 return irb->codegen->invalid_instruction;7364 return irb->codegen->invalid_instruction;
6736 } else {7365 } else {
...@@ -6800,7 +7429,11 @@ static IrInstruction *ir_gen_break(IrBuilder *irb, Scope *break_scope, AstNode *...@@ -6800,7 +7429,11 @@ static IrInstruction *ir_gen_break(IrBuilder *irb, Scope *break_scope, AstNode *
68007429
6801 IrInstruction *result_value;7430 IrInstruction *result_value;
6802 if (node->data.break_expr.expr) {7431 if (node->data.break_expr.expr) {
6803 result_value = ir_gen_node(irb, node->data.break_expr.expr, break_scope);7432 ResultLocPeer *peer_result = create_peer_result(loop_scope->peer_parent);
7433 loop_scope->peer_parent->peers.append(peer_result);
7434
7435 result_value = ir_gen_node_extra(irb, node->data.break_expr.expr, break_scope,
7436 loop_scope->lval, &peer_result->base);
6804 if (result_value == irb->codegen->invalid_instruction)7437 if (result_value == irb->codegen->invalid_instruction)
6805 return irb->codegen->invalid_instruction;7438 return irb->codegen->invalid_instruction;
6806 } else {7439 } else {
...@@ -6888,7 +7521,7 @@ static IrInstruction *ir_gen_defer(IrBuilder *irb, Scope *parent_scope, AstNode...@@ -6888,7 +7521,7 @@ static IrInstruction *ir_gen_defer(IrBuilder *irb, Scope *parent_scope, AstNode
6888 return ir_build_const_void(irb, parent_scope, node);7521 return ir_build_const_void(irb, parent_scope, node);
6889}7522}
68907523
6891static IrInstruction *ir_gen_slice(IrBuilder *irb, Scope *scope, AstNode *node) {7524static IrInstruction *ir_gen_slice(IrBuilder *irb, Scope *scope, AstNode *node, LVal lval, ResultLoc *result_loc) {
6892 assert(node->type == NodeTypeSliceExpr);7525 assert(node->type == NodeTypeSliceExpr);
68937526
6894 AstNodeSliceExpr *slice_expr = &node->data.slice_expr;7527 AstNodeSliceExpr *slice_expr = &node->data.slice_expr;
...@@ -6896,7 +7529,7 @@ static IrInstruction *ir_gen_slice(IrBuilder *irb, Scope *scope, AstNode *node)...@@ -6896,7 +7529,7 @@ static IrInstruction *ir_gen_slice(IrBuilder *irb, Scope *scope, AstNode *node)
6896 AstNode *start_node = slice_expr->start;7529 AstNode *start_node = slice_expr->start;
6897 AstNode *end_node = slice_expr->end;7530 AstNode *end_node = slice_expr->end;
68987531
6899 IrInstruction *ptr_value = ir_gen_node_extra(irb, array_node, scope, LValPtr);7532 IrInstruction *ptr_value = ir_gen_node_extra(irb, array_node, scope, LValPtr, nullptr);
6900 if (ptr_value == irb->codegen->invalid_instruction)7533 if (ptr_value == irb->codegen->invalid_instruction)
6901 return irb->codegen->invalid_instruction;7534 return irb->codegen->invalid_instruction;
69027535
...@@ -6913,11 +7546,14 @@ static IrInstruction *ir_gen_slice(IrBuilder *irb, Scope *scope, AstNode *node)...@@ -6913,11 +7546,14 @@ static IrInstruction *ir_gen_slice(IrBuilder *irb, Scope *scope, AstNode *node)
6913 end_value = nullptr;7546 end_value = nullptr;
6914 }7547 }
69157548
6916 return ir_build_slice(irb, scope, node, ptr_value, start_value, end_value, true);7549 IrInstruction *slice = ir_build_slice_src(irb, scope, node, ptr_value, start_value, end_value, true, result_loc);
7550 return ir_lval_wrap(irb, scope, slice, lval, result_loc);
6917}7551}
69187552
6919static IrInstruction *ir_gen_catch(IrBuilder *irb, Scope *parent_scope, AstNode *node) {7553static IrInstruction *ir_gen_catch(IrBuilder *irb, Scope *parent_scope, AstNode *node, LVal lval,
6920 assert(node->type == NodeTypeUnwrapErrorExpr);7554 ResultLoc *result_loc)
7555{
7556 assert(node->type == NodeTypeCatchExpr);
69217557
6922 AstNode *op1_node = node->data.unwrap_err_expr.op1;7558 AstNode *op1_node = node->data.unwrap_err_expr.op1;
6923 AstNode *op2_node = node->data.unwrap_err_expr.op2;7559 AstNode *op2_node = node->data.unwrap_err_expr.op2;
...@@ -6930,16 +7566,15 @@ static IrInstruction *ir_gen_catch(IrBuilder *irb, Scope *parent_scope, AstNode...@@ -6930,16 +7566,15 @@ static IrInstruction *ir_gen_catch(IrBuilder *irb, Scope *parent_scope, AstNode
6930 add_node_error(irb->codegen, var_node, buf_sprintf("unused variable: '%s'", buf_ptr(var_name)));7566 add_node_error(irb->codegen, var_node, buf_sprintf("unused variable: '%s'", buf_ptr(var_name)));
6931 return irb->codegen->invalid_instruction;7567 return irb->codegen->invalid_instruction;
6932 }7568 }
6933 return ir_gen_catch_unreachable(irb, parent_scope, node, op1_node, LValNone);7569 return ir_gen_catch_unreachable(irb, parent_scope, node, op1_node, lval, result_loc);
6934 }7570 }
69357571
69367572
6937 IrInstruction *err_union_ptr = ir_gen_node_extra(irb, op1_node, parent_scope, LValPtr);7573 IrInstruction *err_union_ptr = ir_gen_node_extra(irb, op1_node, parent_scope, LValPtr, nullptr);
6938 if (err_union_ptr == irb->codegen->invalid_instruction)7574 if (err_union_ptr == irb->codegen->invalid_instruction)
6939 return irb->codegen->invalid_instruction;7575 return irb->codegen->invalid_instruction;
69407576
6941 IrInstruction *err_union_val = ir_build_load_ptr(irb, parent_scope, node, err_union_ptr);7577 IrInstruction *is_err = ir_build_test_err_src(irb, parent_scope, node, err_union_ptr, true);
6942 IrInstruction *is_err = ir_build_test_err(irb, parent_scope, node, err_union_val);
69437578
6944 IrInstruction *is_comptime;7579 IrInstruction *is_comptime;
6945 if (ir_should_inline(irb->exec, parent_scope)) {7580 if (ir_should_inline(irb->exec, parent_scope)) {
...@@ -6951,7 +7586,10 @@ static IrInstruction *ir_gen_catch(IrBuilder *irb, Scope *parent_scope, AstNode...@@ -6951,7 +7586,10 @@ static IrInstruction *ir_gen_catch(IrBuilder *irb, Scope *parent_scope, AstNode
6951 IrBasicBlock *ok_block = ir_create_basic_block(irb, parent_scope, "UnwrapErrOk");7586 IrBasicBlock *ok_block = ir_create_basic_block(irb, parent_scope, "UnwrapErrOk");
6952 IrBasicBlock *err_block = ir_create_basic_block(irb, parent_scope, "UnwrapErrError");7587 IrBasicBlock *err_block = ir_create_basic_block(irb, parent_scope, "UnwrapErrError");
6953 IrBasicBlock *end_block = ir_create_basic_block(irb, parent_scope, "UnwrapErrEnd");7588 IrBasicBlock *end_block = ir_create_basic_block(irb, parent_scope, "UnwrapErrEnd");
6954 ir_build_cond_br(irb, parent_scope, node, is_err, err_block, ok_block, is_comptime);7589 IrInstruction *cond_br_inst = ir_build_cond_br(irb, parent_scope, node, is_err, err_block, ok_block, is_comptime);
7590
7591 ResultLocPeerParent *peer_parent = ir_build_binary_result_peers(irb, cond_br_inst, ok_block, end_block, result_loc,
7592 is_comptime);
69557593
6956 ir_set_cursor_at_end_and_append_block(irb, err_block);7594 ir_set_cursor_at_end_and_append_block(irb, err_block);
6957 Scope *err_scope;7595 Scope *err_scope;
...@@ -6963,12 +7601,12 @@ static IrInstruction *ir_gen_catch(IrBuilder *irb, Scope *parent_scope, AstNode...@@ -6963,12 +7601,12 @@ static IrInstruction *ir_gen_catch(IrBuilder *irb, Scope *parent_scope, AstNode
6963 ZigVar *var = ir_create_var(irb, node, parent_scope, var_name,7601 ZigVar *var = ir_create_var(irb, node, parent_scope, var_name,
6964 is_const, is_const, is_shadowable, is_comptime);7602 is_const, is_const, is_shadowable, is_comptime);
6965 err_scope = var->child_scope;7603 err_scope = var->child_scope;
6966 IrInstruction *err_val = ir_build_unwrap_err_code(irb, err_scope, node, err_union_ptr);7604 IrInstruction *err_ptr = ir_build_unwrap_err_code(irb, err_scope, node, err_union_ptr);
6967 ir_build_var_decl_src(irb, err_scope, var_node, var, nullptr, nullptr, err_val);7605 ir_build_var_decl_src(irb, err_scope, var_node, var, nullptr, err_ptr);
6968 } else {7606 } else {
6969 err_scope = parent_scope;7607 err_scope = parent_scope;
6970 }7608 }
6971 IrInstruction *err_result = ir_gen_node(irb, op2_node, err_scope);7609 IrInstruction *err_result = ir_gen_node_extra(irb, op2_node, err_scope, LValNone, &peer_parent->peers.at(0)->base);
6972 if (err_result == irb->codegen->invalid_instruction)7610 if (err_result == irb->codegen->invalid_instruction)
6973 return irb->codegen->invalid_instruction;7611 return irb->codegen->invalid_instruction;
6974 IrBasicBlock *after_err_block = irb->current_basic_block;7612 IrBasicBlock *after_err_block = irb->current_basic_block;
...@@ -6976,8 +7614,9 @@ static IrInstruction *ir_gen_catch(IrBuilder *irb, Scope *parent_scope, AstNode...@@ -6976,8 +7614,9 @@ static IrInstruction *ir_gen_catch(IrBuilder *irb, Scope *parent_scope, AstNode
6976 ir_mark_gen(ir_build_br(irb, err_scope, node, end_block, is_comptime));7614 ir_mark_gen(ir_build_br(irb, err_scope, node, end_block, is_comptime));
69777615
6978 ir_set_cursor_at_end_and_append_block(irb, ok_block);7616 ir_set_cursor_at_end_and_append_block(irb, ok_block);
6979 IrInstruction *unwrapped_ptr = ir_build_unwrap_err_payload(irb, parent_scope, node, err_union_ptr, false);7617 IrInstruction *unwrapped_ptr = ir_build_unwrap_err_payload(irb, parent_scope, node, err_union_ptr, false, false);
6980 IrInstruction *unwrapped_payload = ir_build_load_ptr(irb, parent_scope, node, unwrapped_ptr);7618 IrInstruction *unwrapped_payload = ir_build_load_ptr(irb, parent_scope, node, unwrapped_ptr);
7619 ir_build_end_expr(irb, parent_scope, node, unwrapped_payload, &peer_parent->peers.at(1)->base);
6981 IrBasicBlock *after_ok_block = irb->current_basic_block;7620 IrBasicBlock *after_ok_block = irb->current_basic_block;
6982 ir_build_br(irb, parent_scope, node, end_block, is_comptime);7621 ir_build_br(irb, parent_scope, node, end_block, is_comptime);
69837622
...@@ -6988,7 +7627,8 @@ static IrInstruction *ir_gen_catch(IrBuilder *irb, Scope *parent_scope, AstNode...@@ -6988,7 +7627,8 @@ static IrInstruction *ir_gen_catch(IrBuilder *irb, Scope *parent_scope, AstNode
6988 IrBasicBlock **incoming_blocks = allocate<IrBasicBlock *>(2);7627 IrBasicBlock **incoming_blocks = allocate<IrBasicBlock *>(2);
6989 incoming_blocks[0] = after_err_block;7628 incoming_blocks[0] = after_err_block;
6990 incoming_blocks[1] = after_ok_block;7629 incoming_blocks[1] = after_ok_block;
6991 return ir_build_phi(irb, parent_scope, node, 2, incoming_blocks, incoming_values);7630 IrInstruction *phi = ir_build_phi(irb, parent_scope, node, 2, incoming_blocks, incoming_values, peer_parent);
7631 return ir_lval_wrap(irb, parent_scope, phi, lval, result_loc);
6992}7632}
69937633
6994static bool render_instance_name_recursive(CodeGen *codegen, Buf *name, Scope *outer_scope, Scope *inner_scope) {7634static bool render_instance_name_recursive(CodeGen *codegen, Buf *name, Scope *outer_scope, Scope *inner_scope) {
...@@ -7264,7 +7904,7 @@ static IrInstruction *ir_gen_cancel_target(IrBuilder *irb, Scope *scope, AstNode...@@ -7264,7 +7904,7 @@ static IrInstruction *ir_gen_cancel_target(IrBuilder *irb, Scope *scope, AstNode
7264 IrInstruction *coro_promise_ptr = ir_build_coro_promise(irb, scope, node, casted_target_inst);7904 IrInstruction *coro_promise_ptr = ir_build_coro_promise(irb, scope, node, casted_target_inst);
7265 Buf *atomic_state_field_name = buf_create_from_str(ATOMIC_STATE_FIELD_NAME);7905 Buf *atomic_state_field_name = buf_create_from_str(ATOMIC_STATE_FIELD_NAME);
7266 IrInstruction *atomic_state_ptr = ir_build_field_ptr(irb, scope, node, coro_promise_ptr,7906 IrInstruction *atomic_state_ptr = ir_build_field_ptr(irb, scope, node, coro_promise_ptr,
7267 atomic_state_field_name);7907 atomic_state_field_name, false);
72687908
7269 // set the is_canceled bit7909 // set the is_canceled bit
7270 IrInstruction *prev_atomic_value = ir_build_atomic_rmw(irb, scope, node,7910 IrInstruction *prev_atomic_value = ir_build_atomic_rmw(irb, scope, node,
...@@ -7343,7 +7983,7 @@ static IrInstruction *ir_gen_resume_target(IrBuilder *irb, Scope *scope, AstNode...@@ -7343,7 +7983,7 @@ static IrInstruction *ir_gen_resume_target(IrBuilder *irb, Scope *scope, AstNode
7343 IrInstruction *coro_promise_ptr = ir_build_coro_promise(irb, scope, node, casted_target_inst);7983 IrInstruction *coro_promise_ptr = ir_build_coro_promise(irb, scope, node, casted_target_inst);
7344 Buf *atomic_state_field_name = buf_create_from_str(ATOMIC_STATE_FIELD_NAME);7984 Buf *atomic_state_field_name = buf_create_from_str(ATOMIC_STATE_FIELD_NAME);
7345 IrInstruction *atomic_state_ptr = ir_build_field_ptr(irb, scope, node, coro_promise_ptr,7985 IrInstruction *atomic_state_ptr = ir_build_field_ptr(irb, scope, node, coro_promise_ptr,
7346 atomic_state_field_name);7986 atomic_state_field_name, false);
73477987
7348 // clear the is_suspended bit7988 // clear the is_suspended bit
7349 IrInstruction *prev_atomic_value = ir_build_atomic_rmw(irb, scope, node,7989 IrInstruction *prev_atomic_value = ir_build_atomic_rmw(irb, scope, node,
...@@ -7410,12 +8050,12 @@ static IrInstruction *ir_gen_await_expr(IrBuilder *irb, Scope *scope, AstNode *n...@@ -7410,12 +8050,12 @@ static IrInstruction *ir_gen_await_expr(IrBuilder *irb, Scope *scope, AstNode *n
74108050
7411 IrInstruction *coro_promise_ptr = ir_build_coro_promise(irb, scope, node, target_inst);8051 IrInstruction *coro_promise_ptr = ir_build_coro_promise(irb, scope, node, target_inst);
7412 Buf *result_ptr_field_name = buf_create_from_str(RESULT_PTR_FIELD_NAME);8052 Buf *result_ptr_field_name = buf_create_from_str(RESULT_PTR_FIELD_NAME);
7413 IrInstruction *result_ptr_field_ptr = ir_build_field_ptr(irb, scope, node, coro_promise_ptr, result_ptr_field_name);8053 IrInstruction *result_ptr_field_ptr = ir_build_field_ptr(irb, scope, node, coro_promise_ptr, result_ptr_field_name, false);
74148054
7415 if (irb->codegen->have_err_ret_tracing) {8055 if (irb->codegen->have_err_ret_tracing) {
7416 IrInstruction *err_ret_trace_ptr = ir_build_error_return_trace(irb, scope, node, IrInstructionErrorReturnTrace::NonNull);8056 IrInstruction *err_ret_trace_ptr = ir_build_error_return_trace(irb, scope, node, IrInstructionErrorReturnTrace::NonNull);
7417 Buf *err_ret_trace_ptr_field_name = buf_create_from_str(ERR_RET_TRACE_PTR_FIELD_NAME);8057 Buf *err_ret_trace_ptr_field_name = buf_create_from_str(ERR_RET_TRACE_PTR_FIELD_NAME);
7418 IrInstruction *err_ret_trace_ptr_field_ptr = ir_build_field_ptr(irb, scope, node, coro_promise_ptr, err_ret_trace_ptr_field_name);8058 IrInstruction *err_ret_trace_ptr_field_ptr = ir_build_field_ptr(irb, scope, node, coro_promise_ptr, err_ret_trace_ptr_field_name, false);
7419 ir_build_store_ptr(irb, scope, node, err_ret_trace_ptr_field_ptr, err_ret_trace_ptr);8059 ir_build_store_ptr(irb, scope, node, err_ret_trace_ptr_field_ptr, err_ret_trace_ptr);
7420 }8060 }
74218061
...@@ -7437,11 +8077,11 @@ static IrInstruction *ir_gen_await_expr(IrBuilder *irb, Scope *scope, AstNode *n...@@ -7437,11 +8077,11 @@ static IrInstruction *ir_gen_await_expr(IrBuilder *irb, Scope *scope, AstNode *n
74378077
7438 Buf *atomic_state_field_name = buf_create_from_str(ATOMIC_STATE_FIELD_NAME);8078 Buf *atomic_state_field_name = buf_create_from_str(ATOMIC_STATE_FIELD_NAME);
7439 IrInstruction *atomic_state_ptr = ir_build_field_ptr(irb, scope, node, coro_promise_ptr,8079 IrInstruction *atomic_state_ptr = ir_build_field_ptr(irb, scope, node, coro_promise_ptr,
7440 atomic_state_field_name);8080 atomic_state_field_name, false);
74418081
7442 IrInstruction *promise_type_val = ir_build_const_type(irb, scope, node, irb->codegen->builtin_types.entry_promise);8082 IrInstruction *promise_type_val = ir_build_const_type(irb, scope, node, irb->codegen->builtin_types.entry_promise);
7443 IrInstruction *const_bool_false = ir_build_const_bool(irb, scope, node, false);8083 IrInstruction *const_bool_false = ir_build_const_bool(irb, scope, node, false);
7444 IrInstruction *undefined_value = ir_build_const_undefined(irb, scope, node);8084 IrInstruction *undef = ir_build_const_undefined(irb, scope, node);
7445 IrInstruction *usize_type_val = ir_build_const_type(irb, scope, node, irb->codegen->builtin_types.entry_usize);8085 IrInstruction *usize_type_val = ir_build_const_type(irb, scope, node, irb->codegen->builtin_types.entry_usize);
7446 IrInstruction *zero = ir_build_const_usize(irb, scope, node, 0);8086 IrInstruction *zero = ir_build_const_usize(irb, scope, node, 0);
7447 IrInstruction *inverted_ptr_mask = ir_build_const_usize(irb, scope, node, 0x7); // 0b1118087 IrInstruction *inverted_ptr_mask = ir_build_const_usize(irb, scope, node, 0x7); // 0b111
...@@ -7455,7 +8095,8 @@ static IrInstruction *ir_gen_await_expr(IrBuilder *irb, Scope *scope, AstNode *n...@@ -7455,7 +8095,8 @@ static IrInstruction *ir_gen_await_expr(IrBuilder *irb, Scope *scope, AstNode *n
7455 IrInstruction *target_promise_type = ir_build_typeof(irb, scope, node, target_inst);8095 IrInstruction *target_promise_type = ir_build_typeof(irb, scope, node, target_inst);
7456 IrInstruction *promise_result_type = ir_build_promise_result_type(irb, scope, node, target_promise_type);8096 IrInstruction *promise_result_type = ir_build_promise_result_type(irb, scope, node, target_promise_type);
7457 ir_build_await_bookkeeping(irb, scope, node, promise_result_type);8097 ir_build_await_bookkeeping(irb, scope, node, promise_result_type);
7458 ir_build_var_decl_src(irb, scope, node, result_var, promise_result_type, nullptr, undefined_value);8098 IrInstruction *undef_promise_result = ir_build_implicit_cast(irb, scope, node, promise_result_type, undef, nullptr);
8099 build_decl_var_and_init(irb, scope, node, result_var, undef_promise_result, "result", const_bool_false);
7459 IrInstruction *my_result_var_ptr = ir_build_var_ptr(irb, scope, node, result_var);8100 IrInstruction *my_result_var_ptr = ir_build_var_ptr(irb, scope, node, result_var);
7460 ir_build_store_ptr(irb, scope, node, result_ptr_field_ptr, my_result_var_ptr);8101 ir_build_store_ptr(irb, scope, node, result_ptr_field_ptr, my_result_var_ptr);
7461 IrInstruction *save_token = ir_build_coro_save(irb, scope, node, irb->exec->coro_handle);8102 IrInstruction *save_token = ir_build_coro_save(irb, scope, node, irb->exec->coro_handle);
...@@ -7490,12 +8131,12 @@ static IrInstruction *ir_gen_await_expr(IrBuilder *irb, Scope *scope, AstNode *n...@@ -7490,12 +8131,12 @@ static IrInstruction *ir_gen_await_expr(IrBuilder *irb, Scope *scope, AstNode *n
7490 ir_set_cursor_at_end_and_append_block(irb, no_suspend_block);8131 ir_set_cursor_at_end_and_append_block(irb, no_suspend_block);
7491 if (irb->codegen->have_err_ret_tracing) {8132 if (irb->codegen->have_err_ret_tracing) {
7492 Buf *err_ret_trace_field_name = buf_create_from_str(ERR_RET_TRACE_FIELD_NAME);8133 Buf *err_ret_trace_field_name = buf_create_from_str(ERR_RET_TRACE_FIELD_NAME);
7493 IrInstruction *src_err_ret_trace_ptr = ir_build_field_ptr(irb, scope, node, coro_promise_ptr, err_ret_trace_field_name);8134 IrInstruction *src_err_ret_trace_ptr = ir_build_field_ptr(irb, scope, node, coro_promise_ptr, err_ret_trace_field_name, false);
7494 IrInstruction *dest_err_ret_trace_ptr = ir_build_error_return_trace(irb, scope, node, IrInstructionErrorReturnTrace::NonNull);8135 IrInstruction *dest_err_ret_trace_ptr = ir_build_error_return_trace(irb, scope, node, IrInstructionErrorReturnTrace::NonNull);
7495 ir_build_merge_err_ret_traces(irb, scope, node, coro_promise_ptr, src_err_ret_trace_ptr, dest_err_ret_trace_ptr);8136 ir_build_merge_err_ret_traces(irb, scope, node, coro_promise_ptr, src_err_ret_trace_ptr, dest_err_ret_trace_ptr);
7496 }8137 }
7497 Buf *result_field_name = buf_create_from_str(RESULT_FIELD_NAME);8138 Buf *result_field_name = buf_create_from_str(RESULT_FIELD_NAME);
7498 IrInstruction *promise_result_ptr = ir_build_field_ptr(irb, scope, node, coro_promise_ptr, result_field_name);8139 IrInstruction *promise_result_ptr = ir_build_field_ptr(irb, scope, node, coro_promise_ptr, result_field_name, false);
7499 // If the type of the result handle_is_ptr then this does not actually perform a load. But we need it to,8140 // If the type of the result handle_is_ptr then this does not actually perform a load. But we need it to,
7500 // because we're about to destroy the memory. So we store it into our result variable.8141 // because we're about to destroy the memory. So we store it into our result variable.
7501 IrInstruction *no_suspend_result = ir_build_load_ptr(irb, scope, node, promise_result_ptr);8142 IrInstruction *no_suspend_result = ir_build_load_ptr(irb, scope, node, promise_result_ptr);
...@@ -7671,7 +8312,8 @@ static IrInstruction *ir_gen_suspend(IrBuilder *irb, Scope *parent_scope, AstNod...@@ -7671,7 +8312,8 @@ static IrInstruction *ir_gen_suspend(IrBuilder *irb, Scope *parent_scope, AstNod
7671 incoming_values[0] = const_bool_true;8312 incoming_values[0] = const_bool_true;
7672 incoming_blocks[1] = post_cancel_awaiter_block;8313 incoming_blocks[1] = post_cancel_awaiter_block;
7673 incoming_values[1] = const_bool_false;8314 incoming_values[1] = const_bool_false;
7674 IrInstruction *destroy_ourselves = ir_build_phi(irb, parent_scope, node, 2, incoming_blocks, incoming_values);8315 IrInstruction *destroy_ourselves = ir_build_phi(irb, parent_scope, node, 2, incoming_blocks, incoming_values,
8316 nullptr);
7675 ir_gen_defers_for_block(irb, parent_scope, outer_scope, true);8317 ir_gen_defers_for_block(irb, parent_scope, outer_scope, true);
7676 ir_mark_gen(ir_build_cond_br(irb, parent_scope, node, destroy_ourselves, irb->exec->coro_final_cleanup_block, irb->exec->coro_early_final, const_bool_false));8318 ir_mark_gen(ir_build_cond_br(irb, parent_scope, node, destroy_ourselves, irb->exec->coro_final_cleanup_block, irb->exec->coro_early_final, const_bool_false));
76778319
...@@ -7680,7 +8322,7 @@ static IrInstruction *ir_gen_suspend(IrBuilder *irb, Scope *parent_scope, AstNod...@@ -7680,7 +8322,7 @@ static IrInstruction *ir_gen_suspend(IrBuilder *irb, Scope *parent_scope, AstNod
7680}8322}
76818323
7682static IrInstruction *ir_gen_node_raw(IrBuilder *irb, AstNode *node, Scope *scope,8324static IrInstruction *ir_gen_node_raw(IrBuilder *irb, AstNode *node, Scope *scope,
7683 LVal lval)8325 LVal lval, ResultLoc *result_loc)
7684{8326{
7685 assert(scope);8327 assert(scope);
7686 switch (node->type) {8328 switch (node->type) {
...@@ -7694,37 +8336,37 @@ static IrInstruction *ir_gen_node_raw(IrBuilder *irb, AstNode *node, Scope *scop...@@ -7694,37 +8336,37 @@ static IrInstruction *ir_gen_node_raw(IrBuilder *irb, AstNode *node, Scope *scop
7694 case NodeTypeTestDecl:8336 case NodeTypeTestDecl:
7695 zig_unreachable();8337 zig_unreachable();
7696 case NodeTypeBlock:8338 case NodeTypeBlock:
7697 return ir_lval_wrap(irb, scope, ir_gen_block(irb, scope, node), lval);8339 return ir_gen_block(irb, scope, node, lval, result_loc);
7698 case NodeTypeGroupedExpr:8340 case NodeTypeGroupedExpr:
7699 return ir_gen_node_raw(irb, node->data.grouped_expr, scope, lval);8341 return ir_gen_node_raw(irb, node->data.grouped_expr, scope, lval, result_loc);
7700 case NodeTypeBinOpExpr:8342 case NodeTypeBinOpExpr:
7701 return ir_lval_wrap(irb, scope, ir_gen_bin_op(irb, scope, node), lval);8343 return ir_gen_bin_op(irb, scope, node, lval, result_loc);
7702 case NodeTypeIntLiteral:8344 case NodeTypeIntLiteral:
7703 return ir_lval_wrap(irb, scope, ir_gen_int_lit(irb, scope, node), lval);8345 return ir_lval_wrap(irb, scope, ir_gen_int_lit(irb, scope, node), lval, result_loc);
7704 case NodeTypeFloatLiteral:8346 case NodeTypeFloatLiteral:
7705 return ir_lval_wrap(irb, scope, ir_gen_float_lit(irb, scope, node), lval);8347 return ir_lval_wrap(irb, scope, ir_gen_float_lit(irb, scope, node), lval, result_loc);
7706 case NodeTypeCharLiteral:8348 case NodeTypeCharLiteral:
7707 return ir_lval_wrap(irb, scope, ir_gen_char_lit(irb, scope, node), lval);8349 return ir_lval_wrap(irb, scope, ir_gen_char_lit(irb, scope, node), lval, result_loc);
7708 case NodeTypeSymbol:8350 case NodeTypeSymbol:
7709 return ir_gen_symbol(irb, scope, node, lval);8351 return ir_gen_symbol(irb, scope, node, lval, result_loc);
7710 case NodeTypeFnCallExpr:8352 case NodeTypeFnCallExpr:
7711 return ir_gen_fn_call(irb, scope, node, lval);8353 return ir_gen_fn_call(irb, scope, node, lval, result_loc);
7712 case NodeTypeIfBoolExpr:8354 case NodeTypeIfBoolExpr:
7713 return ir_lval_wrap(irb, scope, ir_gen_if_bool_expr(irb, scope, node), lval);8355 return ir_gen_if_bool_expr(irb, scope, node, lval, result_loc);
7714 case NodeTypePrefixOpExpr:8356 case NodeTypePrefixOpExpr:
7715 return ir_gen_prefix_op_expr(irb, scope, node, lval);8357 return ir_gen_prefix_op_expr(irb, scope, node, lval, result_loc);
7716 case NodeTypeContainerInitExpr:8358 case NodeTypeContainerInitExpr:
7717 return ir_lval_wrap(irb, scope, ir_gen_container_init_expr(irb, scope, node), lval);8359 return ir_gen_container_init_expr(irb, scope, node, lval, result_loc);
7718 case NodeTypeVariableDeclaration:8360 case NodeTypeVariableDeclaration:
7719 return ir_lval_wrap(irb, scope, ir_gen_var_decl(irb, scope, node), lval);8361 return ir_gen_var_decl(irb, scope, node);
7720 case NodeTypeWhileExpr:8362 case NodeTypeWhileExpr:
7721 return ir_lval_wrap(irb, scope, ir_gen_while_expr(irb, scope, node), lval);8363 return ir_gen_while_expr(irb, scope, node, lval, result_loc);
7722 case NodeTypeForExpr:8364 case NodeTypeForExpr:
7723 return ir_lval_wrap(irb, scope, ir_gen_for_expr(irb, scope, node), lval);8365 return ir_gen_for_expr(irb, scope, node, lval, result_loc);
7724 case NodeTypeArrayAccessExpr:8366 case NodeTypeArrayAccessExpr:
7725 return ir_gen_array_access(irb, scope, node, lval);8367 return ir_gen_array_access(irb, scope, node, lval, result_loc);
7726 case NodeTypeReturnExpr:8368 case NodeTypeReturnExpr:
7727 return ir_gen_return(irb, scope, node, lval);8369 return ir_gen_return(irb, scope, node, lval, result_loc);
7728 case NodeTypeFieldAccessExpr:8370 case NodeTypeFieldAccessExpr:
7729 {8371 {
7730 IrInstruction *ptr_instruction = ir_gen_field_access(irb, scope, node);8372 IrInstruction *ptr_instruction = ir_gen_field_access(irb, scope, node);
...@@ -7733,86 +8375,89 @@ static IrInstruction *ir_gen_node_raw(IrBuilder *irb, AstNode *node, Scope *scop...@@ -7733,86 +8375,89 @@ static IrInstruction *ir_gen_node_raw(IrBuilder *irb, AstNode *node, Scope *scop
7733 if (lval == LValPtr)8375 if (lval == LValPtr)
7734 return ptr_instruction;8376 return ptr_instruction;
77358377
7736 return ir_build_load_ptr(irb, scope, node, ptr_instruction);8378 IrInstruction *load_ptr = ir_build_load_ptr(irb, scope, node, ptr_instruction);
8379 return ir_expr_wrap(irb, scope, load_ptr, result_loc);
7737 }8380 }
7738 case NodeTypePtrDeref: {8381 case NodeTypePtrDeref: {
7739 AstNode *expr_node = node->data.ptr_deref_expr.target;8382 AstNode *expr_node = node->data.ptr_deref_expr.target;
7740 IrInstruction *value = ir_gen_node_extra(irb, expr_node, scope, lval);8383 IrInstruction *value = ir_gen_node_extra(irb, expr_node, scope, lval, nullptr);
7741 if (value == irb->codegen->invalid_instruction)8384 if (value == irb->codegen->invalid_instruction)
7742 return value;8385 return value;
77438386
7744 // We essentially just converted any lvalue from &(x.*) to (&x).*;8387 // We essentially just converted any lvalue from &(x.*) to (&x).*;
7745 // this inhibits checking that x is a pointer later, so we directly8388 // this inhibits checking that x is a pointer later, so we directly
7746 // record whether the pointer check is needed8389 // record whether the pointer check is needed
7747 return ir_build_un_op_lval(irb, scope, node, IrUnOpDereference, value, lval);8390 IrInstruction *un_op = ir_build_un_op_lval(irb, scope, node, IrUnOpDereference, value, lval, result_loc);
8391 return ir_expr_wrap(irb, scope, un_op, result_loc);
7748 }8392 }
7749 case NodeTypeUnwrapOptional: {8393 case NodeTypeUnwrapOptional: {
7750 AstNode *expr_node = node->data.unwrap_optional.expr;8394 AstNode *expr_node = node->data.unwrap_optional.expr;
77518395
7752 IrInstruction *maybe_ptr = ir_gen_node_extra(irb, expr_node, scope, LValPtr);8396 IrInstruction *maybe_ptr = ir_gen_node_extra(irb, expr_node, scope, LValPtr, nullptr);
7753 if (maybe_ptr == irb->codegen->invalid_instruction)8397 if (maybe_ptr == irb->codegen->invalid_instruction)
7754 return irb->codegen->invalid_instruction;8398 return irb->codegen->invalid_instruction;
77558399
7756 IrInstruction *unwrapped_ptr = ir_build_optional_unwrap_ptr(irb, scope, node, maybe_ptr, true);8400 IrInstruction *unwrapped_ptr = ir_build_optional_unwrap_ptr(irb, scope, node, maybe_ptr, true, false);
7757 if (lval == LValPtr)8401 if (lval == LValPtr)
7758 return unwrapped_ptr;8402 return unwrapped_ptr;
77598403
7760 return ir_build_load_ptr(irb, scope, node, unwrapped_ptr);8404 IrInstruction *load_ptr = ir_build_load_ptr(irb, scope, node, unwrapped_ptr);
8405 return ir_expr_wrap(irb, scope, load_ptr, result_loc);
7761 }8406 }
7762 case NodeTypeBoolLiteral:8407 case NodeTypeBoolLiteral:
7763 return ir_lval_wrap(irb, scope, ir_gen_bool_literal(irb, scope, node), lval);8408 return ir_lval_wrap(irb, scope, ir_gen_bool_literal(irb, scope, node), lval, result_loc);
7764 case NodeTypeArrayType:8409 case NodeTypeArrayType:
7765 return ir_lval_wrap(irb, scope, ir_gen_array_type(irb, scope, node), lval);8410 return ir_lval_wrap(irb, scope, ir_gen_array_type(irb, scope, node), lval, result_loc);
7766 case NodeTypePointerType:8411 case NodeTypePointerType:
7767 return ir_lval_wrap(irb, scope, ir_gen_pointer_type(irb, scope, node), lval);8412 return ir_lval_wrap(irb, scope, ir_gen_pointer_type(irb, scope, node), lval, result_loc);
7768 case NodeTypePromiseType:8413 case NodeTypePromiseType:
7769 return ir_lval_wrap(irb, scope, ir_gen_promise_type(irb, scope, node), lval);8414 return ir_lval_wrap(irb, scope, ir_gen_promise_type(irb, scope, node), lval, result_loc);
7770 case NodeTypeStringLiteral:8415 case NodeTypeStringLiteral:
7771 return ir_lval_wrap(irb, scope, ir_gen_string_literal(irb, scope, node), lval);8416 return ir_lval_wrap(irb, scope, ir_gen_string_literal(irb, scope, node), lval, result_loc);
7772 case NodeTypeUndefinedLiteral:8417 case NodeTypeUndefinedLiteral:
7773 return ir_lval_wrap(irb, scope, ir_gen_undefined_literal(irb, scope, node), lval);8418 return ir_lval_wrap(irb, scope, ir_gen_undefined_literal(irb, scope, node), lval, result_loc);
7774 case NodeTypeAsmExpr:8419 case NodeTypeAsmExpr:
7775 return ir_lval_wrap(irb, scope, ir_gen_asm_expr(irb, scope, node), lval);8420 return ir_lval_wrap(irb, scope, ir_gen_asm_expr(irb, scope, node), lval, result_loc);
7776 case NodeTypeNullLiteral:8421 case NodeTypeNullLiteral:
7777 return ir_lval_wrap(irb, scope, ir_gen_null_literal(irb, scope, node), lval);8422 return ir_lval_wrap(irb, scope, ir_gen_null_literal(irb, scope, node), lval, result_loc);
7778 case NodeTypeIfErrorExpr:8423 case NodeTypeIfErrorExpr:
7779 return ir_lval_wrap(irb, scope, ir_gen_if_err_expr(irb, scope, node), lval);8424 return ir_gen_if_err_expr(irb, scope, node, lval, result_loc);
7780 case NodeTypeIfOptional:8425 case NodeTypeIfOptional:
7781 return ir_lval_wrap(irb, scope, ir_gen_if_optional_expr(irb, scope, node), lval);8426 return ir_gen_if_optional_expr(irb, scope, node, lval, result_loc);
7782 case NodeTypeSwitchExpr:8427 case NodeTypeSwitchExpr:
7783 return ir_lval_wrap(irb, scope, ir_gen_switch_expr(irb, scope, node), lval);8428 return ir_gen_switch_expr(irb, scope, node, lval, result_loc);
7784 case NodeTypeCompTime:8429 case NodeTypeCompTime:
7785 return ir_gen_comptime(irb, scope, node, lval);8430 return ir_expr_wrap(irb, scope, ir_gen_comptime(irb, scope, node, lval), result_loc);
7786 case NodeTypeErrorType:8431 case NodeTypeErrorType:
7787 return ir_lval_wrap(irb, scope, ir_gen_error_type(irb, scope, node), lval);8432 return ir_lval_wrap(irb, scope, ir_gen_error_type(irb, scope, node), lval, result_loc);
7788 case NodeTypeBreak:8433 case NodeTypeBreak:
7789 return ir_lval_wrap(irb, scope, ir_gen_break(irb, scope, node), lval);8434 return ir_lval_wrap(irb, scope, ir_gen_break(irb, scope, node), lval, result_loc);
7790 case NodeTypeContinue:8435 case NodeTypeContinue:
7791 return ir_lval_wrap(irb, scope, ir_gen_continue(irb, scope, node), lval);8436 return ir_lval_wrap(irb, scope, ir_gen_continue(irb, scope, node), lval, result_loc);
7792 case NodeTypeUnreachable:8437 case NodeTypeUnreachable:
7793 return ir_lval_wrap(irb, scope, ir_build_unreachable(irb, scope, node), lval);8438 return ir_build_unreachable(irb, scope, node);
7794 case NodeTypeDefer:8439 case NodeTypeDefer:
7795 return ir_lval_wrap(irb, scope, ir_gen_defer(irb, scope, node), lval);8440 return ir_lval_wrap(irb, scope, ir_gen_defer(irb, scope, node), lval, result_loc);
7796 case NodeTypeSliceExpr:8441 case NodeTypeSliceExpr:
7797 return ir_lval_wrap(irb, scope, ir_gen_slice(irb, scope, node), lval);8442 return ir_gen_slice(irb, scope, node, lval, result_loc);
7798 case NodeTypeUnwrapErrorExpr:8443 case NodeTypeCatchExpr:
7799 return ir_lval_wrap(irb, scope, ir_gen_catch(irb, scope, node), lval);8444 return ir_gen_catch(irb, scope, node, lval, result_loc);
7800 case NodeTypeContainerDecl:8445 case NodeTypeContainerDecl:
7801 return ir_lval_wrap(irb, scope, ir_gen_container_decl(irb, scope, node), lval);8446 return ir_lval_wrap(irb, scope, ir_gen_container_decl(irb, scope, node), lval, result_loc);
7802 case NodeTypeFnProto:8447 case NodeTypeFnProto:
7803 return ir_lval_wrap(irb, scope, ir_gen_fn_proto(irb, scope, node), lval);8448 return ir_lval_wrap(irb, scope, ir_gen_fn_proto(irb, scope, node), lval, result_loc);
7804 case NodeTypeErrorSetDecl:8449 case NodeTypeErrorSetDecl:
7805 return ir_lval_wrap(irb, scope, ir_gen_err_set_decl(irb, scope, node), lval);8450 return ir_lval_wrap(irb, scope, ir_gen_err_set_decl(irb, scope, node), lval, result_loc);
7806 case NodeTypeCancel:8451 case NodeTypeCancel:
7807 return ir_lval_wrap(irb, scope, ir_gen_cancel(irb, scope, node), lval);8452 return ir_lval_wrap(irb, scope, ir_gen_cancel(irb, scope, node), lval, result_loc);
7808 case NodeTypeResume:8453 case NodeTypeResume:
7809 return ir_lval_wrap(irb, scope, ir_gen_resume(irb, scope, node), lval);8454 return ir_lval_wrap(irb, scope, ir_gen_resume(irb, scope, node), lval, result_loc);
7810 case NodeTypeAwaitExpr:8455 case NodeTypeAwaitExpr:
7811 return ir_lval_wrap(irb, scope, ir_gen_await_expr(irb, scope, node), lval);8456 return ir_lval_wrap(irb, scope, ir_gen_await_expr(irb, scope, node), lval, result_loc);
7812 case NodeTypeSuspend:8457 case NodeTypeSuspend:
7813 return ir_lval_wrap(irb, scope, ir_gen_suspend(irb, scope, node), lval);8458 return ir_lval_wrap(irb, scope, ir_gen_suspend(irb, scope, node), lval, result_loc);
7814 case NodeTypeEnumLiteral:8459 case NodeTypeEnumLiteral:
7815 return ir_lval_wrap(irb, scope, ir_gen_enum_literal(irb, scope, node), lval);8460 return ir_lval_wrap(irb, scope, ir_gen_enum_literal(irb, scope, node), lval, result_loc);
7816 case NodeTypeInferredArrayType:8461 case NodeTypeInferredArrayType:
7817 add_node_error(irb->codegen, node,8462 add_node_error(irb->codegen, node,
7818 buf_sprintf("inferred array size invalid here"));8463 buf_sprintf("inferred array size invalid here"));
...@@ -7821,14 +8466,28 @@ static IrInstruction *ir_gen_node_raw(IrBuilder *irb, AstNode *node, Scope *scop...@@ -7821,14 +8466,28 @@ static IrInstruction *ir_gen_node_raw(IrBuilder *irb, AstNode *node, Scope *scop
7821 zig_unreachable();8466 zig_unreachable();
7822}8467}
78238468
7824static IrInstruction *ir_gen_node_extra(IrBuilder *irb, AstNode *node, Scope *scope, LVal lval) {8469static ResultLoc *no_result_loc(void) {
7825 IrInstruction *result = ir_gen_node_raw(irb, node, scope, lval);8470 ResultLocNone *result_loc_none = allocate<ResultLocNone>(1);
8471 result_loc_none->base.id = ResultLocIdNone;
8472 return &result_loc_none->base;
8473}
8474
8475static IrInstruction *ir_gen_node_extra(IrBuilder *irb, AstNode *node, Scope *scope, LVal lval,
8476 ResultLoc *result_loc)
8477{
8478 if (result_loc == nullptr) {
8479 // Create a result location indicating there is none - but if one gets created
8480 // it will be properly distributed.
8481 result_loc = no_result_loc();
8482 ir_build_reset_result(irb, scope, node, result_loc);
8483 }
8484 IrInstruction *result = ir_gen_node_raw(irb, node, scope, lval, result_loc);
7826 irb->exec->invalid = irb->exec->invalid || (result == irb->codegen->invalid_instruction);8485 irb->exec->invalid = irb->exec->invalid || (result == irb->codegen->invalid_instruction);
7827 return result;8486 return result;
7828}8487}
78298488
7830static IrInstruction *ir_gen_node(IrBuilder *irb, AstNode *node, Scope *scope) {8489static IrInstruction *ir_gen_node(IrBuilder *irb, AstNode *node, Scope *scope) {
7831 return ir_gen_node_extra(irb, node, scope, LValNone);8490 return ir_gen_node_extra(irb, node, scope, LValNone, nullptr);
7832}8491}
78338492
7834static void invalidate_exec(IrExecutable *exec) {8493static void invalidate_exec(IrExecutable *exec) {
...@@ -7879,17 +8538,19 @@ bool ir_gen(CodeGen *codegen, AstNode *node, Scope *scope, IrExecutable *ir_exec...@@ -7879,17 +8538,19 @@ bool ir_gen(CodeGen *codegen, AstNode *node, Scope *scope, IrExecutable *ir_exec
78798538
7880 return_type = fn_entry->type_entry->data.fn.fn_type_id.return_type;8539 return_type = fn_entry->type_entry->data.fn.fn_type_id.return_type;
7881 IrInstruction *undef = ir_build_const_undefined(irb, coro_scope, node);8540 IrInstruction *undef = ir_build_const_undefined(irb, coro_scope, node);
8541 // TODO mark this var decl as "no safety" e.g. disable initializing the undef value to 0xaa
7882 ZigType *coro_frame_type = get_promise_frame_type(irb->codegen, return_type);8542 ZigType *coro_frame_type = get_promise_frame_type(irb->codegen, return_type);
7883 IrInstruction *coro_frame_type_value = ir_build_const_type(irb, coro_scope, node, coro_frame_type);8543 IrInstruction *coro_frame_type_value = ir_build_const_type(irb, coro_scope, node, coro_frame_type);
7884 // TODO mark this var decl as "no safety" e.g. disable initializing the undef value to 0xaa8544 IrInstruction *undef_coro_frame = ir_build_implicit_cast(irb, coro_scope, node, coro_frame_type_value, undef, nullptr);
7885 ir_build_var_decl_src(irb, coro_scope, node, promise_var, coro_frame_type_value, nullptr, undef);8545 build_decl_var_and_init(irb, coro_scope, node, promise_var, undef_coro_frame, "promise", const_bool_false);
7886 coro_promise_ptr = ir_build_var_ptr(irb, coro_scope, node, promise_var);8546 coro_promise_ptr = ir_build_var_ptr(irb, coro_scope, node, promise_var);
78878547
7888 ZigVar *await_handle_var = ir_create_var(irb, node, coro_scope, nullptr, false, false, true, const_bool_false);8548 ZigVar *await_handle_var = ir_create_var(irb, node, coro_scope, nullptr, false, false, true, const_bool_false);
7889 IrInstruction *null_value = ir_build_const_null(irb, coro_scope, node);8549 IrInstruction *null_value = ir_build_const_null(irb, coro_scope, node);
7890 IrInstruction *await_handle_type_val = ir_build_const_type(irb, coro_scope, node,8550 IrInstruction *await_handle_type_val = ir_build_const_type(irb, coro_scope, node,
7891 get_optional_type(irb->codegen, irb->codegen->builtin_types.entry_promise));8551 get_optional_type(irb->codegen, irb->codegen->builtin_types.entry_promise));
7892 ir_build_var_decl_src(irb, coro_scope, node, await_handle_var, await_handle_type_val, nullptr, null_value);8552 IrInstruction *null_await_handle = ir_build_implicit_cast(irb, coro_scope, node, await_handle_type_val, null_value, nullptr);
8553 build_decl_var_and_init(irb, coro_scope, node, await_handle_var, null_await_handle, "await_handle", const_bool_false);
7893 irb->exec->await_handle_var_ptr = ir_build_var_ptr(irb, coro_scope, node, await_handle_var);8554 irb->exec->await_handle_var_ptr = ir_build_var_ptr(irb, coro_scope, node, await_handle_var);
78948555
7895 u8_ptr_type = ir_build_const_type(irb, coro_scope, node,8556 u8_ptr_type = ir_build_const_type(irb, coro_scope, node,
...@@ -7899,13 +8560,14 @@ bool ir_gen(CodeGen *codegen, AstNode *node, Scope *scope, IrExecutable *ir_exec...@@ -7899,13 +8560,14 @@ bool ir_gen(CodeGen *codegen, AstNode *node, Scope *scope, IrExecutable *ir_exec
7899 coro_id = ir_build_coro_id(irb, coro_scope, node, promise_as_u8_ptr);8560 coro_id = ir_build_coro_id(irb, coro_scope, node, promise_as_u8_ptr);
7900 coro_size_var = ir_create_var(irb, node, coro_scope, nullptr, false, false, true, const_bool_false);8561 coro_size_var = ir_create_var(irb, node, coro_scope, nullptr, false, false, true, const_bool_false);
7901 IrInstruction *coro_size = ir_build_coro_size(irb, coro_scope, node);8562 IrInstruction *coro_size = ir_build_coro_size(irb, coro_scope, node);
7902 ir_build_var_decl_src(irb, coro_scope, node, coro_size_var, nullptr, nullptr, coro_size);8563 build_decl_var_and_init(irb, coro_scope, node, coro_size_var, coro_size, "coro_size", const_bool_false);
7903 IrInstruction *implicit_allocator_ptr = ir_build_get_implicit_allocator(irb, coro_scope, node,8564 IrInstruction *implicit_allocator_ptr = ir_build_get_implicit_allocator(irb, coro_scope, node,
7904 ImplicitAllocatorIdArg);8565 ImplicitAllocatorIdArg);
7905 irb->exec->coro_allocator_var = ir_create_var(irb, node, coro_scope, nullptr, true, true, true, const_bool_false);8566 irb->exec->coro_allocator_var = ir_create_var(irb, node, coro_scope, nullptr, true, true, true, const_bool_false);
7906 ir_build_var_decl_src(irb, coro_scope, node, irb->exec->coro_allocator_var, nullptr, nullptr, implicit_allocator_ptr);8567 build_decl_var_and_init(irb, coro_scope, node, irb->exec->coro_allocator_var, implicit_allocator_ptr,
8568 "allocator", const_bool_false);
7907 Buf *realloc_field_name = buf_create_from_str(ASYNC_REALLOC_FIELD_NAME);8569 Buf *realloc_field_name = buf_create_from_str(ASYNC_REALLOC_FIELD_NAME);
7908 IrInstruction *realloc_fn_ptr = ir_build_field_ptr(irb, coro_scope, node, implicit_allocator_ptr, realloc_field_name);8570 IrInstruction *realloc_fn_ptr = ir_build_field_ptr(irb, coro_scope, node, implicit_allocator_ptr, realloc_field_name, false);
7909 IrInstruction *realloc_fn = ir_build_load_ptr(irb, coro_scope, node, realloc_fn_ptr);8571 IrInstruction *realloc_fn = ir_build_load_ptr(irb, coro_scope, node, realloc_fn_ptr);
7910 IrInstruction *maybe_coro_mem_ptr = ir_build_coro_alloc_helper(irb, coro_scope, node, realloc_fn, coro_size);8572 IrInstruction *maybe_coro_mem_ptr = ir_build_coro_alloc_helper(irb, coro_scope, node, realloc_fn, coro_size);
7911 IrInstruction *alloc_result_is_ok = ir_build_test_nonnull(irb, coro_scope, node, maybe_coro_mem_ptr);8573 IrInstruction *alloc_result_is_ok = ir_build_test_nonnull(irb, coro_scope, node, maybe_coro_mem_ptr);
...@@ -7925,32 +8587,32 @@ bool ir_gen(CodeGen *codegen, AstNode *node, Scope *scope, IrExecutable *ir_exec...@@ -7925,32 +8587,32 @@ bool ir_gen(CodeGen *codegen, AstNode *node, Scope *scope, IrExecutable *ir_exec
79258587
7926 Buf *atomic_state_field_name = buf_create_from_str(ATOMIC_STATE_FIELD_NAME);8588 Buf *atomic_state_field_name = buf_create_from_str(ATOMIC_STATE_FIELD_NAME);
7927 irb->exec->atomic_state_field_ptr = ir_build_field_ptr(irb, scope, node, coro_promise_ptr,8589 irb->exec->atomic_state_field_ptr = ir_build_field_ptr(irb, scope, node, coro_promise_ptr,
7928 atomic_state_field_name);8590 atomic_state_field_name, false);
7929 IrInstruction *zero = ir_build_const_usize(irb, scope, node, 0);8591 IrInstruction *zero = ir_build_const_usize(irb, scope, node, 0);
7930 ir_build_store_ptr(irb, scope, node, irb->exec->atomic_state_field_ptr, zero);8592 ir_build_store_ptr(irb, scope, node, irb->exec->atomic_state_field_ptr, zero);
7931 Buf *result_field_name = buf_create_from_str(RESULT_FIELD_NAME);8593 Buf *result_field_name = buf_create_from_str(RESULT_FIELD_NAME);
7932 irb->exec->coro_result_field_ptr = ir_build_field_ptr(irb, scope, node, coro_promise_ptr, result_field_name);8594 irb->exec->coro_result_field_ptr = ir_build_field_ptr(irb, scope, node, coro_promise_ptr, result_field_name, false);
7933 result_ptr_field_name = buf_create_from_str(RESULT_PTR_FIELD_NAME);8595 result_ptr_field_name = buf_create_from_str(RESULT_PTR_FIELD_NAME);
7934 irb->exec->coro_result_ptr_field_ptr = ir_build_field_ptr(irb, scope, node, coro_promise_ptr, result_ptr_field_name);8596 irb->exec->coro_result_ptr_field_ptr = ir_build_field_ptr(irb, scope, node, coro_promise_ptr, result_ptr_field_name, false);
7935 ir_build_store_ptr(irb, scope, node, irb->exec->coro_result_ptr_field_ptr, irb->exec->coro_result_field_ptr);8597 ir_build_store_ptr(irb, scope, node, irb->exec->coro_result_ptr_field_ptr, irb->exec->coro_result_field_ptr);
7936 if (irb->codegen->have_err_ret_tracing) {8598 if (irb->codegen->have_err_ret_tracing) {
7937 // initialize the error return trace8599 // initialize the error return trace
7938 Buf *return_addresses_field_name = buf_create_from_str(RETURN_ADDRESSES_FIELD_NAME);8600 Buf *return_addresses_field_name = buf_create_from_str(RETURN_ADDRESSES_FIELD_NAME);
7939 IrInstruction *return_addresses_ptr = ir_build_field_ptr(irb, scope, node, coro_promise_ptr, return_addresses_field_name);8601 IrInstruction *return_addresses_ptr = ir_build_field_ptr(irb, scope, node, coro_promise_ptr, return_addresses_field_name, false);
79408602
7941 Buf *err_ret_trace_field_name = buf_create_from_str(ERR_RET_TRACE_FIELD_NAME);8603 Buf *err_ret_trace_field_name = buf_create_from_str(ERR_RET_TRACE_FIELD_NAME);
7942 err_ret_trace_ptr = ir_build_field_ptr(irb, scope, node, coro_promise_ptr, err_ret_trace_field_name);8604 err_ret_trace_ptr = ir_build_field_ptr(irb, scope, node, coro_promise_ptr, err_ret_trace_field_name, false);
7943 ir_build_mark_err_ret_trace_ptr(irb, scope, node, err_ret_trace_ptr);8605 ir_build_mark_err_ret_trace_ptr(irb, scope, node, err_ret_trace_ptr);
79448606
7945 // coordinate with builtin.zig8607 // coordinate with builtin.zig
7946 Buf *index_name = buf_create_from_str("index");8608 Buf *index_name = buf_create_from_str("index");
7947 IrInstruction *index_ptr = ir_build_field_ptr(irb, scope, node, err_ret_trace_ptr, index_name);8609 IrInstruction *index_ptr = ir_build_field_ptr(irb, scope, node, err_ret_trace_ptr, index_name, false);
7948 ir_build_store_ptr(irb, scope, node, index_ptr, zero);8610 ir_build_store_ptr(irb, scope, node, index_ptr, zero);
79498611
7950 Buf *instruction_addresses_name = buf_create_from_str("instruction_addresses");8612 Buf *instruction_addresses_name = buf_create_from_str("instruction_addresses");
7951 IrInstruction *addrs_slice_ptr = ir_build_field_ptr(irb, scope, node, err_ret_trace_ptr, instruction_addresses_name);8613 IrInstruction *addrs_slice_ptr = ir_build_field_ptr(irb, scope, node, err_ret_trace_ptr, instruction_addresses_name, false);
79528614
7953 IrInstruction *slice_value = ir_build_slice(irb, scope, node, return_addresses_ptr, zero, nullptr, false);8615 IrInstruction *slice_value = ir_build_slice_src(irb, scope, node, return_addresses_ptr, zero, nullptr, false, no_result_loc());
7954 ir_build_store_ptr(irb, scope, node, addrs_slice_ptr, slice_value);8616 ir_build_store_ptr(irb, scope, node, addrs_slice_ptr, slice_value);
7955 }8617 }
79568618
...@@ -7961,7 +8623,7 @@ bool ir_gen(CodeGen *codegen, AstNode *node, Scope *scope, IrExecutable *ir_exec...@@ -7961,7 +8623,7 @@ bool ir_gen(CodeGen *codegen, AstNode *node, Scope *scope, IrExecutable *ir_exec
7961 irb->exec->coro_final_cleanup_block = ir_create_basic_block(irb, scope, "FinalCleanup");8623 irb->exec->coro_final_cleanup_block = ir_create_basic_block(irb, scope, "FinalCleanup");
7962 }8624 }
79638625
7964 IrInstruction *result = ir_gen_node_extra(irb, node, scope, LValNone);8626 IrInstruction *result = ir_gen_node_extra(irb, node, scope, LValNone, nullptr);
7965 assert(result);8627 assert(result);
7966 if (irb->exec->invalid)8628 if (irb->exec->invalid)
7967 return false;8629 return false;
...@@ -8009,7 +8671,7 @@ bool ir_gen(CodeGen *codegen, AstNode *node, Scope *scope, IrExecutable *ir_exec...@@ -8009,7 +8671,7 @@ bool ir_gen(CodeGen *codegen, AstNode *node, Scope *scope, IrExecutable *ir_exec
8009 }8671 }
8010 if (irb->codegen->have_err_ret_tracing) {8672 if (irb->codegen->have_err_ret_tracing) {
8011 Buf *err_ret_trace_ptr_field_name = buf_create_from_str(ERR_RET_TRACE_PTR_FIELD_NAME);8673 Buf *err_ret_trace_ptr_field_name = buf_create_from_str(ERR_RET_TRACE_PTR_FIELD_NAME);
8012 IrInstruction *err_ret_trace_ptr_field_ptr = ir_build_field_ptr(irb, scope, node, coro_promise_ptr, err_ret_trace_ptr_field_name);8674 IrInstruction *err_ret_trace_ptr_field_ptr = ir_build_field_ptr(irb, scope, node, coro_promise_ptr, err_ret_trace_ptr_field_name, false);
8013 IrInstruction *dest_err_ret_trace_ptr = ir_build_load_ptr(irb, scope, node, err_ret_trace_ptr_field_ptr);8675 IrInstruction *dest_err_ret_trace_ptr = ir_build_load_ptr(irb, scope, node, err_ret_trace_ptr_field_ptr);
8014 ir_build_merge_err_ret_traces(irb, scope, node, coro_promise_ptr, err_ret_trace_ptr, dest_err_ret_trace_ptr);8676 ir_build_merge_err_ret_traces(irb, scope, node, coro_promise_ptr, err_ret_trace_ptr, dest_err_ret_trace_ptr);
8015 }8677 }
...@@ -8017,7 +8679,7 @@ bool ir_gen(CodeGen *codegen, AstNode *node, Scope *scope, IrExecutable *ir_exec...@@ -8017,7 +8679,7 @@ bool ir_gen(CodeGen *codegen, AstNode *node, Scope *scope, IrExecutable *ir_exec
8017 // a register or local variable which does not get spilled into the frame,8679 // a register or local variable which does not get spilled into the frame,
8018 // otherwise llvm tries to access memory inside the destroyed frame.8680 // otherwise llvm tries to access memory inside the destroyed frame.
8019 IrInstruction *unwrapped_await_handle_ptr = ir_build_optional_unwrap_ptr(irb, scope, node,8681 IrInstruction *unwrapped_await_handle_ptr = ir_build_optional_unwrap_ptr(irb, scope, node,
8020 irb->exec->await_handle_var_ptr, false);8682 irb->exec->await_handle_var_ptr, false, false);
8021 IrInstruction *await_handle_in_block = ir_build_load_ptr(irb, scope, node, unwrapped_await_handle_ptr);8683 IrInstruction *await_handle_in_block = ir_build_load_ptr(irb, scope, node, unwrapped_await_handle_ptr);
8022 ir_build_br(irb, scope, node, check_free_block, const_bool_false);8684 ir_build_br(irb, scope, node, check_free_block, const_bool_false);
80238685
...@@ -8031,7 +8693,7 @@ bool ir_gen(CodeGen *codegen, AstNode *node, Scope *scope, IrExecutable *ir_exec...@@ -8031,7 +8693,7 @@ bool ir_gen(CodeGen *codegen, AstNode *node, Scope *scope, IrExecutable *ir_exec
8031 incoming_values[0] = const_bool_false;8693 incoming_values[0] = const_bool_false;
8032 incoming_blocks[1] = irb->exec->coro_normal_final;8694 incoming_blocks[1] = irb->exec->coro_normal_final;
8033 incoming_values[1] = const_bool_true;8695 incoming_values[1] = const_bool_true;
8034 IrInstruction *resume_awaiter = ir_build_phi(irb, scope, node, 2, incoming_blocks, incoming_values);8696 IrInstruction *resume_awaiter = ir_build_phi(irb, scope, node, 2, incoming_blocks, incoming_values, nullptr);
80358697
8036 IrBasicBlock **merge_incoming_blocks = allocate<IrBasicBlock *>(2);8698 IrBasicBlock **merge_incoming_blocks = allocate<IrBasicBlock *>(2);
8037 IrInstruction **merge_incoming_values = allocate<IrInstruction *>(2);8699 IrInstruction **merge_incoming_values = allocate<IrInstruction *>(2);
...@@ -8039,12 +8701,12 @@ bool ir_gen(CodeGen *codegen, AstNode *node, Scope *scope, IrExecutable *ir_exec...@@ -8039,12 +8701,12 @@ bool ir_gen(CodeGen *codegen, AstNode *node, Scope *scope, IrExecutable *ir_exec
8039 merge_incoming_values[0] = ir_build_const_undefined(irb, scope, node);8701 merge_incoming_values[0] = ir_build_const_undefined(irb, scope, node);
8040 merge_incoming_blocks[1] = irb->exec->coro_normal_final;8702 merge_incoming_blocks[1] = irb->exec->coro_normal_final;
8041 merge_incoming_values[1] = await_handle_in_block;8703 merge_incoming_values[1] = await_handle_in_block;
8042 IrInstruction *awaiter_handle = ir_build_phi(irb, scope, node, 2, merge_incoming_blocks, merge_incoming_values);8704 IrInstruction *awaiter_handle = ir_build_phi(irb, scope, node, 2, merge_incoming_blocks, merge_incoming_values, nullptr);
80438705
8044 Buf *shrink_field_name = buf_create_from_str(ASYNC_SHRINK_FIELD_NAME);8706 Buf *shrink_field_name = buf_create_from_str(ASYNC_SHRINK_FIELD_NAME);
8045 IrInstruction *implicit_allocator_ptr = ir_build_get_implicit_allocator(irb, scope, node,8707 IrInstruction *implicit_allocator_ptr = ir_build_get_implicit_allocator(irb, scope, node,
8046 ImplicitAllocatorIdLocalVar);8708 ImplicitAllocatorIdLocalVar);
8047 IrInstruction *shrink_fn_ptr = ir_build_field_ptr(irb, scope, node, implicit_allocator_ptr, shrink_field_name);8709 IrInstruction *shrink_fn_ptr = ir_build_field_ptr(irb, scope, node, implicit_allocator_ptr, shrink_field_name, false);
8048 IrInstruction *shrink_fn = ir_build_load_ptr(irb, scope, node, shrink_fn_ptr);8710 IrInstruction *shrink_fn = ir_build_load_ptr(irb, scope, node, shrink_fn_ptr);
8049 IrInstruction *zero = ir_build_const_usize(irb, scope, node, 0);8711 IrInstruction *zero = ir_build_const_usize(irb, scope, node, 0);
8050 IrInstruction *coro_mem_ptr_maybe = ir_build_coro_free(irb, scope, node, coro_id, irb->exec->coro_handle);8712 IrInstruction *coro_mem_ptr_maybe = ir_build_coro_free(irb, scope, node, coro_id, irb->exec->coro_handle);
...@@ -8056,7 +8718,8 @@ bool ir_gen(CodeGen *codegen, AstNode *node, Scope *scope, IrExecutable *ir_exec...@@ -8056,7 +8718,8 @@ bool ir_gen(CodeGen *codegen, AstNode *node, Scope *scope, IrExecutable *ir_exec
8056 IrInstruction *coro_mem_ptr_ref = ir_build_ref(irb, scope, node, coro_mem_ptr, true, false);8718 IrInstruction *coro_mem_ptr_ref = ir_build_ref(irb, scope, node, coro_mem_ptr, true, false);
8057 IrInstruction *coro_size_ptr = ir_build_var_ptr(irb, scope, node, coro_size_var);8719 IrInstruction *coro_size_ptr = ir_build_var_ptr(irb, scope, node, coro_size_var);
8058 IrInstruction *coro_size = ir_build_load_ptr(irb, scope, node, coro_size_ptr);8720 IrInstruction *coro_size = ir_build_load_ptr(irb, scope, node, coro_size_ptr);
8059 IrInstruction *mem_slice = ir_build_slice(irb, scope, node, coro_mem_ptr_ref, zero, coro_size, false);8721 IrInstruction *mem_slice = ir_build_slice_src(irb, scope, node, coro_mem_ptr_ref, zero, coro_size, false,
8722 no_result_loc());
8060 size_t arg_count = 5;8723 size_t arg_count = 5;
8061 IrInstruction **args = allocate<IrInstruction *>(arg_count);8724 IrInstruction **args = allocate<IrInstruction *>(arg_count);
8062 args[0] = implicit_allocator_ptr; // self8725 args[0] = implicit_allocator_ptr; // self
...@@ -8070,7 +8733,8 @@ bool ir_gen(CodeGen *codegen, AstNode *node, Scope *scope, IrExecutable *ir_exec...@@ -8070,7 +8733,8 @@ bool ir_gen(CodeGen *codegen, AstNode *node, Scope *scope, IrExecutable *ir_exec
8070 // non-allocating. Basically coroutines are not supported right now until they are reworked.8733 // non-allocating. Basically coroutines are not supported right now until they are reworked.
8071 args[3] = ir_build_const_usize(irb, scope, node, 1); // new_size8734 args[3] = ir_build_const_usize(irb, scope, node, 1); // new_size
8072 args[4] = ir_build_const_usize(irb, scope, node, 1); // new_align8735 args[4] = ir_build_const_usize(irb, scope, node, 1); // new_align
8073 ir_build_call(irb, scope, node, nullptr, shrink_fn, arg_count, args, false, FnInlineAuto, false, nullptr, nullptr);8736 ir_build_call_src(irb, scope, node, nullptr, shrink_fn, arg_count, args, false, FnInlineAuto, false, nullptr,
8737 nullptr, no_result_loc());
80748738
8075 IrBasicBlock *resume_block = ir_create_basic_block(irb, scope, "Resume");8739 IrBasicBlock *resume_block = ir_create_basic_block(irb, scope, "Resume");
8076 ir_build_cond_br(irb, scope, node, resume_awaiter, resume_block, irb->exec->coro_suspend_block, const_bool_false);8740 ir_build_cond_br(irb, scope, node, resume_awaiter, resume_block, irb->exec->coro_suspend_block, const_bool_false);
...@@ -8177,6 +8841,15 @@ static ConstExprValue *ir_exec_const_result(CodeGen *codegen, IrExecutable *exec...@@ -8177,6 +8841,15 @@ static ConstExprValue *ir_exec_const_result(CodeGen *codegen, IrExecutable *exec
8177 }8841 }
8178 return &value->value;8842 return &value->value;
8179 } else if (ir_has_side_effects(instruction)) {8843 } else if (ir_has_side_effects(instruction)) {
8844 if (instr_is_comptime(instruction)) {
8845 switch (instruction->id) {
8846 case IrInstructionIdUnwrapErrPayload:
8847 case IrInstructionIdUnionFieldPtr:
8848 continue;
8849 default:
8850 break;
8851 }
8852 }
8180 exec_add_error_node(codegen, exec, instruction->source_node,8853 exec_add_error_node(codegen, exec, instruction->source_node,
8181 buf_sprintf("unable to evaluate constant expression"));8854 buf_sprintf("unable to evaluate constant expression"));
8182 return &codegen->invalid_instruction->value;8855 return &codegen->invalid_instruction->value;
...@@ -9154,15 +9827,6 @@ static bool ir_num_lit_fits_in_other_type(IrAnalyze *ira, IrInstruction *instruc...@@ -9154,15 +9827,6 @@ static bool ir_num_lit_fits_in_other_type(IrAnalyze *ira, IrInstruction *instruc
9154 return false;9827 return false;
9155}9828}
91569829
9157static bool is_slice(ZigType *type) {
9158 return type->id == ZigTypeIdStruct && type->data.structure.is_slice;
9159}
9160
9161static bool slice_is_const(ZigType *type) {
9162 assert(is_slice(type));
9163 return type->data.structure.fields[slice_ptr_index].type_entry->data.pointer.is_const;
9164}
9165
9166static bool is_tagged_union(ZigType *type) {9830static bool is_tagged_union(ZigType *type) {
9167 if (type->id != ZigTypeIdUnion)9831 if (type->id != ZigTypeIdUnion)
9168 return false;9832 return false;
...@@ -9533,9 +10197,21 @@ static ZigType *ir_resolve_peer_types(IrAnalyze *ira, AstNode *source_node, ZigT...@@ -9533,9 +10197,21 @@ static ZigType *ir_resolve_peer_types(IrAnalyze *ira, AstNode *source_node, ZigT
9533{10197{
9534 Error err;10198 Error err;
9535 assert(instruction_count >= 1);10199 assert(instruction_count >= 1);
9536 IrInstruction *prev_inst = instructions[0];10200 IrInstruction *prev_inst;
9537 if (type_is_invalid(prev_inst->value.type)) {10201 size_t i = 0;
9538 return ira->codegen->builtin_types.entry_invalid;10202 for (;;) {
10203 prev_inst = instructions[i];
10204 if (type_is_invalid(prev_inst->value.type)) {
10205 return ira->codegen->builtin_types.entry_invalid;
10206 }
10207 if (prev_inst->value.type->id == ZigTypeIdUnreachable) {
10208 i += 1;
10209 if (i == instruction_count) {
10210 return prev_inst->value.type;
10211 }
10212 continue;
10213 }
10214 break;
9539 }10215 }
9540 ErrorTableEntry **errors = nullptr;10216 ErrorTableEntry **errors = nullptr;
9541 size_t errors_count = 0;10217 size_t errors_count = 0;
...@@ -9560,7 +10236,7 @@ static ZigType *ir_resolve_peer_types(IrAnalyze *ira, AstNode *source_node, ZigT...@@ -9560,7 +10236,7 @@ static ZigType *ir_resolve_peer_types(IrAnalyze *ira, AstNode *source_node, ZigT
956010236
9561 bool any_are_null = (prev_inst->value.type->id == ZigTypeIdNull);10237 bool any_are_null = (prev_inst->value.type->id == ZigTypeIdNull);
9562 bool convert_to_const_slice = false;10238 bool convert_to_const_slice = false;
9563 for (size_t i = 1; i < instruction_count; i += 1) {10239 for (; i < instruction_count; i += 1) {
9564 IrInstruction *cur_inst = instructions[i];10240 IrInstruction *cur_inst = instructions[i];
9565 ZigType *cur_type = cur_inst->value.type;10241 ZigType *cur_type = cur_inst->value.type;
9566 ZigType *prev_type = prev_inst->value.type;10242 ZigType *prev_type = prev_inst->value.type;
...@@ -9579,7 +10255,7 @@ static ZigType *ir_resolve_peer_types(IrAnalyze *ira, AstNode *source_node, ZigT...@@ -9579,7 +10255,7 @@ static ZigType *ir_resolve_peer_types(IrAnalyze *ira, AstNode *source_node, ZigT
9579 }10255 }
958010256
9581 if (prev_type->id == ZigTypeIdErrorSet) {10257 if (prev_type->id == ZigTypeIdErrorSet) {
9582 assert(err_set_type != nullptr);10258 ir_assert(err_set_type != nullptr, prev_inst);
9583 if (cur_type->id == ZigTypeIdErrorSet) {10259 if (cur_type->id == ZigTypeIdErrorSet) {
9584 if (type_is_global_error_set(err_set_type)) {10260 if (type_is_global_error_set(err_set_type)) {
9585 continue;10261 continue;
...@@ -9839,6 +10515,7 @@ static ZigType *ir_resolve_peer_types(IrAnalyze *ira, AstNode *source_node, ZigT...@@ -9839,6 +10515,7 @@ static ZigType *ir_resolve_peer_types(IrAnalyze *ira, AstNode *source_node, ZigT
983910515
9840 if (prev_type->id == ZigTypeIdNull) {10516 if (prev_type->id == ZigTypeIdNull) {
9841 prev_inst = cur_inst;10517 prev_inst = cur_inst;
10518 any_are_null = true;
9842 continue;10519 continue;
9843 }10520 }
984410521
...@@ -10153,6 +10830,8 @@ static ZigType *ir_resolve_peer_types(IrAnalyze *ira, AstNode *source_node, ZigT...@@ -10153,6 +10830,8 @@ static ZigType *ir_resolve_peer_types(IrAnalyze *ira, AstNode *source_node, ZigT
10153 } else if (prev_inst->value.type->id == ZigTypeIdOptional) {10830 } else if (prev_inst->value.type->id == ZigTypeIdOptional) {
10154 return prev_inst->value.type;10831 return prev_inst->value.type;
10155 } else {10832 } else {
10833 if ((err = type_resolve(ira->codegen, prev_inst->value.type, ResolveStatusSizeKnown)))
10834 return ira->codegen->builtin_types.entry_invalid;
10156 return get_optional_type(ira->codegen, prev_inst->value.type);10835 return get_optional_type(ira->codegen, prev_inst->value.type);
10157 }10836 }
10158 } else {10837 } else {
...@@ -10160,24 +10839,18 @@ static ZigType *ir_resolve_peer_types(IrAnalyze *ira, AstNode *source_node, ZigT...@@ -10160,24 +10839,18 @@ static ZigType *ir_resolve_peer_types(IrAnalyze *ira, AstNode *source_node, ZigT
10160 }10839 }
10161}10840}
1016210841
10163static void ir_add_alloca(IrAnalyze *ira, IrInstruction *instruction, ZigType *type_entry) {
10164 if (type_has_bits(type_entry) && handle_is_ptr(type_entry)) {
10165 ZigFn *fn_entry = exec_fn_entry(ira->new_irb.exec);
10166 if (fn_entry != nullptr) {
10167 fn_entry->alloca_list.append(instruction);
10168 }
10169 }
10170}
10171
10172static void copy_const_val(ConstExprValue *dest, ConstExprValue *src, bool same_global_refs) {10842static void copy_const_val(ConstExprValue *dest, ConstExprValue *src, bool same_global_refs) {
10173 ConstGlobalRefs *global_refs = dest->global_refs;10843 ConstGlobalRefs *global_refs = dest->global_refs;
10174 assert(!same_global_refs || src->global_refs != nullptr);10844 memcpy(dest, src, sizeof(ConstExprValue));
10175 *dest = *src;
10176 if (!same_global_refs) {10845 if (!same_global_refs) {
10177 dest->global_refs = global_refs;10846 dest->global_refs = global_refs;
10847 if (src->special == ConstValSpecialUndef)
10848 return;
10178 if (dest->type->id == ZigTypeIdStruct) {10849 if (dest->type->id == ZigTypeIdStruct) {
10179 dest->data.x_struct.fields = allocate_nonzero<ConstExprValue>(dest->type->data.structure.src_field_count);10850 dest->data.x_struct.fields = create_const_vals(dest->type->data.structure.src_field_count);
10180 memcpy(dest->data.x_struct.fields, src->data.x_struct.fields, sizeof(ConstExprValue) * dest->type->data.structure.src_field_count);10851 for (size_t i = 0; i < dest->type->data.structure.src_field_count; i += 1) {
10852 copy_const_val(&dest->data.x_struct.fields[i], &src->data.x_struct.fields[i], false);
10853 }
10181 }10854 }
10182 }10855 }
10183}10856}
...@@ -10195,7 +10868,6 @@ static bool eval_const_expr_implicit_cast(IrAnalyze *ira, IrInstruction *source_...@@ -10195,7 +10868,6 @@ static bool eval_const_expr_implicit_cast(IrAnalyze *ira, IrInstruction *source_
10195 zig_unreachable();10868 zig_unreachable();
10196 case CastOpErrSet:10869 case CastOpErrSet:
10197 case CastOpBitCast:10870 case CastOpBitCast:
10198 case CastOpPtrOfArrayToSlice:
10199 zig_panic("TODO");10871 zig_panic("TODO");
10200 case CastOpNoop:10872 case CastOpNoop:
10201 {10873 {
...@@ -10295,7 +10967,7 @@ static IrInstruction *ir_const(IrAnalyze *ira, IrInstruction *old_instruction, Z...@@ -10295,7 +10967,7 @@ static IrInstruction *ir_const(IrAnalyze *ira, IrInstruction *old_instruction, Z
10295}10967}
1029610968
10297static IrInstruction *ir_resolve_cast(IrAnalyze *ira, IrInstruction *source_instr, IrInstruction *value,10969static IrInstruction *ir_resolve_cast(IrAnalyze *ira, IrInstruction *source_instr, IrInstruction *value,
10298 ZigType *wanted_type, CastOp cast_op, bool need_alloca)10970 ZigType *wanted_type, CastOp cast_op)
10299{10971{
10300 if (instr_is_comptime(value) || !type_has_bits(wanted_type)) {10972 if (instr_is_comptime(value) || !type_has_bits(wanted_type)) {
10301 IrInstruction *result = ir_const(ira, source_instr, wanted_type);10973 IrInstruction *result = ir_const(ira, source_instr, wanted_type);
...@@ -10308,9 +10980,6 @@ static IrInstruction *ir_resolve_cast(IrAnalyze *ira, IrInstruction *source_inst...@@ -10308,9 +10980,6 @@ static IrInstruction *ir_resolve_cast(IrAnalyze *ira, IrInstruction *source_inst
10308 } else {10980 } else {
10309 IrInstruction *result = ir_build_cast(&ira->new_irb, source_instr->scope, source_instr->source_node, wanted_type, value, cast_op);10981 IrInstruction *result = ir_build_cast(&ira->new_irb, source_instr->scope, source_instr->source_node, wanted_type, value, cast_op);
10310 result->value.type = wanted_type;10982 result->value.type = wanted_type;
10311 if (need_alloca) {
10312 ir_add_alloca(ira, result, wanted_type);
10313 }
10314 return result;10983 return result;
10315 }10984 }
10316}10985}
...@@ -10352,7 +11021,7 @@ static IrInstruction *ir_resolve_ptr_of_array_to_unknown_len_ptr(IrAnalyze *ira,...@@ -10352,7 +11021,7 @@ static IrInstruction *ir_resolve_ptr_of_array_to_unknown_len_ptr(IrAnalyze *ira,
10352}11021}
1035311022
10354static IrInstruction *ir_resolve_ptr_of_array_to_slice(IrAnalyze *ira, IrInstruction *source_instr,11023static IrInstruction *ir_resolve_ptr_of_array_to_slice(IrAnalyze *ira, IrInstruction *source_instr,
10355 IrInstruction *value, ZigType *wanted_type)11024 IrInstruction *value, ZigType *wanted_type, ResultLoc *result_loc)
10356{11025{
10357 Error err;11026 Error err;
1035811027
...@@ -10383,11 +11052,12 @@ static IrInstruction *ir_resolve_ptr_of_array_to_slice(IrAnalyze *ira, IrInstruc...@@ -10383,11 +11052,12 @@ static IrInstruction *ir_resolve_ptr_of_array_to_slice(IrAnalyze *ira, IrInstruc
10383 }11052 }
10384 }11053 }
1038511054
10386 IrInstruction *result = ir_build_cast(&ira->new_irb, source_instr->scope, source_instr->source_node,11055 if (result_loc == nullptr) result_loc = no_result_loc();
10387 wanted_type, value, CastOpPtrOfArrayToSlice);11056 IrInstruction *result_loc_inst = ir_resolve_result(ira, source_instr, result_loc, wanted_type, nullptr, true, false);
10388 result->value.type = wanted_type;11057 if (type_is_invalid(result_loc_inst->value.type) || instr_is_unreachable(result_loc_inst)) {
10389 ir_add_alloca(ira, result, wanted_type);11058 return result_loc_inst;
10390 return result;11059 }
11060 return ir_build_ptr_of_array_to_slice(ira, source_instr, wanted_type, value, result_loc_inst);
10391}11061}
1039211062
10393static IrBasicBlock *ir_get_new_bb(IrAnalyze *ira, IrBasicBlock *old_bb, IrInstruction *ref_old_instruction) {11063static IrBasicBlock *ir_get_new_bb(IrAnalyze *ira, IrBasicBlock *old_bb, IrInstruction *ref_old_instruction) {
...@@ -10419,51 +11089,136 @@ static IrBasicBlock *ir_get_new_bb_runtime(IrAnalyze *ira, IrBasicBlock *old_bb,...@@ -10419,51 +11089,136 @@ static IrBasicBlock *ir_get_new_bb_runtime(IrAnalyze *ira, IrBasicBlock *old_bb,
10419}11089}
1042011090
10421static void ir_start_bb(IrAnalyze *ira, IrBasicBlock *old_bb, IrBasicBlock *const_predecessor_bb) {11091static void ir_start_bb(IrAnalyze *ira, IrBasicBlock *old_bb, IrBasicBlock *const_predecessor_bb) {
11092 assert(!old_bb->suspended);
10422 ira->instruction_index = 0;11093 ira->instruction_index = 0;
10423 ira->old_irb.current_basic_block = old_bb;11094 ira->old_irb.current_basic_block = old_bb;
10424 ira->const_predecessor_bb = const_predecessor_bb;11095 ira->const_predecessor_bb = const_predecessor_bb;
11096 ira->old_bb_index = old_bb->index;
10425}11097}
1042611098
10427static void ir_finish_bb(IrAnalyze *ira) {11099static IrInstruction *ira_suspend(IrAnalyze *ira, IrInstruction *old_instruction, IrBasicBlock *next_bb,
10428 ira->new_irb.exec->basic_block_list.append(ira->new_irb.current_basic_block);11100 IrSuspendPosition *suspend_pos)
10429 ira->instruction_index += 1;11101{
10430 while (ira->instruction_index < ira->old_irb.current_basic_block->instruction_list.length) {11102 if (ira->codegen->verbose_ir) {
10431 IrInstruction *next_instruction = ira->old_irb.current_basic_block->instruction_list.at(ira->instruction_index);11103 fprintf(stderr, "suspend %s_%zu %s_%zu #%zu (%zu,%zu)\n", ira->old_irb.current_basic_block->name_hint,
10432 if (!next_instruction->is_gen) {11104 ira->old_irb.current_basic_block->debug_id,
10433 ir_add_error(ira, next_instruction, buf_sprintf("unreachable code"));11105 ira->old_irb.exec->basic_block_list.at(ira->old_bb_index)->name_hint,
10434 break;11106 ira->old_irb.exec->basic_block_list.at(ira->old_bb_index)->debug_id,
10435 }11107 ira->old_irb.current_basic_block->instruction_list.at(ira->instruction_index)->debug_id,
10436 ira->instruction_index += 1;11108 ira->old_bb_index, ira->instruction_index);
11109 }
11110 suspend_pos->basic_block_index = ira->old_bb_index;
11111 suspend_pos->instruction_index = ira->instruction_index;
11112
11113 ira->old_irb.current_basic_block->suspended = true;
11114
11115 // null next_bb means that the caller plans to call ira_resume before returning
11116 if (next_bb != nullptr) {
11117 ira->old_bb_index = next_bb->index;
11118 ira->old_irb.current_basic_block = ira->old_irb.exec->basic_block_list.at(ira->old_bb_index);
11119 assert(ira->old_irb.current_basic_block == next_bb);
11120 ira->instruction_index = 0;
11121 ira->const_predecessor_bb = nullptr;
11122 next_bb->other = ir_get_new_bb_runtime(ira, next_bb, old_instruction);
11123 ira->new_irb.current_basic_block = next_bb->other;
10437 }11124 }
11125 return ira->codegen->unreach_instruction;
11126}
11127
11128static IrInstruction *ira_resume(IrAnalyze *ira) {
11129 IrSuspendPosition pos = ira->resume_stack.pop();
11130 if (ira->codegen->verbose_ir) {
11131 fprintf(stderr, "resume (%zu,%zu) ", pos.basic_block_index, pos.instruction_index);
11132 }
11133 ira->old_bb_index = pos.basic_block_index;
11134 ira->old_irb.current_basic_block = ira->old_irb.exec->basic_block_list.at(ira->old_bb_index);
11135 assert(ira->old_irb.current_basic_block->in_resume_stack);
11136 ira->old_irb.current_basic_block->in_resume_stack = false;
11137 ira->old_irb.current_basic_block->suspended = false;
11138 ira->instruction_index = pos.instruction_index;
11139 assert(pos.instruction_index < ira->old_irb.current_basic_block->instruction_list.length);
11140 if (ira->codegen->verbose_ir) {
11141 fprintf(stderr, "%s_%zu #%zu\n", ira->old_irb.current_basic_block->name_hint,
11142 ira->old_irb.current_basic_block->debug_id,
11143 ira->old_irb.current_basic_block->instruction_list.at(pos.instruction_index)->debug_id);
11144 }
11145 ira->const_predecessor_bb = nullptr;
11146 ira->new_irb.current_basic_block = ira->old_irb.current_basic_block->other;
11147 assert(ira->new_irb.current_basic_block != nullptr);
11148 return ira->codegen->unreach_instruction;
11149}
1043811150
10439 size_t my_old_bb_index = ira->old_bb_index;11151static void ir_start_next_bb(IrAnalyze *ira) {
10440 ira->old_bb_index += 1;11152 ira->old_bb_index += 1;
1044111153
10442 bool need_repeat = true;11154 bool need_repeat = true;
10443 for (;;) {11155 for (;;) {
10444 while (ira->old_bb_index < ira->old_irb.exec->basic_block_list.length) {11156 while (ira->old_bb_index < ira->old_irb.exec->basic_block_list.length) {
10445 IrBasicBlock *old_bb = ira->old_irb.exec->basic_block_list.at(ira->old_bb_index);11157 IrBasicBlock *old_bb = ira->old_irb.exec->basic_block_list.at(ira->old_bb_index);
10446 if (old_bb->other == nullptr) {11158 if (old_bb->other == nullptr && old_bb->suspend_instruction_ref == nullptr) {
10447 ira->old_bb_index += 1;11159 ira->old_bb_index += 1;
10448 continue;11160 continue;
10449 }11161 }
10450 if (old_bb->other->instruction_list.length != 0 || ira->old_bb_index == my_old_bb_index) {11162 // if it's already started, or
11163 // if it's a suspended block,
11164 // then skip it
11165 if (old_bb->suspended ||
11166 (old_bb->other != nullptr && old_bb->other->instruction_list.length != 0) ||
11167 (old_bb->other != nullptr && old_bb->other->already_appended))
11168 {
10451 ira->old_bb_index += 1;11169 ira->old_bb_index += 1;
10452 continue;11170 continue;
10453 }11171 }
10454 ira->new_irb.current_basic_block = old_bb->other;
1045511172
11173 // if there is a resume_stack, pop one from there rather than moving on.
11174 // the last item of the resume stack will be a basic block that will
11175 // move on to the next one below
11176 if (ira->resume_stack.length != 0) {
11177 ira_resume(ira);
11178 return;
11179 }
11180
11181 if (old_bb->other == nullptr) {
11182 old_bb->other = ir_get_new_bb_runtime(ira, old_bb, old_bb->suspend_instruction_ref);
11183 }
11184 ira->new_irb.current_basic_block = old_bb->other;
10456 ir_start_bb(ira, old_bb, nullptr);11185 ir_start_bb(ira, old_bb, nullptr);
10457 return;11186 return;
10458 }11187 }
10459 if (!need_repeat)11188 if (!need_repeat) {
11189 if (ira->resume_stack.length != 0) {
11190 ira_resume(ira);
11191 }
10460 return;11192 return;
11193 }
10461 need_repeat = false;11194 need_repeat = false;
10462 ira->old_bb_index = 0;11195 ira->old_bb_index = 0;
10463 continue;11196 continue;
10464 }11197 }
10465}11198}
1046611199
11200static void ir_finish_bb(IrAnalyze *ira) {
11201 if (!ira->new_irb.current_basic_block->already_appended) {
11202 ira->new_irb.current_basic_block->already_appended = true;
11203 if (ira->codegen->verbose_ir) {
11204 fprintf(stderr, "append new bb %s_%zu\n", ira->new_irb.current_basic_block->name_hint,
11205 ira->new_irb.current_basic_block->debug_id);
11206 }
11207 ira->new_irb.exec->basic_block_list.append(ira->new_irb.current_basic_block);
11208 }
11209 ira->instruction_index += 1;
11210 while (ira->instruction_index < ira->old_irb.current_basic_block->instruction_list.length) {
11211 IrInstruction *next_instruction = ira->old_irb.current_basic_block->instruction_list.at(ira->instruction_index);
11212 if (!next_instruction->is_gen) {
11213 ir_add_error(ira, next_instruction, buf_sprintf("unreachable code"));
11214 break;
11215 }
11216 ira->instruction_index += 1;
11217 }
11218
11219 ir_start_next_bb(ira);
11220}
11221
10467static IrInstruction *ir_unreach_error(IrAnalyze *ira) {11222static IrInstruction *ir_unreach_error(IrAnalyze *ira) {
10468 ira->old_bb_index = SIZE_MAX;11223 ira->old_bb_index = SIZE_MAX;
10469 ira->new_irb.exec->invalid = true;11224 ira->new_irb.exec->invalid = true;
...@@ -10524,6 +11279,12 @@ static IrInstruction *ir_const_undef(IrAnalyze *ira, IrInstruction *source_instr...@@ -10524,6 +11279,12 @@ static IrInstruction *ir_const_undef(IrAnalyze *ira, IrInstruction *source_instr
10524 return result;11279 return result;
10525}11280}
1052611281
11282static IrInstruction *ir_const_unreachable(IrAnalyze *ira, IrInstruction *source_instruction) {
11283 IrInstruction *result = ir_const(ira, source_instruction, ira->codegen->builtin_types.entry_unreachable);
11284 result->value.special = ConstValSpecialStatic;
11285 return result;
11286}
11287
10527static IrInstruction *ir_const_void(IrAnalyze *ira, IrInstruction *source_instruction) {11288static IrInstruction *ir_const_void(IrAnalyze *ira, IrInstruction *source_instruction) {
10528 return ir_const(ira, source_instruction, ira->codegen->builtin_types.entry_void);11289 return ir_const(ira, source_instruction, ira->codegen->builtin_types.entry_void);
10529}11290}
...@@ -10721,7 +11482,7 @@ static ZigFn *ir_resolve_fn(IrAnalyze *ira, IrInstruction *fn_value) {...@@ -10721,7 +11482,7 @@ static ZigFn *ir_resolve_fn(IrAnalyze *ira, IrInstruction *fn_value) {
10721}11482}
1072211483
10723static IrInstruction *ir_analyze_optional_wrap(IrAnalyze *ira, IrInstruction *source_instr, IrInstruction *value,11484static IrInstruction *ir_analyze_optional_wrap(IrAnalyze *ira, IrInstruction *source_instr, IrInstruction *value,
10724 ZigType *wanted_type)11485 ZigType *wanted_type, ResultLoc *result_loc)
10725{11486{
10726 assert(wanted_type->id == ZigTypeIdOptional);11487 assert(wanted_type->id == ZigTypeIdOptional);
1072711488
...@@ -10747,20 +11508,29 @@ static IrInstruction *ir_analyze_optional_wrap(IrAnalyze *ira, IrInstruction *so...@@ -10747,20 +11508,29 @@ static IrInstruction *ir_analyze_optional_wrap(IrAnalyze *ira, IrInstruction *so
10747 return &const_instruction->base;11508 return &const_instruction->base;
10748 }11509 }
1074911510
10750 IrInstruction *result = ir_build_maybe_wrap(&ira->new_irb, source_instr->scope, source_instr->source_node, value);11511 if (result_loc == nullptr && handle_is_ptr(wanted_type)) {
10751 result->value.type = wanted_type;11512 result_loc = no_result_loc();
11513 }
11514 IrInstruction *result_loc_inst = nullptr;
11515 if (result_loc != nullptr) {
11516 result_loc_inst = ir_resolve_result(ira, source_instr, result_loc, wanted_type, nullptr, true, false);
11517 if (type_is_invalid(result_loc_inst->value.type) || instr_is_unreachable(result_loc_inst)) {
11518 return result_loc_inst;
11519 }
11520 }
11521 IrInstruction *result = ir_build_optional_wrap(ira, source_instr, wanted_type, value, result_loc_inst);
10752 result->value.data.rh_maybe = RuntimeHintOptionalNonNull;11522 result->value.data.rh_maybe = RuntimeHintOptionalNonNull;
10753 ir_add_alloca(ira, result, wanted_type);
10754 return result;11523 return result;
10755}11524}
1075611525
10757static IrInstruction *ir_analyze_err_wrap_payload(IrAnalyze *ira, IrInstruction *source_instr,11526static IrInstruction *ir_analyze_err_wrap_payload(IrAnalyze *ira, IrInstruction *source_instr,
10758 IrInstruction *value, ZigType *wanted_type)11527 IrInstruction *value, ZigType *wanted_type, ResultLoc *result_loc)
10759{11528{
10760 assert(wanted_type->id == ZigTypeIdErrorUnion);11529 assert(wanted_type->id == ZigTypeIdErrorUnion);
1076111530
11531 ZigType *payload_type = wanted_type->data.error_union.payload_type;
11532 ZigType *err_set_type = wanted_type->data.error_union.err_set_type;
10762 if (instr_is_comptime(value)) {11533 if (instr_is_comptime(value)) {
10763 ZigType *payload_type = wanted_type->data.error_union.payload_type;
10764 IrInstruction *casted_payload = ir_implicit_cast(ira, value, payload_type);11534 IrInstruction *casted_payload = ir_implicit_cast(ira, value, payload_type);
10765 if (type_is_invalid(casted_payload->value.type))11535 if (type_is_invalid(casted_payload->value.type))
10766 return ira->codegen->invalid_instruction;11536 return ira->codegen->invalid_instruction;
...@@ -10770,7 +11540,7 @@ static IrInstruction *ir_analyze_err_wrap_payload(IrAnalyze *ira, IrInstruction...@@ -10770,7 +11540,7 @@ static IrInstruction *ir_analyze_err_wrap_payload(IrAnalyze *ira, IrInstruction
10770 return ira->codegen->invalid_instruction;11540 return ira->codegen->invalid_instruction;
1077111541
10772 ConstExprValue *err_set_val = create_const_vals(1);11542 ConstExprValue *err_set_val = create_const_vals(1);
10773 err_set_val->type = wanted_type->data.error_union.err_set_type;11543 err_set_val->type = err_set_type;
10774 err_set_val->special = ConstValSpecialStatic;11544 err_set_val->special = ConstValSpecialStatic;
10775 err_set_val->data.x_err_set = nullptr;11545 err_set_val->data.x_err_set = nullptr;
1077611546
...@@ -10783,10 +11553,19 @@ static IrInstruction *ir_analyze_err_wrap_payload(IrAnalyze *ira, IrInstruction...@@ -10783,10 +11553,19 @@ static IrInstruction *ir_analyze_err_wrap_payload(IrAnalyze *ira, IrInstruction
10783 return &const_instruction->base;11553 return &const_instruction->base;
10784 }11554 }
1078511555
10786 IrInstruction *result = ir_build_err_wrap_payload(&ira->new_irb, source_instr->scope, source_instr->source_node, value);11556 IrInstruction *result_loc_inst;
10787 result->value.type = wanted_type;11557 if (handle_is_ptr(wanted_type)) {
11558 if (result_loc == nullptr) result_loc = no_result_loc();
11559 result_loc_inst = ir_resolve_result(ira, source_instr, result_loc, wanted_type, nullptr, true, false);
11560 if (type_is_invalid(result_loc_inst->value.type) || instr_is_unreachable(result_loc_inst)) {
11561 return result_loc_inst;
11562 }
11563 } else {
11564 result_loc_inst = nullptr;
11565 }
11566
11567 IrInstruction *result = ir_build_err_wrap_payload(ira, source_instr, wanted_type, value, result_loc_inst);
10788 result->value.data.rh_error_union = RuntimeHintErrorUnionNonError;11568 result->value.data.rh_error_union = RuntimeHintErrorUnionNonError;
10789 ir_add_alloca(ira, result, wanted_type);
10790 return result;11569 return result;
10791}11570}
1079211571
...@@ -10833,7 +11612,9 @@ static IrInstruction *ir_analyze_err_set_cast(IrAnalyze *ira, IrInstruction *sou...@@ -10833,7 +11612,9 @@ static IrInstruction *ir_analyze_err_set_cast(IrAnalyze *ira, IrInstruction *sou
10833 return result;11612 return result;
10834}11613}
1083511614
10836static IrInstruction *ir_analyze_err_wrap_code(IrAnalyze *ira, IrInstruction *source_instr, IrInstruction *value, ZigType *wanted_type) {11615static IrInstruction *ir_analyze_err_wrap_code(IrAnalyze *ira, IrInstruction *source_instr, IrInstruction *value,
11616 ZigType *wanted_type, ResultLoc *result_loc)
11617{
10837 assert(wanted_type->id == ZigTypeIdErrorUnion);11618 assert(wanted_type->id == ZigTypeIdErrorUnion);
1083811619
10839 IrInstruction *casted_value = ir_implicit_cast(ira, value, wanted_type->data.error_union.err_set_type);11620 IrInstruction *casted_value = ir_implicit_cast(ira, value, wanted_type->data.error_union.err_set_type);
...@@ -10857,10 +11638,20 @@ static IrInstruction *ir_analyze_err_wrap_code(IrAnalyze *ira, IrInstruction *so...@@ -10857,10 +11638,20 @@ static IrInstruction *ir_analyze_err_wrap_code(IrAnalyze *ira, IrInstruction *so
10857 return &const_instruction->base;11638 return &const_instruction->base;
10858 }11639 }
1085911640
10860 IrInstruction *result = ir_build_err_wrap_code(&ira->new_irb, source_instr->scope, source_instr->source_node, value);11641 IrInstruction *result_loc_inst;
10861 result->value.type = wanted_type;11642 if (handle_is_ptr(wanted_type)) {
11643 if (result_loc == nullptr) result_loc = no_result_loc();
11644 result_loc_inst = ir_resolve_result(ira, source_instr, result_loc, wanted_type, nullptr, true, false);
11645 if (type_is_invalid(result_loc_inst->value.type) || instr_is_unreachable(result_loc_inst)) {
11646 return result_loc_inst;
11647 }
11648 } else {
11649 result_loc_inst = nullptr;
11650 }
11651
11652
11653 IrInstruction *result = ir_build_err_wrap_code(ira, source_instr, wanted_type, value, result_loc_inst);
10862 result->value.data.rh_error_union = RuntimeHintErrorUnionError;11654 result->value.data.rh_error_union = RuntimeHintErrorUnionError;
10863 ir_add_alloca(ira, result, wanted_type);
10864 return result;11655 return result;
10865}11656}
1086611657
...@@ -10920,20 +11711,21 @@ static IrInstruction *ir_get_ref(IrAnalyze *ira, IrInstruction *source_instructi...@@ -10920,20 +11711,21 @@ static IrInstruction *ir_get_ref(IrAnalyze *ira, IrInstruction *source_instructi
1092011711
10921 ZigType *ptr_type = get_pointer_to_type_extra(ira->codegen, value->value.type,11712 ZigType *ptr_type = get_pointer_to_type_extra(ira->codegen, value->value.type,
10922 is_const, is_volatile, PtrLenSingle, 0, 0, 0, false);11713 is_const, is_volatile, PtrLenSingle, 0, 0, 0, false);
10923 IrInstruction *new_instruction = ir_build_ref(&ira->new_irb, source_instruction->scope,11714
10924 source_instruction->source_node, value, is_const, is_volatile);11715 IrInstruction *result_loc;
10925 new_instruction->value.type = ptr_type;
10926 new_instruction->value.data.rh_ptr = RuntimeHintPtrStack;
10927 if (type_has_bits(ptr_type) && !handle_is_ptr(value->value.type)) {11716 if (type_has_bits(ptr_type) && !handle_is_ptr(value->value.type)) {
10928 ZigFn *fn_entry = exec_fn_entry(ira->new_irb.exec);11717 result_loc = ir_resolve_result(ira, source_instruction, no_result_loc(), value->value.type, nullptr, true, false);
10929 assert(fn_entry);11718 } else {
10930 fn_entry->alloca_list.append(new_instruction);11719 result_loc = nullptr;
10931 }11720 }
11721
11722 IrInstruction *new_instruction = ir_build_ref_gen(ira, source_instruction, ptr_type, value, result_loc);
11723 new_instruction->value.data.rh_ptr = RuntimeHintPtrStack;
10932 return new_instruction;11724 return new_instruction;
10933}11725}
1093411726
10935static IrInstruction *ir_analyze_array_to_slice(IrAnalyze *ira, IrInstruction *source_instr,11727static IrInstruction *ir_analyze_array_to_slice(IrAnalyze *ira, IrInstruction *source_instr,
10936 IrInstruction *array_arg, ZigType *wanted_type)11728 IrInstruction *array_arg, ZigType *wanted_type, ResultLoc *result_loc)
10937{11729{
10938 assert(is_slice(wanted_type));11730 assert(is_slice(wanted_type));
10939 // In this function we honor the const-ness of wanted_type, because11731 // In this function we honor the const-ness of wanted_type, because
...@@ -10942,7 +11734,7 @@ static IrInstruction *ir_analyze_array_to_slice(IrAnalyze *ira, IrInstruction *s...@@ -10942,7 +11734,7 @@ static IrInstruction *ir_analyze_array_to_slice(IrAnalyze *ira, IrInstruction *s
10942 IrInstruction *array_ptr = nullptr;11734 IrInstruction *array_ptr = nullptr;
10943 IrInstruction *array;11735 IrInstruction *array;
10944 if (array_arg->value.type->id == ZigTypeIdPointer) {11736 if (array_arg->value.type->id == ZigTypeIdPointer) {
10945 array = ir_get_deref(ira, source_instr, array_arg);11737 array = ir_get_deref(ira, source_instr, array_arg, nullptr);
10946 array_ptr = array_arg;11738 array_ptr = array_arg;
10947 } else {11739 } else {
10948 array = array_arg;11740 array = array_arg;
...@@ -10965,12 +11757,14 @@ static IrInstruction *ir_analyze_array_to_slice(IrAnalyze *ira, IrInstruction *s...@@ -10965,12 +11757,14 @@ static IrInstruction *ir_analyze_array_to_slice(IrAnalyze *ira, IrInstruction *s
1096511757
10966 if (!array_ptr) array_ptr = ir_get_ref(ira, source_instr, array, true, false);11758 if (!array_ptr) array_ptr = ir_get_ref(ira, source_instr, array, true, false);
1096711759
10968 IrInstruction *result = ir_build_slice(&ira->new_irb, source_instr->scope,11760 if (result_loc == nullptr) result_loc = no_result_loc();
10969 source_instr->source_node, array_ptr, start, end, false);11761 IrInstruction *result_loc_inst = ir_resolve_result(ira, source_instr, result_loc, wanted_type, nullptr, true, false);
10970 result->value.type = wanted_type;11762 if (type_is_invalid(result_loc_inst->value.type) || instr_is_unreachable(result_loc_inst)) {
11763 return result_loc_inst;
11764 }
11765 IrInstruction *result = ir_build_slice_gen(ira, source_instr, wanted_type, array_ptr, start, end, false, result_loc_inst);
10971 result->value.data.rh_slice.id = RuntimeHintSliceIdLen;11766 result->value.data.rh_slice.id = RuntimeHintSliceIdLen;
10972 result->value.data.rh_slice.len = array_type->data.array.len;11767 result->value.data.rh_slice.len = array_type->data.array.len;
10973 ir_add_alloca(ira, result, result->value.type);
1097411768
10975 return result;11769 return result;
10976}11770}
...@@ -11608,7 +12402,7 @@ static IrInstruction *ir_analyze_array_to_vector(IrAnalyze *ira, IrInstruction *...@@ -11608,7 +12402,7 @@ static IrInstruction *ir_analyze_array_to_vector(IrAnalyze *ira, IrInstruction *
11608}12402}
1160912403
11610static IrInstruction *ir_analyze_vector_to_array(IrAnalyze *ira, IrInstruction *source_instr,12404static IrInstruction *ir_analyze_vector_to_array(IrAnalyze *ira, IrInstruction *source_instr,
11611 IrInstruction *vector, ZigType *array_type)12405 IrInstruction *vector, ZigType *array_type, ResultLoc *result_loc)
11612{12406{
11613 if (instr_is_comptime(vector)) {12407 if (instr_is_comptime(vector)) {
11614 // arrays and vectors have the same ConstExprValue representation12408 // arrays and vectors have the same ConstExprValue representation
...@@ -11617,7 +12411,14 @@ static IrInstruction *ir_analyze_vector_to_array(IrAnalyze *ira, IrInstruction *...@@ -11617,7 +12411,14 @@ static IrInstruction *ir_analyze_vector_to_array(IrAnalyze *ira, IrInstruction *
11617 result->value.type = array_type;12411 result->value.type = array_type;
11618 return result;12412 return result;
11619 }12413 }
11620 return ir_build_vector_to_array(ira, source_instr, vector, array_type);12414 if (result_loc == nullptr) {
12415 result_loc = no_result_loc();
12416 }
12417 IrInstruction *result_loc_inst = ir_resolve_result(ira, source_instr, result_loc, array_type, nullptr, true, false);
12418 if (type_is_invalid(result_loc_inst->value.type) || instr_is_unreachable(result_loc_inst)) {
12419 return result_loc_inst;
12420 }
12421 return ir_build_vector_to_array(ira, source_instr, array_type, vector, result_loc_inst);
11621}12422}
1162212423
11623static IrInstruction *ir_analyze_int_to_c_ptr(IrAnalyze *ira, IrInstruction *source_instr,12424static IrInstruction *ir_analyze_int_to_c_ptr(IrAnalyze *ira, IrInstruction *source_instr,
...@@ -11667,7 +12468,7 @@ static bool is_pointery_and_elem_is_not_pointery(ZigType *ty) {...@@ -11667,7 +12468,7 @@ static bool is_pointery_and_elem_is_not_pointery(ZigType *ty) {
11667}12468}
1166812469
11669static IrInstruction *ir_analyze_cast(IrAnalyze *ira, IrInstruction *source_instr,12470static IrInstruction *ir_analyze_cast(IrAnalyze *ira, IrInstruction *source_instr,
11670 ZigType *wanted_type, IrInstruction *value)12471 ZigType *wanted_type, IrInstruction *value, ResultLoc *result_loc)
11671{12472{
11672 Error err;12473 Error err;
11673 ZigType *actual_type = value->value.type;12474 ZigType *actual_type = value->value.type;
...@@ -11683,7 +12484,7 @@ static IrInstruction *ir_analyze_cast(IrAnalyze *ira, IrInstruction *source_inst...@@ -11683,7 +12484,7 @@ static IrInstruction *ir_analyze_cast(IrAnalyze *ira, IrInstruction *source_inst
11683 if (const_cast_result.id == ConstCastResultIdInvalid)12484 if (const_cast_result.id == ConstCastResultIdInvalid)
11684 return ira->codegen->invalid_instruction;12485 return ira->codegen->invalid_instruction;
11685 if (const_cast_result.id == ConstCastResultIdOk) {12486 if (const_cast_result.id == ConstCastResultIdOk) {
11686 return ir_resolve_cast(ira, source_instr, value, wanted_type, CastOpNoop, false);12487 return ir_resolve_cast(ira, source_instr, value, wanted_type, CastOpNoop);
11687 }12488 }
1168812489
11689 // cast from T to ?T12490 // cast from T to ?T
...@@ -11693,12 +12494,12 @@ static IrInstruction *ir_analyze_cast(IrAnalyze *ira, IrInstruction *source_inst...@@ -11693,12 +12494,12 @@ static IrInstruction *ir_analyze_cast(IrAnalyze *ira, IrInstruction *source_inst
11693 if (types_match_const_cast_only(ira, wanted_child_type, actual_type, source_node,12494 if (types_match_const_cast_only(ira, wanted_child_type, actual_type, source_node,
11694 false).id == ConstCastResultIdOk)12495 false).id == ConstCastResultIdOk)
11695 {12496 {
11696 return ir_analyze_optional_wrap(ira, source_instr, value, wanted_type);12497 return ir_analyze_optional_wrap(ira, source_instr, value, wanted_type, result_loc);
11697 } else if (actual_type->id == ZigTypeIdComptimeInt ||12498 } else if (actual_type->id == ZigTypeIdComptimeInt ||
11698 actual_type->id == ZigTypeIdComptimeFloat)12499 actual_type->id == ZigTypeIdComptimeFloat)
11699 {12500 {
11700 if (ir_num_lit_fits_in_other_type(ira, value, wanted_child_type, true)) {12501 if (ir_num_lit_fits_in_other_type(ira, value, wanted_child_type, true)) {
11701 return ir_analyze_optional_wrap(ira, source_instr, value, wanted_type);12502 return ir_analyze_optional_wrap(ira, source_instr, value, wanted_type, result_loc);
11702 } else {12503 } else {
11703 return ira->codegen->invalid_instruction;12504 return ira->codegen->invalid_instruction;
11704 }12505 }
...@@ -11722,7 +12523,7 @@ static IrInstruction *ir_analyze_cast(IrAnalyze *ira, IrInstruction *source_inst...@@ -11722,7 +12523,7 @@ static IrInstruction *ir_analyze_cast(IrAnalyze *ira, IrInstruction *source_inst
11722 wanted_child_type);12523 wanted_child_type);
11723 if (type_is_invalid(cast1->value.type))12524 if (type_is_invalid(cast1->value.type))
11724 return ira->codegen->invalid_instruction;12525 return ira->codegen->invalid_instruction;
11725 return ir_analyze_optional_wrap(ira, source_instr, cast1, wanted_type);12526 return ir_analyze_optional_wrap(ira, source_instr, cast1, wanted_type, result_loc);
11726 }12527 }
11727 }12528 }
11728 }12529 }
...@@ -11732,12 +12533,12 @@ static IrInstruction *ir_analyze_cast(IrAnalyze *ira, IrInstruction *source_inst...@@ -11732,12 +12533,12 @@ static IrInstruction *ir_analyze_cast(IrAnalyze *ira, IrInstruction *source_inst
11732 if (types_match_const_cast_only(ira, wanted_type->data.error_union.payload_type, actual_type,12533 if (types_match_const_cast_only(ira, wanted_type->data.error_union.payload_type, actual_type,
11733 source_node, false).id == ConstCastResultIdOk)12534 source_node, false).id == ConstCastResultIdOk)
11734 {12535 {
11735 return ir_analyze_err_wrap_payload(ira, source_instr, value, wanted_type);12536 return ir_analyze_err_wrap_payload(ira, source_instr, value, wanted_type, result_loc);
11736 } else if (actual_type->id == ZigTypeIdComptimeInt ||12537 } else if (actual_type->id == ZigTypeIdComptimeInt ||
11737 actual_type->id == ZigTypeIdComptimeFloat)12538 actual_type->id == ZigTypeIdComptimeFloat)
11738 {12539 {
11739 if (ir_num_lit_fits_in_other_type(ira, value, wanted_type->data.error_union.payload_type, true)) {12540 if (ir_num_lit_fits_in_other_type(ira, value, wanted_type->data.error_union.payload_type, true)) {
11740 return ir_analyze_err_wrap_payload(ira, source_instr, value, wanted_type);12541 return ir_analyze_err_wrap_payload(ira, source_instr, value, wanted_type, result_loc);
11741 } else {12542 } else {
11742 return ira->codegen->invalid_instruction;12543 return ira->codegen->invalid_instruction;
11743 }12544 }
...@@ -11755,11 +12556,11 @@ static IrInstruction *ir_analyze_cast(IrAnalyze *ira, IrInstruction *source_inst...@@ -11755,11 +12556,11 @@ static IrInstruction *ir_analyze_cast(IrAnalyze *ira, IrInstruction *source_inst
11755 actual_type->id == ZigTypeIdComptimeInt ||12556 actual_type->id == ZigTypeIdComptimeInt ||
11756 actual_type->id == ZigTypeIdComptimeFloat)12557 actual_type->id == ZigTypeIdComptimeFloat)
11757 {12558 {
11758 IrInstruction *cast1 = ir_analyze_cast(ira, source_instr, wanted_type->data.error_union.payload_type, value);12559 IrInstruction *cast1 = ir_analyze_cast(ira, source_instr, wanted_type->data.error_union.payload_type, value, nullptr);
11759 if (type_is_invalid(cast1->value.type))12560 if (type_is_invalid(cast1->value.type))
11760 return ira->codegen->invalid_instruction;12561 return ira->codegen->invalid_instruction;
1176112562
11762 IrInstruction *cast2 = ir_analyze_cast(ira, source_instr, wanted_type, cast1);12563 IrInstruction *cast2 = ir_analyze_cast(ira, source_instr, wanted_type, cast1, result_loc);
11763 if (type_is_invalid(cast2->value.type))12564 if (type_is_invalid(cast2->value.type))
11764 return ira->codegen->invalid_instruction;12565 return ira->codegen->invalid_instruction;
1176512566
...@@ -11841,7 +12642,7 @@ static IrInstruction *ir_analyze_cast(IrAnalyze *ira, IrInstruction *source_inst...@@ -11841,7 +12642,7 @@ static IrInstruction *ir_analyze_cast(IrAnalyze *ira, IrInstruction *source_inst
11841 types_match_const_cast_only(ira, ptr_type->data.pointer.child_type, actual_type->data.array.child_type,12642 types_match_const_cast_only(ira, ptr_type->data.pointer.child_type, actual_type->data.array.child_type,
11842 source_node, false).id == ConstCastResultIdOk)12643 source_node, false).id == ConstCastResultIdOk)
11843 {12644 {
11844 return ir_analyze_array_to_slice(ira, source_instr, value, wanted_type);12645 return ir_analyze_array_to_slice(ira, source_instr, value, wanted_type, result_loc);
11845 }12646 }
11846 }12647 }
1184712648
...@@ -11858,11 +12659,11 @@ static IrInstruction *ir_analyze_cast(IrAnalyze *ira, IrInstruction *source_inst...@@ -11858,11 +12659,11 @@ static IrInstruction *ir_analyze_cast(IrAnalyze *ira, IrInstruction *source_inst
11858 types_match_const_cast_only(ira, ptr_type->data.pointer.child_type, actual_type->data.array.child_type,12659 types_match_const_cast_only(ira, ptr_type->data.pointer.child_type, actual_type->data.array.child_type,
11859 source_node, false).id == ConstCastResultIdOk)12660 source_node, false).id == ConstCastResultIdOk)
11860 {12661 {
11861 IrInstruction *cast1 = ir_analyze_cast(ira, source_instr, wanted_type->data.maybe.child_type, value);12662 IrInstruction *cast1 = ir_analyze_cast(ira, source_instr, wanted_type->data.maybe.child_type, value, nullptr);
11862 if (type_is_invalid(cast1->value.type))12663 if (type_is_invalid(cast1->value.type))
11863 return ira->codegen->invalid_instruction;12664 return ira->codegen->invalid_instruction;
1186412665
11865 IrInstruction *cast2 = ir_analyze_cast(ira, source_instr, wanted_type, cast1);12666 IrInstruction *cast2 = ir_analyze_cast(ira, source_instr, wanted_type, cast1, result_loc);
11866 if (type_is_invalid(cast2->value.type))12667 if (type_is_invalid(cast2->value.type))
11867 return ira->codegen->invalid_instruction;12668 return ira->codegen->invalid_instruction;
1186812669
...@@ -11905,7 +12706,7 @@ static IrInstruction *ir_analyze_cast(IrAnalyze *ira, IrInstruction *source_inst...@@ -11905,7 +12706,7 @@ static IrInstruction *ir_analyze_cast(IrAnalyze *ira, IrInstruction *source_inst
11905 array_type->data.array.child_type, source_node,12706 array_type->data.array.child_type, source_node,
11906 !slice_ptr_type->data.pointer.is_const).id == ConstCastResultIdOk)12707 !slice_ptr_type->data.pointer.is_const).id == ConstCastResultIdOk)
11907 {12708 {
11908 return ir_resolve_ptr_of_array_to_slice(ira, source_instr, value, wanted_type);12709 return ir_resolve_ptr_of_array_to_slice(ira, source_instr, value, wanted_type, result_loc);
11909 }12710 }
11910 }12711 }
1191112712
...@@ -11936,11 +12737,11 @@ static IrInstruction *ir_analyze_cast(IrAnalyze *ira, IrInstruction *source_inst...@@ -11936,11 +12737,11 @@ static IrInstruction *ir_analyze_cast(IrAnalyze *ira, IrInstruction *source_inst
11936 types_match_const_cast_only(ira, ptr_type->data.pointer.child_type, actual_type->data.array.child_type,12737 types_match_const_cast_only(ira, ptr_type->data.pointer.child_type, actual_type->data.array.child_type,
11937 source_node, false).id == ConstCastResultIdOk)12738 source_node, false).id == ConstCastResultIdOk)
11938 {12739 {
11939 IrInstruction *cast1 = ir_analyze_cast(ira, source_instr, wanted_type->data.error_union.payload_type, value);12740 IrInstruction *cast1 = ir_analyze_cast(ira, source_instr, wanted_type->data.error_union.payload_type, value, nullptr);
11940 if (type_is_invalid(cast1->value.type))12741 if (type_is_invalid(cast1->value.type))
11941 return ira->codegen->invalid_instruction;12742 return ira->codegen->invalid_instruction;
1194212743
11943 IrInstruction *cast2 = ir_analyze_cast(ira, source_instr, wanted_type, cast1);12744 IrInstruction *cast2 = ir_analyze_cast(ira, source_instr, wanted_type, cast1, result_loc);
11944 if (type_is_invalid(cast2->value.type))12745 if (type_is_invalid(cast2->value.type))
11945 return ira->codegen->invalid_instruction;12746 return ira->codegen->invalid_instruction;
1194612747
...@@ -11952,7 +12753,7 @@ static IrInstruction *ir_analyze_cast(IrAnalyze *ira, IrInstruction *source_inst...@@ -11952,7 +12753,7 @@ static IrInstruction *ir_analyze_cast(IrAnalyze *ira, IrInstruction *source_inst
11952 if (wanted_type->id == ZigTypeIdErrorUnion &&12753 if (wanted_type->id == ZigTypeIdErrorUnion &&
11953 actual_type->id == ZigTypeIdErrorSet)12754 actual_type->id == ZigTypeIdErrorSet)
11954 {12755 {
11955 return ir_analyze_err_wrap_code(ira, source_instr, value, wanted_type);12756 return ir_analyze_err_wrap_code(ira, source_instr, value, wanted_type, result_loc);
11956 }12757 }
1195712758
11958 // cast from typed number to integer or float literal.12759 // cast from typed number to integer or float literal.
...@@ -12076,7 +12877,7 @@ static IrInstruction *ir_analyze_cast(IrAnalyze *ira, IrInstruction *source_inst...@@ -12076,7 +12877,7 @@ static IrInstruction *ir_analyze_cast(IrAnalyze *ira, IrInstruction *source_inst
12076 types_match_const_cast_only(ira, wanted_type->data.array.child_type,12877 types_match_const_cast_only(ira, wanted_type->data.array.child_type,
12077 actual_type->data.vector.elem_type, source_node, false).id == ConstCastResultIdOk)12878 actual_type->data.vector.elem_type, source_node, false).id == ConstCastResultIdOk)
12078 {12879 {
12079 return ir_analyze_vector_to_array(ira, source_instr, value, wanted_type);12880 return ir_analyze_vector_to_array(ira, source_instr, value, wanted_type, result_loc);
12080 }12881 }
1208112882
12082 // cast from [N]T to @Vector(N, T)12883 // cast from [N]T to @Vector(N, T)
...@@ -12118,7 +12919,9 @@ static IrInstruction *ir_analyze_cast(IrAnalyze *ira, IrInstruction *source_inst...@@ -12118,7 +12919,9 @@ static IrInstruction *ir_analyze_cast(IrAnalyze *ira, IrInstruction *source_inst
12118 return ira->codegen->invalid_instruction;12919 return ira->codegen->invalid_instruction;
12119}12920}
1212012921
12121static IrInstruction *ir_implicit_cast(IrAnalyze *ira, IrInstruction *value, ZigType *expected_type) {12922static IrInstruction *ir_implicit_cast_with_result(IrAnalyze *ira, IrInstruction *value, ZigType *expected_type,
12923 ResultLoc *result_loc)
12924{
12122 assert(value);12925 assert(value);
12123 assert(value != ira->codegen->invalid_instruction);12926 assert(value != ira->codegen->invalid_instruction);
12124 assert(!expected_type || !type_is_invalid(expected_type));12927 assert(!expected_type || !type_is_invalid(expected_type));
...@@ -12131,63 +12934,76 @@ static IrInstruction *ir_implicit_cast(IrAnalyze *ira, IrInstruction *value, Zig...@@ -12131,63 +12934,76 @@ static IrInstruction *ir_implicit_cast(IrAnalyze *ira, IrInstruction *value, Zig
12131 if (value->value.type->id == ZigTypeIdUnreachable)12934 if (value->value.type->id == ZigTypeIdUnreachable)
12132 return value;12935 return value;
1213312936
12134 return ir_analyze_cast(ira, value, expected_type, value);12937 return ir_analyze_cast(ira, value, expected_type, value, result_loc);
12938}
12939
12940static IrInstruction *ir_implicit_cast(IrAnalyze *ira, IrInstruction *value, ZigType *expected_type) {
12941 return ir_implicit_cast_with_result(ira, value, expected_type, nullptr);
12135}12942}
1213612943
12137static IrInstruction *ir_get_deref(IrAnalyze *ira, IrInstruction *source_instruction, IrInstruction *ptr) {12944static IrInstruction *ir_get_deref(IrAnalyze *ira, IrInstruction *source_instruction, IrInstruction *ptr,
12945 ResultLoc *result_loc)
12946{
12138 Error err;12947 Error err;
12139 ZigType *type_entry = ptr->value.type;12948 ZigType *type_entry = ptr->value.type;
12140 if (type_is_invalid(type_entry)) {12949 if (type_is_invalid(type_entry))
12141 return ira->codegen->invalid_instruction;12950 return ira->codegen->invalid_instruction;
12142 } else if (type_entry->id == ZigTypeIdPointer) {
12143 ZigType *child_type = type_entry->data.pointer.child_type;
12144 // if the child type has one possible value, the deref is comptime
12145 switch (type_has_one_possible_value(ira->codegen, child_type)) {
12146 case OnePossibleValueInvalid:
12147 return ira->codegen->invalid_instruction;
12148 case OnePossibleValueYes:
12149 return ir_const(ira, source_instruction, child_type);
12150 case OnePossibleValueNo:
12151 break;
12152 }
12153 if (instr_is_comptime(ptr)) {
12154 if (ptr->value.special == ConstValSpecialUndef) {
12155 ir_add_error(ira, ptr, buf_sprintf("attempt to dereference undefined value"));
12156 return ira->codegen->invalid_instruction;
12157 }
12158 if (ptr->value.data.x_ptr.mut == ConstPtrMutComptimeConst ||
12159 ptr->value.data.x_ptr.mut == ConstPtrMutComptimeVar)
12160 {
12161 ConstExprValue *pointee = const_ptr_pointee_unchecked(ira->codegen, &ptr->value);
12162 if (pointee->special != ConstValSpecialRuntime) {
12163 IrInstruction *result = ir_const(ira, source_instruction, child_type);
1216412951
12165 if ((err = ir_read_const_ptr(ira, ira->codegen, source_instruction->source_node, &result->value,12952 if (type_entry->id != ZigTypeIdPointer) {
12166 &ptr->value)))12953 ir_add_error_node(ira, source_instruction->source_node,
12167 {12954 buf_sprintf("attempt to dereference non-pointer type '%s'",
12168 return ira->codegen->invalid_instruction;12955 buf_ptr(&type_entry->name)));
12169 }12956 return ira->codegen->invalid_instruction;
12170 result->value.type = child_type;12957 }
12171 return result;12958
12959 ZigType *child_type = type_entry->data.pointer.child_type;
12960 // if the child type has one possible value, the deref is comptime
12961 switch (type_has_one_possible_value(ira->codegen, child_type)) {
12962 case OnePossibleValueInvalid:
12963 return ira->codegen->invalid_instruction;
12964 case OnePossibleValueYes:
12965 return ir_const(ira, source_instruction, child_type);
12966 case OnePossibleValueNo:
12967 break;
12968 }
12969 if (instr_is_comptime(ptr)) {
12970 if (ptr->value.special == ConstValSpecialUndef) {
12971 ir_add_error(ira, ptr, buf_sprintf("attempt to dereference undefined value"));
12972 return ira->codegen->invalid_instruction;
12973 }
12974 if (ptr->value.data.x_ptr.mut != ConstPtrMutRuntimeVar) {
12975 ConstExprValue *pointee = const_ptr_pointee_unchecked(ira->codegen, &ptr->value);
12976 if (pointee->special != ConstValSpecialRuntime) {
12977 IrInstruction *result = ir_const(ira, source_instruction, child_type);
12978
12979 if ((err = ir_read_const_ptr(ira, ira->codegen, source_instruction->source_node, &result->value,
12980 &ptr->value)))
12981 {
12982 return ira->codegen->invalid_instruction;
12172 }12983 }
12984 result->value.type = child_type;
12985 return result;
12173 }12986 }
12174 }12987 }
12175 // if the instruction is a const ref instruction we can skip it12988 }
12176 if (ptr->id == IrInstructionIdRef) {12989 // if the instruction is a const ref instruction we can skip it
12177 IrInstructionRef *ref_inst = reinterpret_cast<IrInstructionRef *>(ptr);12990 if (ptr->id == IrInstructionIdRef) {
12178 return ref_inst->value;12991 IrInstructionRef *ref_inst = reinterpret_cast<IrInstructionRef *>(ptr);
12179 }12992 return ref_inst->value;
12180 IrInstruction *result = ir_build_load_ptr_gen(ira, source_instruction, ptr, child_type);12993 }
12181 if (type_entry->data.pointer.host_int_bytes != 0 && handle_is_ptr(child_type)) {12994
12182 ir_add_alloca(ira, result, child_type);12995 IrInstruction *result_loc_inst;
12996 if (type_entry->data.pointer.host_int_bytes != 0 && handle_is_ptr(child_type)) {
12997 if (result_loc == nullptr) result_loc = no_result_loc();
12998 result_loc_inst = ir_resolve_result(ira, source_instruction, result_loc, child_type, nullptr, true, false);
12999 if (type_is_invalid(result_loc_inst->value.type) || instr_is_unreachable(result_loc_inst)) {
13000 return result_loc_inst;
12183 }13001 }
12184 return result;
12185 } else {13002 } else {
12186 ir_add_error_node(ira, source_instruction->source_node,13003 result_loc_inst = nullptr;
12187 buf_sprintf("attempt to dereference non-pointer type '%s'",
12188 buf_ptr(&type_entry->name)));
12189 return ira->codegen->invalid_instruction;
12190 }13004 }
13005
13006 return ir_build_load_ptr_gen(ira, source_instruction, ptr, child_type, result_loc_inst);
12191}13007}
1219213008
12193static bool ir_resolve_align(IrAnalyze *ira, IrInstruction *value, uint32_t *out) {13009static bool ir_resolve_align(IrAnalyze *ira, IrInstruction *value, uint32_t *out) {
...@@ -12401,6 +13217,14 @@ static IrInstruction *ir_analyze_instruction_return(IrAnalyze *ira, IrInstructio...@@ -12401,6 +13217,14 @@ static IrInstruction *ir_analyze_instruction_return(IrAnalyze *ira, IrInstructio
12401 if (type_is_invalid(value->value.type))13217 if (type_is_invalid(value->value.type))
12402 return ir_unreach_error(ira);13218 return ir_unreach_error(ira);
1240313219
13220 if (!instr_is_comptime(value) && handle_is_ptr(ira->explicit_return_type)) {
13221 // result location mechanism took care of it.
13222 IrInstruction *result = ir_build_return(&ira->new_irb, instruction->base.scope,
13223 instruction->base.source_node, nullptr);
13224 result->value.type = ira->codegen->builtin_types.entry_unreachable;
13225 return ir_finish_anal(ira, result);
13226 }
13227
12404 IrInstruction *casted_value = ir_implicit_cast(ira, value, ira->explicit_return_type);13228 IrInstruction *casted_value = ir_implicit_cast(ira, value, ira->explicit_return_type);
12405 if (type_is_invalid(casted_value->value.type)) {13229 if (type_is_invalid(casted_value->value.type)) {
12406 AstNode *source_node = ira->explicit_return_type_source_node;13230 AstNode *source_node = ira->explicit_return_type_source_node;
...@@ -12563,7 +13387,7 @@ static IrInstruction *ir_analyze_bin_op_cmp(IrAnalyze *ira, IrInstructionBinOp *...@@ -12563,7 +13387,7 @@ static IrInstruction *ir_analyze_bin_op_cmp(IrAnalyze *ira, IrInstructionBinOp *
12563 } else {13387 } else {
12564 return is_non_null;13388 return is_non_null;
12565 }13389 }
12566 } else if (is_equality_cmp && 13390 } else if (is_equality_cmp &&
12567 ((op1->value.type->id == ZigTypeIdNull && op2->value.type->id == ZigTypeIdPointer &&13391 ((op1->value.type->id == ZigTypeIdNull && op2->value.type->id == ZigTypeIdPointer &&
12568 op2->value.type->data.pointer.ptr_len == PtrLenC) ||13392 op2->value.type->data.pointer.ptr_len == PtrLenC) ||
12569 (op2->value.type->id == ZigTypeIdNull && op1->value.type->id == ZigTypeIdPointer &&13393 (op2->value.type->id == ZigTypeIdNull && op1->value.type->id == ZigTypeIdPointer &&
...@@ -13005,7 +13829,7 @@ static ErrorMsg *ir_eval_math_op_scalar(IrAnalyze *ira, IrInstruction *source_in...@@ -13005,7 +13829,7 @@ static ErrorMsg *ir_eval_math_op_scalar(IrAnalyze *ira, IrInstruction *source_in
13005 }13829 }
13006 } else {13830 } else {
13007 float_div_trunc(out_val, op1_val, op2_val);13831 float_div_trunc(out_val, op1_val, op2_val);
13008 ConstExprValue remainder;13832 ConstExprValue remainder = {};
13009 float_rem(&remainder, op1_val, op2_val);13833 float_rem(&remainder, op1_val, op2_val);
13010 if (float_cmp_zero(&remainder) != CmpEQ) {13834 if (float_cmp_zero(&remainder) != CmpEQ) {
13011 return ir_add_error(ira, source_instr, buf_sprintf("exact division had a remainder"));13835 return ir_add_error(ira, source_instr, buf_sprintf("exact division had a remainder"));
...@@ -13380,8 +14204,8 @@ static IrInstruction *ir_analyze_bin_op_math(IrAnalyze *ira, IrInstructionBinOp...@@ -13380,8 +14204,8 @@ static IrInstruction *ir_analyze_bin_op_math(IrAnalyze *ira, IrInstructionBinOp
13380 // have a remainder function ambiguity problem14204 // have a remainder function ambiguity problem
13381 ok = true;14205 ok = true;
13382 } else {14206 } else {
13383 ConstExprValue rem_result;14207 ConstExprValue rem_result = {};
13384 ConstExprValue mod_result;14208 ConstExprValue mod_result = {};
13385 float_rem(&rem_result, op1_val, op2_val);14209 float_rem(&rem_result, op1_val, op2_val);
13386 float_mod(&mod_result, op1_val, op2_val);14210 float_mod(&mod_result, op1_val, op2_val);
13387 ok = float_cmp(&rem_result, &mod_result) == CmpEQ;14211 ok = float_cmp(&rem_result, &mod_result) == CmpEQ;
...@@ -13604,10 +14428,12 @@ static IrInstruction *ir_analyze_array_cat(IrAnalyze *ira, IrInstructionBinOp *i...@@ -13604,10 +14428,12 @@ static IrInstruction *ir_analyze_array_cat(IrAnalyze *ira, IrInstructionBinOp *i
1360414428
13605 size_t next_index = 0;14429 size_t next_index = 0;
13606 for (size_t i = op1_array_index; i < op1_array_end; i += 1, next_index += 1) {14430 for (size_t i = op1_array_index; i < op1_array_end; i += 1, next_index += 1) {
13607 out_array_val->data.x_array.data.s_none.elements[next_index] = op1_array_val->data.x_array.data.s_none.elements[i];14431 copy_const_val(&out_array_val->data.x_array.data.s_none.elements[next_index],
14432 &op1_array_val->data.x_array.data.s_none.elements[i], true);
13608 }14433 }
13609 for (size_t i = op2_array_index; i < op2_array_end; i += 1, next_index += 1) {14434 for (size_t i = op2_array_index; i < op2_array_end; i += 1, next_index += 1) {
13610 out_array_val->data.x_array.data.s_none.elements[next_index] = op2_array_val->data.x_array.data.s_none.elements[i];14435 copy_const_val(&out_array_val->data.x_array.data.s_none.elements[next_index],
14436 &op2_array_val->data.x_array.data.s_none.elements[i], true);
13611 }14437 }
13612 if (next_index < new_len) {14438 if (next_index < new_len) {
13613 ConstExprValue *null_byte = &out_array_val->data.x_array.data.s_none.elements[next_index];14439 ConstExprValue *null_byte = &out_array_val->data.x_array.data.s_none.elements[next_index];
...@@ -13668,7 +14494,8 @@ static IrInstruction *ir_analyze_array_mult(IrAnalyze *ira, IrInstructionBinOp *...@@ -13668,7 +14494,8 @@ static IrInstruction *ir_analyze_array_mult(IrAnalyze *ira, IrInstructionBinOp *
13668 uint64_t i = 0;14494 uint64_t i = 0;
13669 for (uint64_t x = 0; x < mult_amt; x += 1) {14495 for (uint64_t x = 0; x < mult_amt; x += 1) {
13670 for (uint64_t y = 0; y < old_array_len; y += 1) {14496 for (uint64_t y = 0; y < old_array_len; y += 1) {
13671 out_val->data.x_array.data.s_none.elements[i] = array_val->data.x_array.data.s_none.elements[y];14497 copy_const_val(&out_val->data.x_array.data.s_none.elements[i],
14498 &array_val->data.x_array.data.s_none.elements[y], true);
13672 i += 1;14499 i += 1;
13673 }14500 }
13674 }14501 }
...@@ -13765,12 +14592,6 @@ static IrInstruction *ir_analyze_instruction_decl_var(IrAnalyze *ira,...@@ -13765,12 +14592,6 @@ static IrInstruction *ir_analyze_instruction_decl_var(IrAnalyze *ira,
13765 Error err;14592 Error err;
13766 ZigVar *var = decl_var_instruction->var;14593 ZigVar *var = decl_var_instruction->var;
1376714594
13768 IrInstruction *init_value = decl_var_instruction->init_value->child;
13769 if (type_is_invalid(init_value->value.type)) {
13770 var->var_type = ira->codegen->builtin_types.entry_invalid;
13771 return ira->codegen->invalid_instruction;
13772 }
13773
13774 ZigType *explicit_type = nullptr;14595 ZigType *explicit_type = nullptr;
13775 IrInstruction *var_type = nullptr;14596 IrInstruction *var_type = nullptr;
13776 if (decl_var_instruction->var_type != nullptr) {14597 if (decl_var_instruction->var_type != nullptr) {
...@@ -13785,18 +14606,40 @@ static IrInstruction *ir_analyze_instruction_decl_var(IrAnalyze *ira,...@@ -13785,18 +14606,40 @@ static IrInstruction *ir_analyze_instruction_decl_var(IrAnalyze *ira,
1378514606
13786 AstNode *source_node = decl_var_instruction->base.source_node;14607 AstNode *source_node = decl_var_instruction->base.source_node;
1378714608
13788 IrInstruction *casted_init_value = ir_implicit_cast(ira, init_value, explicit_type);
13789 bool is_comptime_var = ir_get_var_is_comptime(var);14609 bool is_comptime_var = ir_get_var_is_comptime(var);
1379014610
13791 bool var_class_requires_const = false;14611 bool var_class_requires_const = false;
1379214612
13793 ZigType *result_type = casted_init_value->value.type;14613 IrInstruction *var_ptr = decl_var_instruction->ptr->child;
14614 // if this is null, a compiler error happened and did not initialize the variable.
14615 // if there are no compile errors there may be a missing ir_expr_wrap in pass1 IR generation.
14616 if (var_ptr == nullptr || type_is_invalid(var_ptr->value.type)) {
14617 ir_assert(var_ptr != nullptr || ira->codegen->errors.length != 0, &decl_var_instruction->base);
14618 var->var_type = ira->codegen->builtin_types.entry_invalid;
14619 return ira->codegen->invalid_instruction;
14620 }
14621
14622 // The ir_build_var_decl_src call is supposed to pass a pointer to the allocation, not an initialization value.
14623 ir_assert(var_ptr->value.type->id == ZigTypeIdPointer, &decl_var_instruction->base);
14624
14625 ZigType *result_type = var_ptr->value.type->data.pointer.child_type;
13794 if (type_is_invalid(result_type)) {14626 if (type_is_invalid(result_type)) {
13795 result_type = ira->codegen->builtin_types.entry_invalid;14627 result_type = ira->codegen->builtin_types.entry_invalid;
13796 } else if (result_type->id == ZigTypeIdUnreachable || result_type->id == ZigTypeIdOpaque) {14628 } else if (result_type->id == ZigTypeIdUnreachable || result_type->id == ZigTypeIdOpaque) {
13797 ir_add_error_node(ira, source_node,14629 zig_unreachable();
13798 buf_sprintf("variable of type '%s' not allowed", buf_ptr(&result_type->name)));14630 }
13799 result_type = ira->codegen->builtin_types.entry_invalid;14631
14632 ConstExprValue *init_val = nullptr;
14633 if (instr_is_comptime(var_ptr) && var_ptr->value.data.x_ptr.mut != ConstPtrMutRuntimeVar) {
14634 init_val = const_ptr_pointee(ira, ira->codegen, &var_ptr->value, decl_var_instruction->base.source_node);
14635 if (is_comptime_var) {
14636 if (var->gen_is_const) {
14637 var->const_value = init_val;
14638 } else {
14639 var->const_value = create_const_vals(1);
14640 copy_const_val(var->const_value, init_val, false);
14641 }
14642 }
13800 }14643 }
1380114644
13802 switch (type_requires_comptime(ira->codegen, result_type)) {14645 switch (type_requires_comptime(ira->codegen, result_type)) {
...@@ -13813,18 +14656,20 @@ static IrInstruction *ir_analyze_instruction_decl_var(IrAnalyze *ira,...@@ -13813,18 +14656,20 @@ static IrInstruction *ir_analyze_instruction_decl_var(IrAnalyze *ira,
13813 }14656 }
13814 break;14657 break;
13815 case ReqCompTimeNo:14658 case ReqCompTimeNo:
13816 if (casted_init_value->value.special == ConstValSpecialStatic &&14659 if (init_val != nullptr) {
13817 casted_init_value->value.type->id == ZigTypeIdFn &&14660 if (init_val->special == ConstValSpecialStatic &&
13818 casted_init_value->value.data.x_ptr.special != ConstPtrSpecialHardCodedAddr &&14661 init_val->type->id == ZigTypeIdFn &&
13819 casted_init_value->value.data.x_ptr.data.fn.fn_entry->fn_inline == FnInlineAlways)14662 init_val->data.x_ptr.special != ConstPtrSpecialHardCodedAddr &&
13820 {14663 init_val->data.x_ptr.data.fn.fn_entry->fn_inline == FnInlineAlways)
13821 var_class_requires_const = true;14664 {
13822 if (!var->src_is_const && !is_comptime_var) {14665 var_class_requires_const = true;
13823 ErrorMsg *msg = ir_add_error_node(ira, source_node,14666 if (!var->src_is_const && !is_comptime_var) {
13824 buf_sprintf("functions marked inline must be stored in const or comptime var"));14667 ErrorMsg *msg = ir_add_error_node(ira, source_node,
13825 AstNode *proto_node = casted_init_value->value.data.x_ptr.data.fn.fn_entry->proto_node;14668 buf_sprintf("functions marked inline must be stored in const or comptime var"));
13826 add_error_note(ira->codegen, msg, proto_node, buf_sprintf("declared here"));14669 AstNode *proto_node = init_val->data.x_ptr.data.fn.fn_entry->proto_node;
13827 result_type = ira->codegen->builtin_types.entry_invalid;14670 add_error_note(ira->codegen, msg, proto_node, buf_sprintf("declared here"));
14671 result_type = ira->codegen->builtin_types.entry_invalid;
14672 }
13828 }14673 }
13829 }14674 }
13830 break;14675 break;
...@@ -13871,11 +14716,29 @@ static IrInstruction *ir_analyze_instruction_decl_var(IrAnalyze *ira,...@@ -13871,11 +14716,29 @@ static IrInstruction *ir_analyze_instruction_decl_var(IrAnalyze *ira,
13871 }14716 }
13872 }14717 }
1387314718
13874 if (casted_init_value->value.special != ConstValSpecialRuntime) {14719 if (init_val != nullptr && init_val->special != ConstValSpecialRuntime) {
13875 if (var->mem_slot_index != SIZE_MAX) {14720 // Resolve ConstPtrMutInfer
14721 if (var->gen_is_const) {
14722 var_ptr->value.data.x_ptr.mut = ConstPtrMutComptimeConst;
14723 } else if (is_comptime_var) {
14724 var_ptr->value.data.x_ptr.mut = ConstPtrMutComptimeVar;
14725 } else {
14726 // we need a runtime ptr but we have a comptime val.
14727 // since it's a comptime val there are no instructions for it.
14728 // we memcpy the init value here
14729 IrInstruction *deref = ir_get_deref(ira, var_ptr, var_ptr, nullptr);
14730 // If this assertion trips, something is wrong with the IR instructions, because
14731 // we expected the above deref to return a constant value, but it created a runtime
14732 // instruction.
14733 assert(deref->value.special != ConstValSpecialRuntime);
14734 var_ptr->value.special = ConstValSpecialRuntime;
14735 ir_analyze_store_ptr(ira, var_ptr, var_ptr, deref);
14736 }
14737
14738 if (var_ptr->value.special == ConstValSpecialStatic && var->mem_slot_index != SIZE_MAX) {
13876 assert(var->mem_slot_index < ira->exec_context.mem_slot_list.length);14739 assert(var->mem_slot_index < ira->exec_context.mem_slot_list.length);
13877 ConstExprValue *mem_slot = ira->exec_context.mem_slot_list.at(var->mem_slot_index);14740 ConstExprValue *mem_slot = ira->exec_context.mem_slot_list.at(var->mem_slot_index);
13878 copy_const_val(mem_slot, &casted_init_value->value, !is_comptime_var || var->gen_is_const);14741 copy_const_val(mem_slot, init_val, !is_comptime_var || var->gen_is_const);
1387914742
13880 if (is_comptime_var || (var_class_requires_const && var->gen_is_const)) {14743 if (is_comptime_var || (var_class_requires_const && var->gen_is_const)) {
13881 return ir_const_void(ira, &decl_var_instruction->base);14744 return ir_const_void(ira, &decl_var_instruction->base);
...@@ -13892,7 +14755,7 @@ static IrInstruction *ir_analyze_instruction_decl_var(IrAnalyze *ira,...@@ -13892,7 +14755,7 @@ static IrInstruction *ir_analyze_instruction_decl_var(IrAnalyze *ira,
13892 if (fn_entry)14755 if (fn_entry)
13893 fn_entry->variable_list.append(var);14756 fn_entry->variable_list.append(var);
1389414757
13895 return ir_build_var_decl_gen(ira, &decl_var_instruction->base, var, casted_init_value);14758 return ir_build_var_decl_gen(ira, &decl_var_instruction->base, var, var_ptr);
13896}14759}
1389714760
13898static IrInstruction *ir_analyze_instruction_export(IrAnalyze *ira, IrInstructionExport *instruction) {14761static IrInstruction *ir_analyze_instruction_export(IrAnalyze *ira, IrInstructionExport *instruction) {
...@@ -14186,7 +15049,7 @@ IrInstruction *ir_get_implicit_allocator(IrAnalyze *ira, IrInstruction *source_i...@@ -14186,7 +15049,7 @@ IrInstruction *ir_get_implicit_allocator(IrAnalyze *ira, IrInstruction *source_i
14186 ZigVar *coro_allocator_var = ira->old_irb.exec->coro_allocator_var;15049 ZigVar *coro_allocator_var = ira->old_irb.exec->coro_allocator_var;
14187 assert(coro_allocator_var != nullptr);15050 assert(coro_allocator_var != nullptr);
14188 IrInstruction *var_ptr_inst = ir_get_var_ptr(ira, source_instr, coro_allocator_var);15051 IrInstruction *var_ptr_inst = ir_get_var_ptr(ira, source_instr, coro_allocator_var);
14189 IrInstruction *result = ir_get_deref(ira, source_instr, var_ptr_inst);15052 IrInstruction *result = ir_get_deref(ira, source_instr, var_ptr_inst, nullptr);
14190 assert(result->value.type != nullptr);15053 assert(result->value.type != nullptr);
14191 return result;15054 return result;
14192 }15055 }
...@@ -14194,7 +15057,436 @@ IrInstruction *ir_get_implicit_allocator(IrAnalyze *ira, IrInstruction *source_i...@@ -14194,7 +15057,436 @@ IrInstruction *ir_get_implicit_allocator(IrAnalyze *ira, IrInstruction *source_i
14194 zig_unreachable();15057 zig_unreachable();
14195}15058}
1419615059
14197static IrInstruction *ir_analyze_async_call(IrAnalyze *ira, IrInstructionCall *call_instruction, ZigFn *fn_entry,15060static IrInstruction *ir_analyze_alloca(IrAnalyze *ira, IrInstruction *source_inst, ZigType *var_type,
15061 uint32_t align, const char *name_hint, bool force_comptime)
15062{
15063 Error err;
15064
15065 ConstExprValue *pointee = create_const_vals(1);
15066 pointee->special = ConstValSpecialUndef;
15067
15068 IrInstructionAllocaGen *result = ir_create_alloca_gen(ira, source_inst, align, name_hint);
15069 result->base.value.special = ConstValSpecialStatic;
15070 result->base.value.data.x_ptr.special = ConstPtrSpecialRef;
15071 result->base.value.data.x_ptr.mut = force_comptime ? ConstPtrMutComptimeVar : ConstPtrMutInfer;
15072 result->base.value.data.x_ptr.data.ref.pointee = pointee;
15073
15074 if ((err = type_resolve(ira->codegen, var_type, ResolveStatusZeroBitsKnown)))
15075 return ira->codegen->invalid_instruction;
15076 assert(result->base.value.data.x_ptr.special != ConstPtrSpecialInvalid);
15077
15078 pointee->type = var_type;
15079 result->base.value.type = get_pointer_to_type_extra(ira->codegen, var_type, false, false,
15080 PtrLenSingle, align, 0, 0, false);
15081
15082 ZigFn *fn_entry = exec_fn_entry(ira->new_irb.exec);
15083 if (fn_entry != nullptr) {
15084 fn_entry->alloca_gen_list.append(result);
15085 }
15086 result->base.is_gen = true;
15087 return &result->base;
15088}
15089
15090static ZigType *ir_result_loc_expected_type(IrAnalyze *ira, IrInstruction *suspend_source_instr,
15091 ResultLoc *result_loc)
15092{
15093 switch (result_loc->id) {
15094 case ResultLocIdInvalid:
15095 case ResultLocIdPeerParent:
15096 zig_unreachable();
15097 case ResultLocIdNone:
15098 case ResultLocIdVar:
15099 case ResultLocIdBitCast:
15100 return nullptr;
15101 case ResultLocIdInstruction:
15102 return result_loc->source_instruction->child->value.type;
15103 case ResultLocIdReturn:
15104 return ira->explicit_return_type;
15105 case ResultLocIdPeer:
15106 return reinterpret_cast<ResultLocPeer*>(result_loc)->parent->resolved_type;
15107 }
15108 zig_unreachable();
15109}
15110
15111static bool type_can_bit_cast(ZigType *t) {
15112 switch (t->id) {
15113 case ZigTypeIdInvalid:
15114 zig_unreachable();
15115 case ZigTypeIdMetaType:
15116 case ZigTypeIdOpaque:
15117 case ZigTypeIdBoundFn:
15118 case ZigTypeIdArgTuple:
15119 case ZigTypeIdUnreachable:
15120 case ZigTypeIdComptimeFloat:
15121 case ZigTypeIdComptimeInt:
15122 case ZigTypeIdEnumLiteral:
15123 case ZigTypeIdUndefined:
15124 case ZigTypeIdNull:
15125 case ZigTypeIdPointer:
15126 return false;
15127 default:
15128 // TODO list these types out explicitly, there are probably some other invalid ones here
15129 return true;
15130 }
15131}
15132
15133static void set_up_result_loc_for_inferred_comptime(IrInstruction *ptr) {
15134 ConstExprValue *undef_child = create_const_vals(1);
15135 undef_child->type = ptr->value.type->data.pointer.child_type;
15136 undef_child->special = ConstValSpecialUndef;
15137 ptr->value.special = ConstValSpecialStatic;
15138 ptr->value.data.x_ptr.mut = ConstPtrMutInfer;
15139 ptr->value.data.x_ptr.special = ConstPtrSpecialRef;
15140 ptr->value.data.x_ptr.data.ref.pointee = undef_child;
15141}
15142
15143// when calling this function, at the callsite must check for result type noreturn and propagate it up
15144static IrInstruction *ir_resolve_result_raw(IrAnalyze *ira, IrInstruction *suspend_source_instr,
15145 ResultLoc *result_loc, ZigType *value_type, IrInstruction *value, bool force_runtime, bool non_null_comptime)
15146{
15147 Error err;
15148 if (result_loc->resolved_loc != nullptr) {
15149 // allow to redo the result location if the value is known and comptime and the previous one isn't
15150 if (value == nullptr || !instr_is_comptime(value) || instr_is_comptime(result_loc->resolved_loc)) {
15151 return result_loc->resolved_loc;
15152 }
15153 }
15154 result_loc->gen_instruction = value;
15155 result_loc->implicit_elem_type = value_type;
15156 switch (result_loc->id) {
15157 case ResultLocIdInvalid:
15158 case ResultLocIdPeerParent:
15159 zig_unreachable();
15160 case ResultLocIdNone: {
15161 if (value != nullptr) {
15162 return nullptr;
15163 }
15164 // need to return a result location and don't have one. use a stack allocation
15165 IrInstructionAllocaGen *alloca_gen = ir_create_alloca_gen(ira, suspend_source_instr, 0, "");
15166 if ((err = type_resolve(ira->codegen, value_type, ResolveStatusZeroBitsKnown)))
15167 return ira->codegen->invalid_instruction;
15168 alloca_gen->base.value.type = get_pointer_to_type_extra(ira->codegen, value_type, false, false,
15169 PtrLenSingle, 0, 0, 0, false);
15170 set_up_result_loc_for_inferred_comptime(&alloca_gen->base);
15171 ZigFn *fn_entry = exec_fn_entry(ira->new_irb.exec);
15172 if (fn_entry != nullptr) {
15173 fn_entry->alloca_gen_list.append(alloca_gen);
15174 }
15175 result_loc->written = true;
15176 result_loc->resolved_loc = &alloca_gen->base;
15177 return result_loc->resolved_loc;
15178 }
15179 case ResultLocIdVar: {
15180 ResultLocVar *result_loc_var = reinterpret_cast<ResultLocVar *>(result_loc);
15181 assert(result_loc->source_instruction->id == IrInstructionIdAllocaSrc);
15182
15183 if (value_type->id == ZigTypeIdUnreachable || value_type->id == ZigTypeIdOpaque) {
15184 ir_add_error(ira, result_loc->source_instruction,
15185 buf_sprintf("variable of type '%s' not allowed", buf_ptr(&value_type->name)));
15186 return ira->codegen->invalid_instruction;
15187 }
15188
15189 IrInstructionAllocaSrc *alloca_src =
15190 reinterpret_cast<IrInstructionAllocaSrc *>(result_loc->source_instruction);
15191 bool force_comptime;
15192 if (!ir_resolve_comptime(ira, alloca_src->is_comptime->child, &force_comptime))
15193 return ira->codegen->invalid_instruction;
15194 bool is_comptime = force_comptime || (value != nullptr &&
15195 value->value.special != ConstValSpecialRuntime && result_loc_var->var->gen_is_const);
15196
15197 if (alloca_src->base.child == nullptr || is_comptime) {
15198 uint32_t align = 0;
15199 if (alloca_src->align != nullptr && !ir_resolve_align(ira, alloca_src->align->child, &align)) {
15200 return ira->codegen->invalid_instruction;
15201 }
15202 IrInstruction *alloca_gen;
15203 if (is_comptime && value != nullptr) {
15204 if (align > value->value.global_refs->align) {
15205 value->value.global_refs->align = align;
15206 }
15207 alloca_gen = ir_get_ref(ira, result_loc->source_instruction, value, true, false);
15208 } else {
15209 alloca_gen = ir_analyze_alloca(ira, result_loc->source_instruction, value_type, align,
15210 alloca_src->name_hint, force_comptime);
15211 }
15212 if (alloca_src->base.child != nullptr) {
15213 alloca_src->base.child->ref_count = 0;
15214 }
15215 alloca_src->base.child = alloca_gen;
15216 }
15217 result_loc->written = true;
15218 result_loc->resolved_loc = is_comptime ? nullptr : alloca_src->base.child;
15219 return result_loc->resolved_loc;
15220 }
15221 case ResultLocIdInstruction: {
15222 result_loc->written = true;
15223 result_loc->resolved_loc = result_loc->source_instruction->child;
15224 return result_loc->resolved_loc;
15225 }
15226 case ResultLocIdReturn: {
15227 if (!non_null_comptime) {
15228 bool is_comptime = value != nullptr && value->value.special != ConstValSpecialRuntime;
15229 if (is_comptime)
15230 return nullptr;
15231 }
15232 if ((err = type_resolve(ira->codegen, ira->explicit_return_type, ResolveStatusZeroBitsKnown))) {
15233 return ira->codegen->invalid_instruction;
15234 }
15235 if (!type_has_bits(ira->explicit_return_type) || !handle_is_ptr(ira->explicit_return_type))
15236 return nullptr;
15237
15238 ZigType *ptr_return_type = get_pointer_to_type(ira->codegen, ira->explicit_return_type, false);
15239 result_loc->written = true;
15240 result_loc->resolved_loc = ir_build_return_ptr(ira, result_loc->source_instruction, ptr_return_type);
15241 if (ir_should_inline(ira->old_irb.exec, result_loc->source_instruction->scope)) {
15242 set_up_result_loc_for_inferred_comptime(result_loc->resolved_loc);
15243 }
15244 return result_loc->resolved_loc;
15245 }
15246 case ResultLocIdPeer: {
15247 ResultLocPeer *result_peer = reinterpret_cast<ResultLocPeer *>(result_loc);
15248 ResultLocPeerParent *peer_parent = result_peer->parent;
15249
15250 if (peer_parent->peers.length == 1) {
15251 IrInstruction *parent_result_loc = ir_resolve_result(ira, suspend_source_instr, peer_parent->parent,
15252 value_type, value, force_runtime, non_null_comptime);
15253 result_peer->suspend_pos.basic_block_index = SIZE_MAX;
15254 result_peer->suspend_pos.instruction_index = SIZE_MAX;
15255 if (parent_result_loc == nullptr || type_is_invalid(parent_result_loc->value.type) ||
15256 parent_result_loc->value.type->id == ZigTypeIdUnreachable)
15257 {
15258 return parent_result_loc;
15259 }
15260 result_loc->written = true;
15261 result_loc->resolved_loc = parent_result_loc;
15262 return result_loc->resolved_loc;
15263 }
15264
15265 bool is_comptime;
15266 if (!ir_resolve_comptime(ira, peer_parent->is_comptime->child, &is_comptime))
15267 return ira->codegen->invalid_instruction;
15268 peer_parent->skipped = is_comptime;
15269 if (peer_parent->skipped) {
15270 if (non_null_comptime) {
15271 return ir_resolve_result(ira, suspend_source_instr, peer_parent->parent,
15272 value_type, value, force_runtime, non_null_comptime);
15273 }
15274 return nullptr;
15275 }
15276
15277 if (peer_parent->resolved_type == nullptr) {
15278 if (peer_parent->end_bb->suspend_instruction_ref == nullptr) {
15279 peer_parent->end_bb->suspend_instruction_ref = suspend_source_instr;
15280 }
15281 IrInstruction *unreach_inst = ira_suspend(ira, suspend_source_instr, result_peer->next_bb,
15282 &result_peer->suspend_pos);
15283 if (result_peer->next_bb == nullptr) {
15284 ir_start_next_bb(ira);
15285 }
15286 return unreach_inst;
15287 }
15288
15289 IrInstruction *parent_result_loc = ir_resolve_result(ira, suspend_source_instr, peer_parent->parent,
15290 peer_parent->resolved_type, nullptr, force_runtime, non_null_comptime);
15291 if (parent_result_loc == nullptr || type_is_invalid(parent_result_loc->value.type) ||
15292 parent_result_loc->value.type->id == ZigTypeIdUnreachable)
15293 {
15294 return parent_result_loc;
15295 }
15296 // because is_comptime is false, we mark this a runtime pointer
15297 parent_result_loc->value.special = ConstValSpecialRuntime;
15298 result_loc->written = true;
15299 result_loc->resolved_loc = parent_result_loc;
15300 return result_loc->resolved_loc;
15301 }
15302 case ResultLocIdBitCast: {
15303 ResultLocBitCast *result_bit_cast = reinterpret_cast<ResultLocBitCast *>(result_loc);
15304 ZigType *dest_type = ir_resolve_type(ira, result_bit_cast->base.source_instruction->child);
15305 if (type_is_invalid(dest_type))
15306 return ira->codegen->invalid_instruction;
15307
15308 if (get_codegen_ptr_type(dest_type) != nullptr) {
15309 ir_add_error(ira, result_loc->source_instruction,
15310 buf_sprintf("unable to @bitCast to pointer type '%s'", buf_ptr(&dest_type->name)));
15311 return ira->codegen->invalid_instruction;
15312 }
15313
15314 if (!type_can_bit_cast(dest_type)) {
15315 ir_add_error(ira, result_loc->source_instruction,
15316 buf_sprintf("unable to @bitCast to type '%s'", buf_ptr(&dest_type->name)));
15317 return ira->codegen->invalid_instruction;
15318 }
15319
15320 if (get_codegen_ptr_type(value_type) != nullptr) {
15321 ir_add_error(ira, suspend_source_instr,
15322 buf_sprintf("unable to @bitCast from pointer type '%s'", buf_ptr(&value_type->name)));
15323 return ira->codegen->invalid_instruction;
15324 }
15325
15326 if (!type_can_bit_cast(value_type)) {
15327 ir_add_error(ira, suspend_source_instr,
15328 buf_sprintf("unable to @bitCast from type '%s'", buf_ptr(&value_type->name)));
15329 return ira->codegen->invalid_instruction;
15330 }
15331
15332 IrInstruction *bitcasted_value;
15333 if (value != nullptr) {
15334 bitcasted_value = ir_analyze_bit_cast(ira, result_loc->source_instruction, value, dest_type);
15335 } else {
15336 bitcasted_value = nullptr;
15337 }
15338
15339 IrInstruction *parent_result_loc = ir_resolve_result(ira, suspend_source_instr, result_bit_cast->parent,
15340 dest_type, bitcasted_value, force_runtime, non_null_comptime);
15341 if (parent_result_loc == nullptr || type_is_invalid(parent_result_loc->value.type) ||
15342 parent_result_loc->value.type->id == ZigTypeIdUnreachable)
15343 {
15344 return parent_result_loc;
15345 }
15346 ZigType *parent_ptr_type = parent_result_loc->value.type;
15347 assert(parent_ptr_type->id == ZigTypeIdPointer);
15348 if ((err = type_resolve(ira->codegen, parent_ptr_type->data.pointer.child_type,
15349 ResolveStatusAlignmentKnown)))
15350 {
15351 return ira->codegen->invalid_instruction;
15352 }
15353 uint64_t parent_ptr_align = get_ptr_align(ira->codegen, parent_ptr_type);
15354 ZigType *ptr_type = get_pointer_to_type_extra(ira->codegen, value_type,
15355 parent_ptr_type->data.pointer.is_const, parent_ptr_type->data.pointer.is_volatile, PtrLenSingle,
15356 parent_ptr_align, 0, 0, parent_ptr_type->data.pointer.allow_zero);
15357
15358 result_loc->written = true;
15359 result_loc->resolved_loc = ir_analyze_ptr_cast(ira, suspend_source_instr, parent_result_loc,
15360 ptr_type, result_bit_cast->base.source_instruction, false);
15361 return result_loc->resolved_loc;
15362 }
15363 }
15364 zig_unreachable();
15365}
15366
15367static IrInstruction *ir_resolve_result(IrAnalyze *ira, IrInstruction *suspend_source_instr,
15368 ResultLoc *result_loc_pass1, ZigType *value_type, IrInstruction *value, bool force_runtime,
15369 bool non_null_comptime)
15370{
15371 IrInstruction *result_loc = ir_resolve_result_raw(ira, suspend_source_instr, result_loc_pass1, value_type,
15372 value, force_runtime, non_null_comptime);
15373 if (result_loc == nullptr || (instr_is_unreachable(result_loc) || type_is_invalid(result_loc->value.type)))
15374 return result_loc;
15375
15376 if ((force_runtime || (value != nullptr && !instr_is_comptime(value))) &&
15377 result_loc_pass1->written && result_loc->value.data.x_ptr.mut == ConstPtrMutInfer)
15378 {
15379 result_loc->value.special = ConstValSpecialRuntime;
15380 }
15381
15382 ir_assert(result_loc->value.type->id == ZigTypeIdPointer, suspend_source_instr);
15383 ZigType *actual_elem_type = result_loc->value.type->data.pointer.child_type;
15384 if (actual_elem_type->id == ZigTypeIdOptional && value_type->id != ZigTypeIdOptional &&
15385 value_type->id != ZigTypeIdNull)
15386 {
15387 return ir_analyze_unwrap_optional_payload(ira, suspend_source_instr, result_loc, false, true);
15388 } else if (actual_elem_type->id == ZigTypeIdErrorUnion && value_type->id != ZigTypeIdErrorUnion) {
15389 if (value_type->id == ZigTypeIdErrorSet) {
15390 return ir_analyze_unwrap_err_code(ira, suspend_source_instr, result_loc, true);
15391 } else {
15392 IrInstruction *unwrapped_err_ptr = ir_analyze_unwrap_error_payload(ira, suspend_source_instr,
15393 result_loc, false, true);
15394 ZigType *actual_payload_type = actual_elem_type->data.error_union.payload_type;
15395 if (actual_payload_type->id == ZigTypeIdOptional && value_type->id != ZigTypeIdOptional) {
15396 return ir_analyze_unwrap_optional_payload(ira, suspend_source_instr, unwrapped_err_ptr, false, true);
15397 } else {
15398 return unwrapped_err_ptr;
15399 }
15400 }
15401 } else if (is_slice(actual_elem_type) && value_type->id == ZigTypeIdArray) {
15402 // need to allow EndExpr to do the implicit cast from array to slice
15403 result_loc_pass1->written = false;
15404 }
15405 return result_loc;
15406}
15407
15408static IrInstruction *ir_analyze_instruction_implicit_cast(IrAnalyze *ira, IrInstructionImplicitCast *instruction) {
15409 ZigType *dest_type = ir_resolve_type(ira, instruction->dest_type->child);
15410 if (type_is_invalid(dest_type))
15411 return ira->codegen->invalid_instruction;
15412
15413 IrInstruction *target = instruction->target->child;
15414 if (type_is_invalid(target->value.type))
15415 return ira->codegen->invalid_instruction;
15416
15417 return ir_implicit_cast_with_result(ira, target, dest_type, instruction->result_loc);
15418}
15419
15420static IrInstruction *ir_analyze_instruction_resolve_result(IrAnalyze *ira, IrInstructionResolveResult *instruction) {
15421 ZigType *implicit_elem_type = ir_resolve_type(ira, instruction->ty->child);
15422 if (type_is_invalid(implicit_elem_type))
15423 return ira->codegen->invalid_instruction;
15424 IrInstruction *result_loc = ir_resolve_result(ira, &instruction->base, instruction->result_loc,
15425 implicit_elem_type, nullptr, false, true);
15426 if (result_loc != nullptr)
15427 return result_loc;
15428
15429 ZigFn *fn = exec_fn_entry(ira->new_irb.exec);
15430 if (fn != nullptr && fn->type_entry->data.fn.fn_type_id.cc == CallingConventionAsync &&
15431 instruction->result_loc->id == ResultLocIdReturn)
15432 {
15433 result_loc = ir_resolve_result(ira, &instruction->base, no_result_loc(),
15434 implicit_elem_type, nullptr, false, true);
15435 if (result_loc != nullptr &&
15436 (type_is_invalid(result_loc->value.type) || instr_is_unreachable(result_loc)))
15437 {
15438 return result_loc;
15439 }
15440 result_loc->value.special = ConstValSpecialRuntime;
15441 return result_loc;
15442 }
15443
15444 IrInstruction *result = ir_const(ira, &instruction->base, implicit_elem_type);
15445 result->value.special = ConstValSpecialUndef;
15446 IrInstruction *ptr = ir_get_ref(ira, &instruction->base, result, false, false);
15447 ptr->value.data.x_ptr.mut = ConstPtrMutComptimeVar;
15448 return ptr;
15449}
15450
15451static void ir_reset_result(ResultLoc *result_loc) {
15452 result_loc->written = false;
15453 result_loc->resolved_loc = nullptr;
15454 result_loc->gen_instruction = nullptr;
15455 result_loc->implicit_elem_type = nullptr;
15456 switch (result_loc->id) {
15457 case ResultLocIdInvalid:
15458 zig_unreachable();
15459 case ResultLocIdPeerParent: {
15460 ResultLocPeerParent *peer_parent = reinterpret_cast<ResultLocPeerParent *>(result_loc);
15461 peer_parent->skipped = false;
15462 peer_parent->done_resuming = false;
15463 peer_parent->resolved_type = nullptr;
15464 for (size_t i = 0; i < peer_parent->peers.length; i += 1) {
15465 ir_reset_result(&peer_parent->peers.at(i)->base);
15466 }
15467 break;
15468 }
15469 case ResultLocIdVar: {
15470 IrInstructionAllocaSrc *alloca_src =
15471 reinterpret_cast<IrInstructionAllocaSrc *>(result_loc->source_instruction);
15472 alloca_src->base.child = nullptr;
15473 break;
15474 }
15475 case ResultLocIdPeer:
15476 case ResultLocIdNone:
15477 case ResultLocIdReturn:
15478 case ResultLocIdInstruction:
15479 case ResultLocIdBitCast:
15480 break;
15481 }
15482}
15483
15484static IrInstruction *ir_analyze_instruction_reset_result(IrAnalyze *ira, IrInstructionResetResult *instruction) {
15485 ir_reset_result(instruction->result_loc);
15486 return ir_const_void(ira, &instruction->base);
15487}
15488
15489static IrInstruction *ir_analyze_async_call(IrAnalyze *ira, IrInstructionCallSrc *call_instruction, ZigFn *fn_entry,
14198 ZigType *fn_type, IrInstruction *fn_ref, IrInstruction **casted_args, size_t arg_count,15490 ZigType *fn_type, IrInstruction *fn_ref, IrInstruction **casted_args, size_t arg_count,
14199 IrInstruction *async_allocator_inst)15491 IrInstruction *async_allocator_inst)
14200{15492{
...@@ -14202,7 +15494,7 @@ static IrInstruction *ir_analyze_async_call(IrAnalyze *ira, IrInstructionCall *c...@@ -14202,7 +15494,7 @@ static IrInstruction *ir_analyze_async_call(IrAnalyze *ira, IrInstructionCall *c
14202 ir_assert(async_allocator_inst->value.type->id == ZigTypeIdPointer, &call_instruction->base);15494 ir_assert(async_allocator_inst->value.type->id == ZigTypeIdPointer, &call_instruction->base);
14203 ZigType *container_type = async_allocator_inst->value.type->data.pointer.child_type;15495 ZigType *container_type = async_allocator_inst->value.type->data.pointer.child_type;
14204 IrInstruction *field_ptr_inst = ir_analyze_container_field_ptr(ira, realloc_field_name, &call_instruction->base,15496 IrInstruction *field_ptr_inst = ir_analyze_container_field_ptr(ira, realloc_field_name, &call_instruction->base,
14205 async_allocator_inst, container_type);15497 async_allocator_inst, container_type, false);
14206 if (type_is_invalid(field_ptr_inst->value.type)) {15498 if (type_is_invalid(field_ptr_inst->value.type)) {
14207 return ira->codegen->invalid_instruction;15499 return ira->codegen->invalid_instruction;
14208 }15500 }
...@@ -14227,10 +15519,15 @@ static IrInstruction *ir_analyze_async_call(IrAnalyze *ira, IrInstructionCall *c...@@ -14227,10 +15519,15 @@ static IrInstruction *ir_analyze_async_call(IrAnalyze *ira, IrInstructionCall *c
14227 ZigType *promise_type = get_promise_type(ira->codegen, return_type);15519 ZigType *promise_type = get_promise_type(ira->codegen, return_type);
14228 ZigType *async_return_type = get_error_union_type(ira->codegen, alloc_fn_error_set_type, promise_type);15520 ZigType *async_return_type = get_error_union_type(ira->codegen, alloc_fn_error_set_type, promise_type);
1422915521
14230 IrInstruction *result = ir_build_call(&ira->new_irb, call_instruction->base.scope, call_instruction->base.source_node,15522 IrInstruction *result_loc = ir_resolve_result(ira, &call_instruction->base, no_result_loc(),
14231 fn_entry, fn_ref, arg_count, casted_args, false, FnInlineAuto, true, async_allocator_inst, nullptr);15523 async_return_type, nullptr, true, true);
14232 result->value.type = async_return_type;15524 if (type_is_invalid(result_loc->value.type) || instr_is_unreachable(result_loc)) {
14233 return result;15525 return result_loc;
15526 }
15527
15528 return ir_build_call_gen(ira, &call_instruction->base, fn_entry, fn_ref, arg_count,
15529 casted_args, FnInlineAuto, true, async_allocator_inst, nullptr, result_loc,
15530 async_return_type);
14234}15531}
1423515532
14236static bool ir_analyze_fn_call_inline_arg(IrAnalyze *ira, AstNode *fn_proto_node,15533static bool ir_analyze_fn_call_inline_arg(IrAnalyze *ira, AstNode *fn_proto_node,
...@@ -14253,7 +15550,7 @@ static bool ir_analyze_fn_call_inline_arg(IrAnalyze *ira, AstNode *fn_proto_node...@@ -14253,7 +15550,7 @@ static bool ir_analyze_fn_call_inline_arg(IrAnalyze *ira, AstNode *fn_proto_node
14253 casted_arg = arg;15550 casted_arg = arg;
14254 }15551 }
1425515552
14256 ConstExprValue *arg_val = ir_resolve_const(ira, casted_arg, UndefBad);15553 ConstExprValue *arg_val = ir_resolve_const(ira, casted_arg, UndefOk);
14257 if (!arg_val)15554 if (!arg_val)
14258 return false;15555 return false;
1425915556
...@@ -14309,7 +15606,7 @@ static bool ir_analyze_fn_call_generic_arg(IrAnalyze *ira, AstNode *fn_proto_nod...@@ -14309,7 +15606,7 @@ static bool ir_analyze_fn_call_generic_arg(IrAnalyze *ira, AstNode *fn_proto_nod
14309 arg_val = create_const_runtime(casted_arg->value.type);15606 arg_val = create_const_runtime(casted_arg->value.type);
14310 }15607 }
14311 if (arg_part_of_generic_id) {15608 if (arg_part_of_generic_id) {
14312 generic_id->params[generic_id->param_count] = *arg_val;15609 copy_const_val(&generic_id->params[generic_id->param_count], arg_val, true);
14313 generic_id->param_count += 1;15610 generic_id->param_count += 1;
14314 }15611 }
1431515612
...@@ -14480,7 +15777,9 @@ static IrInstruction *ir_analyze_store_ptr(IrAnalyze *ira, IrInstruction *source...@@ -14480,7 +15777,9 @@ static IrInstruction *ir_analyze_store_ptr(IrAnalyze *ira, IrInstruction *source
14480 ir_add_error(ira, source_instr, buf_sprintf("cannot assign to constant"));15777 ir_add_error(ira, source_instr, buf_sprintf("cannot assign to constant"));
14481 return ira->codegen->invalid_instruction;15778 return ira->codegen->invalid_instruction;
14482 }15779 }
14483 if (ptr->value.data.x_ptr.mut == ConstPtrMutComptimeVar) {15780 if (ptr->value.data.x_ptr.mut == ConstPtrMutComptimeVar ||
15781 ptr->value.data.x_ptr.mut == ConstPtrMutInfer)
15782 {
14484 if (instr_is_comptime(value)) {15783 if (instr_is_comptime(value)) {
14485 ConstExprValue *dest_val = const_ptr_pointee(ira, ira->codegen, &ptr->value, source_instr->source_node);15784 ConstExprValue *dest_val = const_ptr_pointee(ira, ira->codegen, &ptr->value, source_instr->source_node);
14486 if (dest_val == nullptr)15785 if (dest_val == nullptr)
...@@ -14494,18 +15793,24 @@ static IrInstruction *ir_analyze_store_ptr(IrAnalyze *ira, IrInstruction *source...@@ -14494,18 +15793,24 @@ static IrInstruction *ir_analyze_store_ptr(IrAnalyze *ira, IrInstruction *source
14494 // ConstPtrMutComptimeVar, thus defeating the logic below.15793 // ConstPtrMutComptimeVar, thus defeating the logic below.
14495 bool same_global_refs = ptr->value.data.x_ptr.mut != ConstPtrMutComptimeVar;15794 bool same_global_refs = ptr->value.data.x_ptr.mut != ConstPtrMutComptimeVar;
14496 copy_const_val(dest_val, &value->value, same_global_refs);15795 copy_const_val(dest_val, &value->value, same_global_refs);
14497 if (!ira->new_irb.current_basic_block->must_be_comptime_source_instr) {15796 if (ptr->value.data.x_ptr.mut == ConstPtrMutComptimeVar &&
15797 !ira->new_irb.current_basic_block->must_be_comptime_source_instr)
15798 {
14498 ira->new_irb.current_basic_block->must_be_comptime_source_instr = source_instr;15799 ira->new_irb.current_basic_block->must_be_comptime_source_instr = source_instr;
14499 }15800 }
14500 return ir_const_void(ira, source_instr);15801 return ir_const_void(ira, source_instr);
14501 }15802 }
14502 }15803 }
14503 ir_add_error(ira, source_instr,15804 if (ptr->value.data.x_ptr.mut == ConstPtrMutInfer) {
14504 buf_sprintf("cannot store runtime value in compile time variable"));15805 ptr->value.special = ConstValSpecialRuntime;
14505 ConstExprValue *dest_val = const_ptr_pointee_unchecked(ira->codegen, &ptr->value);15806 } else {
14506 dest_val->type = ira->codegen->builtin_types.entry_invalid;15807 ir_add_error(ira, source_instr,
15808 buf_sprintf("cannot store runtime value in compile time variable"));
15809 ConstExprValue *dest_val = const_ptr_pointee_unchecked(ira->codegen, &ptr->value);
15810 dest_val->type = ira->codegen->builtin_types.entry_invalid;
1450715811
14508 return ira->codegen->invalid_instruction;15812 return ira->codegen->invalid_instruction;
15813 }
14509 }15814 }
14510 }15815 }
1451115816
...@@ -14534,7 +15839,7 @@ static IrInstruction *ir_analyze_store_ptr(IrAnalyze *ira, IrInstruction *source...@@ -14534,7 +15839,7 @@ static IrInstruction *ir_analyze_store_ptr(IrAnalyze *ira, IrInstruction *source
14534 return result;15839 return result;
14535}15840}
1453615841
14537static IrInstruction *ir_analyze_fn_call(IrAnalyze *ira, IrInstructionCall *call_instruction,15842static IrInstruction *ir_analyze_fn_call(IrAnalyze *ira, IrInstructionCallSrc *call_instruction,
14538 ZigFn *fn_entry, ZigType *fn_type, IrInstruction *fn_ref,15843 ZigFn *fn_entry, ZigType *fn_type, IrInstruction *fn_ref,
14539 IrInstruction *first_arg_ptr, bool comptime_fn_call, FnInline fn_inline)15844 IrInstruction *first_arg_ptr, bool comptime_fn_call, FnInline fn_inline)
14540{15845{
...@@ -14637,7 +15942,7 @@ static IrInstruction *ir_analyze_fn_call(IrAnalyze *ira, IrInstructionCall *call...@@ -14637,7 +15942,7 @@ static IrInstruction *ir_analyze_fn_call(IrAnalyze *ira, IrInstructionCall *call
14637 if (!first_arg_known_bare && handle_is_ptr(first_arg_ptr->value.type->data.pointer.child_type)) {15942 if (!first_arg_known_bare && handle_is_ptr(first_arg_ptr->value.type->data.pointer.child_type)) {
14638 first_arg = first_arg_ptr;15943 first_arg = first_arg_ptr;
14639 } else {15944 } else {
14640 first_arg = ir_get_deref(ira, first_arg_ptr, first_arg_ptr);15945 first_arg = ir_get_deref(ira, first_arg_ptr, first_arg_ptr, nullptr);
14641 if (type_is_invalid(first_arg->value.type))15946 if (type_is_invalid(first_arg->value.type))
14642 return ira->codegen->invalid_instruction;15947 return ira->codegen->invalid_instruction;
14643 }15948 }
...@@ -14796,7 +16101,7 @@ static IrInstruction *ir_analyze_fn_call(IrAnalyze *ira, IrInstructionCall *call...@@ -14796,7 +16101,7 @@ static IrInstruction *ir_analyze_fn_call(IrAnalyze *ira, IrInstructionCall *call
14796 if (!first_arg_known_bare && handle_is_ptr(first_arg_ptr->value.type->data.pointer.child_type)) {16101 if (!first_arg_known_bare && handle_is_ptr(first_arg_ptr->value.type->data.pointer.child_type)) {
14797 first_arg = first_arg_ptr;16102 first_arg = first_arg_ptr;
14798 } else {16103 } else {
14799 first_arg = ir_get_deref(ira, first_arg_ptr, first_arg_ptr);16104 first_arg = ir_get_deref(ira, first_arg_ptr, first_arg_ptr, nullptr);
14800 if (type_is_invalid(first_arg->value.type))16105 if (type_is_invalid(first_arg->value.type))
14801 return ira->codegen->invalid_instruction;16106 return ira->codegen->invalid_instruction;
14802 }16107 }
...@@ -14840,7 +16145,7 @@ static IrInstruction *ir_analyze_fn_call(IrAnalyze *ira, IrInstructionCall *call...@@ -14840,7 +16145,7 @@ static IrInstruction *ir_analyze_fn_call(IrAnalyze *ira, IrInstructionCall *call
14840 if (type_is_invalid(arg_var_ptr_inst->value.type))16145 if (type_is_invalid(arg_var_ptr_inst->value.type))
14841 return ira->codegen->invalid_instruction;16146 return ira->codegen->invalid_instruction;
1484216147
14843 IrInstruction *arg_tuple_arg = ir_get_deref(ira, arg, arg_var_ptr_inst);16148 IrInstruction *arg_tuple_arg = ir_get_deref(ira, arg, arg_var_ptr_inst, nullptr);
14844 if (type_is_invalid(arg_tuple_arg->value.type))16149 if (type_is_invalid(arg_tuple_arg->value.type))
14845 return ira->codegen->invalid_instruction;16150 return ira->codegen->invalid_instruction;
1484616151
...@@ -14889,7 +16194,7 @@ static IrInstruction *ir_analyze_fn_call(IrAnalyze *ira, IrInstructionCall *call...@@ -14889,7 +16194,7 @@ static IrInstruction *ir_analyze_fn_call(IrAnalyze *ira, IrInstructionCall *call
14889 nullptr, nullptr, fn_proto_node->data.fn_proto.align_expr, nullptr, ira->new_irb.exec, nullptr);16194 nullptr, nullptr, fn_proto_node->data.fn_proto.align_expr, nullptr, ira->new_irb.exec, nullptr);
14890 IrInstructionConst *const_instruction = ir_create_instruction<IrInstructionConst>(&ira->new_irb,16195 IrInstructionConst *const_instruction = ir_create_instruction<IrInstructionConst>(&ira->new_irb,
14891 impl_fn->child_scope, fn_proto_node->data.fn_proto.align_expr);16196 impl_fn->child_scope, fn_proto_node->data.fn_proto.align_expr);
14892 const_instruction->base.value = *align_result;16197 copy_const_val(&const_instruction->base.value, align_result, true);
1489316198
14894 uint32_t align_bytes = 0;16199 uint32_t align_bytes = 0;
14895 ir_resolve_align(ira, &const_instruction->base, &align_bytes);16200 ir_resolve_align(ira, &const_instruction->base, &align_bytes);
...@@ -14971,6 +16276,19 @@ static IrInstruction *ir_analyze_fn_call(IrAnalyze *ira, IrInstructionCall *call...@@ -14971,6 +16276,19 @@ static IrInstruction *ir_analyze_fn_call(IrAnalyze *ira, IrInstructionCall *call
14971 }16276 }
1497216277
14973 FnTypeId *impl_fn_type_id = &impl_fn->type_entry->data.fn.fn_type_id;16278 FnTypeId *impl_fn_type_id = &impl_fn->type_entry->data.fn.fn_type_id;
16279 IrInstruction *result_loc;
16280 if (handle_is_ptr(impl_fn_type_id->return_type)) {
16281 result_loc = ir_resolve_result(ira, &call_instruction->base, call_instruction->result_loc,
16282 impl_fn_type_id->return_type, nullptr, true, true);
16283 if (result_loc != nullptr && (type_is_invalid(result_loc->value.type) ||
16284 instr_is_unreachable(result_loc)))
16285 {
16286 return result_loc;
16287 }
16288 } else {
16289 result_loc = nullptr;
16290 }
16291
14974 if (fn_type_can_fail(impl_fn_type_id)) {16292 if (fn_type_can_fail(impl_fn_type_id)) {
14975 parent_fn_entry->calls_or_awaits_errorable_fn = true;16293 parent_fn_entry->calls_or_awaits_errorable_fn = true;
14976 }16294 }
...@@ -14979,18 +16297,14 @@ static IrInstruction *ir_analyze_fn_call(IrAnalyze *ira, IrInstructionCall *call...@@ -14979,18 +16297,14 @@ static IrInstruction *ir_analyze_fn_call(IrAnalyze *ira, IrInstructionCall *call
14979 if (call_instruction->is_async) {16297 if (call_instruction->is_async) {
14980 IrInstruction *result = ir_analyze_async_call(ira, call_instruction, impl_fn, impl_fn->type_entry,16298 IrInstruction *result = ir_analyze_async_call(ira, call_instruction, impl_fn, impl_fn->type_entry,
14981 fn_ref, casted_args, impl_param_count, async_allocator_inst);16299 fn_ref, casted_args, impl_param_count, async_allocator_inst);
14982 ir_add_alloca(ira, result, result->value.type);
14983 return ir_finish_anal(ira, result);16300 return ir_finish_anal(ira, result);
14984 }16301 }
1498516302
14986 assert(async_allocator_inst == nullptr);16303 assert(async_allocator_inst == nullptr);
14987 IrInstruction *new_call_instruction = ir_build_call(&ira->new_irb,16304 IrInstruction *new_call_instruction = ir_build_call_gen(ira, &call_instruction->base,
14988 call_instruction->base.scope, call_instruction->base.source_node,16305 impl_fn, nullptr, impl_param_count, casted_args, fn_inline,
14989 impl_fn, nullptr, impl_param_count, casted_args, false, fn_inline,16306 call_instruction->is_async, nullptr, casted_new_stack, result_loc,
14990 call_instruction->is_async, nullptr, casted_new_stack);16307 impl_fn_type_id->return_type);
14991 new_call_instruction->value.type = impl_fn_type_id->return_type;
14992
14993 ir_add_alloca(ira, new_call_instruction, impl_fn_type_id->return_type);
1499416308
14995 return ir_finish_anal(ira, new_call_instruction);16309 return ir_finish_anal(ira, new_call_instruction);
14996 }16310 }
...@@ -15018,7 +16332,7 @@ static IrInstruction *ir_analyze_fn_call(IrAnalyze *ira, IrInstructionCall *call...@@ -15018,7 +16332,7 @@ static IrInstruction *ir_analyze_fn_call(IrAnalyze *ira, IrInstructionCall *call
15018 {16332 {
15019 first_arg = first_arg_ptr;16333 first_arg = first_arg_ptr;
15020 } else {16334 } else {
15021 first_arg = ir_get_deref(ira, first_arg_ptr, first_arg_ptr);16335 first_arg = ir_get_deref(ira, first_arg_ptr, first_arg_ptr, nullptr);
15022 if (type_is_invalid(first_arg->value.type))16336 if (type_is_invalid(first_arg->value.type))
15023 return ira->codegen->invalid_instruction;16337 return ira->codegen->invalid_instruction;
15024 }16338 }
...@@ -15075,7 +16389,6 @@ static IrInstruction *ir_analyze_fn_call(IrAnalyze *ira, IrInstructionCall *call...@@ -15075,7 +16389,6 @@ static IrInstruction *ir_analyze_fn_call(IrAnalyze *ira, IrInstructionCall *call
1507516389
15076 IrInstruction *result = ir_analyze_async_call(ira, call_instruction, fn_entry, fn_type, fn_ref,16390 IrInstruction *result = ir_analyze_async_call(ira, call_instruction, fn_entry, fn_type, fn_ref,
15077 casted_args, call_param_count, async_allocator_inst);16391 casted_args, call_param_count, async_allocator_inst);
15078 ir_add_alloca(ira, result, result->value.type);
15079 return ir_finish_anal(ira, result);16392 return ir_finish_anal(ira, result);
15080 }16393 }
1508116394
...@@ -15085,15 +16398,24 @@ static IrInstruction *ir_analyze_fn_call(IrAnalyze *ira, IrInstructionCall *call...@@ -15085,15 +16398,24 @@ static IrInstruction *ir_analyze_fn_call(IrAnalyze *ira, IrInstructionCall *call
15085 return ira->codegen->invalid_instruction;16398 return ira->codegen->invalid_instruction;
15086 }16399 }
1508716400
15088 IrInstruction *new_call_instruction = ir_build_call(&ira->new_irb,16401 IrInstruction *result_loc;
15089 call_instruction->base.scope, call_instruction->base.source_node,16402 if (handle_is_ptr(return_type)) {
15090 fn_entry, fn_ref, call_param_count, casted_args, false, fn_inline, false, nullptr, casted_new_stack);16403 result_loc = ir_resolve_result(ira, &call_instruction->base, call_instruction->result_loc,
15091 new_call_instruction->value.type = return_type;16404 return_type, nullptr, true, true);
15092 ir_add_alloca(ira, new_call_instruction, return_type);16405 if (result_loc != nullptr && (type_is_invalid(result_loc->value.type) || instr_is_unreachable(result_loc))) {
16406 return result_loc;
16407 }
16408 } else {
16409 result_loc = nullptr;
16410 }
16411
16412 IrInstruction *new_call_instruction = ir_build_call_gen(ira, &call_instruction->base, fn_entry, fn_ref,
16413 call_param_count, casted_args, fn_inline, false, nullptr, casted_new_stack,
16414 result_loc, return_type);
15093 return ir_finish_anal(ira, new_call_instruction);16415 return ir_finish_anal(ira, new_call_instruction);
15094}16416}
1509516417
15096static IrInstruction *ir_analyze_instruction_call(IrAnalyze *ira, IrInstructionCall *call_instruction) {16418static IrInstruction *ir_analyze_instruction_call(IrAnalyze *ira, IrInstructionCallSrc *call_instruction) {
15097 IrInstruction *fn_ref = call_instruction->fn_ref->child;16419 IrInstruction *fn_ref = call_instruction->fn_ref->child;
15098 if (type_is_invalid(fn_ref->value.type))16420 if (type_is_invalid(fn_ref->value.type))
15099 return ira->codegen->invalid_instruction;16421 return ira->codegen->invalid_instruction;
...@@ -15117,7 +16439,8 @@ static IrInstruction *ir_analyze_instruction_call(IrAnalyze *ira, IrInstructionC...@@ -15117,7 +16439,8 @@ static IrInstruction *ir_analyze_instruction_call(IrAnalyze *ira, IrInstructionC
1511716439
15118 IrInstruction *arg = call_instruction->args[0]->child;16440 IrInstruction *arg = call_instruction->args[0]->child;
1511916441
15120 IrInstruction *cast_instruction = ir_analyze_cast(ira, &call_instruction->base, dest_type, arg);16442 IrInstruction *cast_instruction = ir_analyze_cast(ira, &call_instruction->base, dest_type, arg,
16443 call_instruction->result_loc);
15121 if (type_is_invalid(cast_instruction->value.type))16444 if (type_is_invalid(cast_instruction->value.type))
15122 return ira->codegen->invalid_instruction;16445 return ira->codegen->invalid_instruction;
15123 return ir_finish_anal(ira, cast_instruction);16446 return ir_finish_anal(ira, cast_instruction);
...@@ -15170,7 +16493,7 @@ static Error ir_read_const_ptr(IrAnalyze *ira, CodeGen *codegen, AstNode *source...@@ -15170,7 +16493,7 @@ static Error ir_read_const_ptr(IrAnalyze *ira, CodeGen *codegen, AstNode *source
1517016493
15171 if (dst_size <= src_size) {16494 if (dst_size <= src_size) {
15172 if (src_size == dst_size && types_have_same_zig_comptime_repr(pointee->type, out_val->type)) {16495 if (src_size == dst_size && types_have_same_zig_comptime_repr(pointee->type, out_val->type)) {
15173 copy_const_val(out_val, pointee, ptr_val->data.x_ptr.mut == ConstPtrMutComptimeConst);16496 copy_const_val(out_val, pointee, ptr_val->data.x_ptr.mut != ConstPtrMutComptimeVar);
15174 return ErrorNone;16497 return ErrorNone;
15175 }16498 }
15176 Buf buf = BUF_INIT;16499 Buf buf = BUF_INIT;
...@@ -15419,7 +16742,7 @@ static IrInstruction *ir_analyze_instruction_un_op(IrAnalyze *ira, IrInstruction...@@ -15419,7 +16742,7 @@ static IrInstruction *ir_analyze_instruction_un_op(IrAnalyze *ira, IrInstruction
15419 return ira->codegen->invalid_instruction;16742 return ira->codegen->invalid_instruction;
15420 }16743 }
1542116744
15422 IrInstruction *result = ir_get_deref(ira, &instruction->base, ptr);16745 IrInstruction *result = ir_get_deref(ira, &instruction->base, ptr, instruction->result_loc);
15423 if (result == ira->codegen->invalid_instruction)16746 if (result == ira->codegen->invalid_instruction)
15424 return ira->codegen->invalid_instruction;16747 return ira->codegen->invalid_instruction;
1542516748
...@@ -15438,6 +16761,19 @@ static IrInstruction *ir_analyze_instruction_un_op(IrAnalyze *ira, IrInstruction...@@ -15438,6 +16761,19 @@ static IrInstruction *ir_analyze_instruction_un_op(IrAnalyze *ira, IrInstruction
15438 zig_unreachable();16761 zig_unreachable();
15439}16762}
1544016763
16764static void ir_push_resume(IrAnalyze *ira, IrSuspendPosition pos) {
16765 IrBasicBlock *old_bb = ira->old_irb.exec->basic_block_list.at(pos.basic_block_index);
16766 if (old_bb->in_resume_stack) return;
16767 ira->resume_stack.append(pos);
16768 old_bb->in_resume_stack = true;
16769}
16770
16771static void ir_push_resume_block(IrAnalyze *ira, IrBasicBlock *old_bb) {
16772 if (ira->resume_stack.length != 0) {
16773 ir_push_resume(ira, {old_bb->index, 0});
16774 }
16775}
16776
15441static IrInstruction *ir_analyze_instruction_br(IrAnalyze *ira, IrInstructionBr *br_instruction) {16777static IrInstruction *ir_analyze_instruction_br(IrAnalyze *ira, IrInstructionBr *br_instruction) {
15442 IrBasicBlock *old_dest_block = br_instruction->dest_block;16778 IrBasicBlock *old_dest_block = br_instruction->dest_block;
1544316779
...@@ -15445,13 +16781,15 @@ static IrInstruction *ir_analyze_instruction_br(IrAnalyze *ira, IrInstructionBr...@@ -15445,13 +16781,15 @@ static IrInstruction *ir_analyze_instruction_br(IrAnalyze *ira, IrInstructionBr
15445 if (!ir_resolve_comptime(ira, br_instruction->is_comptime->child, &is_comptime))16781 if (!ir_resolve_comptime(ira, br_instruction->is_comptime->child, &is_comptime))
15446 return ir_unreach_error(ira);16782 return ir_unreach_error(ira);
1544716783
15448 if (is_comptime || old_dest_block->ref_count == 1)16784 if (is_comptime || (old_dest_block->ref_count == 1 && old_dest_block->suspend_instruction_ref == nullptr))
15449 return ir_inline_bb(ira, &br_instruction->base, old_dest_block);16785 return ir_inline_bb(ira, &br_instruction->base, old_dest_block);
1545016786
15451 IrBasicBlock *new_bb = ir_get_new_bb_runtime(ira, old_dest_block, &br_instruction->base);16787 IrBasicBlock *new_bb = ir_get_new_bb_runtime(ira, old_dest_block, &br_instruction->base);
15452 if (new_bb == nullptr)16788 if (new_bb == nullptr)
15453 return ir_unreach_error(ira);16789 return ir_unreach_error(ira);
1545416790
16791 ir_push_resume_block(ira, old_dest_block);
16792
15455 IrInstruction *result = ir_build_br(&ira->new_irb,16793 IrInstruction *result = ir_build_br(&ira->new_irb,
15456 br_instruction->base.scope, br_instruction->base.source_node, new_bb, nullptr);16794 br_instruction->base.scope, br_instruction->base.source_node, new_bb, nullptr);
15457 result->value.type = ira->codegen->builtin_types.entry_unreachable;16795 result->value.type = ira->codegen->builtin_types.entry_unreachable;
...@@ -15480,13 +16818,15 @@ static IrInstruction *ir_analyze_instruction_cond_br(IrAnalyze *ira, IrInstructi...@@ -15480,13 +16818,15 @@ static IrInstruction *ir_analyze_instruction_cond_br(IrAnalyze *ira, IrInstructi
15480 IrBasicBlock *old_dest_block = cond_is_true ?16818 IrBasicBlock *old_dest_block = cond_is_true ?
15481 cond_br_instruction->then_block : cond_br_instruction->else_block;16819 cond_br_instruction->then_block : cond_br_instruction->else_block;
1548216820
15483 if (is_comptime || old_dest_block->ref_count == 1)16821 if (is_comptime || (old_dest_block->ref_count == 1 && old_dest_block->suspend_instruction_ref == nullptr))
15484 return ir_inline_bb(ira, &cond_br_instruction->base, old_dest_block);16822 return ir_inline_bb(ira, &cond_br_instruction->base, old_dest_block);
1548516823
15486 IrBasicBlock *new_dest_block = ir_get_new_bb_runtime(ira, old_dest_block, &cond_br_instruction->base);16824 IrBasicBlock *new_dest_block = ir_get_new_bb_runtime(ira, old_dest_block, &cond_br_instruction->base);
15487 if (new_dest_block == nullptr)16825 if (new_dest_block == nullptr)
15488 return ir_unreach_error(ira);16826 return ir_unreach_error(ira);
1548916827
16828 ir_push_resume_block(ira, old_dest_block);
16829
15490 IrInstruction *result = ir_build_br(&ira->new_irb,16830 IrInstruction *result = ir_build_br(&ira->new_irb,
15491 cond_br_instruction->base.scope, cond_br_instruction->base.source_node, new_dest_block, nullptr);16831 cond_br_instruction->base.scope, cond_br_instruction->base.source_node, new_dest_block, nullptr);
15492 result->value.type = ira->codegen->builtin_types.entry_unreachable;16832 result->value.type = ira->codegen->builtin_types.entry_unreachable;
...@@ -15502,6 +16842,9 @@ static IrInstruction *ir_analyze_instruction_cond_br(IrAnalyze *ira, IrInstructi...@@ -15502,6 +16842,9 @@ static IrInstruction *ir_analyze_instruction_cond_br(IrAnalyze *ira, IrInstructi
15502 if (new_else_block == nullptr)16842 if (new_else_block == nullptr)
15503 return ir_unreach_error(ira);16843 return ir_unreach_error(ira);
1550416844
16845 ir_push_resume_block(ira, cond_br_instruction->else_block);
16846 ir_push_resume_block(ira, cond_br_instruction->then_block);
16847
15505 IrInstruction *result = ir_build_cond_br(&ira->new_irb,16848 IrInstruction *result = ir_build_cond_br(&ira->new_irb,
15506 cond_br_instruction->base.scope, cond_br_instruction->base.source_node,16849 cond_br_instruction->base.scope, cond_br_instruction->base.source_node,
15507 casted_condition, new_then_block, new_else_block, nullptr);16850 casted_condition, new_then_block, new_else_block, nullptr);
...@@ -15540,11 +16883,85 @@ static IrInstruction *ir_analyze_instruction_phi(IrAnalyze *ira, IrInstructionPh...@@ -15540,11 +16883,85 @@ static IrInstruction *ir_analyze_instruction_phi(IrAnalyze *ira, IrInstructionPh
15540 zig_unreachable();16883 zig_unreachable();
15541 }16884 }
1554216885
15543 ZigList<IrBasicBlock*> new_incoming_blocks = {0};16886 ResultLocPeerParent *peer_parent = phi_instruction->peer_parent;
15544 ZigList<IrInstruction*> new_incoming_values = {0};16887 if (peer_parent != nullptr && !peer_parent->skipped && !peer_parent->done_resuming &&
1554516888 peer_parent->peers.length >= 2)
15546 for (size_t i = 0; i < phi_instruction->incoming_count; i += 1) {16889 {
15547 IrBasicBlock *predecessor = phi_instruction->incoming_blocks[i];16890 if (peer_parent->resolved_type == nullptr) {
16891 IrInstruction **instructions = allocate<IrInstruction *>(peer_parent->peers.length);
16892 for (size_t i = 0; i < peer_parent->peers.length; i += 1) {
16893 ResultLocPeer *this_peer = peer_parent->peers.at(i);
16894
16895 IrInstruction *gen_instruction = this_peer->base.gen_instruction;
16896 if (gen_instruction == nullptr) {
16897 // unreachable instructions will cause implicit_elem_type to be null
16898 if (this_peer->base.implicit_elem_type == nullptr) {
16899 instructions[i] = ir_const_unreachable(ira, this_peer->base.source_instruction);
16900 } else {
16901 instructions[i] = ir_const(ira, this_peer->base.source_instruction,
16902 this_peer->base.implicit_elem_type);
16903 instructions[i]->value.special = ConstValSpecialRuntime;
16904 }
16905 } else {
16906 instructions[i] = gen_instruction;
16907 }
16908
16909 }
16910 ZigType *expected_type = ir_result_loc_expected_type(ira, &phi_instruction->base, peer_parent->parent);
16911 peer_parent->resolved_type = ir_resolve_peer_types(ira,
16912 peer_parent->base.source_instruction->source_node, expected_type, instructions,
16913 peer_parent->peers.length);
16914
16915 // the logic below assumes there are no instructions in the new current basic block yet
16916 ir_assert(ira->new_irb.current_basic_block->instruction_list.length == 0, &phi_instruction->base);
16917
16918 // In case resolving the parent activates a suspend, do it now
16919 IrInstruction *parent_result_loc = ir_resolve_result(ira, &phi_instruction->base, peer_parent->parent,
16920 peer_parent->resolved_type, nullptr, false, false);
16921 if (parent_result_loc != nullptr &&
16922 (type_is_invalid(parent_result_loc->value.type) || instr_is_unreachable(parent_result_loc)))
16923 {
16924 return parent_result_loc;
16925 }
16926 // If the above code generated any instructions in the current basic block, we need
16927 // to move them to the peer parent predecessor.
16928 ZigList<IrInstruction *> instrs_to_move = {};
16929 while (ira->new_irb.current_basic_block->instruction_list.length != 0) {
16930 instrs_to_move.append(ira->new_irb.current_basic_block->instruction_list.pop());
16931 }
16932 if (instrs_to_move.length != 0) {
16933 IrBasicBlock *predecessor = peer_parent->base.source_instruction->child->owner_bb;
16934 IrInstruction *branch_instruction = predecessor->instruction_list.pop();
16935 ir_assert(branch_instruction->value.type->id == ZigTypeIdUnreachable, &phi_instruction->base);
16936 while (instrs_to_move.length != 0) {
16937 predecessor->instruction_list.append(instrs_to_move.pop());
16938 }
16939 predecessor->instruction_list.append(branch_instruction);
16940 }
16941 }
16942
16943 IrSuspendPosition suspend_pos;
16944 ira_suspend(ira, &phi_instruction->base, nullptr, &suspend_pos);
16945 ir_push_resume(ira, suspend_pos);
16946
16947 for (size_t i = 0; i < peer_parent->peers.length; i += 1) {
16948 ResultLocPeer *opposite_peer = peer_parent->peers.at(peer_parent->peers.length - i - 1);
16949 if (opposite_peer->base.implicit_elem_type != nullptr &&
16950 opposite_peer->base.implicit_elem_type->id != ZigTypeIdUnreachable)
16951 {
16952 ir_push_resume(ira, opposite_peer->suspend_pos);
16953 }
16954 }
16955
16956 peer_parent->done_resuming = true;
16957 return ira_resume(ira);
16958 }
16959
16960 ZigList<IrBasicBlock*> new_incoming_blocks = {0};
16961 ZigList<IrInstruction*> new_incoming_values = {0};
16962
16963 for (size_t i = 0; i < phi_instruction->incoming_count; i += 1) {
16964 IrBasicBlock *predecessor = phi_instruction->incoming_blocks[i];
15548 if (predecessor->ref_count == 0)16965 if (predecessor->ref_count == 0)
15549 continue;16966 continue;
1555016967
...@@ -15612,7 +17029,7 @@ static IrInstruction *ir_analyze_instruction_phi(IrAnalyze *ira, IrInstructionPh...@@ -15612,7 +17029,7 @@ static IrInstruction *ir_analyze_instruction_phi(IrAnalyze *ira, IrInstructionPh
15612 IrInstruction *branch_instruction = predecessor->instruction_list.pop();17029 IrInstruction *branch_instruction = predecessor->instruction_list.pop();
15613 ir_set_cursor_at_end(&ira->new_irb, predecessor);17030 ir_set_cursor_at_end(&ira->new_irb, predecessor);
15614 IrInstruction *casted_value = ir_implicit_cast(ira, new_value, resolved_type);17031 IrInstruction *casted_value = ir_implicit_cast(ira, new_value, resolved_type);
15615 if (casted_value == ira->codegen->invalid_instruction) {17032 if (type_is_invalid(casted_value->value.type)) {
15616 return ira->codegen->invalid_instruction;17033 return ira->codegen->invalid_instruction;
15617 }17034 }
15618 new_incoming_values.items[i] = casted_value;17035 new_incoming_values.items[i] = casted_value;
...@@ -15628,7 +17045,7 @@ static IrInstruction *ir_analyze_instruction_phi(IrAnalyze *ira, IrInstructionPh...@@ -15628,7 +17045,7 @@ static IrInstruction *ir_analyze_instruction_phi(IrAnalyze *ira, IrInstructionPh
1562817045
15629 IrInstruction *result = ir_build_phi(&ira->new_irb,17046 IrInstruction *result = ir_build_phi(&ira->new_irb,
15630 phi_instruction->base.scope, phi_instruction->base.source_node,17047 phi_instruction->base.scope, phi_instruction->base.source_node,
15631 new_incoming_blocks.length, new_incoming_blocks.items, new_incoming_values.items);17048 new_incoming_blocks.length, new_incoming_blocks.items, new_incoming_values.items, nullptr);
15632 result->value.type = resolved_type;17049 result->value.type = resolved_type;
1563317050
15634 if (all_stack_ptrs) {17051 if (all_stack_ptrs) {
...@@ -15846,6 +17263,48 @@ static IrInstruction *ir_analyze_instruction_elem_ptr(IrAnalyze *ira, IrInstruct...@@ -15846,6 +17263,48 @@ static IrInstruction *ir_analyze_instruction_elem_ptr(IrAnalyze *ira, IrInstruct
15846 if (array_ptr_val == nullptr)17263 if (array_ptr_val == nullptr)
15847 return ira->codegen->invalid_instruction;17264 return ira->codegen->invalid_instruction;
1584817265
17266 if (array_ptr_val->special == ConstValSpecialUndef && elem_ptr_instruction->init_array_type != nullptr) {
17267 if (array_type->id == ZigTypeIdArray) {
17268 array_ptr_val->data.x_array.special = ConstArraySpecialNone;
17269 array_ptr_val->data.x_array.data.s_none.elements = create_const_vals(array_type->data.array.len);
17270 array_ptr_val->special = ConstValSpecialStatic;
17271 for (size_t i = 0; i < array_type->data.array.len; i += 1) {
17272 ConstExprValue *elem_val = &array_ptr_val->data.x_array.data.s_none.elements[i];
17273 elem_val->special = ConstValSpecialUndef;
17274 elem_val->type = array_type->data.array.child_type;
17275 elem_val->parent.id = ConstParentIdArray;
17276 elem_val->parent.data.p_array.array_val = array_ptr_val;
17277 elem_val->parent.data.p_array.elem_index = i;
17278 }
17279 } else if (is_slice(array_type)) {
17280 ZigType *actual_array_type = ir_resolve_type(ira, elem_ptr_instruction->init_array_type->child);
17281 if (type_is_invalid(actual_array_type))
17282 return ira->codegen->invalid_instruction;
17283 assert(actual_array_type->id == ZigTypeIdArray);
17284
17285 ConstExprValue *array_init_val = create_const_vals(1);
17286 array_init_val->special = ConstValSpecialStatic;
17287 array_init_val->type = actual_array_type;
17288 array_init_val->data.x_array.special = ConstArraySpecialNone;
17289 array_init_val->data.x_array.data.s_none.elements = create_const_vals(actual_array_type->data.array.len);
17290 array_init_val->special = ConstValSpecialStatic;
17291 for (size_t i = 0; i < actual_array_type->data.array.len; i += 1) {
17292 ConstExprValue *elem_val = &array_init_val->data.x_array.data.s_none.elements[i];
17293 elem_val->special = ConstValSpecialUndef;
17294 elem_val->type = actual_array_type->data.array.child_type;
17295 elem_val->parent.id = ConstParentIdArray;
17296 elem_val->parent.data.p_array.array_val = array_init_val;
17297 elem_val->parent.data.p_array.elem_index = i;
17298 }
17299
17300 init_const_slice(ira->codegen, array_ptr_val, array_init_val, 0, actual_array_type->data.array.len,
17301 false);
17302 array_ptr_val->data.x_struct.fields[slice_ptr_index].data.x_ptr.mut = ConstPtrMutInfer;
17303 } else {
17304 zig_unreachable();
17305 }
17306 }
17307
15849 if (array_ptr_val->special != ConstValSpecialRuntime &&17308 if (array_ptr_val->special != ConstValSpecialRuntime &&
15850 (array_type->id != ZigTypeIdPointer ||17309 (array_type->id != ZigTypeIdPointer ||
15851 array_ptr_val->data.x_ptr.special != ConstPtrSpecialHardCodedAddr))17310 array_ptr_val->data.x_ptr.special != ConstPtrSpecialHardCodedAddr))
...@@ -15911,8 +17370,9 @@ static IrInstruction *ir_analyze_instruction_elem_ptr(IrAnalyze *ira, IrInstruct...@@ -15911,8 +17370,9 @@ static IrInstruction *ir_analyze_instruction_elem_ptr(IrAnalyze *ira, IrInstruct
15911 } else if (is_slice(array_type)) {17370 } else if (is_slice(array_type)) {
15912 ConstExprValue *ptr_field = &array_ptr_val->data.x_struct.fields[slice_ptr_index];17371 ConstExprValue *ptr_field = &array_ptr_val->data.x_struct.fields[slice_ptr_index];
15913 if (ptr_field->data.x_ptr.special == ConstPtrSpecialHardCodedAddr) {17372 if (ptr_field->data.x_ptr.special == ConstPtrSpecialHardCodedAddr) {
15914 IrInstruction *result = ir_build_elem_ptr(&ira->new_irb, elem_ptr_instruction->base.scope, elem_ptr_instruction->base.source_node,17373 IrInstruction *result = ir_build_elem_ptr(&ira->new_irb, elem_ptr_instruction->base.scope,
15915 array_ptr, casted_elem_index, false, elem_ptr_instruction->ptr_len);17374 elem_ptr_instruction->base.source_node, array_ptr, casted_elem_index, false,
17375 elem_ptr_instruction->ptr_len, nullptr);
15916 result->value.type = return_type;17376 result->value.type = return_type;
15917 return result;17377 return result;
15918 }17378 }
...@@ -15965,7 +17425,16 @@ static IrInstruction *ir_analyze_instruction_elem_ptr(IrAnalyze *ira, IrInstruct...@@ -15965,7 +17425,16 @@ static IrInstruction *ir_analyze_instruction_elem_ptr(IrAnalyze *ira, IrInstruct
15965 }17425 }
15966 return result;17426 return result;
15967 } else if (array_type->id == ZigTypeIdArray) {17427 } else if (array_type->id == ZigTypeIdArray) {
15968 IrInstruction *result = ir_const(ira, &elem_ptr_instruction->base, return_type);17428 IrInstruction *result;
17429 if (orig_array_ptr_val->data.x_ptr.mut == ConstPtrMutInfer) {
17430 result = ir_build_elem_ptr(&ira->new_irb, elem_ptr_instruction->base.scope,
17431 elem_ptr_instruction->base.source_node, array_ptr, casted_elem_index,
17432 false, elem_ptr_instruction->ptr_len, elem_ptr_instruction->init_array_type);
17433 result->value.type = return_type;
17434 result->value.special = ConstValSpecialStatic;
17435 } else {
17436 result = ir_const(ira, &elem_ptr_instruction->base, return_type);
17437 }
15969 ConstExprValue *out_val = &result->value;17438 ConstExprValue *out_val = &result->value;
15970 out_val->data.x_ptr.special = ConstPtrSpecialBaseArray;17439 out_val->data.x_ptr.special = ConstPtrSpecialBaseArray;
15971 out_val->data.x_ptr.mut = orig_array_ptr_val->data.x_ptr.mut;17440 out_val->data.x_ptr.mut = orig_array_ptr_val->data.x_ptr.mut;
...@@ -15977,7 +17446,6 @@ static IrInstruction *ir_analyze_instruction_elem_ptr(IrAnalyze *ira, IrInstruct...@@ -15977,7 +17446,6 @@ static IrInstruction *ir_analyze_instruction_elem_ptr(IrAnalyze *ira, IrInstruct
15977 }17446 }
15978 }17447 }
15979 }17448 }
15980
15981 } else {17449 } else {
15982 // runtime known element index17450 // runtime known element index
15983 switch (type_requires_comptime(ira->codegen, return_type)) {17451 switch (type_requires_comptime(ira->codegen, return_type)) {
...@@ -16003,8 +17471,9 @@ static IrInstruction *ir_analyze_instruction_elem_ptr(IrAnalyze *ira, IrInstruct...@@ -16003,8 +17471,9 @@ static IrInstruction *ir_analyze_instruction_elem_ptr(IrAnalyze *ira, IrInstruct
16003 }17471 }
16004 }17472 }
1600517473
16006 IrInstruction *result = ir_build_elem_ptr(&ira->new_irb, elem_ptr_instruction->base.scope, elem_ptr_instruction->base.source_node,17474 IrInstruction *result = ir_build_elem_ptr(&ira->new_irb, elem_ptr_instruction->base.scope,
16007 array_ptr, casted_elem_index, safety_check_on, elem_ptr_instruction->ptr_len);17475 elem_ptr_instruction->base.source_node, array_ptr, casted_elem_index, safety_check_on,
17476 elem_ptr_instruction->ptr_len, elem_ptr_instruction->init_array_type);
16008 result->value.type = return_type;17477 result->value.type = return_type;
16009 return result;17478 return result;
16010}17479}
...@@ -16049,8 +17518,80 @@ static IrInstruction *ir_analyze_container_member_access_inner(IrAnalyze *ira,...@@ -16049,8 +17518,80 @@ static IrInstruction *ir_analyze_container_member_access_inner(IrAnalyze *ira,
16049 return ira->codegen->invalid_instruction;17518 return ira->codegen->invalid_instruction;
16050}17519}
1605117520
17521static IrInstruction *ir_analyze_struct_field_ptr(IrAnalyze *ira, IrInstruction *source_instr,
17522 TypeStructField *field, IrInstruction *struct_ptr, ZigType *struct_type, bool initializing)
17523{
17524 switch (type_has_one_possible_value(ira->codegen, field->type_entry)) {
17525 case OnePossibleValueInvalid:
17526 return ira->codegen->invalid_instruction;
17527 case OnePossibleValueYes: {
17528 IrInstruction *elem = ir_const(ira, source_instr, field->type_entry);
17529 return ir_get_ref(ira, source_instr, elem, false, false);
17530 }
17531 case OnePossibleValueNo:
17532 break;
17533 }
17534 assert(struct_ptr->value.type->id == ZigTypeIdPointer);
17535 bool is_packed = (struct_type->data.structure.layout == ContainerLayoutPacked);
17536 uint32_t align_bytes = is_packed ? 1 : get_abi_alignment(ira->codegen, field->type_entry);
17537 uint32_t ptr_bit_offset = struct_ptr->value.type->data.pointer.bit_offset_in_host;
17538 uint32_t ptr_host_int_bytes = struct_ptr->value.type->data.pointer.host_int_bytes;
17539 uint32_t host_int_bytes_for_result_type = (ptr_host_int_bytes == 0) ?
17540 get_host_int_bytes(ira->codegen, struct_type, field) : ptr_host_int_bytes;
17541 bool is_const = struct_ptr->value.type->data.pointer.is_const;
17542 bool is_volatile = struct_ptr->value.type->data.pointer.is_volatile;
17543 ZigType *ptr_type = get_pointer_to_type_extra(ira->codegen, field->type_entry,
17544 is_const, is_volatile, PtrLenSingle, align_bytes,
17545 (uint32_t)(ptr_bit_offset + field->bit_offset_in_host),
17546 (uint32_t)host_int_bytes_for_result_type, false);
17547 if (instr_is_comptime(struct_ptr)) {
17548 ConstExprValue *ptr_val = ir_resolve_const(ira, struct_ptr, UndefBad);
17549 if (!ptr_val)
17550 return ira->codegen->invalid_instruction;
17551
17552 if (ptr_val->data.x_ptr.special != ConstPtrSpecialHardCodedAddr) {
17553 ConstExprValue *struct_val = const_ptr_pointee(ira, ira->codegen, ptr_val, source_instr->source_node);
17554 if (struct_val == nullptr)
17555 return ira->codegen->invalid_instruction;
17556 if (type_is_invalid(struct_val->type))
17557 return ira->codegen->invalid_instruction;
17558 if (struct_val->special == ConstValSpecialUndef && initializing) {
17559 struct_val->data.x_struct.fields = create_const_vals(struct_type->data.structure.src_field_count);
17560 struct_val->special = ConstValSpecialStatic;
17561 for (size_t i = 0; i < struct_type->data.structure.src_field_count; i += 1) {
17562 ConstExprValue *field_val = &struct_val->data.x_struct.fields[i];
17563 field_val->special = ConstValSpecialUndef;
17564 field_val->type = struct_type->data.structure.fields[i].type_entry;
17565 field_val->parent.id = ConstParentIdStruct;
17566 field_val->parent.data.p_struct.struct_val = struct_val;
17567 field_val->parent.data.p_struct.field_index = i;
17568 }
17569 }
17570 IrInstruction *result;
17571 if (ptr_val->data.x_ptr.mut == ConstPtrMutInfer) {
17572 result = ir_build_struct_field_ptr(&ira->new_irb, source_instr->scope,
17573 source_instr->source_node, struct_ptr, field);
17574 result->value.type = ptr_type;
17575 result->value.special = ConstValSpecialStatic;
17576 } else {
17577 result = ir_const(ira, source_instr, ptr_type);
17578 }
17579 ConstExprValue *const_val = &result->value;
17580 const_val->data.x_ptr.special = ConstPtrSpecialBaseStruct;
17581 const_val->data.x_ptr.mut = ptr_val->data.x_ptr.mut;
17582 const_val->data.x_ptr.data.base_struct.struct_val = struct_val;
17583 const_val->data.x_ptr.data.base_struct.field_index = field->src_index;
17584 return result;
17585 }
17586 }
17587 IrInstruction *result = ir_build_struct_field_ptr(&ira->new_irb, source_instr->scope, source_instr->source_node,
17588 struct_ptr, field);
17589 result->value.type = ptr_type;
17590 return result;
17591}
17592
16052static IrInstruction *ir_analyze_container_field_ptr(IrAnalyze *ira, Buf *field_name,17593static IrInstruction *ir_analyze_container_field_ptr(IrAnalyze *ira, Buf *field_name,
16053 IrInstruction *source_instr, IrInstruction *container_ptr, ZigType *container_type)17594 IrInstruction *source_instr, IrInstruction *container_ptr, ZigType *container_type, bool initializing)
16054{17595{
16055 Error err;17596 Error err;
1605617597
...@@ -16059,81 +17600,55 @@ static IrInstruction *ir_analyze_container_field_ptr(IrAnalyze *ira, Buf *field_...@@ -16059,81 +17600,55 @@ static IrInstruction *ir_analyze_container_field_ptr(IrAnalyze *ira, Buf *field_
16059 return ira->codegen->invalid_instruction;17600 return ira->codegen->invalid_instruction;
1606017601
16061 assert(container_ptr->value.type->id == ZigTypeIdPointer);17602 assert(container_ptr->value.type->id == ZigTypeIdPointer);
16062 bool is_const = container_ptr->value.type->data.pointer.is_const;
16063 bool is_volatile = container_ptr->value.type->data.pointer.is_volatile;
16064 if (bare_type->id == ZigTypeIdStruct) {17603 if (bare_type->id == ZigTypeIdStruct) {
16065 TypeStructField *field = find_struct_type_field(bare_type, field_name);17604 TypeStructField *field = find_struct_type_field(bare_type, field_name);
16066 if (field) {17605 if (field != nullptr) {
16067 switch (type_has_one_possible_value(ira->codegen, field->type_entry)) {17606 return ir_analyze_struct_field_ptr(ira, source_instr, field, container_ptr, bare_type, initializing);
16068 case OnePossibleValueInvalid:
16069 return ira->codegen->invalid_instruction;
16070 case OnePossibleValueYes: {
16071 IrInstruction *elem = ir_const(ira, source_instr, field->type_entry);
16072 return ir_get_ref(ira, source_instr, elem, false, false);
16073 }
16074 case OnePossibleValueNo:
16075 break;
16076 }
16077 bool is_packed = (bare_type->data.structure.layout == ContainerLayoutPacked);
16078 uint32_t align_bytes = is_packed ? 1 : get_abi_alignment(ira->codegen, field->type_entry);
16079 uint32_t ptr_bit_offset = container_ptr->value.type->data.pointer.bit_offset_in_host;
16080 uint32_t ptr_host_int_bytes = container_ptr->value.type->data.pointer.host_int_bytes;
16081 uint32_t host_int_bytes_for_result_type = (ptr_host_int_bytes == 0) ?
16082 get_host_int_bytes(ira->codegen, bare_type, field) : ptr_host_int_bytes;
16083 if (instr_is_comptime(container_ptr)) {
16084 ConstExprValue *ptr_val = ir_resolve_const(ira, container_ptr, UndefBad);
16085 if (!ptr_val)
16086 return ira->codegen->invalid_instruction;
16087
16088 if (ptr_val->data.x_ptr.special != ConstPtrSpecialHardCodedAddr) {
16089 ConstExprValue *struct_val = const_ptr_pointee(ira, ira->codegen, ptr_val, source_instr->source_node);
16090 if (struct_val == nullptr)
16091 return ira->codegen->invalid_instruction;
16092 if (type_is_invalid(struct_val->type))
16093 return ira->codegen->invalid_instruction;
16094 ZigType *ptr_type = get_pointer_to_type_extra(ira->codegen, field->type_entry,
16095 is_const, is_volatile, PtrLenSingle, align_bytes,
16096 (uint32_t)(ptr_bit_offset + field->bit_offset_in_host),
16097 (uint32_t)host_int_bytes_for_result_type, false);
16098 IrInstruction *result = ir_const(ira, source_instr, ptr_type);
16099 ConstExprValue *const_val = &result->value;
16100 const_val->data.x_ptr.special = ConstPtrSpecialBaseStruct;
16101 const_val->data.x_ptr.mut = container_ptr->value.data.x_ptr.mut;
16102 const_val->data.x_ptr.data.base_struct.struct_val = struct_val;
16103 const_val->data.x_ptr.data.base_struct.field_index = field->src_index;
16104 return result;
16105 }
16106 }
16107 IrInstruction *result = ir_build_struct_field_ptr(&ira->new_irb, source_instr->scope, source_instr->source_node,
16108 container_ptr, field);
16109 result->value.type = get_pointer_to_type_extra(ira->codegen, field->type_entry, is_const, is_volatile,
16110 PtrLenSingle,
16111 align_bytes,
16112 (uint32_t)(ptr_bit_offset + field->bit_offset_in_host),
16113 host_int_bytes_for_result_type, false);
16114 return result;
16115 } else {17607 } else {
16116 return ir_analyze_container_member_access_inner(ira, bare_type, field_name,17608 return ir_analyze_container_member_access_inner(ira, bare_type, field_name,
16117 source_instr, container_ptr, container_type);17609 source_instr, container_ptr, container_type);
16118 }17610 }
16119 } else if (bare_type->id == ZigTypeIdEnum) {17611 }
17612
17613 if (bare_type->id == ZigTypeIdEnum) {
16120 return ir_analyze_container_member_access_inner(ira, bare_type, field_name,17614 return ir_analyze_container_member_access_inner(ira, bare_type, field_name,
16121 source_instr, container_ptr, container_type);17615 source_instr, container_ptr, container_type);
16122 } else if (bare_type->id == ZigTypeIdUnion) {17616 }
17617
17618 if (bare_type->id == ZigTypeIdUnion) {
17619 bool is_const = container_ptr->value.type->data.pointer.is_const;
17620 bool is_volatile = container_ptr->value.type->data.pointer.is_volatile;
17621
16123 TypeUnionField *field = find_union_type_field(bare_type, field_name);17622 TypeUnionField *field = find_union_type_field(bare_type, field_name);
16124 if (field) {17623 if (field == nullptr) {
16125 if (instr_is_comptime(container_ptr)) {17624 return ir_analyze_container_member_access_inner(ira, bare_type, field_name,
16126 ConstExprValue *ptr_val = ir_resolve_const(ira, container_ptr, UndefBad);17625 source_instr, container_ptr, container_type);
16127 if (!ptr_val)17626 }
17627 ZigType *ptr_type = get_pointer_to_type_extra(ira->codegen, field->type_entry,
17628 is_const, is_volatile, PtrLenSingle, 0, 0, 0, false);
17629 if (instr_is_comptime(container_ptr)) {
17630 ConstExprValue *ptr_val = ir_resolve_const(ira, container_ptr, UndefBad);
17631 if (!ptr_val)
17632 return ira->codegen->invalid_instruction;
17633
17634 if (ptr_val->data.x_ptr.special != ConstPtrSpecialHardCodedAddr) {
17635 ConstExprValue *union_val = const_ptr_pointee(ira, ira->codegen, ptr_val, source_instr->source_node);
17636 if (union_val == nullptr)
17637 return ira->codegen->invalid_instruction;
17638 if (type_is_invalid(union_val->type))
16128 return ira->codegen->invalid_instruction;17639 return ira->codegen->invalid_instruction;
1612917640
16130 if (ptr_val->data.x_ptr.special != ConstPtrSpecialHardCodedAddr) {17641 if (initializing) {
16131 ConstExprValue *union_val = const_ptr_pointee(ira, ira->codegen, ptr_val, source_instr->source_node);17642 ConstExprValue *payload_val = create_const_vals(1);
16132 if (union_val == nullptr)17643 payload_val->special = ConstValSpecialUndef;
16133 return ira->codegen->invalid_instruction;17644 payload_val->type = field->type_entry;
16134 if (type_is_invalid(union_val->type))17645 payload_val->parent.id = ConstParentIdUnion;
16135 return ira->codegen->invalid_instruction;17646 payload_val->parent.data.p_union.union_val = union_val;
1613617647
17648 union_val->special = ConstValSpecialStatic;
17649 bigint_init_bigint(&union_val->data.x_union.tag, &field->enum_field->value);
17650 union_val->data.x_union.payload = payload_val;
17651 } else {
16137 TypeUnionField *actual_field = find_union_field_by_tag(bare_type, &union_val->data.x_union.tag);17652 TypeUnionField *actual_field = find_union_field_by_tag(bare_type, &union_val->data.x_union.tag);
16138 if (actual_field == nullptr)17653 if (actual_field == nullptr)
16139 zig_unreachable();17654 zig_unreachable();
...@@ -16144,33 +17659,35 @@ static IrInstruction *ir_analyze_container_field_ptr(IrAnalyze *ira, Buf *field_...@@ -16144,33 +17659,35 @@ static IrInstruction *ir_analyze_container_field_ptr(IrAnalyze *ira, Buf *field_
16144 buf_ptr(actual_field->name)));17659 buf_ptr(actual_field->name)));
16145 return ira->codegen->invalid_instruction;17660 return ira->codegen->invalid_instruction;
16146 }17661 }
17662 }
1614717663
16148 ConstExprValue *payload_val = union_val->data.x_union.payload;17664 ConstExprValue *payload_val = union_val->data.x_union.payload;
1614917665
16150 ZigType *field_type = field->type_entry;
16151 ZigType *ptr_type = get_pointer_to_type_extra(ira->codegen, field_type,
16152 is_const, is_volatile, PtrLenSingle, 0, 0, 0, false);
1615317666
16154 IrInstruction *result = ir_const(ira, source_instr, ptr_type);17667 IrInstruction *result;
16155 ConstExprValue *const_val = &result->value;17668 if (ptr_val->data.x_ptr.mut == ConstPtrMutInfer) {
16156 const_val->data.x_ptr.special = ConstPtrSpecialRef;17669 result = ir_build_union_field_ptr(&ira->new_irb, source_instr->scope,
16157 const_val->data.x_ptr.mut = container_ptr->value.data.x_ptr.mut;17670 source_instr->source_node, container_ptr, field, true, initializing);
16158 const_val->data.x_ptr.data.ref.pointee = payload_val;17671 result->value.type = ptr_type;
16159 return result;17672 result->value.special = ConstValSpecialStatic;
17673 } else {
17674 result = ir_const(ira, source_instr, ptr_type);
16160 }17675 }
17676 ConstExprValue *const_val = &result->value;
17677 const_val->data.x_ptr.special = ConstPtrSpecialRef;
17678 const_val->data.x_ptr.mut = container_ptr->value.data.x_ptr.mut;
17679 const_val->data.x_ptr.data.ref.pointee = payload_val;
17680 return result;
16161 }17681 }
16162
16163 IrInstruction *result = ir_build_union_field_ptr(&ira->new_irb, source_instr->scope, source_instr->source_node, container_ptr, field);
16164 result->value.type = get_pointer_to_type_extra(ira->codegen, field->type_entry, is_const, is_volatile,
16165 PtrLenSingle, 0, 0, 0, false);
16166 return result;
16167 } else {
16168 return ir_analyze_container_member_access_inner(ira, bare_type, field_name,
16169 source_instr, container_ptr, container_type);
16170 }17682 }
16171 } else {17683
16172 zig_unreachable();17684 IrInstruction *result = ir_build_union_field_ptr(&ira->new_irb, source_instr->scope,
17685 source_instr->source_node, container_ptr, field, true, initializing);
17686 result->value.type = ptr_type;
17687 return result;
16173 }17688 }
17689
17690 zig_unreachable();
16174}17691}
1617517692
16176static void add_link_lib_symbol(IrAnalyze *ira, Buf *lib_name, Buf *symbol_name, AstNode *source_node) {17693static void add_link_lib_symbol(IrAnalyze *ira, Buf *lib_name, Buf *symbol_name, AstNode *source_node) {
...@@ -16208,6 +17725,11 @@ static void add_link_lib_symbol(IrAnalyze *ira, Buf *lib_name, Buf *symbol_name,...@@ -16208,6 +17725,11 @@ static void add_link_lib_symbol(IrAnalyze *ira, Buf *lib_name, Buf *symbol_name,
16208 link_lib->symbols.append(symbol_name);17725 link_lib->symbols.append(symbol_name);
16209}17726}
1621017727
17728static IrInstruction *ir_error_dependency_loop(IrAnalyze *ira, IrInstruction *source_instr) {
17729 ErrorMsg *msg = ir_add_error(ira, source_instr, buf_sprintf("dependency loop detected"));
17730 emit_error_notes_for_ref_stack(ira->codegen, msg);
17731 return ira->codegen->invalid_instruction;
17732}
1621117733
16212static IrInstruction *ir_analyze_decl_ref(IrAnalyze *ira, IrInstruction *source_instruction, Tld *tld) {17734static IrInstruction *ir_analyze_decl_ref(IrAnalyze *ira, IrInstruction *source_instruction, Tld *tld) {
16213 resolve_top_level_decl(ira->codegen, tld, source_instruction->source_node);17735 resolve_top_level_decl(ira->codegen, tld, source_instruction->source_node);
...@@ -16222,6 +17744,9 @@ static IrInstruction *ir_analyze_decl_ref(IrAnalyze *ira, IrInstruction *source_...@@ -16222,6 +17744,9 @@ static IrInstruction *ir_analyze_decl_ref(IrAnalyze *ira, IrInstruction *source_
16222 {17744 {
16223 TldVar *tld_var = (TldVar *)tld;17745 TldVar *tld_var = (TldVar *)tld;
16224 ZigVar *var = tld_var->var;17746 ZigVar *var = tld_var->var;
17747 if (var == nullptr) {
17748 return ir_error_dependency_loop(ira, source_instruction);
17749 }
16225 if (tld_var->extern_lib_name != nullptr) {17750 if (tld_var->extern_lib_name != nullptr) {
16226 add_link_lib_symbol(ira, tld_var->extern_lib_name, &var->name, source_instruction->source_node);17751 add_link_lib_symbol(ira, tld_var->extern_lib_name, &var->name, source_instruction->source_node);
16227 }17752 }
...@@ -16237,23 +17762,13 @@ static IrInstruction *ir_analyze_decl_ref(IrAnalyze *ira, IrInstruction *source_...@@ -16237,23 +17762,13 @@ static IrInstruction *ir_analyze_decl_ref(IrAnalyze *ira, IrInstruction *source_
16237 if (type_is_invalid(fn_entry->type_entry))17762 if (type_is_invalid(fn_entry->type_entry))
16238 return ira->codegen->invalid_instruction;17763 return ira->codegen->invalid_instruction;
1623917764
16240 // TODO instead of allocating this every time, put it in the tld value and we can reference
16241 // the same one every time
16242 ConstExprValue *const_val = create_const_vals(1);
16243 const_val->special = ConstValSpecialStatic;
16244 const_val->type = fn_entry->type_entry;
16245 const_val->data.x_ptr.data.fn.fn_entry = fn_entry;
16246 const_val->data.x_ptr.special = ConstPtrSpecialFunction;
16247 const_val->data.x_ptr.mut = ConstPtrMutComptimeConst;
16248
16249 if (tld_fn->extern_lib_name != nullptr) {17765 if (tld_fn->extern_lib_name != nullptr) {
16250 add_link_lib_symbol(ira, tld_fn->extern_lib_name, &fn_entry->symbol_name, source_instruction->source_node);17766 add_link_lib_symbol(ira, tld_fn->extern_lib_name, &fn_entry->symbol_name, source_instruction->source_node);
16251 }17767 }
1625217768
16253 bool ptr_is_const = true;17769 IrInstruction *fn_inst = ir_create_const_fn(&ira->new_irb, source_instruction->scope,
16254 bool ptr_is_volatile = false;17770 source_instruction->source_node, fn_entry);
16255 return ir_get_const_ptr(ira, source_instruction, const_val, fn_entry->type_entry,17771 return ir_get_ref(ira, source_instruction, fn_inst, true, false);
16256 ConstPtrMutComptimeConst, ptr_is_const, ptr_is_volatile, 0);
16257 }17772 }
16258 }17773 }
16259 zig_unreachable();17774 zig_unreachable();
...@@ -16295,14 +17810,14 @@ static IrInstruction *ir_analyze_instruction_field_ptr(IrAnalyze *ira, IrInstruc...@@ -16295,14 +17810,14 @@ static IrInstruction *ir_analyze_instruction_field_ptr(IrAnalyze *ira, IrInstruc
16295 assert(container_ptr->value.type->id == ZigTypeIdPointer);17810 assert(container_ptr->value.type->id == ZigTypeIdPointer);
16296 if (container_type->id == ZigTypeIdPointer) {17811 if (container_type->id == ZigTypeIdPointer) {
16297 ZigType *bare_type = container_ref_type(container_type);17812 ZigType *bare_type = container_ref_type(container_type);
16298 IrInstruction *container_child = ir_get_deref(ira, &field_ptr_instruction->base, container_ptr);17813 IrInstruction *container_child = ir_get_deref(ira, &field_ptr_instruction->base, container_ptr, nullptr);
16299 IrInstruction *result = ir_analyze_container_field_ptr(ira, field_name, &field_ptr_instruction->base, container_child, bare_type);17814 IrInstruction *result = ir_analyze_container_field_ptr(ira, field_name, &field_ptr_instruction->base, container_child, bare_type, field_ptr_instruction->initializing);
16300 return result;17815 return result;
16301 } else {17816 } else {
16302 IrInstruction *result = ir_analyze_container_field_ptr(ira, field_name, &field_ptr_instruction->base, container_ptr, container_type);17817 IrInstruction *result = ir_analyze_container_field_ptr(ira, field_name, &field_ptr_instruction->base, container_ptr, container_type, field_ptr_instruction->initializing);
16303 return result;17818 return result;
16304 }17819 }
16305 } else if (is_array_ref(container_type)) {17820 } else if (is_array_ref(container_type) && !field_ptr_instruction->initializing) {
16306 if (buf_eql_str(field_name, "len")) {17821 if (buf_eql_str(field_name, "len")) {
16307 ConstExprValue *len_val = create_const_vals(1);17822 ConstExprValue *len_val = create_const_vals(1);
16308 if (container_type->id == ZigTypeIdPointer) {17823 if (container_type->id == ZigTypeIdPointer) {
...@@ -16617,6 +18132,10 @@ static IrInstruction *ir_analyze_instruction_field_ptr(IrAnalyze *ira, IrInstruc...@@ -16617,6 +18132,10 @@ static IrInstruction *ir_analyze_instruction_field_ptr(IrAnalyze *ira, IrInstruc
16617 buf_sprintf("type '%s' does not support field access", buf_ptr(&child_type->name)));18132 buf_sprintf("type '%s' does not support field access", buf_ptr(&child_type->name)));
16618 return ira->codegen->invalid_instruction;18133 return ira->codegen->invalid_instruction;
16619 }18134 }
18135 } else if (field_ptr_instruction->initializing) {
18136 ir_add_error(ira, &field_ptr_instruction->base,
18137 buf_sprintf("type '%s' does not support struct initialization syntax", buf_ptr(&container_type->name)));
18138 return ira->codegen->invalid_instruction;
16620 } else {18139 } else {
16621 ir_add_error_node(ira, field_ptr_instruction->base.source_node,18140 ir_add_error_node(ira, field_ptr_instruction->base.source_node,
16622 buf_sprintf("type '%s' does not support field access", buf_ptr(&container_type->name)));18141 buf_sprintf("type '%s' does not support field access", buf_ptr(&container_type->name)));
...@@ -16640,7 +18159,7 @@ static IrInstruction *ir_analyze_instruction_load_ptr(IrAnalyze *ira, IrInstruct...@@ -16640,7 +18159,7 @@ static IrInstruction *ir_analyze_instruction_load_ptr(IrAnalyze *ira, IrInstruct
16640 IrInstruction *ptr = instruction->ptr->child;18159 IrInstruction *ptr = instruction->ptr->child;
16641 if (type_is_invalid(ptr->value.type))18160 if (type_is_invalid(ptr->value.type))
16642 return ira->codegen->invalid_instruction;18161 return ira->codegen->invalid_instruction;
16643 return ir_get_deref(ira, &instruction->base, ptr);18162 return ir_get_deref(ira, &instruction->base, ptr, nullptr);
16644}18163}
1664518164
16646static IrInstruction *ir_analyze_instruction_typeof(IrAnalyze *ira, IrInstructionTypeOf *typeof_instruction) {18165static IrInstruction *ir_analyze_instruction_typeof(IrAnalyze *ira, IrInstructionTypeOf *typeof_instruction) {
...@@ -16651,64 +18170,6 @@ static IrInstruction *ir_analyze_instruction_typeof(IrAnalyze *ira, IrInstructio...@@ -16651,64 +18170,6 @@ static IrInstruction *ir_analyze_instruction_typeof(IrAnalyze *ira, IrInstructio
16651 return ir_const_type(ira, &typeof_instruction->base, type_entry);18170 return ir_const_type(ira, &typeof_instruction->base, type_entry);
16652}18171}
1665318172
16654static IrInstruction *ir_analyze_instruction_to_ptr_type(IrAnalyze *ira,
16655 IrInstructionToPtrType *to_ptr_type_instruction)
16656{
16657 Error err;
16658 IrInstruction *ptr_ptr = to_ptr_type_instruction->ptr->child;
16659 if (type_is_invalid(ptr_ptr->value.type))
16660 return ira->codegen->invalid_instruction;
16661
16662 ZigType *ptr_ptr_type = ptr_ptr->value.type;
16663 assert(ptr_ptr_type->id == ZigTypeIdPointer);
16664 ZigType *type_entry = ptr_ptr_type->data.pointer.child_type;
16665
16666 ZigType *ptr_type;
16667 if (type_entry->id == ZigTypeIdArray) {
16668 ptr_type = get_pointer_to_type(ira->codegen, type_entry->data.array.child_type, ptr_ptr_type->data.pointer.is_const);
16669 } else if (is_array_ref(type_entry)) {
16670 ptr_type = get_pointer_to_type(ira->codegen,
16671 type_entry->data.pointer.child_type->data.array.child_type, type_entry->data.pointer.is_const);
16672 } else if (is_slice(type_entry)) {
16673 ZigType *slice_ptr_type = type_entry->data.structure.fields[0].type_entry;
16674 ptr_type = adjust_ptr_len(ira->codegen, slice_ptr_type, PtrLenSingle);
16675 // If the pointer is over-aligned, we may have to reduce it based on the alignment of the element type.
16676 if (slice_ptr_type->data.pointer.explicit_alignment != 0) {
16677 ZigType *elem_type = slice_ptr_type->data.pointer.child_type;
16678 if ((err = type_resolve(ira->codegen, elem_type, ResolveStatusAlignmentKnown)))
16679 return ira->codegen->invalid_instruction;
16680 uint32_t elem_align = get_abi_alignment(ira->codegen, elem_type);
16681 uint32_t reduced_align = min(elem_align, slice_ptr_type->data.pointer.explicit_alignment);
16682 ptr_type = adjust_ptr_align(ira->codegen, ptr_type, reduced_align);
16683 }
16684 } else if (type_entry->id == ZigTypeIdArgTuple) {
16685 zig_panic("TODO for loop on var args");
16686 } else {
16687 ir_add_error_node(ira, to_ptr_type_instruction->base.source_node,
16688 buf_sprintf("expected array type, found '%s'", buf_ptr(&type_entry->name)));
16689 return ira->codegen->invalid_instruction;
16690 }
16691
16692 return ir_const_type(ira, &to_ptr_type_instruction->base, ptr_type);
16693}
16694
16695static IrInstruction *ir_analyze_instruction_ptr_type_child(IrAnalyze *ira,
16696 IrInstructionPtrTypeChild *ptr_type_child_instruction)
16697{
16698 IrInstruction *type_value = ptr_type_child_instruction->value->child;
16699 ZigType *type_entry = ir_resolve_type(ira, type_value);
16700 if (type_is_invalid(type_entry))
16701 return ira->codegen->invalid_instruction;
16702
16703 if (type_entry->id != ZigTypeIdPointer) {
16704 ir_add_error_node(ira, ptr_type_child_instruction->base.source_node,
16705 buf_sprintf("expected pointer type, found '%s'", buf_ptr(&type_entry->name)));
16706 return ira->codegen->invalid_instruction;
16707 }
16708
16709 return ir_const_type(ira, &ptr_type_child_instruction->base, type_entry->data.pointer.child_type);
16710}
16711
16712static IrInstruction *ir_analyze_instruction_set_cold(IrAnalyze *ira, IrInstructionSetCold *instruction) {18173static IrInstruction *ir_analyze_instruction_set_cold(IrAnalyze *ira, IrInstructionSetCold *instruction) {
16713 if (ira->new_irb.exec->is_inline) {18174 if (ira->new_irb.exec->is_inline) {
16714 // ignore setCold when running functions at compile time18175 // ignore setCold when running functions at compile time
...@@ -17138,7 +18599,7 @@ static IrInstruction *ir_analyze_instruction_test_non_null(IrAnalyze *ira, IrIns...@@ -17138,7 +18599,7 @@ static IrInstruction *ir_analyze_instruction_test_non_null(IrAnalyze *ira, IrIns
17138}18599}
1713918600
17140static IrInstruction *ir_analyze_unwrap_optional_payload(IrAnalyze *ira, IrInstruction *source_instr,18601static IrInstruction *ir_analyze_unwrap_optional_payload(IrAnalyze *ira, IrInstruction *source_instr,
17141 IrInstruction *base_ptr, bool safety_check_on)18602 IrInstruction *base_ptr, bool safety_check_on, bool initializing)
17142{18603{
17143 ZigType *ptr_type = base_ptr->value.type;18604 ZigType *ptr_type = base_ptr->value.type;
17144 assert(ptr_type->id == ZigTypeIdPointer);18605 assert(ptr_type->id == ZigTypeIdPointer);
...@@ -17168,7 +18629,7 @@ static IrInstruction *ir_analyze_unwrap_optional_payload(IrAnalyze *ira, IrInstr...@@ -17168,7 +18629,7 @@ static IrInstruction *ir_analyze_unwrap_optional_payload(IrAnalyze *ira, IrInstr
17168 }18629 }
17169 if (!safety_check_on)18630 if (!safety_check_on)
17170 return base_ptr;18631 return base_ptr;
17171 IrInstruction *c_ptr_val = ir_get_deref(ira, source_instr, base_ptr);18632 IrInstruction *c_ptr_val = ir_get_deref(ira, source_instr, base_ptr, nullptr);
17172 ir_build_assert_non_null(ira, source_instr, c_ptr_val);18633 ir_build_assert_non_null(ira, source_instr, c_ptr_val);
17173 return base_ptr;18634 return base_ptr;
17174 }18635 }
...@@ -17183,34 +18644,84 @@ static IrInstruction *ir_analyze_unwrap_optional_payload(IrAnalyze *ira, IrInstr...@@ -17183,34 +18644,84 @@ static IrInstruction *ir_analyze_unwrap_optional_payload(IrAnalyze *ira, IrInstr
17183 ZigType *result_type = get_pointer_to_type_extra(ira->codegen, child_type,18644 ZigType *result_type = get_pointer_to_type_extra(ira->codegen, child_type,
17184 ptr_type->data.pointer.is_const, ptr_type->data.pointer.is_volatile, PtrLenSingle, 0, 0, 0, false);18645 ptr_type->data.pointer.is_const, ptr_type->data.pointer.is_volatile, PtrLenSingle, 0, 0, 0, false);
1718518646
18647 bool same_comptime_repr = types_have_same_zig_comptime_repr(type_entry, child_type);
18648
17186 if (instr_is_comptime(base_ptr)) {18649 if (instr_is_comptime(base_ptr)) {
17187 ConstExprValue *val = ir_resolve_const(ira, base_ptr, UndefBad);18650 ConstExprValue *ptr_val = ir_resolve_const(ira, base_ptr, UndefBad);
17188 if (!val)18651 if (!ptr_val)
17189 return ira->codegen->invalid_instruction;18652 return ira->codegen->invalid_instruction;
17190 if (val->data.x_ptr.mut != ConstPtrMutRuntimeVar) {18653 if (ptr_val->data.x_ptr.mut != ConstPtrMutRuntimeVar) {
17191 ConstExprValue *maybe_val = const_ptr_pointee(ira, ira->codegen, val, source_instr->source_node);18654 ConstExprValue *optional_val = const_ptr_pointee(ira, ira->codegen, ptr_val, source_instr->source_node);
17192 if (maybe_val == nullptr)18655 if (optional_val == nullptr)
17193 return ira->codegen->invalid_instruction;18656 return ira->codegen->invalid_instruction;
1719418657
17195 if (optional_value_is_null(maybe_val)) {18658 if (initializing && optional_val->special == ConstValSpecialUndef) {
18659 switch (type_has_one_possible_value(ira->codegen, child_type)) {
18660 case OnePossibleValueInvalid:
18661 return ira->codegen->invalid_instruction;
18662 case OnePossibleValueNo:
18663 if (!same_comptime_repr) {
18664 ConstExprValue *payload_val = create_const_vals(1);
18665 payload_val->type = child_type;
18666 payload_val->special = ConstValSpecialUndef;
18667 payload_val->parent.id = ConstParentIdOptionalPayload;
18668 payload_val->parent.data.p_optional_payload.optional_val = optional_val;
18669
18670 optional_val->data.x_optional = payload_val;
18671 optional_val->special = ConstValSpecialStatic;
18672 }
18673 break;
18674 case OnePossibleValueYes: {
18675 ConstExprValue *pointee = create_const_vals(1);
18676 pointee->special = ConstValSpecialStatic;
18677 pointee->type = child_type;
18678 pointee->parent.id = ConstParentIdOptionalPayload;
18679 pointee->parent.data.p_optional_payload.optional_val = optional_val;
18680
18681 optional_val->special = ConstValSpecialStatic;
18682 optional_val->data.x_optional = pointee;
18683 break;
18684 }
18685 }
18686 } else if (optional_value_is_null(optional_val)) {
17196 ir_add_error(ira, source_instr, buf_sprintf("unable to unwrap null"));18687 ir_add_error(ira, source_instr, buf_sprintf("unable to unwrap null"));
17197 return ira->codegen->invalid_instruction;18688 return ira->codegen->invalid_instruction;
17198 }18689 }
17199 IrInstruction *result = ir_const(ira, source_instr, result_type);18690
17200 ConstExprValue *out_val = &result->value;18691 IrInstruction *result;
17201 out_val->data.x_ptr.special = ConstPtrSpecialRef;18692 if (ptr_val->data.x_ptr.mut == ConstPtrMutInfer) {
17202 out_val->data.x_ptr.mut = val->data.x_ptr.mut;18693 result = ir_build_optional_unwrap_ptr(&ira->new_irb, source_instr->scope,
17203 if (types_have_same_zig_comptime_repr(type_entry, child_type)) {18694 source_instr->source_node, base_ptr, false, initializing);
17204 out_val->data.x_ptr.data.ref.pointee = maybe_val;18695 result->value.type = result_type;
18696 result->value.special = ConstValSpecialStatic;
17205 } else {18697 } else {
17206 out_val->data.x_ptr.data.ref.pointee = maybe_val->data.x_optional;18698 result = ir_const(ira, source_instr, result_type);
18699 }
18700 ConstExprValue *result_val = &result->value;
18701 result_val->data.x_ptr.special = ConstPtrSpecialRef;
18702 result_val->data.x_ptr.mut = ptr_val->data.x_ptr.mut;
18703 switch (type_has_one_possible_value(ira->codegen, child_type)) {
18704 case OnePossibleValueInvalid:
18705 return ira->codegen->invalid_instruction;
18706 case OnePossibleValueNo:
18707 if (same_comptime_repr) {
18708 result_val->data.x_ptr.data.ref.pointee = optional_val;
18709 } else {
18710 assert(optional_val->data.x_optional != nullptr);
18711 result_val->data.x_ptr.data.ref.pointee = optional_val->data.x_optional;
18712 }
18713 break;
18714 case OnePossibleValueYes:
18715 assert(optional_val->data.x_optional != nullptr);
18716 result_val->data.x_ptr.data.ref.pointee = optional_val->data.x_optional;
18717 break;
17207 }18718 }
17208 return result;18719 return result;
17209 }18720 }
17210 }18721 }
1721118722
17212 IrInstruction *result = ir_build_optional_unwrap_ptr(&ira->new_irb, source_instr->scope,18723 IrInstruction *result = ir_build_optional_unwrap_ptr(&ira->new_irb, source_instr->scope,
17213 source_instr->source_node, base_ptr, safety_check_on);18724 source_instr->source_node, base_ptr, safety_check_on, initializing);
17214 result->value.type = result_type;18725 result->value.type = result_type;
17215 return result;18726 return result;
17216}18727}
...@@ -17222,7 +18733,8 @@ static IrInstruction *ir_analyze_instruction_optional_unwrap_ptr(IrAnalyze *ira,...@@ -17222,7 +18733,8 @@ static IrInstruction *ir_analyze_instruction_optional_unwrap_ptr(IrAnalyze *ira,
17222 if (type_is_invalid(base_ptr->value.type))18733 if (type_is_invalid(base_ptr->value.type))
17223 return ira->codegen->invalid_instruction;18734 return ira->codegen->invalid_instruction;
1722418735
17225 return ir_analyze_unwrap_optional_payload(ira, &instruction->base, base_ptr, instruction->safety_check_on);18736 return ir_analyze_unwrap_optional_payload(ira, &instruction->base, base_ptr,
18737 instruction->safety_check_on, false);
17226}18738}
1722718739
17228static IrInstruction *ir_analyze_instruction_ctz(IrAnalyze *ira, IrInstructionCtz *instruction) {18740static IrInstruction *ir_analyze_instruction_ctz(IrAnalyze *ira, IrInstructionCtz *instruction) {
...@@ -17523,7 +19035,7 @@ static IrInstruction *ir_analyze_instruction_switch_target(IrAnalyze *ira,...@@ -17523,7 +19035,7 @@ static IrInstruction *ir_analyze_instruction_switch_target(IrAnalyze *ira,
17523 return result;19035 return result;
17524 }19036 }
1752519037
17526 IrInstruction *result = ir_get_deref(ira, &switch_target_instruction->base, target_value_ptr);19038 IrInstruction *result = ir_get_deref(ira, &switch_target_instruction->base, target_value_ptr, nullptr);
17527 result->value.type = target_type;19039 result->value.type = target_type;
17528 return result;19040 return result;
17529 }19041 }
...@@ -17553,7 +19065,7 @@ static IrInstruction *ir_analyze_instruction_switch_target(IrAnalyze *ira,...@@ -17553,7 +19065,7 @@ static IrInstruction *ir_analyze_instruction_switch_target(IrAnalyze *ira,
17553 return result;19065 return result;
17554 }19066 }
1755519067
17556 IrInstruction *union_value = ir_get_deref(ira, &switch_target_instruction->base, target_value_ptr);19068 IrInstruction *union_value = ir_get_deref(ira, &switch_target_instruction->base, target_value_ptr, nullptr);
17557 union_value->value.type = target_type;19069 union_value->value.type = target_type;
1755819070
17559 IrInstruction *union_tag_inst = ir_build_union_tag(&ira->new_irb, switch_target_instruction->base.scope,19071 IrInstruction *union_tag_inst = ir_build_union_tag(&ira->new_irb, switch_target_instruction->base.scope,
...@@ -17577,7 +19089,7 @@ static IrInstruction *ir_analyze_instruction_switch_target(IrAnalyze *ira,...@@ -17577,7 +19089,7 @@ static IrInstruction *ir_analyze_instruction_switch_target(IrAnalyze *ira,
17577 return result;19089 return result;
17578 }19090 }
1757919091
17580 IrInstruction *enum_value = ir_get_deref(ira, &switch_target_instruction->base, target_value_ptr);19092 IrInstruction *enum_value = ir_get_deref(ira, &switch_target_instruction->base, target_value_ptr, nullptr);
17581 enum_value->value.type = target_type;19093 enum_value->value.type = target_type;
17582 return enum_value;19094 return enum_value;
17583 }19095 }
...@@ -17650,7 +19162,7 @@ static IrInstruction *ir_analyze_instruction_switch_var(IrAnalyze *ira, IrInstru...@@ -17650,7 +19162,7 @@ static IrInstruction *ir_analyze_instruction_switch_var(IrAnalyze *ira, IrInstru
17650 }19162 }
1765119163
17652 IrInstruction *result = ir_build_union_field_ptr(&ira->new_irb,19164 IrInstruction *result = ir_build_union_field_ptr(&ira->new_irb,
17653 instruction->base.scope, instruction->base.source_node, target_value_ptr, field);19165 instruction->base.scope, instruction->base.source_node, target_value_ptr, field, false, false);
17654 result->value.type = get_pointer_to_type(ira->codegen, field->type_entry,19166 result->value.type = get_pointer_to_type(ira->codegen, field->type_entry,
17655 target_value_ptr->value.type->data.pointer.is_const);19167 target_value_ptr->value.type->data.pointer.is_const);
17656 return result;19168 return result;
...@@ -17860,7 +19372,8 @@ static IrInstruction *ir_analyze_instruction_ref(IrAnalyze *ira, IrInstructionRe...@@ -17860,7 +19372,8 @@ static IrInstruction *ir_analyze_instruction_ref(IrAnalyze *ira, IrInstructionRe
17860}19372}
1786119373
17862static IrInstruction *ir_analyze_container_init_fields_union(IrAnalyze *ira, IrInstruction *instruction,19374static IrInstruction *ir_analyze_container_init_fields_union(IrAnalyze *ira, IrInstruction *instruction,
17863 ZigType *container_type, size_t instr_field_count, IrInstructionContainerInitFieldsField *fields)19375 ZigType *container_type, size_t instr_field_count, IrInstructionContainerInitFieldsField *fields,
19376 IrInstruction *result_loc)
17864{19377{
17865 Error err;19378 Error err;
17866 assert(container_type->id == ZigTypeIdUnion);19379 assert(container_type->id == ZigTypeIdUnion);
...@@ -17875,12 +19388,12 @@ static IrInstruction *ir_analyze_container_init_fields_union(IrAnalyze *ira, IrI...@@ -17875,12 +19388,12 @@ static IrInstruction *ir_analyze_container_init_fields_union(IrAnalyze *ira, IrI
17875 }19388 }
1787619389
17877 IrInstructionContainerInitFieldsField *field = &fields[0];19390 IrInstructionContainerInitFieldsField *field = &fields[0];
17878 IrInstruction *field_value = field->value->child;19391 IrInstruction *field_result_loc = field->result_loc->child;
17879 if (type_is_invalid(field_value->value.type))19392 if (type_is_invalid(field_result_loc->value.type))
17880 return ira->codegen->invalid_instruction;19393 return ira->codegen->invalid_instruction;
1788119394
17882 TypeUnionField *type_field = find_union_type_field(container_type, field->name);19395 TypeUnionField *type_field = find_union_type_field(container_type, field->name);
17883 if (!type_field) {19396 if (type_field == nullptr) {
17884 ir_add_error_node(ira, field->source_node,19397 ir_add_error_node(ira, field->source_node,
17885 buf_sprintf("no member named '%s' in union '%s'",19398 buf_sprintf("no member named '%s' in union '%s'",
17886 buf_ptr(field->name), buf_ptr(&container_type->name)));19399 buf_ptr(field->name), buf_ptr(&container_type->name)));
...@@ -17890,46 +19403,36 @@ static IrInstruction *ir_analyze_container_init_fields_union(IrAnalyze *ira, IrI...@@ -17890,46 +19403,36 @@ static IrInstruction *ir_analyze_container_init_fields_union(IrAnalyze *ira, IrI
17890 if (type_is_invalid(type_field->type_entry))19403 if (type_is_invalid(type_field->type_entry))
17891 return ira->codegen->invalid_instruction;19404 return ira->codegen->invalid_instruction;
1789219405
17893 IrInstruction *casted_field_value = ir_implicit_cast(ira, field_value, type_field->type_entry);19406 if (result_loc->value.data.x_ptr.mut == ConstPtrMutInfer) {
17894 if (casted_field_value == ira->codegen->invalid_instruction)19407 if (instr_is_comptime(field_result_loc) &&
17895 return ira->codegen->invalid_instruction;19408 field_result_loc->value.data.x_ptr.mut != ConstPtrMutRuntimeVar)
1789619409 {
17897 if ((err = type_resolve(ira->codegen, casted_field_value->value.type, ResolveStatusZeroBitsKnown)))19410 // nothing
17898 return ira->codegen->invalid_instruction;19411 } else {
19412 result_loc->value.special = ConstValSpecialRuntime;
19413 }
19414 }
1789919415
17900 bool is_comptime = ir_should_inline(ira->new_irb.exec, instruction->scope)19416 bool is_comptime = ir_should_inline(ira->new_irb.exec, instruction->scope)
17901 || type_requires_comptime(ira->codegen, container_type) == ReqCompTimeYes;19417 || type_requires_comptime(ira->codegen, container_type) == ReqCompTimeYes;
17902 if (is_comptime || casted_field_value->value.special != ConstValSpecialRuntime ||
17903 !type_has_bits(casted_field_value->value.type))
17904 {
17905 ConstExprValue *field_val = ir_resolve_const(ira, casted_field_value, UndefOk);
17906 if (!field_val)
17907 return ira->codegen->invalid_instruction;
17908
17909 IrInstruction *result = ir_const(ira, instruction, container_type);
17910 ConstExprValue *out_val = &result->value;
17911 out_val->data.x_union.payload = field_val;
17912 out_val->data.x_union.tag = type_field->enum_field->value;
17913 out_val->parent.id = ConstParentIdUnion;
17914 out_val->parent.data.p_union.union_val = out_val;
1791519418
17916 return result;19419 IrInstruction *result = ir_get_deref(ira, instruction, result_loc, nullptr);
19420 if (is_comptime && !instr_is_comptime(result)) {
19421 ir_add_error(ira, field->result_loc,
19422 buf_sprintf("unable to evaluate constant expression"));
19423 return ira->codegen->invalid_instruction;
17917 }19424 }
1791819425 return result;
17919 IrInstruction *new_instruction = ir_build_union_init(&ira->new_irb,
17920 instruction->scope, instruction->source_node,
17921 container_type, type_field, casted_field_value);
17922 new_instruction->value.type = container_type;
17923 ir_add_alloca(ira, new_instruction, container_type);
17924 return new_instruction;
17925}19426}
1792619427
17927static IrInstruction *ir_analyze_container_init_fields(IrAnalyze *ira, IrInstruction *instruction,19428static IrInstruction *ir_analyze_container_init_fields(IrAnalyze *ira, IrInstruction *instruction,
17928 ZigType *container_type, size_t instr_field_count, IrInstructionContainerInitFieldsField *fields)19429 ZigType *container_type, size_t instr_field_count, IrInstructionContainerInitFieldsField *fields,
19430 IrInstruction *result_loc)
17929{19431{
17930 Error err;19432 Error err;
17931 if (container_type->id == ZigTypeIdUnion) {19433 if (container_type->id == ZigTypeIdUnion) {
17932 return ir_analyze_container_init_fields_union(ira, instruction, container_type, instr_field_count, fields);19434 return ir_analyze_container_init_fields_union(ira, instruction, container_type, instr_field_count,
19435 fields, result_loc);
17933 }19436 }
17934 if (container_type->id != ZigTypeIdStruct || is_slice(container_type)) {19437 if (container_type->id != ZigTypeIdStruct || is_slice(container_type)) {
17935 ir_add_error(ira, instruction,19438 ir_add_error(ira, instruction,
...@@ -17946,22 +19449,28 @@ static IrInstruction *ir_analyze_container_init_fields(IrAnalyze *ira, IrInstruc...@@ -17946,22 +19449,28 @@ static IrInstruction *ir_analyze_container_init_fields(IrAnalyze *ira, IrInstruc
17946 IrInstruction *first_non_const_instruction = nullptr;19449 IrInstruction *first_non_const_instruction = nullptr;
1794719450
17948 AstNode **field_assign_nodes = allocate<AstNode *>(actual_field_count);19451 AstNode **field_assign_nodes = allocate<AstNode *>(actual_field_count);
1794919452 ZigList<IrInstruction *> const_ptrs = {};
17950 IrInstructionStructInitField *new_fields = allocate<IrInstructionStructInitField>(actual_field_count);
1795119453
17952 bool is_comptime = ir_should_inline(ira->new_irb.exec, instruction->scope)19454 bool is_comptime = ir_should_inline(ira->new_irb.exec, instruction->scope)
17953 || type_requires_comptime(ira->codegen, container_type) == ReqCompTimeYes;19455 || type_requires_comptime(ira->codegen, container_type) == ReqCompTimeYes;
1795419456
17955 ConstExprValue const_val = {};19457
17956 const_val.special = ConstValSpecialStatic;19458 // Here we iterate over the fields that have been initialized, and emit
17957 const_val.type = container_type;19459 // compile errors for missing fields and duplicate fields.
17958 // const_val.global_refs = allocate<ConstGlobalRefs>(1);19460 // It is only now that we find out whether the struct initialization can be a comptime
17959 const_val.data.x_struct.fields = create_const_vals(actual_field_count);19461 // value, but we have already emitted runtime instructions for the fields that
19462 // were initialized with runtime values, and have omitted instructions that would have
19463 // initialized fields with comptime values.
19464 // So now we must clean up this situation. If it turns out the struct initialization can
19465 // be a comptime value, overwrite ConstPtrMutInfer with ConstPtrMutComptimeConst.
19466 // Otherwise, we must emit instructions to runtime-initialize the fields that have
19467 // comptime-known values.
19468
17960 for (size_t i = 0; i < instr_field_count; i += 1) {19469 for (size_t i = 0; i < instr_field_count; i += 1) {
17961 IrInstructionContainerInitFieldsField *field = &fields[i];19470 IrInstructionContainerInitFieldsField *field = &fields[i];
1796219471
17963 IrInstruction *field_value = field->value->child;19472 IrInstruction *field_result_loc = field->result_loc->child;
17964 if (type_is_invalid(field_value->value.type))19473 if (type_is_invalid(field_result_loc->value.type))
17965 return ira->codegen->invalid_instruction;19474 return ira->codegen->invalid_instruction;
1796619475
17967 TypeStructField *type_field = find_struct_type_field(container_type, field->name);19476 TypeStructField *type_field = find_struct_type_field(container_type, field->name);
...@@ -17975,10 +19484,6 @@ static IrInstruction *ir_analyze_container_init_fields(IrAnalyze *ira, IrInstruc...@@ -17975,10 +19484,6 @@ static IrInstruction *ir_analyze_container_init_fields(IrAnalyze *ira, IrInstruc
17975 if (type_is_invalid(type_field->type_entry))19484 if (type_is_invalid(type_field->type_entry))
17976 return ira->codegen->invalid_instruction;19485 return ira->codegen->invalid_instruction;
1797719486
17978 IrInstruction *casted_field_value = ir_implicit_cast(ira, field_value, type_field->type_entry);
17979 if (casted_field_value == ira->codegen->invalid_instruction)
17980 return ira->codegen->invalid_instruction;
17981
17982 size_t field_index = type_field->src_index;19487 size_t field_index = type_field->src_index;
17983 AstNode *existing_assign_node = field_assign_nodes[field_index];19488 AstNode *existing_assign_node = field_assign_nodes[field_index];
17984 if (existing_assign_node) {19489 if (existing_assign_node) {
...@@ -17988,26 +19493,18 @@ static IrInstruction *ir_analyze_container_init_fields(IrAnalyze *ira, IrInstruc...@@ -17988,26 +19493,18 @@ static IrInstruction *ir_analyze_container_init_fields(IrAnalyze *ira, IrInstruc
17988 }19493 }
17989 field_assign_nodes[field_index] = field->source_node;19494 field_assign_nodes[field_index] = field->source_node;
1799019495
17991 new_fields[field_index].value = casted_field_value;19496 if (instr_is_comptime(field_result_loc) &&
17992 new_fields[field_index].type_struct_field = type_field;19497 field_result_loc->value.data.x_ptr.mut != ConstPtrMutRuntimeVar)
1799319498 {
17994 if (const_val.special == ConstValSpecialStatic) {19499 const_ptrs.append(field_result_loc);
17995 if (is_comptime || casted_field_value->value.special != ConstValSpecialRuntime) {19500 } else {
17996 ConstExprValue *field_val = ir_resolve_const(ira, casted_field_value, UndefOk);19501 first_non_const_instruction = field_result_loc;
17997 if (!field_val)
17998 return ira->codegen->invalid_instruction;
17999
18000 copy_const_val(&const_val.data.x_struct.fields[field_index], field_val, true);
18001 } else {
18002 first_non_const_instruction = casted_field_value;
18003 const_val.special = ConstValSpecialRuntime;
18004 }
18005 }19502 }
18006 }19503 }
1800719504
18008 bool any_missing = false;19505 bool any_missing = false;
18009 for (size_t i = 0; i < actual_field_count; i += 1) {19506 for (size_t i = 0; i < actual_field_count; i += 1) {
18010 if (field_assign_nodes[i]) continue;19507 if (field_assign_nodes[i] != nullptr) continue;
1801119508
18012 // look for a default field value19509 // look for a default field value
18013 TypeStructField *field = &container_type->data.structure.fields[i];19510 TypeStructField *field = &container_type->data.structure.fields[i];
...@@ -18033,182 +19530,177 @@ static IrInstruction *ir_analyze_container_init_fields(IrAnalyze *ira, IrInstruc...@@ -18033,182 +19530,177 @@ static IrInstruction *ir_analyze_container_init_fields(IrAnalyze *ira, IrInstruc
18033 IrInstruction *runtime_inst = ir_const(ira, instruction, field->init_val->type);19530 IrInstruction *runtime_inst = ir_const(ira, instruction, field->init_val->type);
18034 copy_const_val(&runtime_inst->value, field->init_val, true);19531 copy_const_val(&runtime_inst->value, field->init_val, true);
1803519532
18036 new_fields[i].value = runtime_inst;19533 IrInstruction *field_ptr = ir_analyze_struct_field_ptr(ira, instruction, field, result_loc,
18037 new_fields[i].type_struct_field = field;19534 container_type, true);
1803819535 ir_analyze_store_ptr(ira, instruction, field_ptr, runtime_inst);
18039 if (const_val.special == ConstValSpecialStatic) {19536 if (instr_is_comptime(field_ptr) && field_ptr->value.data.x_ptr.mut != ConstPtrMutRuntimeVar) {
18040 copy_const_val(&const_val.data.x_struct.fields[i], field->init_val, true);19537 const_ptrs.append(field_ptr);
19538 } else {
19539 first_non_const_instruction = result_loc;
18041 }19540 }
18042 }19541 }
18043 if (any_missing)19542 if (any_missing)
18044 return ira->codegen->invalid_instruction;19543 return ira->codegen->invalid_instruction;
1804519544
18046 if (const_val.special == ConstValSpecialStatic) {19545 if (result_loc->value.data.x_ptr.mut == ConstPtrMutInfer) {
18047 IrInstruction *result = ir_const(ira, instruction, nullptr);19546 if (const_ptrs.length != actual_field_count) {
18048 ConstExprValue *out_val = &result->value;19547 result_loc->value.special = ConstValSpecialRuntime;
18049 copy_const_val(out_val, &const_val, false);19548 for (size_t i = 0; i < const_ptrs.length; i += 1) {
18050 out_val->type = container_type;19549 IrInstruction *field_result_loc = const_ptrs.at(i);
1805119550 IrInstruction *deref = ir_get_deref(ira, field_result_loc, field_result_loc, nullptr);
18052 for (size_t i = 0; i < instr_field_count; i += 1) {19551 field_result_loc->value.special = ConstValSpecialRuntime;
18053 ConstExprValue *field_val = &out_val->data.x_struct.fields[i];19552 ir_analyze_store_ptr(ira, field_result_loc, field_result_loc, deref);
18054 ConstParent *parent = get_const_val_parent(ira->codegen, field_val);
18055 if (parent != nullptr) {
18056 parent->id = ConstParentIdStruct;
18057 parent->data.p_struct.field_index = i;
18058 parent->data.p_struct.struct_val = out_val;
18059 }19553 }
18060 }19554 }
18061
18062 return result;
18063 }19555 }
1806419556
18065 if (is_comptime) {19557 IrInstruction *result = ir_get_deref(ira, instruction, result_loc, nullptr);
19558
19559 if (is_comptime && !instr_is_comptime(result)) {
18066 ir_add_error_node(ira, first_non_const_instruction->source_node,19560 ir_add_error_node(ira, first_non_const_instruction->source_node,
18067 buf_sprintf("unable to evaluate constant expression"));19561 buf_sprintf("unable to evaluate constant expression"));
18068 return ira->codegen->invalid_instruction;19562 return ira->codegen->invalid_instruction;
18069 }19563 }
1807019564
18071 IrInstruction *new_instruction = ir_build_struct_init(&ira->new_irb,19565 return result;
18072 instruction->scope, instruction->source_node,
18073 container_type, actual_field_count, new_fields);
18074 new_instruction->value.type = container_type;
18075 ir_add_alloca(ira, new_instruction, container_type);
18076 return new_instruction;
18077}19566}
1807819567
18079static IrInstruction *ir_analyze_instruction_container_init_list(IrAnalyze *ira,19568static IrInstruction *ir_analyze_instruction_container_init_list(IrAnalyze *ira,
18080 IrInstructionContainerInitList *instruction)19569 IrInstructionContainerInitList *instruction)
18081{19570{
18082 Error err;19571 ZigType *container_type = ir_resolve_type(ira, instruction->container_type->child);
19572 if (type_is_invalid(container_type))
19573 return ira->codegen->invalid_instruction;
1808319574
18084 size_t elem_count = instruction->item_count;19575 size_t elem_count = instruction->item_count;
1808519576
18086 ZigType *container_type;
18087 if (instruction->container_type != nullptr) {
18088 container_type = ir_resolve_type(ira, instruction->container_type->child);
18089 if (type_is_invalid(container_type))
18090 return ira->codegen->invalid_instruction;
18091 } else {
18092 ZigType *elem_type = ir_resolve_type(ira, instruction->elem_type->child);
18093 if (type_is_invalid(elem_type))
18094 return ira->codegen->invalid_instruction;
18095 if ((err = type_resolve(ira->codegen, elem_type, ResolveStatusSizeKnown))) {
18096 return ira->codegen->invalid_instruction;
18097 }
18098 container_type = get_array_type(ira->codegen, elem_type, elem_count);
18099 }
18100
18101 if (is_slice(container_type)) {19577 if (is_slice(container_type)) {
18102 ir_add_error(ira, &instruction->base,19578 ir_add_error(ira, &instruction->base,
18103 buf_sprintf("expected array type or [_], found slice"));19579 buf_sprintf("expected array type or [_], found slice"));
18104 return ira->codegen->invalid_instruction;19580 return ira->codegen->invalid_instruction;
18105 } else if (container_type->id == ZigTypeIdStruct && !is_slice(container_type) && elem_count == 0) {19581 }
18106 return ir_analyze_container_init_fields(ira, &instruction->base, container_type,
18107 0, nullptr);
18108 } else if (container_type->id == ZigTypeIdArray) {
18109 // array is same as slice init but we make a compile error if the length is wrong
18110 ZigType *child_type;
18111 if (container_type->id == ZigTypeIdArray) {
18112 child_type = container_type->data.array.child_type;
18113 if (container_type->data.array.len != elem_count) {
18114 ZigType *literal_type = get_array_type(ira->codegen, child_type, elem_count);
18115
18116 ir_add_error(ira, &instruction->base,
18117 buf_sprintf("expected %s literal, found %s literal",
18118 buf_ptr(&container_type->name), buf_ptr(&literal_type->name)));
18119 return ira->codegen->invalid_instruction;
18120 }
18121 } else {
18122 ZigType *pointer_type = container_type->data.structure.fields[slice_ptr_index].type_entry;
18123 assert(pointer_type->id == ZigTypeIdPointer);
18124 child_type = pointer_type->data.pointer.child_type;
18125 }
1812619582
18127 if ((err = type_resolve(ira->codegen, child_type, ResolveStatusSizeKnown))) {19583 if (container_type->id == ZigTypeIdVoid) {
19584 if (elem_count != 0) {
19585 ir_add_error_node(ira, instruction->base.source_node,
19586 buf_sprintf("void expression expects no arguments"));
18128 return ira->codegen->invalid_instruction;19587 return ira->codegen->invalid_instruction;
18129 }19588 }
19589 return ir_const_void(ira, &instruction->base);
19590 }
1813019591
18131 ZigType *fixed_size_array_type = get_array_type(ira->codegen, child_type, elem_count);19592 if (container_type->id == ZigTypeIdStruct && elem_count == 0) {
19593 ir_assert(instruction->result_loc != nullptr, &instruction->base);
19594 IrInstruction *result_loc = instruction->result_loc->child;
19595 if (type_is_invalid(result_loc->value.type))
19596 return result_loc;
19597 return ir_analyze_container_init_fields(ira, &instruction->base, container_type, 0, nullptr, result_loc);
19598 }
19599
19600 if (container_type->id != ZigTypeIdArray) {
19601 ir_add_error_node(ira, instruction->base.source_node,
19602 buf_sprintf("type '%s' does not support array initialization",
19603 buf_ptr(&container_type->name)));
19604 return ira->codegen->invalid_instruction;
19605 }
1813219606
18133 ConstExprValue const_val = {};19607 ir_assert(instruction->result_loc != nullptr, &instruction->base);
18134 const_val.special = ConstValSpecialStatic;19608 IrInstruction *result_loc = instruction->result_loc->child;
18135 const_val.type = fixed_size_array_type;19609 if (type_is_invalid(result_loc->value.type))
18136 // const_val.global_refs = allocate<ConstGlobalRefs>(1);19610 return result_loc;
18137 const_val.data.x_array.data.s_none.elements = create_const_vals(elem_count);19611 ir_assert(result_loc->value.type->id == ZigTypeIdPointer, &instruction->base);
1813819612
18139 bool is_comptime = ir_should_inline(ira->new_irb.exec, instruction->base.scope);19613 ZigType *child_type = container_type->data.array.child_type;
19614 if (container_type->data.array.len != elem_count) {
19615 ZigType *literal_type = get_array_type(ira->codegen, child_type, elem_count);
1814019616
18141 IrInstruction **new_items = allocate<IrInstruction *>(elem_count);19617 ir_add_error(ira, &instruction->base,
19618 buf_sprintf("expected %s literal, found %s literal",
19619 buf_ptr(&container_type->name), buf_ptr(&literal_type->name)));
19620 return ira->codegen->invalid_instruction;
19621 }
1814219622
18143 IrInstruction *first_non_const_instruction = nullptr;19623 switch (type_has_one_possible_value(ira->codegen, container_type)) {
19624 case OnePossibleValueInvalid:
19625 return ira->codegen->invalid_instruction;
19626 case OnePossibleValueYes:
19627 return ir_const(ira, &instruction->base, container_type);
19628 case OnePossibleValueNo:
19629 break;
19630 }
1814419631
18145 for (size_t i = 0; i < elem_count; i += 1) {19632 bool is_comptime;
18146 IrInstruction *arg_value = instruction->items[i]->child;19633 switch (type_requires_comptime(ira->codegen, container_type)) {
18147 if (type_is_invalid(arg_value->value.type))19634 case ReqCompTimeInvalid:
18148 return ira->codegen->invalid_instruction;19635 return ira->codegen->invalid_instruction;
19636 case ReqCompTimeNo:
19637 is_comptime = ir_should_inline(ira->new_irb.exec, instruction->base.scope);
19638 break;
19639 case ReqCompTimeYes:
19640 is_comptime = true;
19641 break;
19642 }
1814919643
18150 IrInstruction *casted_arg = ir_implicit_cast(ira, arg_value, child_type);19644 IrInstruction *first_non_const_instruction = nullptr;
18151 if (casted_arg == ira->codegen->invalid_instruction)
18152 return ira->codegen->invalid_instruction;
1815319645
18154 new_items[i] = casted_arg;19646 // The Result Location Mechanism has already emitted runtime instructions to
19647 // initialize runtime elements and has omitted instructions for the comptime
19648 // elements. However it is only now that we find out whether the array initialization
19649 // can be a comptime value. So we must clean up the situation. If it turns out
19650 // array initialization can be a comptime value, overwrite ConstPtrMutInfer with
19651 // ConstPtrMutComptimeConst. Otherwise, emit instructions to runtime-initialize the
19652 // elements that have comptime-known values.
19653 ZigList<IrInstruction *> const_ptrs = {};
19654
19655 for (size_t i = 0; i < elem_count; i += 1) {
19656 IrInstruction *elem_result_loc = instruction->elem_result_loc_list[i]->child;
19657 if (type_is_invalid(elem_result_loc->value.type))
19658 return ira->codegen->invalid_instruction;
1815519659
18156 if (const_val.special == ConstValSpecialStatic) {19660 assert(elem_result_loc->value.type->id == ZigTypeIdPointer);
18157 if (is_comptime || casted_arg->value.special != ConstValSpecialRuntime) {
18158 ConstExprValue *elem_val = ir_resolve_const(ira, casted_arg, UndefBad);
18159 if (!elem_val)
18160 return ira->codegen->invalid_instruction;
1816119661
18162 copy_const_val(&const_val.data.x_array.data.s_none.elements[i], elem_val, true);19662 if (instr_is_comptime(elem_result_loc) &&
18163 } else {19663 elem_result_loc->value.data.x_ptr.mut != ConstPtrMutRuntimeVar)
18164 first_non_const_instruction = casted_arg;19664 {
18165 const_val.special = ConstValSpecialRuntime;19665 const_ptrs.append(elem_result_loc);
18166 }19666 } else {
18167 }19667 first_non_const_instruction = elem_result_loc;
18168 }19668 }
19669 }
1816919670
18170 if (const_val.special == ConstValSpecialStatic) {19671 if (result_loc->value.data.x_ptr.mut == ConstPtrMutInfer) {
18171 IrInstruction *result = ir_const(ira, &instruction->base, nullptr);19672 if (const_ptrs.length != elem_count) {
18172 ConstExprValue *out_val = &result->value;19673 result_loc->value.special = ConstValSpecialRuntime;
18173 copy_const_val(out_val, &const_val, false);19674 for (size_t i = 0; i < const_ptrs.length; i += 1) {
18174 result->value.type = fixed_size_array_type;19675 IrInstruction *elem_result_loc = const_ptrs.at(i);
18175 for (size_t i = 0; i < elem_count; i += 1) {19676 assert(elem_result_loc->value.special == ConstValSpecialStatic);
18176 ConstExprValue *elem_val = &out_val->data.x_array.data.s_none.elements[i];19677 IrInstruction *deref = ir_get_deref(ira, elem_result_loc, elem_result_loc, nullptr);
18177 ConstParent *parent = get_const_val_parent(ira->codegen, elem_val);19678 elem_result_loc->value.special = ConstValSpecialRuntime;
18178 if (parent != nullptr) {19679 ir_analyze_store_ptr(ira, elem_result_loc, elem_result_loc, deref);
18179 parent->id = ConstParentIdArray;
18180 parent->data.p_array.array_val = out_val;
18181 parent->data.p_array.elem_index = i;
18182 }
18183 }19680 }
18184 return result;
18185 }19681 }
19682 }
1818619683
18187 if (is_comptime) {19684 IrInstruction *result = ir_get_deref(ira, &instruction->base, result_loc, nullptr);
18188 ir_add_error_node(ira, first_non_const_instruction->source_node,19685 if (instr_is_comptime(result))
18189 buf_sprintf("unable to evaluate constant expression"));19686 return result;
18190 return ira->codegen->invalid_instruction;
18191 }
1819219687
18193 IrInstruction *new_instruction = ir_build_container_init_list(&ira->new_irb,19688 if (is_comptime) {
18194 instruction->base.scope, instruction->base.source_node,19689 ir_add_error_node(ira, first_non_const_instruction->source_node,
18195 nullptr, nullptr, elem_count, new_items);19690 buf_sprintf("unable to evaluate constant expression"));
18196 new_instruction->value.type = fixed_size_array_type;19691 return ira->codegen->invalid_instruction;
18197 ir_add_alloca(ira, new_instruction, fixed_size_array_type);19692 }
18198 return new_instruction;19693
18199 } else if (container_type->id == ZigTypeIdVoid) {19694 ZigType *result_elem_type = result_loc->value.type->data.pointer.child_type;
18200 if (elem_count != 0) {19695 if (is_slice(result_elem_type)) {
18201 ir_add_error_node(ira, instruction->base.source_node,19696 ErrorMsg *msg = ir_add_error(ira, &instruction->base,
18202 buf_sprintf("void expression expects no arguments"));19697 buf_sprintf("runtime-initialized array cannot be casted to slice type '%s'",
18203 return ira->codegen->invalid_instruction;19698 buf_ptr(&result_elem_type->name)));
18204 }19699 add_error_note(ira->codegen, msg, first_non_const_instruction->source_node,
18205 return ir_const_void(ira, &instruction->base);19700 buf_sprintf("this value is not comptime-known"));
18206 } else {
18207 ir_add_error_node(ira, instruction->base.source_node,
18208 buf_sprintf("type '%s' does not support array initialization",
18209 buf_ptr(&container_type->name)));
18210 return ira->codegen->invalid_instruction;19701 return ira->codegen->invalid_instruction;
18211 }19702 }
19703 return result;
18212}19704}
1821319705
18214static IrInstruction *ir_analyze_instruction_container_init_fields(IrAnalyze *ira,19706static IrInstruction *ir_analyze_instruction_container_init_fields(IrAnalyze *ira,
...@@ -18219,8 +19711,13 @@ static IrInstruction *ir_analyze_instruction_container_init_fields(IrAnalyze *ir...@@ -18219,8 +19711,13 @@ static IrInstruction *ir_analyze_instruction_container_init_fields(IrAnalyze *ir
18219 if (type_is_invalid(container_type))19711 if (type_is_invalid(container_type))
18220 return ira->codegen->invalid_instruction;19712 return ira->codegen->invalid_instruction;
1822119713
19714 ir_assert(instruction->result_loc != nullptr, &instruction->base);
19715 IrInstruction *result_loc = instruction->result_loc->child;
19716 if (type_is_invalid(result_loc->value.type))
19717 return result_loc;
19718
18222 return ir_analyze_container_init_fields(ira, &instruction->base, container_type,19719 return ir_analyze_container_init_fields(ira, &instruction->base, container_type,
18223 instruction->field_count, instruction->fields);19720 instruction->field_count, instruction->fields, result_loc);
18224}19721}
1822519722
18226static IrInstruction *ir_analyze_instruction_compile_err(IrAnalyze *ira,19723static IrInstruction *ir_analyze_instruction_compile_err(IrAnalyze *ira,
...@@ -18489,12 +19986,6 @@ static IrInstruction *ir_analyze_instruction_bit_offset_of(IrAnalyze *ira,...@@ -18489,12 +19986,6 @@ static IrInstruction *ir_analyze_instruction_bit_offset_of(IrAnalyze *ira,
18489 return ir_const_unsigned(ira, &instruction->base, bit_offset);19986 return ir_const_unsigned(ira, &instruction->base, bit_offset);
18490}19987}
1849119988
18492static IrInstruction *ir_error_dependency_loop(IrAnalyze *ira, IrInstruction *source_instr) {
18493 ErrorMsg *msg = ir_add_error(ira, source_instr, buf_sprintf("dependency loop detected"));
18494 emit_error_notes_for_ref_stack(ira->codegen, msg);
18495 return ira->codegen->invalid_instruction;
18496}
18497
18498static void ensure_field_index(ZigType *type, const char *field_name, size_t index) {19989static void ensure_field_index(ZigType *type, const char *field_name, size_t index) {
18499 Buf *field_name_buf;19990 Buf *field_name_buf;
1850019991
...@@ -19613,7 +21104,7 @@ static IrInstruction *ir_analyze_instruction_c_import(IrAnalyze *ira, IrInstruct...@@ -19613,7 +21104,7 @@ static IrInstruction *ir_analyze_instruction_c_import(IrAnalyze *ira, IrInstruct
19613 ir_add_error_node(ira, node, buf_sprintf("C import failed: unable to make dir: %s", err_str(err)));21104 ir_add_error_node(ira, node, buf_sprintf("C import failed: unable to make dir: %s", err_str(err)));
19614 return ira->codegen->invalid_instruction;21105 return ira->codegen->invalid_instruction;
19615 }21106 }
19616 21107
19617 if ((err = os_write_file(&tmp_c_file_path, &cimport_scope->buf))) {21108 if ((err = os_write_file(&tmp_c_file_path, &cimport_scope->buf))) {
19618 ir_add_error_node(ira, node, buf_sprintf("C import failed: unable to write .h file: %s", err_str(err)));21109 ir_add_error_node(ira, node, buf_sprintf("C import failed: unable to write .h file: %s", err_str(err)));
19619 return ira->codegen->invalid_instruction;21110 return ira->codegen->invalid_instruction;
...@@ -19900,12 +21391,21 @@ static IrInstruction *ir_analyze_instruction_cmpxchg(IrAnalyze *ira, IrInstructi...@@ -19900,12 +21391,21 @@ static IrInstruction *ir_analyze_instruction_cmpxchg(IrAnalyze *ira, IrInstructi
19900 zig_panic("TODO compile-time execution of cmpxchg");21391 zig_panic("TODO compile-time execution of cmpxchg");
19901 }21392 }
1990221393
19903 IrInstruction *result = ir_build_cmpxchg_gen(ira, &instruction->base,21394 ZigType *result_type = get_optional_type(ira->codegen, operand_type);
21395 IrInstruction *result_loc;
21396 if (handle_is_ptr(result_type)) {
21397 result_loc = ir_resolve_result(ira, &instruction->base, instruction->result_loc,
21398 result_type, nullptr, true, false);
21399 if (type_is_invalid(result_loc->value.type) || instr_is_unreachable(result_loc)) {
21400 return result_loc;
21401 }
21402 } else {
21403 result_loc = nullptr;
21404 }
21405
21406 return ir_build_cmpxchg_gen(ira, &instruction->base, result_type,
19904 casted_ptr, casted_cmp_value, casted_new_value,21407 casted_ptr, casted_cmp_value, casted_new_value,
19905 success_order, failure_order, instruction->is_weak);21408 success_order, failure_order, instruction->is_weak, result_loc);
19906 result->value.type = get_optional_type(ira->codegen, operand_type);
19907 ir_add_alloca(ira, result, result->value.type);
19908 return result;
19909}21409}
1991021410
19911static IrInstruction *ir_analyze_instruction_fence(IrAnalyze *ira, IrInstructionFence *instruction) {21411static IrInstruction *ir_analyze_instruction_fence(IrAnalyze *ira, IrInstructionFence *instruction) {
...@@ -20043,7 +21543,7 @@ static IrInstruction *ir_analyze_instruction_float_cast(IrAnalyze *ira, IrInstru...@@ -20043,7 +21543,7 @@ static IrInstruction *ir_analyze_instruction_float_cast(IrAnalyze *ira, IrInstru
20043 } else {21543 } else {
20044 op = CastOpNumLitToConcrete;21544 op = CastOpNumLitToConcrete;
20045 }21545 }
20046 return ir_resolve_cast(ira, &instruction->base, target, dest_type, op, false);21546 return ir_resolve_cast(ira, &instruction->base, target, dest_type, op);
20047 } else {21547 } else {
20048 return ira->codegen->invalid_instruction;21548 return ira->codegen->invalid_instruction;
20049 }21549 }
...@@ -20151,6 +21651,12 @@ static IrInstruction *ir_analyze_instruction_from_bytes(IrAnalyze *ira, IrInstru...@@ -20151,6 +21651,12 @@ static IrInstruction *ir_analyze_instruction_from_bytes(IrAnalyze *ira, IrInstru
20151 }21651 }
20152 }21652 }
2015321653
21654 IrInstruction *result_loc = ir_resolve_result(ira, &instruction->base, instruction->result_loc,
21655 dest_slice_type, nullptr, true, false);
21656 if (result_loc != nullptr && (type_is_invalid(result_loc->value.type) || instr_is_unreachable(result_loc))) {
21657 return result_loc;
21658 }
21659
20154 if (casted_value->value.data.rh_slice.id == RuntimeHintSliceIdLen) {21660 if (casted_value->value.data.rh_slice.id == RuntimeHintSliceIdLen) {
20155 known_len = casted_value->value.data.rh_slice.len;21661 known_len = casted_value->value.data.rh_slice.len;
20156 have_known_len = true;21662 have_known_len = true;
...@@ -20170,9 +21676,7 @@ static IrInstruction *ir_analyze_instruction_from_bytes(IrAnalyze *ira, IrInstru...@@ -20170,9 +21676,7 @@ static IrInstruction *ir_analyze_instruction_from_bytes(IrAnalyze *ira, IrInstru
20170 }21676 }
20171 }21677 }
2017221678
20173 IrInstruction *result = ir_build_resize_slice(ira, &instruction->base, casted_value, dest_slice_type);21679 return ir_build_resize_slice(ira, &instruction->base, casted_value, dest_slice_type, result_loc);
20174 ir_add_alloca(ira, result, dest_slice_type);
20175 return result;
20176}21680}
2017721681
20178static IrInstruction *ir_analyze_instruction_to_bytes(IrAnalyze *ira, IrInstructionToBytes *instruction) {21682static IrInstruction *ir_analyze_instruction_to_bytes(IrAnalyze *ira, IrInstructionToBytes *instruction) {
...@@ -20224,9 +21728,13 @@ static IrInstruction *ir_analyze_instruction_to_bytes(IrAnalyze *ira, IrInstruct...@@ -20224,9 +21728,13 @@ static IrInstruction *ir_analyze_instruction_to_bytes(IrAnalyze *ira, IrInstruct
20224 return result;21728 return result;
20225 }21729 }
2022621730
20227 IrInstruction *result = ir_build_resize_slice(ira, &instruction->base, target, dest_slice_type);21731 IrInstruction *result_loc = ir_resolve_result(ira, &instruction->base, instruction->result_loc,
20228 ir_add_alloca(ira, result, dest_slice_type);21732 dest_slice_type, nullptr, true, false);
20229 return result;21733 if (type_is_invalid(result_loc->value.type) || instr_is_unreachable(result_loc)) {
21734 return result_loc;
21735 }
21736
21737 return ir_build_resize_slice(ira, &instruction->base, target, dest_slice_type, result_loc);
20230}21738}
2023121739
20232static Error resolve_ptr_align(IrAnalyze *ira, ZigType *ty, uint32_t *result_align) {21740static Error resolve_ptr_align(IrAnalyze *ira, ZigType *ty, uint32_t *result_align) {
...@@ -20258,7 +21766,7 @@ static IrInstruction *ir_analyze_instruction_int_to_float(IrAnalyze *ira, IrInst...@@ -20258,7 +21766,7 @@ static IrInstruction *ir_analyze_instruction_int_to_float(IrAnalyze *ira, IrInst
20258 return ira->codegen->invalid_instruction;21766 return ira->codegen->invalid_instruction;
20259 }21767 }
2026021768
20261 return ir_resolve_cast(ira, &instruction->base, target, dest_type, CastOpIntToFloat, false);21769 return ir_resolve_cast(ira, &instruction->base, target, dest_type, CastOpIntToFloat);
20262}21770}
2026321771
20264static IrInstruction *ir_analyze_instruction_float_to_int(IrAnalyze *ira, IrInstructionFloatToInt *instruction) {21772static IrInstruction *ir_analyze_instruction_float_to_int(IrAnalyze *ira, IrInstructionFloatToInt *instruction) {
...@@ -20280,7 +21788,7 @@ static IrInstruction *ir_analyze_instruction_float_to_int(IrAnalyze *ira, IrInst...@@ -20280,7 +21788,7 @@ static IrInstruction *ir_analyze_instruction_float_to_int(IrAnalyze *ira, IrInst
20280 return ira->codegen->invalid_instruction;21788 return ira->codegen->invalid_instruction;
20281 }21789 }
2028221790
20283 return ir_resolve_cast(ira, &instruction->base, target, dest_type, CastOpFloatToInt, false);21791 return ir_resolve_cast(ira, &instruction->base, target, dest_type, CastOpFloatToInt);
20284}21792}
2028521793
20286static IrInstruction *ir_analyze_instruction_err_to_int(IrAnalyze *ira, IrInstructionErrToInt *instruction) {21794static IrInstruction *ir_analyze_instruction_err_to_int(IrAnalyze *ira, IrInstructionErrToInt *instruction) {
...@@ -20332,7 +21840,7 @@ static IrInstruction *ir_analyze_instruction_bool_to_int(IrAnalyze *ira, IrInstr...@@ -20332,7 +21840,7 @@ static IrInstruction *ir_analyze_instruction_bool_to_int(IrAnalyze *ira, IrInstr
20332 }21840 }
2033321841
20334 ZigType *u1_type = get_int_type(ira->codegen, false, 1);21842 ZigType *u1_type = get_int_type(ira->codegen, false, 1);
20335 return ir_resolve_cast(ira, &instruction->base, target, u1_type, CastOpBoolToInt, false);21843 return ir_resolve_cast(ira, &instruction->base, target, u1_type, CastOpBoolToInt);
20336}21844}
2033721845
20338static IrInstruction *ir_analyze_instruction_int_type(IrAnalyze *ira, IrInstructionIntType *instruction) {21846static IrInstruction *ir_analyze_instruction_int_type(IrAnalyze *ira, IrInstructionIntType *instruction) {
...@@ -20493,7 +22001,7 @@ static IrInstruction *ir_analyze_instruction_memset(IrAnalyze *ira, IrInstructio...@@ -20493,7 +22001,7 @@ static IrInstruction *ir_analyze_instruction_memset(IrAnalyze *ira, IrInstructio
2049322001
20494 ConstExprValue *byte_val = &casted_byte->value;22002 ConstExprValue *byte_val = &casted_byte->value;
20495 for (size_t i = start; i < end; i += 1) {22003 for (size_t i = start; i < end; i += 1) {
20496 dest_elements[i] = *byte_val;22004 copy_const_val(&dest_elements[i], byte_val, true);
20497 }22005 }
2049822006
20499 return ir_const_void(ira, &instruction->base);22007 return ir_const_void(ira, &instruction->base);
...@@ -20563,7 +22071,7 @@ static IrInstruction *ir_analyze_instruction_memcpy(IrAnalyze *ira, IrInstructio...@@ -20563,7 +22071,7 @@ static IrInstruction *ir_analyze_instruction_memcpy(IrAnalyze *ira, IrInstructio
20563 return ira->codegen->invalid_instruction;22071 return ira->codegen->invalid_instruction;
2056422072
20565 // TODO test this at comptime with u8 and non-u8 types22073 // TODO test this at comptime with u8 and non-u8 types
20566 // TODO test with dest ptr being a global runtime variable 22074 // TODO test with dest ptr being a global runtime variable
20567 if (casted_dest_ptr->value.special == ConstValSpecialStatic &&22075 if (casted_dest_ptr->value.special == ConstValSpecialStatic &&
20568 casted_src_ptr->value.special == ConstValSpecialStatic &&22076 casted_src_ptr->value.special == ConstValSpecialStatic &&
20569 casted_count->value.special == ConstValSpecialStatic &&22077 casted_count->value.special == ConstValSpecialStatic &&
...@@ -20661,7 +22169,7 @@ static IrInstruction *ir_analyze_instruction_memcpy(IrAnalyze *ira, IrInstructio...@@ -20661,7 +22169,7 @@ static IrInstruction *ir_analyze_instruction_memcpy(IrAnalyze *ira, IrInstructio
20661 // TODO check for noalias violations - this should be generalized to work for any function22169 // TODO check for noalias violations - this should be generalized to work for any function
2066222170
20663 for (size_t i = 0; i < count; i += 1) {22171 for (size_t i = 0; i < count; i += 1) {
20664 dest_elements[dest_start + i] = src_elements[src_start + i];22172 copy_const_val(&dest_elements[dest_start + i], &src_elements[src_start + i], true);
20665 }22173 }
2066622174
20667 return ir_const_void(ira, &instruction->base);22175 return ir_const_void(ira, &instruction->base);
...@@ -20673,7 +22181,7 @@ static IrInstruction *ir_analyze_instruction_memcpy(IrAnalyze *ira, IrInstructio...@@ -20673,7 +22181,7 @@ static IrInstruction *ir_analyze_instruction_memcpy(IrAnalyze *ira, IrInstructio
20673 return result;22181 return result;
20674}22182}
2067522183
20676static IrInstruction *ir_analyze_instruction_slice(IrAnalyze *ira, IrInstructionSlice *instruction) {22184static IrInstruction *ir_analyze_instruction_slice(IrAnalyze *ira, IrInstructionSliceSrc *instruction) {
20677 IrInstruction *ptr_ptr = instruction->ptr->child;22185 IrInstruction *ptr_ptr = instruction->ptr->child;
20678 if (type_is_invalid(ptr_ptr->value.type))22186 if (type_is_invalid(ptr_ptr->value.type))
20679 return ira->codegen->invalid_instruction;22187 return ira->codegen->invalid_instruction;
...@@ -20962,12 +22470,13 @@ static IrInstruction *ir_analyze_instruction_slice(IrAnalyze *ira, IrInstruction...@@ -20962,12 +22470,13 @@ static IrInstruction *ir_analyze_instruction_slice(IrAnalyze *ira, IrInstruction
20962 return result;22470 return result;
20963 }22471 }
2096422472
20965 IrInstruction *new_instruction = ir_build_slice(&ira->new_irb,22473 IrInstruction *result_loc = ir_resolve_result(ira, &instruction->base, instruction->result_loc,
20966 instruction->base.scope, instruction->base.source_node,22474 return_type, nullptr, true, false);
20967 ptr_ptr, casted_start, end, instruction->safety_check_on);22475 if (type_is_invalid(result_loc->value.type) || instr_is_unreachable(result_loc)) {
20968 new_instruction->value.type = return_type;22476 return result_loc;
20969 ir_add_alloca(ira, new_instruction, return_type);22477 }
20970 return new_instruction;22478 return ir_build_slice_gen(ira, &instruction->base, return_type,
22479 ptr_ptr, casted_start, end, instruction->safety_check_on, result_loc);
20971}22480}
2097222481
20973static IrInstruction *ir_analyze_instruction_member_count(IrAnalyze *ira, IrInstructionMemberCount *instruction) {22482static IrInstruction *ir_analyze_instruction_member_count(IrAnalyze *ira, IrInstructionMemberCount *instruction) {
...@@ -21291,6 +22800,19 @@ static IrInstruction *ir_analyze_instruction_overflow_op(IrAnalyze *ira, IrInstr...@@ -21291,6 +22800,19 @@ static IrInstruction *ir_analyze_instruction_overflow_op(IrAnalyze *ira, IrInstr
21291 return result;22800 return result;
21292}22801}
2129322802
22803static IrInstruction *ir_analyze_instruction_result_ptr(IrAnalyze *ira, IrInstructionResultPtr *instruction) {
22804 IrInstruction *result = instruction->result->child;
22805 if (type_is_invalid(result->value.type))
22806 return result;
22807
22808 if (instruction->result_loc->written && instruction->result_loc->resolved_loc != nullptr &&
22809 !instr_is_comptime(result))
22810 {
22811 return instruction->result_loc->resolved_loc;
22812 }
22813 return ir_get_ref(ira, &instruction->base, result, true, false);
22814}
22815
21294static void ir_eval_mul_add(IrAnalyze *ira, IrInstructionMulAdd *source_instr, ZigType *float_type,22816static void ir_eval_mul_add(IrAnalyze *ira, IrInstructionMulAdd *source_instr, ZigType *float_type,
21295 ConstExprValue *op1, ConstExprValue *op2, ConstExprValue *op3, ConstExprValue *out_val) {22817 ConstExprValue *op1, ConstExprValue *op2, ConstExprValue *op3, ConstExprValue *out_val) {
21296 if (float_type->id == ZigTypeIdComptimeFloat) {22818 if (float_type->id == ZigTypeIdComptimeFloat) {
...@@ -21410,15 +22932,17 @@ static IrInstruction *ir_analyze_instruction_mul_add(IrAnalyze *ira, IrInstructi...@@ -21410,15 +22932,17 @@ static IrInstruction *ir_analyze_instruction_mul_add(IrAnalyze *ira, IrInstructi
21410 return result;22932 return result;
21411}22933}
2141222934
21413static IrInstruction *ir_analyze_instruction_test_err(IrAnalyze *ira, IrInstructionTestErr *instruction) {22935static IrInstruction *ir_analyze_instruction_test_err(IrAnalyze *ira, IrInstructionTestErrSrc *instruction) {
21414 IrInstruction *value = instruction->value->child;22936 IrInstruction *base_ptr = instruction->base_ptr->child;
21415 if (type_is_invalid(value->value.type))22937 if (type_is_invalid(base_ptr->value.type))
21416 return ira->codegen->invalid_instruction;22938 return ira->codegen->invalid_instruction;
2141722939
22940 IrInstruction *value = ir_get_deref(ira, &instruction->base, base_ptr, nullptr);
21418 ZigType *type_entry = value->value.type;22941 ZigType *type_entry = value->value.type;
21419 if (type_is_invalid(type_entry)) {22942 if (type_is_invalid(type_entry))
21420 return ira->codegen->invalid_instruction;22943 return ira->codegen->invalid_instruction;
21421 } else if (type_entry->id == ZigTypeIdErrorUnion) {22944
22945 if (type_entry->id == ZigTypeIdErrorUnion) {
21422 if (instr_is_comptime(value)) {22946 if (instr_is_comptime(value)) {
21423 ConstExprValue *err_union_val = ir_resolve_const(ira, value, UndefBad);22947 ConstExprValue *err_union_val = ir_resolve_const(ira, value, UndefBad);
21424 if (!err_union_val)22948 if (!err_union_val)
...@@ -21430,21 +22954,20 @@ static IrInstruction *ir_analyze_instruction_test_err(IrAnalyze *ira, IrInstruct...@@ -21430,21 +22954,20 @@ static IrInstruction *ir_analyze_instruction_test_err(IrAnalyze *ira, IrInstruct
21430 }22954 }
21431 }22955 }
2143222956
21433 ZigType *err_set_type = type_entry->data.error_union.err_set_type;22957 if (instruction->resolve_err_set) {
21434 if (!resolve_inferred_error_set(ira->codegen, err_set_type, instruction->base.source_node)) {22958 ZigType *err_set_type = type_entry->data.error_union.err_set_type;
21435 return ira->codegen->invalid_instruction;22959 if (!resolve_inferred_error_set(ira->codegen, err_set_type, instruction->base.source_node)) {
21436 }22960 return ira->codegen->invalid_instruction;
21437 if (!type_is_global_error_set(err_set_type) &&22961 }
21438 err_set_type->data.error_set.err_count == 0)22962 if (!type_is_global_error_set(err_set_type) &&
21439 {22963 err_set_type->data.error_set.err_count == 0)
21440 assert(err_set_type->data.error_set.infer_fn == nullptr);22964 {
21441 return ir_const_bool(ira, &instruction->base, false);22965 assert(err_set_type->data.error_set.infer_fn == nullptr);
22966 return ir_const_bool(ira, &instruction->base, false);
22967 }
21442 }22968 }
2144322969
21444 IrInstruction *result = ir_build_test_err(&ira->new_irb,22970 return ir_build_test_err_gen(ira, &instruction->base, value);
21445 instruction->base.scope, instruction->base.source_node, value);
21446 result->value.type = ira->codegen->builtin_types.entry_bool;
21447 return result;
21448 } else if (type_entry->id == ZigTypeIdErrorSet) {22971 } else if (type_entry->id == ZigTypeIdErrorSet) {
21449 return ir_const_bool(ira, &instruction->base, true);22972 return ir_const_bool(ira, &instruction->base, true);
21450 } else {22973 } else {
...@@ -21452,10 +22975,9 @@ static IrInstruction *ir_analyze_instruction_test_err(IrAnalyze *ira, IrInstruct...@@ -21452,10 +22975,9 @@ static IrInstruction *ir_analyze_instruction_test_err(IrAnalyze *ira, IrInstruct
21452 }22975 }
21453}22976}
2145422977
21455static IrInstruction *ir_analyze_instruction_unwrap_err_code(IrAnalyze *ira, IrInstructionUnwrapErrCode *instruction) {22978static IrInstruction *ir_analyze_unwrap_err_code(IrAnalyze *ira, IrInstruction *source_instr,
21456 IrInstruction *base_ptr = instruction->err_union->child;22979 IrInstruction *base_ptr, bool initializing)
21457 if (type_is_invalid(base_ptr->value.type))22980{
21458 return ira->codegen->invalid_instruction;
21459 ZigType *ptr_type = base_ptr->value.type;22981 ZigType *ptr_type = base_ptr->value.type;
2146022982
21461 // This will be a pointer type because unwrap err payload IR instruction operates on a pointer to a thing.22983 // This will be a pointer type because unwrap err payload IR instruction operates on a pointer to a thing.
...@@ -21471,40 +22993,79 @@ static IrInstruction *ir_analyze_instruction_unwrap_err_code(IrAnalyze *ira, IrI...@@ -21471,40 +22993,79 @@ static IrInstruction *ir_analyze_instruction_unwrap_err_code(IrAnalyze *ira, IrI
21471 return ira->codegen->invalid_instruction;22993 return ira->codegen->invalid_instruction;
21472 }22994 }
2147322995
22996 ZigType *err_set_type = type_entry->data.error_union.err_set_type;
22997 ZigType *result_type = get_pointer_to_type_extra(ira->codegen, err_set_type,
22998 ptr_type->data.pointer.is_const, ptr_type->data.pointer.is_volatile, PtrLenSingle,
22999 ptr_type->data.pointer.explicit_alignment, 0, 0, false);
23000
21474 if (instr_is_comptime(base_ptr)) {23001 if (instr_is_comptime(base_ptr)) {
21475 ConstExprValue *ptr_val = ir_resolve_const(ira, base_ptr, UndefBad);23002 ConstExprValue *ptr_val = ir_resolve_const(ira, base_ptr, UndefBad);
21476 if (!ptr_val)23003 if (!ptr_val)
21477 return ira->codegen->invalid_instruction;23004 return ira->codegen->invalid_instruction;
21478 if (ptr_val->data.x_ptr.mut != ConstPtrMutRuntimeVar) {23005 if (ptr_val->data.x_ptr.mut != ConstPtrMutRuntimeVar &&
21479 ConstExprValue *err_union_val = const_ptr_pointee(ira, ira->codegen, ptr_val, instruction->base.source_node);23006 ptr_val->data.x_ptr.special != ConstPtrSpecialHardCodedAddr)
23007 {
23008 ConstExprValue *err_union_val = const_ptr_pointee(ira, ira->codegen, ptr_val, source_instr->source_node);
21480 if (err_union_val == nullptr)23009 if (err_union_val == nullptr)
21481 return ira->codegen->invalid_instruction;23010 return ira->codegen->invalid_instruction;
21482 if (err_union_val->special != ConstValSpecialRuntime) {
21483 ErrorTableEntry *err = err_union_val->data.x_err_union.error_set->data.x_err_set;
21484 assert(err);
2148523011
21486 IrInstruction *result = ir_const(ira, &instruction->base,23012 if (initializing && err_union_val->special == ConstValSpecialUndef) {
21487 type_entry->data.error_union.err_set_type);23013 ConstExprValue *vals = create_const_vals(2);
21488 result->value.data.x_err_set = err;23014 ConstExprValue *err_set_val = &vals[0];
21489 return result;23015 ConstExprValue *payload_val = &vals[1];
23016
23017 err_set_val->special = ConstValSpecialUndef;
23018 err_set_val->type = err_set_type;
23019 err_set_val->parent.id = ConstParentIdErrUnionCode;
23020 err_set_val->parent.data.p_err_union_code.err_union_val = err_union_val;
23021
23022 payload_val->special = ConstValSpecialUndef;
23023 payload_val->type = type_entry->data.error_union.payload_type;
23024 payload_val->parent.id = ConstParentIdErrUnionPayload;
23025 payload_val->parent.data.p_err_union_payload.err_union_val = err_union_val;
23026
23027 err_union_val->special = ConstValSpecialStatic;
23028 err_union_val->data.x_err_union.error_set = err_set_val;
23029 err_union_val->data.x_err_union.payload = payload_val;
23030 }
23031 ir_assert(err_union_val->special != ConstValSpecialRuntime, source_instr);
23032
23033 IrInstruction *result;
23034 if (ptr_val->data.x_ptr.mut == ConstPtrMutInfer) {
23035 result = ir_build_unwrap_err_code(&ira->new_irb, source_instr->scope,
23036 source_instr->source_node, base_ptr);
23037 result->value.type = result_type;
23038 result->value.special = ConstValSpecialStatic;
23039 } else {
23040 result = ir_const(ira, source_instr, result_type);
21490 }23041 }
23042 ConstExprValue *const_val = &result->value;
23043 const_val->data.x_ptr.special = ConstPtrSpecialBaseErrorUnionCode;
23044 const_val->data.x_ptr.data.base_err_union_code.err_union_val = err_union_val;
23045 const_val->data.x_ptr.mut = ptr_val->data.x_ptr.mut;
23046 return result;
21491 }23047 }
21492 }23048 }
2149323049
21494 IrInstruction *result = ir_build_unwrap_err_code(&ira->new_irb,23050 IrInstruction *result = ir_build_unwrap_err_code(&ira->new_irb,
21495 instruction->base.scope, instruction->base.source_node, base_ptr);23051 source_instr->scope, source_instr->source_node, base_ptr);
21496 result->value.type = type_entry->data.error_union.err_set_type;23052 result->value.type = result_type;
21497 return result;23053 return result;
21498}23054}
2149923055
21500static IrInstruction *ir_analyze_instruction_unwrap_err_payload(IrAnalyze *ira,23056static IrInstruction *ir_analyze_instruction_unwrap_err_code(IrAnalyze *ira,
21501 IrInstructionUnwrapErrPayload *instruction)23057 IrInstructionUnwrapErrCode *instruction)
21502{23058{
21503 assert(instruction->value->child);23059 IrInstruction *base_ptr = instruction->err_union_ptr->child;
21504 IrInstruction *value = instruction->value->child;23060 if (type_is_invalid(base_ptr->value.type))
21505 if (type_is_invalid(value->value.type))
21506 return ira->codegen->invalid_instruction;23061 return ira->codegen->invalid_instruction;
21507 ZigType *ptr_type = value->value.type;23062 return ir_analyze_unwrap_err_code(ira, &instruction->base, base_ptr, false);
23063}
23064
23065static IrInstruction *ir_analyze_unwrap_error_payload(IrAnalyze *ira, IrInstruction *source_instr,
23066 IrInstruction *base_ptr, bool safety_check_on, bool initializing)
23067{
23068 ZigType *ptr_type = base_ptr->value.type;
2150823069
21509 // This will be a pointer type because unwrap err payload IR instruction operates on a pointer to a thing.23070 // This will be a pointer type because unwrap err payload IR instruction operates on a pointer to a thing.
21510 assert(ptr_type->id == ZigTypeIdPointer);23071 assert(ptr_type->id == ZigTypeIdPointer);
...@@ -21514,7 +23075,7 @@ static IrInstruction *ir_analyze_instruction_unwrap_err_payload(IrAnalyze *ira,...@@ -21514,7 +23075,7 @@ static IrInstruction *ir_analyze_instruction_unwrap_err_payload(IrAnalyze *ira,
21514 return ira->codegen->invalid_instruction;23075 return ira->codegen->invalid_instruction;
2151523076
21516 if (type_entry->id != ZigTypeIdErrorUnion) {23077 if (type_entry->id != ZigTypeIdErrorUnion) {
21517 ir_add_error(ira, value,23078 ir_add_error(ira, base_ptr,
21518 buf_sprintf("expected error union type, found '%s'", buf_ptr(&type_entry->name)));23079 buf_sprintf("expected error union type, found '%s'", buf_ptr(&type_entry->name)));
21519 return ira->codegen->invalid_instruction;23080 return ira->codegen->invalid_instruction;
21520 }23081 }
...@@ -21526,36 +23087,73 @@ static IrInstruction *ir_analyze_instruction_unwrap_err_payload(IrAnalyze *ira,...@@ -21526,36 +23087,73 @@ static IrInstruction *ir_analyze_instruction_unwrap_err_payload(IrAnalyze *ira,
21526 ZigType *result_type = get_pointer_to_type_extra(ira->codegen, payload_type,23087 ZigType *result_type = get_pointer_to_type_extra(ira->codegen, payload_type,
21527 ptr_type->data.pointer.is_const, ptr_type->data.pointer.is_volatile,23088 ptr_type->data.pointer.is_const, ptr_type->data.pointer.is_volatile,
21528 PtrLenSingle, 0, 0, 0, false);23089 PtrLenSingle, 0, 0, 0, false);
21529 if (instr_is_comptime(value)) {23090 if (instr_is_comptime(base_ptr)) {
21530 ConstExprValue *ptr_val = ir_resolve_const(ira, value, UndefBad);23091 ConstExprValue *ptr_val = ir_resolve_const(ira, base_ptr, UndefBad);
21531 if (!ptr_val)23092 if (!ptr_val)
21532 return ira->codegen->invalid_instruction;23093 return ira->codegen->invalid_instruction;
21533 if (ptr_val->data.x_ptr.mut != ConstPtrMutRuntimeVar) {23094 if (ptr_val->data.x_ptr.mut != ConstPtrMutRuntimeVar) {
21534 ConstExprValue *err_union_val = const_ptr_pointee(ira, ira->codegen, ptr_val, instruction->base.source_node);23095 ConstExprValue *err_union_val = const_ptr_pointee(ira, ira->codegen, ptr_val, source_instr->source_node);
21535 if (err_union_val == nullptr)23096 if (err_union_val == nullptr)
21536 return ira->codegen->invalid_instruction;23097 return ira->codegen->invalid_instruction;
23098 if (err_union_val->special == ConstValSpecialUndef && initializing) {
23099 ConstExprValue *vals = create_const_vals(2);
23100 ConstExprValue *err_set_val = &vals[0];
23101 ConstExprValue *payload_val = &vals[1];
23102
23103 err_set_val->special = ConstValSpecialStatic;
23104 err_set_val->type = type_entry->data.error_union.err_set_type;
23105 err_set_val->data.x_err_set = nullptr;
23106
23107 payload_val->special = ConstValSpecialUndef;
23108 payload_val->type = payload_type;
23109
23110 err_union_val->special = ConstValSpecialStatic;
23111 err_union_val->data.x_err_union.error_set = err_set_val;
23112 err_union_val->data.x_err_union.payload = payload_val;
23113 }
23114
21537 if (err_union_val->special != ConstValSpecialRuntime) {23115 if (err_union_val->special != ConstValSpecialRuntime) {
21538 ErrorTableEntry *err = err_union_val->data.x_err_union.error_set->data.x_err_set;23116 ErrorTableEntry *err = err_union_val->data.x_err_union.error_set->data.x_err_set;
21539 if (err != nullptr) {23117 if (err != nullptr) {
21540 ir_add_error(ira, &instruction->base,23118 ir_add_error(ira, source_instr,
21541 buf_sprintf("caught unexpected error '%s'", buf_ptr(&err->name)));23119 buf_sprintf("caught unexpected error '%s'", buf_ptr(&err->name)));
21542 return ira->codegen->invalid_instruction;23120 return ira->codegen->invalid_instruction;
21543 }23121 }
2154423122
21545 IrInstruction *result = ir_const(ira, &instruction->base, result_type);23123 IrInstruction *result;
23124 if (ptr_val->data.x_ptr.mut == ConstPtrMutInfer) {
23125 result = ir_build_unwrap_err_payload(&ira->new_irb, source_instr->scope,
23126 source_instr->source_node, base_ptr, safety_check_on, initializing);
23127 result->value.type = result_type;
23128 result->value.special = ConstValSpecialStatic;
23129 } else {
23130 result = ir_const(ira, source_instr, result_type);
23131 }
21546 result->value.data.x_ptr.special = ConstPtrSpecialRef;23132 result->value.data.x_ptr.special = ConstPtrSpecialRef;
21547 result->value.data.x_ptr.data.ref.pointee = err_union_val->data.x_err_union.payload;23133 result->value.data.x_ptr.data.ref.pointee = err_union_val->data.x_err_union.payload;
23134 result->value.data.x_ptr.mut = ptr_val->data.x_ptr.mut;
21548 return result;23135 return result;
21549 }23136 }
21550 }23137 }
21551 }23138 }
2155223139
21553 IrInstruction *result = ir_build_unwrap_err_payload(&ira->new_irb,23140 IrInstruction *result = ir_build_unwrap_err_payload(&ira->new_irb, source_instr->scope,
21554 instruction->base.scope, instruction->base.source_node, value, instruction->safety_check_on);23141 source_instr->source_node, base_ptr, safety_check_on, initializing);
21555 result->value.type = result_type;23142 result->value.type = result_type;
21556 return result;23143 return result;
21557}23144}
2155823145
23146static IrInstruction *ir_analyze_instruction_unwrap_err_payload(IrAnalyze *ira,
23147 IrInstructionUnwrapErrPayload *instruction)
23148{
23149 assert(instruction->value->child);
23150 IrInstruction *value = instruction->value->child;
23151 if (type_is_invalid(value->value.type))
23152 return ira->codegen->invalid_instruction;
23153
23154 return ir_analyze_unwrap_error_payload(ira, &instruction->base, value, instruction->safety_check_on, false);
23155}
23156
21559static IrInstruction *ir_analyze_instruction_fn_proto(IrAnalyze *ira, IrInstructionFnProto *instruction) {23157static IrInstruction *ir_analyze_instruction_fn_proto(IrAnalyze *ira, IrInstructionFnProto *instruction) {
21560 AstNode *proto_node = instruction->base.source_node;23158 AstNode *proto_node = instruction->base.source_node;
21561 assert(proto_node->type == NodeTypeFnProto);23159 assert(proto_node->type == NodeTypeFnProto);
...@@ -22047,14 +23645,19 @@ static IrInstruction *ir_analyze_ptr_cast(IrAnalyze *ira, IrInstruction *source_...@@ -22047,14 +23645,19 @@ static IrInstruction *ir_analyze_ptr_cast(IrAnalyze *ira, IrInstruction *source_
22047 }23645 }
22048 }23646 }
2204923647
22050 IrInstruction *result = ir_const(ira, source_instr, dest_type);23648 IrInstruction *result;
23649 if (ptr->value.data.x_ptr.mut == ConstPtrMutInfer) {
23650 result = ir_build_ptr_cast_gen(ira, source_instr, dest_type, ptr, safety_check_on);
23651 } else {
23652 result = ir_const(ira, source_instr, dest_type);
23653 }
22051 copy_const_val(&result->value, val, true);23654 copy_const_val(&result->value, val, true);
22052 result->value.type = dest_type;23655 result->value.type = dest_type;
2205323656
22054 // Keep the bigger alignment, it can only help-23657 // Keep the bigger alignment, it can only help-
22055 // unless the target is zero bits.23658 // unless the target is zero bits.
22056 if (src_align_bytes > dest_align_bytes && type_has_bits(dest_type)) {23659 if (src_align_bytes > dest_align_bytes && type_has_bits(dest_type)) {
22057 result = ir_align_cast(ira, result, src_align_bytes, false);23660 result = ir_align_cast(ira, result, src_align_bytes, false);
22058 }23661 }
2205923662
22060 return result;23663 return result;
...@@ -22138,6 +23741,8 @@ static void buf_write_value_bytes(CodeGen *codegen, uint8_t *buf, ConstExprValue...@@ -22138,6 +23741,8 @@ static void buf_write_value_bytes(CodeGen *codegen, uint8_t *buf, ConstExprValue
22138 case ZigTypeIdUndefined:23741 case ZigTypeIdUndefined:
22139 case ZigTypeIdNull:23742 case ZigTypeIdNull:
22140 case ZigTypeIdPromise:23743 case ZigTypeIdPromise:
23744 case ZigTypeIdErrorUnion:
23745 case ZigTypeIdErrorSet:
22141 zig_unreachable();23746 zig_unreachable();
22142 case ZigTypeIdVoid:23747 case ZigTypeIdVoid:
22143 return;23748 return;
...@@ -22241,10 +23846,6 @@ static void buf_write_value_bytes(CodeGen *codegen, uint8_t *buf, ConstExprValue...@@ -22241,10 +23846,6 @@ static void buf_write_value_bytes(CodeGen *codegen, uint8_t *buf, ConstExprValue
22241 }23846 }
22242 case ZigTypeIdOptional:23847 case ZigTypeIdOptional:
22243 zig_panic("TODO buf_write_value_bytes maybe type");23848 zig_panic("TODO buf_write_value_bytes maybe type");
22244 case ZigTypeIdErrorUnion:
22245 zig_panic("TODO buf_write_value_bytes error union");
22246 case ZigTypeIdErrorSet:
22247 zig_panic("TODO buf_write_value_bytes pure error type");
22248 case ZigTypeIdFn:23849 case ZigTypeIdFn:
22249 zig_panic("TODO buf_write_value_bytes fn type");23850 zig_panic("TODO buf_write_value_bytes fn type");
22250 case ZigTypeIdUnion:23851 case ZigTypeIdUnion:
...@@ -22433,28 +24034,6 @@ static Error buf_read_value_bytes(IrAnalyze *ira, CodeGen *codegen, AstNode *sou...@@ -22433,28 +24034,6 @@ static Error buf_read_value_bytes(IrAnalyze *ira, CodeGen *codegen, AstNode *sou
22433 zig_unreachable();24034 zig_unreachable();
22434}24035}
2243524036
22436static bool type_can_bit_cast(ZigType *t) {
22437 switch (t->id) {
22438 case ZigTypeIdInvalid:
22439 zig_unreachable();
22440 case ZigTypeIdMetaType:
22441 case ZigTypeIdOpaque:
22442 case ZigTypeIdBoundFn:
22443 case ZigTypeIdArgTuple:
22444 case ZigTypeIdUnreachable:
22445 case ZigTypeIdComptimeFloat:
22446 case ZigTypeIdComptimeInt:
22447 case ZigTypeIdEnumLiteral:
22448 case ZigTypeIdUndefined:
22449 case ZigTypeIdNull:
22450 case ZigTypeIdPointer:
22451 return false;
22452 default:
22453 // TODO list these types out explicitly, there are probably some other invalid ones here
22454 return true;
22455 }
22456}
22457
22458static IrInstruction *ir_analyze_bit_cast(IrAnalyze *ira, IrInstruction *source_instr, IrInstruction *value,24037static IrInstruction *ir_analyze_bit_cast(IrAnalyze *ira, IrInstruction *source_instr, IrInstruction *value,
22459 ZigType *dest_type)24038 ZigType *dest_type)
22460{24039{
...@@ -22506,49 +24085,7 @@ static IrInstruction *ir_analyze_bit_cast(IrAnalyze *ira, IrInstruction *source_...@@ -22506,49 +24085,7 @@ static IrInstruction *ir_analyze_bit_cast(IrAnalyze *ira, IrInstruction *source_
22506 return result;24085 return result;
22507 }24086 }
2250824087
22509 IrInstruction *result = ir_build_bit_cast_gen(ira, source_instr, value, dest_type);24088 return ir_build_bit_cast_gen(ira, source_instr, value, dest_type);
22510 if (handle_is_ptr(dest_type) && !handle_is_ptr(src_type)) {
22511 ir_add_alloca(ira, result, dest_type);
22512 }
22513 return result;
22514}
22515
22516static IrInstruction *ir_analyze_instruction_bit_cast(IrAnalyze *ira, IrInstructionBitCast *instruction) {
22517 IrInstruction *dest_type_value = instruction->dest_type->child;
22518 ZigType *dest_type = ir_resolve_type(ira, dest_type_value);
22519 if (type_is_invalid(dest_type))
22520 return ira->codegen->invalid_instruction;
22521
22522 IrInstruction *value = instruction->value->child;
22523 ZigType *src_type = value->value.type;
22524 if (type_is_invalid(src_type))
22525 return ira->codegen->invalid_instruction;
22526
22527 if (get_codegen_ptr_type(src_type) != nullptr) {
22528 ir_add_error(ira, value,
22529 buf_sprintf("unable to @bitCast from pointer type '%s'", buf_ptr(&src_type->name)));
22530 return ira->codegen->invalid_instruction;
22531 }
22532
22533 if (!type_can_bit_cast(src_type)) {
22534 ir_add_error(ira, dest_type_value,
22535 buf_sprintf("unable to @bitCast from type '%s'", buf_ptr(&src_type->name)));
22536 return ira->codegen->invalid_instruction;
22537 }
22538
22539 if (get_codegen_ptr_type(dest_type) != nullptr) {
22540 ir_add_error(ira, dest_type_value,
22541 buf_sprintf("unable to @bitCast to pointer type '%s'", buf_ptr(&dest_type->name)));
22542 return ira->codegen->invalid_instruction;
22543 }
22544
22545 if (!type_can_bit_cast(dest_type)) {
22546 ir_add_error(ira, dest_type_value,
22547 buf_sprintf("unable to @bitCast to type '%s'", buf_ptr(&dest_type->name)));
22548 return ira->codegen->invalid_instruction;
22549 }
22550
22551 return ir_analyze_bit_cast(ira, &instruction->base, value, dest_type);
22552}24089}
2255324090
22554static IrInstruction *ir_analyze_int_to_ptr(IrAnalyze *ira, IrInstruction *source_instr, IrInstruction *target,24091static IrInstruction *ir_analyze_int_to_ptr(IrAnalyze *ira, IrInstruction *source_instr, IrInstruction *target,
...@@ -22618,58 +24155,15 @@ static IrInstruction *ir_analyze_instruction_int_to_ptr(IrAnalyze *ira, IrInstru...@@ -22618,58 +24155,15 @@ static IrInstruction *ir_analyze_instruction_int_to_ptr(IrAnalyze *ira, IrInstru
22618static IrInstruction *ir_analyze_instruction_decl_ref(IrAnalyze *ira,24155static IrInstruction *ir_analyze_instruction_decl_ref(IrAnalyze *ira,
22619 IrInstructionDeclRef *instruction)24156 IrInstructionDeclRef *instruction)
22620{24157{
22621 Tld *tld = instruction->tld;24158 IrInstruction *ref_instruction = ir_analyze_decl_ref(ira, &instruction->base, instruction->tld);
22622 LVal lval = instruction->lval;24159 if (type_is_invalid(ref_instruction->value.type))
22623
22624 resolve_top_level_decl(ira->codegen, tld, instruction->base.source_node);
22625 if (tld->resolution == TldResolutionInvalid)
22626 return ira->codegen->invalid_instruction;24160 return ira->codegen->invalid_instruction;
2262724161
22628 switch (tld->id) {24162 if (instruction->lval == LValPtr) {
22629 case TldIdContainer:24163 return ref_instruction;
22630 case TldIdCompTime:24164 } else {
22631 zig_unreachable();24165 return ir_get_deref(ira, &instruction->base, ref_instruction, nullptr);
22632 case TldIdVar: {
22633 TldVar *tld_var = (TldVar *)tld;
22634 ZigVar *var = tld_var->var;
22635
22636 if (var == nullptr) {
22637 return ir_error_dependency_loop(ira, &instruction->base);
22638 }
22639
22640 IrInstruction *var_ptr = ir_get_var_ptr(ira, &instruction->base, var);
22641 if (type_is_invalid(var_ptr->value.type))
22642 return ira->codegen->invalid_instruction;
22643
22644 if (tld_var->extern_lib_name != nullptr) {
22645 add_link_lib_symbol(ira, tld_var->extern_lib_name, &var->name, instruction->base.source_node);
22646 }
22647
22648 if (lval == LValPtr) {
22649 return var_ptr;
22650 } else {
22651 return ir_get_deref(ira, &instruction->base, var_ptr);
22652 }
22653 }
22654 case TldIdFn: {
22655 TldFn *tld_fn = (TldFn *)tld;
22656 ZigFn *fn_entry = tld_fn->fn_entry;
22657 ir_assert(fn_entry->type_entry, &instruction->base);
22658
22659 if (tld_fn->extern_lib_name != nullptr) {
22660 add_link_lib_symbol(ira, tld_fn->extern_lib_name, &fn_entry->symbol_name, instruction->base.source_node);
22661 }
22662
22663 IrInstruction *ref_instruction = ir_create_const_fn(&ira->new_irb, instruction->base.scope,
22664 instruction->base.source_node, fn_entry);
22665 if (lval == LValPtr) {
22666 return ir_get_ref(ira, &instruction->base, ref_instruction, true, false);
22667 } else {
22668 return ref_instruction;
22669 }
22670 }
22671 }24166 }
22672 zig_unreachable();
22673}24167}
2267424168
22675static IrInstruction *ir_analyze_instruction_ptr_to_int(IrAnalyze *ira, IrInstructionPtrToInt *instruction) {24169static IrInstruction *ir_analyze_instruction_ptr_to_int(IrAnalyze *ira, IrInstructionPtrToInt *instruction) {
...@@ -23183,7 +24677,7 @@ static IrInstruction *ir_analyze_instruction_atomic_load(IrAnalyze *ira, IrInstr...@@ -23183,7 +24677,7 @@ static IrInstruction *ir_analyze_instruction_atomic_load(IrAnalyze *ira, IrInstr
23183 }24677 }
2318424678
23185 if (instr_is_comptime(casted_ptr)) {24679 if (instr_is_comptime(casted_ptr)) {
23186 IrInstruction *result = ir_get_deref(ira, &instruction->base, casted_ptr);24680 IrInstruction *result = ir_get_deref(ira, &instruction->base, casted_ptr, nullptr);
23187 ir_assert(result->value.type != nullptr, &instruction->base);24681 ir_assert(result->value.type != nullptr, &instruction->base);
23188 return result;24682 return result;
23189 }24683 }
...@@ -23721,12 +25215,56 @@ static IrInstruction *ir_analyze_instruction_undeclared_ident(IrAnalyze *ira, Ir...@@ -23721,12 +25215,56 @@ static IrInstruction *ir_analyze_instruction_undeclared_ident(IrAnalyze *ira, Ir
23721 return ira->codegen->invalid_instruction;25215 return ira->codegen->invalid_instruction;
23722}25216}
2372325217
23724static IrInstruction *ir_analyze_instruction_nocast(IrAnalyze *ira, IrInstruction *instruction) {25218static IrInstruction *ir_analyze_instruction_end_expr(IrAnalyze *ira, IrInstructionEndExpr *instruction) {
25219 IrInstruction *value = instruction->value->child;
25220 if (type_is_invalid(value->value.type))
25221 return ira->codegen->invalid_instruction;
25222
25223 bool was_written = instruction->result_loc->written;
25224 IrInstruction *result_loc = ir_resolve_result(ira, &instruction->base, instruction->result_loc,
25225 value->value.type, value, false, false);
25226 if (result_loc != nullptr) {
25227 if (type_is_invalid(result_loc->value.type))
25228 return ira->codegen->invalid_instruction;
25229 if (result_loc->value.type->id == ZigTypeIdUnreachable)
25230 return result_loc;
25231
25232 if (!was_written) {
25233 IrInstruction *store_ptr = ir_analyze_store_ptr(ira, &instruction->base, result_loc, value);
25234 if (type_is_invalid(store_ptr->value.type)) {
25235 return ira->codegen->invalid_instruction;
25236 }
25237 }
25238
25239 if (result_loc->value.data.x_ptr.mut == ConstPtrMutInfer) {
25240 if (instr_is_comptime(value)) {
25241 result_loc->value.data.x_ptr.mut = ConstPtrMutComptimeConst;
25242 } else {
25243 result_loc->value.special = ConstValSpecialRuntime;
25244 }
25245 }
25246 }
25247
25248 return ir_const_void(ira, &instruction->base);
25249}
25250
25251static IrInstruction *ir_analyze_instruction_bit_cast_src(IrAnalyze *ira, IrInstructionBitCastSrc *instruction) {
25252 IrInstruction *operand = instruction->operand->child;
25253 if (type_is_invalid(operand->value.type))
25254 return operand;
25255
25256 IrInstruction *result_loc = ir_resolve_result(ira, &instruction->base,
25257 &instruction->result_loc_bit_cast->base, operand->value.type, operand, false, false);
25258 if (result_loc != nullptr && (type_is_invalid(result_loc->value.type) || instr_is_unreachable(result_loc)))
25259 return result_loc;
25260
25261 return instruction->result_loc_bit_cast->parent->gen_instruction;
25262}
25263
25264static IrInstruction *ir_analyze_instruction_base(IrAnalyze *ira, IrInstruction *instruction) {
23725 switch (instruction->id) {25265 switch (instruction->id) {
23726 case IrInstructionIdInvalid:25266 case IrInstructionIdInvalid:
23727 case IrInstructionIdWidenOrShorten:25267 case IrInstructionIdWidenOrShorten:
23728 case IrInstructionIdStructInit:
23729 case IrInstructionIdUnionInit:
23730 case IrInstructionIdStructFieldPtr:25268 case IrInstructionIdStructFieldPtr:
23731 case IrInstructionIdUnionFieldPtr:25269 case IrInstructionIdUnionFieldPtr:
23732 case IrInstructionIdOptionalWrap:25270 case IrInstructionIdOptionalWrap:
...@@ -23738,11 +25276,18 @@ static IrInstruction *ir_analyze_instruction_nocast(IrAnalyze *ira, IrInstructio...@@ -23738,11 +25276,18 @@ static IrInstruction *ir_analyze_instruction_nocast(IrAnalyze *ira, IrInstructio
23738 case IrInstructionIdCmpxchgGen:25276 case IrInstructionIdCmpxchgGen:
23739 case IrInstructionIdArrayToVector:25277 case IrInstructionIdArrayToVector:
23740 case IrInstructionIdVectorToArray:25278 case IrInstructionIdVectorToArray:
25279 case IrInstructionIdPtrOfArrayToSlice:
23741 case IrInstructionIdAssertZero:25280 case IrInstructionIdAssertZero:
23742 case IrInstructionIdAssertNonNull:25281 case IrInstructionIdAssertNonNull:
23743 case IrInstructionIdResizeSlice:25282 case IrInstructionIdResizeSlice:
23744 case IrInstructionIdLoadPtrGen:25283 case IrInstructionIdLoadPtrGen:
23745 case IrInstructionIdBitCastGen:25284 case IrInstructionIdBitCastGen:
25285 case IrInstructionIdCallGen:
25286 case IrInstructionIdReturnPtr:
25287 case IrInstructionIdAllocaGen:
25288 case IrInstructionIdSliceGen:
25289 case IrInstructionIdRefGen:
25290 case IrInstructionIdTestErrGen:
23746 zig_unreachable();25291 zig_unreachable();
2374725292
23748 case IrInstructionIdReturn:25293 case IrInstructionIdReturn:
...@@ -23765,8 +25310,8 @@ static IrInstruction *ir_analyze_instruction_nocast(IrAnalyze *ira, IrInstructio...@@ -23765,8 +25310,8 @@ static IrInstruction *ir_analyze_instruction_nocast(IrAnalyze *ira, IrInstructio
23765 return ir_analyze_instruction_var_ptr(ira, (IrInstructionVarPtr *)instruction);25310 return ir_analyze_instruction_var_ptr(ira, (IrInstructionVarPtr *)instruction);
23766 case IrInstructionIdFieldPtr:25311 case IrInstructionIdFieldPtr:
23767 return ir_analyze_instruction_field_ptr(ira, (IrInstructionFieldPtr *)instruction);25312 return ir_analyze_instruction_field_ptr(ira, (IrInstructionFieldPtr *)instruction);
23768 case IrInstructionIdCall:25313 case IrInstructionIdCallSrc:
23769 return ir_analyze_instruction_call(ira, (IrInstructionCall *)instruction);25314 return ir_analyze_instruction_call(ira, (IrInstructionCallSrc *)instruction);
23770 case IrInstructionIdBr:25315 case IrInstructionIdBr:
23771 return ir_analyze_instruction_br(ira, (IrInstructionBr *)instruction);25316 return ir_analyze_instruction_br(ira, (IrInstructionBr *)instruction);
23772 case IrInstructionIdCondBr:25317 case IrInstructionIdCondBr:
...@@ -23777,10 +25322,6 @@ static IrInstruction *ir_analyze_instruction_nocast(IrAnalyze *ira, IrInstructio...@@ -23777,10 +25322,6 @@ static IrInstruction *ir_analyze_instruction_nocast(IrAnalyze *ira, IrInstructio
23777 return ir_analyze_instruction_phi(ira, (IrInstructionPhi *)instruction);25322 return ir_analyze_instruction_phi(ira, (IrInstructionPhi *)instruction);
23778 case IrInstructionIdTypeOf:25323 case IrInstructionIdTypeOf:
23779 return ir_analyze_instruction_typeof(ira, (IrInstructionTypeOf *)instruction);25324 return ir_analyze_instruction_typeof(ira, (IrInstructionTypeOf *)instruction);
23780 case IrInstructionIdToPtrType:
23781 return ir_analyze_instruction_to_ptr_type(ira, (IrInstructionToPtrType *)instruction);
23782 case IrInstructionIdPtrTypeChild:
23783 return ir_analyze_instruction_ptr_type_child(ira, (IrInstructionPtrTypeChild *)instruction);
23784 case IrInstructionIdSetCold:25325 case IrInstructionIdSetCold:
23785 return ir_analyze_instruction_set_cold(ira, (IrInstructionSetCold *)instruction);25326 return ir_analyze_instruction_set_cold(ira, (IrInstructionSetCold *)instruction);
23786 case IrInstructionIdSetRuntimeSafety:25327 case IrInstructionIdSetRuntimeSafety:
...@@ -23881,8 +25422,8 @@ static IrInstruction *ir_analyze_instruction_nocast(IrAnalyze *ira, IrInstructio...@@ -23881,8 +25422,8 @@ static IrInstruction *ir_analyze_instruction_nocast(IrAnalyze *ira, IrInstructio
23881 return ir_analyze_instruction_memset(ira, (IrInstructionMemset *)instruction);25422 return ir_analyze_instruction_memset(ira, (IrInstructionMemset *)instruction);
23882 case IrInstructionIdMemcpy:25423 case IrInstructionIdMemcpy:
23883 return ir_analyze_instruction_memcpy(ira, (IrInstructionMemcpy *)instruction);25424 return ir_analyze_instruction_memcpy(ira, (IrInstructionMemcpy *)instruction);
23884 case IrInstructionIdSlice:25425 case IrInstructionIdSliceSrc:
23885 return ir_analyze_instruction_slice(ira, (IrInstructionSlice *)instruction);25426 return ir_analyze_instruction_slice(ira, (IrInstructionSliceSrc *)instruction);
23886 case IrInstructionIdMemberCount:25427 case IrInstructionIdMemberCount:
23887 return ir_analyze_instruction_member_count(ira, (IrInstructionMemberCount *)instruction);25428 return ir_analyze_instruction_member_count(ira, (IrInstructionMemberCount *)instruction);
23888 case IrInstructionIdMemberType:25429 case IrInstructionIdMemberType:
...@@ -23901,8 +25442,8 @@ static IrInstruction *ir_analyze_instruction_nocast(IrAnalyze *ira, IrInstructio...@@ -23901,8 +25442,8 @@ static IrInstruction *ir_analyze_instruction_nocast(IrAnalyze *ira, IrInstructio
23901 return ir_analyze_instruction_align_of(ira, (IrInstructionAlignOf *)instruction);25442 return ir_analyze_instruction_align_of(ira, (IrInstructionAlignOf *)instruction);
23902 case IrInstructionIdOverflowOp:25443 case IrInstructionIdOverflowOp:
23903 return ir_analyze_instruction_overflow_op(ira, (IrInstructionOverflowOp *)instruction);25444 return ir_analyze_instruction_overflow_op(ira, (IrInstructionOverflowOp *)instruction);
23904 case IrInstructionIdTestErr:25445 case IrInstructionIdTestErrSrc:
23905 return ir_analyze_instruction_test_err(ira, (IrInstructionTestErr *)instruction);25446 return ir_analyze_instruction_test_err(ira, (IrInstructionTestErrSrc *)instruction);
23906 case IrInstructionIdUnwrapErrCode:25447 case IrInstructionIdUnwrapErrCode:
23907 return ir_analyze_instruction_unwrap_err_code(ira, (IrInstructionUnwrapErrCode *)instruction);25448 return ir_analyze_instruction_unwrap_err_code(ira, (IrInstructionUnwrapErrCode *)instruction);
23908 case IrInstructionIdUnwrapErrPayload:25449 case IrInstructionIdUnwrapErrPayload:
...@@ -23921,8 +25462,6 @@ static IrInstruction *ir_analyze_instruction_nocast(IrAnalyze *ira, IrInstructio...@@ -23921,8 +25462,6 @@ static IrInstruction *ir_analyze_instruction_nocast(IrAnalyze *ira, IrInstructio
23921 return ir_analyze_instruction_panic(ira, (IrInstructionPanic *)instruction);25462 return ir_analyze_instruction_panic(ira, (IrInstructionPanic *)instruction);
23922 case IrInstructionIdPtrCastSrc:25463 case IrInstructionIdPtrCastSrc:
23923 return ir_analyze_instruction_ptr_cast(ira, (IrInstructionPtrCastSrc *)instruction);25464 return ir_analyze_instruction_ptr_cast(ira, (IrInstructionPtrCastSrc *)instruction);
23924 case IrInstructionIdBitCast:
23925 return ir_analyze_instruction_bit_cast(ira, (IrInstructionBitCast *)instruction);
23926 case IrInstructionIdIntToPtr:25465 case IrInstructionIdIntToPtr:
23927 return ir_analyze_instruction_int_to_ptr(ira, (IrInstructionIntToPtr *)instruction);25466 return ir_analyze_instruction_int_to_ptr(ira, (IrInstructionIntToPtr *)instruction);
23928 case IrInstructionIdPtrToInt:25467 case IrInstructionIdPtrToInt:
...@@ -23945,6 +25484,14 @@ static IrInstruction *ir_analyze_instruction_nocast(IrAnalyze *ira, IrInstructio...@@ -23945,6 +25484,14 @@ static IrInstruction *ir_analyze_instruction_nocast(IrAnalyze *ira, IrInstructio
23945 return ir_analyze_instruction_ptr_type(ira, (IrInstructionPtrType *)instruction);25484 return ir_analyze_instruction_ptr_type(ira, (IrInstructionPtrType *)instruction);
23946 case IrInstructionIdAlignCast:25485 case IrInstructionIdAlignCast:
23947 return ir_analyze_instruction_align_cast(ira, (IrInstructionAlignCast *)instruction);25486 return ir_analyze_instruction_align_cast(ira, (IrInstructionAlignCast *)instruction);
25487 case IrInstructionIdImplicitCast:
25488 return ir_analyze_instruction_implicit_cast(ira, (IrInstructionImplicitCast *)instruction);
25489 case IrInstructionIdResolveResult:
25490 return ir_analyze_instruction_resolve_result(ira, (IrInstructionResolveResult *)instruction);
25491 case IrInstructionIdResetResult:
25492 return ir_analyze_instruction_reset_result(ira, (IrInstructionResetResult *)instruction);
25493 case IrInstructionIdResultPtr:
25494 return ir_analyze_instruction_result_ptr(ira, (IrInstructionResultPtr *)instruction);
23948 case IrInstructionIdOpaqueType:25495 case IrInstructionIdOpaqueType:
23949 return ir_analyze_instruction_opaque_type(ira, (IrInstructionOpaqueType *)instruction);25496 return ir_analyze_instruction_opaque_type(ira, (IrInstructionOpaqueType *)instruction);
23950 case IrInstructionIdSetAlignStack:25497 case IrInstructionIdSetAlignStack:
...@@ -24021,17 +25568,16 @@ static IrInstruction *ir_analyze_instruction_nocast(IrAnalyze *ira, IrInstructio...@@ -24021,17 +25568,16 @@ static IrInstruction *ir_analyze_instruction_nocast(IrAnalyze *ira, IrInstructio
24021 return ir_analyze_instruction_has_decl(ira, (IrInstructionHasDecl *)instruction);25568 return ir_analyze_instruction_has_decl(ira, (IrInstructionHasDecl *)instruction);
24022 case IrInstructionIdUndeclaredIdent:25569 case IrInstructionIdUndeclaredIdent:
24023 return ir_analyze_instruction_undeclared_ident(ira, (IrInstructionUndeclaredIdent *)instruction);25570 return ir_analyze_instruction_undeclared_ident(ira, (IrInstructionUndeclaredIdent *)instruction);
25571 case IrInstructionIdAllocaSrc:
25572 return nullptr;
25573 case IrInstructionIdEndExpr:
25574 return ir_analyze_instruction_end_expr(ira, (IrInstructionEndExpr *)instruction);
25575 case IrInstructionIdBitCastSrc:
25576 return ir_analyze_instruction_bit_cast_src(ira, (IrInstructionBitCastSrc *)instruction);
24024 }25577 }
24025 zig_unreachable();25578 zig_unreachable();
24026}25579}
2402725580
24028static IrInstruction *ir_analyze_instruction(IrAnalyze *ira, IrInstruction *old_instruction) {
24029 IrInstruction *new_instruction = ir_analyze_instruction_nocast(ira, old_instruction);
24030 ir_assert(new_instruction->value.type != nullptr, old_instruction);
24031 old_instruction->child = new_instruction;
24032 return new_instruction;
24033}
24034
24035// This function attempts to evaluate IR code while doing type checking and other analysis.25581// This function attempts to evaluate IR code while doing type checking and other analysis.
24036// It emits a new IrExecutable which is partially evaluated IR code.25582// It emits a new IrExecutable which is partially evaluated IR code.
24037ZigType *ir_analyze(CodeGen *codegen, IrExecutable *old_exec, IrExecutable *new_exec,25583ZigType *ir_analyze(CodeGen *codegen, IrExecutable *old_exec, IrExecutable *new_exec,
...@@ -24077,14 +25623,22 @@ ZigType *ir_analyze(CodeGen *codegen, IrExecutable *old_exec, IrExecutable *new_...@@ -24077,14 +25623,22 @@ ZigType *ir_analyze(CodeGen *codegen, IrExecutable *old_exec, IrExecutable *new_
24077 continue;25623 continue;
24078 }25624 }
2407925625
24080 IrInstruction *new_instruction = ir_analyze_instruction(ira, old_instruction);25626 if (ira->codegen->verbose_ir) {
24081 if (type_is_invalid(new_instruction->value.type) && ir_should_inline(new_exec, old_instruction->scope)) {25627 fprintf(stderr, "analyze #%zu\n", old_instruction->debug_id);
24082 return ira->codegen->builtin_types.entry_invalid;
24083 }25628 }
25629 IrInstruction *new_instruction = ir_analyze_instruction_base(ira, old_instruction);
25630 if (new_instruction != nullptr) {
25631 ir_assert(new_instruction->value.type != nullptr || new_instruction->value.type != nullptr, old_instruction);
25632 old_instruction->child = new_instruction;
2408425633
24085 // unreachable instructions do their own control flow.25634 if (type_is_invalid(new_instruction->value.type)) {
24086 if (new_instruction->value.type->id == ZigTypeIdUnreachable)25635 return ira->codegen->builtin_types.entry_invalid;
24087 continue;25636 }
25637
25638 // unreachable instructions do their own control flow.
25639 if (new_instruction->value.type->id == ZigTypeIdUnreachable)
25640 continue;
25641 }
2408825642
24089 ira->instruction_index += 1;25643 ira->instruction_index += 1;
24090 }25644 }
...@@ -24109,7 +25663,8 @@ bool ir_has_side_effects(IrInstruction *instruction) {...@@ -24109,7 +25663,8 @@ bool ir_has_side_effects(IrInstruction *instruction) {
24109 case IrInstructionIdDeclVarSrc:25663 case IrInstructionIdDeclVarSrc:
24110 case IrInstructionIdDeclVarGen:25664 case IrInstructionIdDeclVarGen:
24111 case IrInstructionIdStorePtr:25665 case IrInstructionIdStorePtr:
24112 case IrInstructionIdCall:25666 case IrInstructionIdCallSrc:
25667 case IrInstructionIdCallGen:
24113 case IrInstructionIdReturn:25668 case IrInstructionIdReturn:
24114 case IrInstructionIdUnreachable:25669 case IrInstructionIdUnreachable:
24115 case IrInstructionIdSetCold:25670 case IrInstructionIdSetCold:
...@@ -24156,27 +25711,28 @@ bool ir_has_side_effects(IrInstruction *instruction) {...@@ -24156,27 +25711,28 @@ bool ir_has_side_effects(IrInstruction *instruction) {
24156 case IrInstructionIdResizeSlice:25711 case IrInstructionIdResizeSlice:
24157 case IrInstructionIdGlobalAsm:25712 case IrInstructionIdGlobalAsm:
24158 case IrInstructionIdUndeclaredIdent:25713 case IrInstructionIdUndeclaredIdent:
25714 case IrInstructionIdEndExpr:
25715 case IrInstructionIdPtrOfArrayToSlice:
25716 case IrInstructionIdSliceGen:
25717 case IrInstructionIdOptionalWrap:
25718 case IrInstructionIdVectorToArray:
25719 case IrInstructionIdResetResult:
24159 return true;25720 return true;
2416025721
24161 case IrInstructionIdPhi:25722 case IrInstructionIdPhi:
24162 case IrInstructionIdUnOp:25723 case IrInstructionIdUnOp:
24163 case IrInstructionIdBinOp:25724 case IrInstructionIdBinOp:
24164 case IrInstructionIdLoadPtr:25725 case IrInstructionIdLoadPtr:
24165 case IrInstructionIdLoadPtrGen:
24166 case IrInstructionIdConst:25726 case IrInstructionIdConst:
24167 case IrInstructionIdCast:25727 case IrInstructionIdCast:
24168 case IrInstructionIdContainerInitList:25728 case IrInstructionIdContainerInitList:
24169 case IrInstructionIdContainerInitFields:25729 case IrInstructionIdContainerInitFields:
24170 case IrInstructionIdStructInit:
24171 case IrInstructionIdUnionInit:
24172 case IrInstructionIdFieldPtr:25730 case IrInstructionIdFieldPtr:
24173 case IrInstructionIdElemPtr:25731 case IrInstructionIdElemPtr:
24174 case IrInstructionIdVarPtr:25732 case IrInstructionIdVarPtr:
25733 case IrInstructionIdReturnPtr:
24175 case IrInstructionIdTypeOf:25734 case IrInstructionIdTypeOf:
24176 case IrInstructionIdToPtrType:
24177 case IrInstructionIdPtrTypeChild:
24178 case IrInstructionIdStructFieldPtr:25735 case IrInstructionIdStructFieldPtr:
24179 case IrInstructionIdUnionFieldPtr:
24180 case IrInstructionIdArrayType:25736 case IrInstructionIdArrayType:
24181 case IrInstructionIdPromiseType:25737 case IrInstructionIdPromiseType:
24182 case IrInstructionIdSliceType:25738 case IrInstructionIdSliceType:
...@@ -24198,7 +25754,7 @@ bool ir_has_side_effects(IrInstruction *instruction) {...@@ -24198,7 +25754,7 @@ bool ir_has_side_effects(IrInstruction *instruction) {
24198 case IrInstructionIdIntType:25754 case IrInstructionIdIntType:
24199 case IrInstructionIdVectorType:25755 case IrInstructionIdVectorType:
24200 case IrInstructionIdBoolNot:25756 case IrInstructionIdBoolNot:
24201 case IrInstructionIdSlice:25757 case IrInstructionIdSliceSrc:
24202 case IrInstructionIdMemberCount:25758 case IrInstructionIdMemberCount:
24203 case IrInstructionIdMemberType:25759 case IrInstructionIdMemberType:
24204 case IrInstructionIdMemberName:25760 case IrInstructionIdMemberName:
...@@ -24206,16 +25762,13 @@ bool ir_has_side_effects(IrInstruction *instruction) {...@@ -24206,16 +25762,13 @@ bool ir_has_side_effects(IrInstruction *instruction) {
24206 case IrInstructionIdReturnAddress:25762 case IrInstructionIdReturnAddress:
24207 case IrInstructionIdFrameAddress:25763 case IrInstructionIdFrameAddress:
24208 case IrInstructionIdHandle:25764 case IrInstructionIdHandle:
24209 case IrInstructionIdTestErr:25765 case IrInstructionIdTestErrSrc:
24210 case IrInstructionIdUnwrapErrCode:25766 case IrInstructionIdTestErrGen:
24211 case IrInstructionIdOptionalWrap:
24212 case IrInstructionIdErrWrapCode:
24213 case IrInstructionIdErrWrapPayload:
24214 case IrInstructionIdFnProto:25767 case IrInstructionIdFnProto:
24215 case IrInstructionIdTestComptime:25768 case IrInstructionIdTestComptime:
24216 case IrInstructionIdPtrCastSrc:25769 case IrInstructionIdPtrCastSrc:
24217 case IrInstructionIdPtrCastGen:25770 case IrInstructionIdPtrCastGen:
24218 case IrInstructionIdBitCast:25771 case IrInstructionIdBitCastSrc:
24219 case IrInstructionIdBitCastGen:25772 case IrInstructionIdBitCastGen:
24220 case IrInstructionIdWidenOrShorten:25773 case IrInstructionIdWidenOrShorten:
24221 case IrInstructionIdPtrToInt:25774 case IrInstructionIdPtrToInt:
...@@ -24233,6 +25786,8 @@ bool ir_has_side_effects(IrInstruction *instruction) {...@@ -24233,6 +25786,8 @@ bool ir_has_side_effects(IrInstruction *instruction) {
24233 case IrInstructionIdTypeInfo:25786 case IrInstructionIdTypeInfo:
24234 case IrInstructionIdTypeId:25787 case IrInstructionIdTypeId:
24235 case IrInstructionIdAlignCast:25788 case IrInstructionIdAlignCast:
25789 case IrInstructionIdImplicitCast:
25790 case IrInstructionIdResolveResult:
24236 case IrInstructionIdOpaqueType:25791 case IrInstructionIdOpaqueType:
24237 case IrInstructionIdArgType:25792 case IrInstructionIdArgType:
24238 case IrInstructionIdTagType:25793 case IrInstructionIdTagType:
...@@ -24257,9 +25812,11 @@ bool ir_has_side_effects(IrInstruction *instruction) {...@@ -24257,9 +25812,11 @@ bool ir_has_side_effects(IrInstruction *instruction) {
24257 case IrInstructionIdFromBytes:25812 case IrInstructionIdFromBytes:
24258 case IrInstructionIdToBytes:25813 case IrInstructionIdToBytes:
24259 case IrInstructionIdEnumToInt:25814 case IrInstructionIdEnumToInt:
24260 case IrInstructionIdVectorToArray:
24261 case IrInstructionIdArrayToVector:25815 case IrInstructionIdArrayToVector:
24262 case IrInstructionIdHasDecl:25816 case IrInstructionIdHasDecl:
25817 case IrInstructionIdAllocaSrc:
25818 case IrInstructionIdAllocaGen:
25819 case IrInstructionIdResultPtr:
24263 return false;25820 return false;
2426425821
24265 case IrInstructionIdAsm:25822 case IrInstructionIdAsm:
...@@ -24271,8 +25828,21 @@ bool ir_has_side_effects(IrInstruction *instruction) {...@@ -24271,8 +25828,21 @@ bool ir_has_side_effects(IrInstruction *instruction) {
24271 {25828 {
24272 IrInstructionUnwrapErrPayload *unwrap_err_payload_instruction =25829 IrInstructionUnwrapErrPayload *unwrap_err_payload_instruction =
24273 (IrInstructionUnwrapErrPayload *)instruction;25830 (IrInstructionUnwrapErrPayload *)instruction;
24274 return unwrap_err_payload_instruction->safety_check_on;25831 return unwrap_err_payload_instruction->safety_check_on ||
25832 unwrap_err_payload_instruction->initializing;
24275 }25833 }
25834 case IrInstructionIdUnwrapErrCode:
25835 return reinterpret_cast<IrInstructionUnwrapErrCode *>(instruction)->initializing;
25836 case IrInstructionIdUnionFieldPtr:
25837 return reinterpret_cast<IrInstructionUnionFieldPtr *>(instruction)->initializing;
25838 case IrInstructionIdErrWrapPayload:
25839 return reinterpret_cast<IrInstructionErrWrapPayload *>(instruction)->result_loc != nullptr;
25840 case IrInstructionIdErrWrapCode:
25841 return reinterpret_cast<IrInstructionErrWrapCode *>(instruction)->result_loc != nullptr;
25842 case IrInstructionIdLoadPtrGen:
25843 return reinterpret_cast<IrInstructionLoadPtrGen *>(instruction)->result_loc != nullptr;
25844 case IrInstructionIdRefGen:
25845 return reinterpret_cast<IrInstructionRefGen *>(instruction)->result_loc != nullptr;
24276 }25846 }
24277 zig_unreachable();25847 zig_unreachable();
24278}25848}
src/ir_print.cpp+253-90
...@@ -57,13 +57,18 @@ static void ir_print_other_instruction(IrPrint *irp, IrInstruction *instruction)...@@ -57,13 +57,18 @@ static void ir_print_other_instruction(IrPrint *irp, IrInstruction *instruction)
57}57}
5858
59static void ir_print_other_block(IrPrint *irp, IrBasicBlock *bb) {59static void ir_print_other_block(IrPrint *irp, IrBasicBlock *bb) {
60 fprintf(irp->f, "$%s_%" ZIG_PRI_usize "", bb->name_hint, bb->debug_id);60 if (bb == nullptr) {
61 fprintf(irp->f, "(null block)");
62 } else {
63 fprintf(irp->f, "$%s_%" ZIG_PRI_usize "", bb->name_hint, bb->debug_id);
64 }
61}65}
6266
63static void ir_print_return(IrPrint *irp, IrInstructionReturn *return_instruction) {67static void ir_print_return(IrPrint *irp, IrInstructionReturn *return_instruction) {
64 assert(return_instruction->value);
65 fprintf(irp->f, "return ");68 fprintf(irp->f, "return ");
66 ir_print_other_instruction(irp, return_instruction->value);69 if (return_instruction->value != nullptr) {
70 ir_print_other_instruction(irp, return_instruction->value);
71 }
67}72}
6873
69static void ir_print_const(IrPrint *irp, IrInstructionConst *const_instruction) {74static void ir_print_const(IrPrint *irp, IrInstructionConst *const_instruction) {
...@@ -188,7 +193,7 @@ static void ir_print_decl_var_src(IrPrint *irp, IrInstructionDeclVarSrc *decl_va...@@ -188,7 +193,7 @@ static void ir_print_decl_var_src(IrPrint *irp, IrInstructionDeclVarSrc *decl_va
188 fprintf(irp->f, " ");193 fprintf(irp->f, " ");
189 }194 }
190 fprintf(irp->f, "= ");195 fprintf(irp->f, "= ");
191 ir_print_other_instruction(irp, decl_var_instruction->init_value);196 ir_print_other_instruction(irp, decl_var_instruction->ptr);
192 if (decl_var_instruction->var->is_comptime != nullptr) {197 if (decl_var_instruction->var->is_comptime != nullptr) {
193 fprintf(irp->f, " // comptime = ");198 fprintf(irp->f, " // comptime = ");
194 ir_print_other_instruction(irp, decl_var_instruction->var->is_comptime);199 ir_print_other_instruction(irp, decl_var_instruction->var->is_comptime);
...@@ -201,7 +206,56 @@ static void ir_print_cast(IrPrint *irp, IrInstructionCast *cast_instruction) {...@@ -201,7 +206,56 @@ static void ir_print_cast(IrPrint *irp, IrInstructionCast *cast_instruction) {
201 fprintf(irp->f, " to %s", buf_ptr(&cast_instruction->dest_type->name));206 fprintf(irp->f, " to %s", buf_ptr(&cast_instruction->dest_type->name));
202}207}
203208
204static void ir_print_call(IrPrint *irp, IrInstructionCall *call_instruction) {209static void ir_print_result_loc_var(IrPrint *irp, ResultLocVar *result_loc_var) {
210 fprintf(irp->f, "var(");
211 ir_print_other_instruction(irp, result_loc_var->base.source_instruction);
212 fprintf(irp->f, ")");
213}
214
215static void ir_print_result_loc_instruction(IrPrint *irp, ResultLocInstruction *result_loc_inst) {
216 fprintf(irp->f, "inst(");
217 ir_print_other_instruction(irp, result_loc_inst->base.source_instruction);
218 fprintf(irp->f, ")");
219}
220
221static void ir_print_result_loc_peer(IrPrint *irp, ResultLocPeer *result_loc_peer) {
222 fprintf(irp->f, "peer(next=");
223 ir_print_other_block(irp, result_loc_peer->next_bb);
224 fprintf(irp->f, ")");
225}
226
227static void ir_print_result_loc_bit_cast(IrPrint *irp, ResultLocBitCast *result_loc_bit_cast) {
228 fprintf(irp->f, "bitcast(ty=");
229 ir_print_other_instruction(irp, result_loc_bit_cast->base.source_instruction);
230 fprintf(irp->f, ")");
231}
232
233static void ir_print_result_loc(IrPrint *irp, ResultLoc *result_loc) {
234 switch (result_loc->id) {
235 case ResultLocIdInvalid:
236 zig_unreachable();
237 case ResultLocIdNone:
238 fprintf(irp->f, "none");
239 return;
240 case ResultLocIdReturn:
241 fprintf(irp->f, "return");
242 return;
243 case ResultLocIdVar:
244 return ir_print_result_loc_var(irp, (ResultLocVar *)result_loc);
245 case ResultLocIdInstruction:
246 return ir_print_result_loc_instruction(irp, (ResultLocInstruction *)result_loc);
247 case ResultLocIdPeer:
248 return ir_print_result_loc_peer(irp, (ResultLocPeer *)result_loc);
249 case ResultLocIdBitCast:
250 return ir_print_result_loc_bit_cast(irp, (ResultLocBitCast *)result_loc);
251 case ResultLocIdPeerParent:
252 fprintf(irp->f, "peer_parent");
253 return;
254 }
255 zig_unreachable();
256}
257
258static void ir_print_call_src(IrPrint *irp, IrInstructionCallSrc *call_instruction) {
205 if (call_instruction->is_async) {259 if (call_instruction->is_async) {
206 fprintf(irp->f, "async");260 fprintf(irp->f, "async");
207 if (call_instruction->async_allocator != nullptr) {261 if (call_instruction->async_allocator != nullptr) {
...@@ -224,7 +278,35 @@ static void ir_print_call(IrPrint *irp, IrInstructionCall *call_instruction) {...@@ -224,7 +278,35 @@ static void ir_print_call(IrPrint *irp, IrInstructionCall *call_instruction) {
224 fprintf(irp->f, ", ");278 fprintf(irp->f, ", ");
225 ir_print_other_instruction(irp, arg);279 ir_print_other_instruction(irp, arg);
226 }280 }
227 fprintf(irp->f, ")");281 fprintf(irp->f, ")result=");
282 ir_print_result_loc(irp, call_instruction->result_loc);
283}
284
285static void ir_print_call_gen(IrPrint *irp, IrInstructionCallGen *call_instruction) {
286 if (call_instruction->is_async) {
287 fprintf(irp->f, "async");
288 if (call_instruction->async_allocator != nullptr) {
289 fprintf(irp->f, "<");
290 ir_print_other_instruction(irp, call_instruction->async_allocator);
291 fprintf(irp->f, ">");
292 }
293 fprintf(irp->f, " ");
294 }
295 if (call_instruction->fn_entry) {
296 fprintf(irp->f, "%s", buf_ptr(&call_instruction->fn_entry->symbol_name));
297 } else {
298 assert(call_instruction->fn_ref);
299 ir_print_other_instruction(irp, call_instruction->fn_ref);
300 }
301 fprintf(irp->f, "(");
302 for (size_t i = 0; i < call_instruction->arg_count; i += 1) {
303 IrInstruction *arg = call_instruction->args[i];
304 if (i != 0)
305 fprintf(irp->f, ", ");
306 ir_print_other_instruction(irp, arg);
307 }
308 fprintf(irp->f, ")result=");
309 ir_print_other_instruction(irp, call_instruction->result_loc);
228}310}
229311
230static void ir_print_cond_br(IrPrint *irp, IrInstructionCondBr *cond_br_instruction) {312static void ir_print_cond_br(IrPrint *irp, IrInstructionCondBr *cond_br_instruction) {
...@@ -270,10 +352,10 @@ static void ir_print_container_init_list(IrPrint *irp, IrInstructionContainerIni...@@ -270,10 +352,10 @@ static void ir_print_container_init_list(IrPrint *irp, IrInstructionContainerIni
270 fprintf(irp->f, "...(%" ZIG_PRI_usize " items)...", instruction->item_count);352 fprintf(irp->f, "...(%" ZIG_PRI_usize " items)...", instruction->item_count);
271 } else {353 } else {
272 for (size_t i = 0; i < instruction->item_count; i += 1) {354 for (size_t i = 0; i < instruction->item_count; i += 1) {
273 IrInstruction *item = instruction->items[i];355 IrInstruction *result_loc = instruction->elem_result_loc_list[i];
274 if (i != 0)356 if (i != 0)
275 fprintf(irp->f, ", ");357 fprintf(irp->f, ", ");
276 ir_print_other_instruction(irp, item);358 ir_print_other_instruction(irp, result_loc);
277 }359 }
278 }360 }
279 fprintf(irp->f, "}");361 fprintf(irp->f, "}");
...@@ -286,32 +368,11 @@ static void ir_print_container_init_fields(IrPrint *irp, IrInstructionContainerI...@@ -286,32 +368,11 @@ static void ir_print_container_init_fields(IrPrint *irp, IrInstructionContainerI
286 IrInstructionContainerInitFieldsField *field = &instruction->fields[i];368 IrInstructionContainerInitFieldsField *field = &instruction->fields[i];
287 const char *comma = (i == 0) ? "" : ", ";369 const char *comma = (i == 0) ? "" : ", ";
288 fprintf(irp->f, "%s.%s = ", comma, buf_ptr(field->name));370 fprintf(irp->f, "%s.%s = ", comma, buf_ptr(field->name));
289 ir_print_other_instruction(irp, field->value);371 ir_print_other_instruction(irp, field->result_loc);
290 }372 }
291 fprintf(irp->f, "} // container init");373 fprintf(irp->f, "} // container init");
292}374}
293375
294static void ir_print_struct_init(IrPrint *irp, IrInstructionStructInit *instruction) {
295 fprintf(irp->f, "%s {", buf_ptr(&instruction->struct_type->name));
296 for (size_t i = 0; i < instruction->field_count; i += 1) {
297 IrInstructionStructInitField *field = &instruction->fields[i];
298 Buf *field_name = field->type_struct_field->name;
299 const char *comma = (i == 0) ? "" : ", ";
300 fprintf(irp->f, "%s.%s = ", comma, buf_ptr(field_name));
301 ir_print_other_instruction(irp, field->value);
302 }
303 fprintf(irp->f, "} // struct init");
304}
305
306static void ir_print_union_init(IrPrint *irp, IrInstructionUnionInit *instruction) {
307 Buf *field_name = instruction->field->enum_field->name;
308
309 fprintf(irp->f, "%s {", buf_ptr(&instruction->union_type->name));
310 fprintf(irp->f, ".%s = ", buf_ptr(field_name));
311 ir_print_other_instruction(irp, instruction->init_value);
312 fprintf(irp->f, "} // union init");
313}
314
315static void ir_print_unreachable(IrPrint *irp, IrInstructionUnreachable *instruction) {376static void ir_print_unreachable(IrPrint *irp, IrInstructionUnreachable *instruction) {
316 fprintf(irp->f, "unreachable");377 fprintf(irp->f, "unreachable");
317}378}
...@@ -331,14 +392,20 @@ static void ir_print_var_ptr(IrPrint *irp, IrInstructionVarPtr *instruction) {...@@ -331,14 +392,20 @@ static void ir_print_var_ptr(IrPrint *irp, IrInstructionVarPtr *instruction) {
331 fprintf(irp->f, "&%s", buf_ptr(&instruction->var->name));392 fprintf(irp->f, "&%s", buf_ptr(&instruction->var->name));
332}393}
333394
395static void ir_print_return_ptr(IrPrint *irp, IrInstructionReturnPtr *instruction) {
396 fprintf(irp->f, "@ReturnPtr");
397}
398
334static void ir_print_load_ptr(IrPrint *irp, IrInstructionLoadPtr *instruction) {399static void ir_print_load_ptr(IrPrint *irp, IrInstructionLoadPtr *instruction) {
335 ir_print_other_instruction(irp, instruction->ptr);400 ir_print_other_instruction(irp, instruction->ptr);
336 fprintf(irp->f, ".*");401 fprintf(irp->f, ".*");
337}402}
338403
339static void ir_print_load_ptr_gen(IrPrint *irp, IrInstructionLoadPtrGen *instruction) {404static void ir_print_load_ptr_gen(IrPrint *irp, IrInstructionLoadPtrGen *instruction) {
405 fprintf(irp->f, "loadptr(");
340 ir_print_other_instruction(irp, instruction->ptr);406 ir_print_other_instruction(irp, instruction->ptr);
341 fprintf(irp->f, ".*");407 fprintf(irp->f, ")result=");
408 ir_print_other_instruction(irp, instruction->result_loc);
342}409}
343410
344static void ir_print_store_ptr(IrPrint *irp, IrInstructionStorePtr *instruction) {411static void ir_print_store_ptr(IrPrint *irp, IrInstructionStorePtr *instruction) {
...@@ -354,18 +421,6 @@ static void ir_print_typeof(IrPrint *irp, IrInstructionTypeOf *instruction) {...@@ -354,18 +421,6 @@ static void ir_print_typeof(IrPrint *irp, IrInstructionTypeOf *instruction) {
354 fprintf(irp->f, ")");421 fprintf(irp->f, ")");
355}422}
356423
357static void ir_print_to_ptr_type(IrPrint *irp, IrInstructionToPtrType *instruction) {
358 fprintf(irp->f, "@toPtrType(");
359 ir_print_other_instruction(irp, instruction->ptr);
360 fprintf(irp->f, ")");
361}
362
363static void ir_print_ptr_type_child(IrPrint *irp, IrInstructionPtrTypeChild *instruction) {
364 fprintf(irp->f, "@ptrTypeChild(");
365 ir_print_other_instruction(irp, instruction->value);
366 fprintf(irp->f, ")");
367}
368
369static void ir_print_field_ptr(IrPrint *irp, IrInstructionFieldPtr *instruction) {424static void ir_print_field_ptr(IrPrint *irp, IrInstructionFieldPtr *instruction) {
370 if (instruction->field_name_buffer) {425 if (instruction->field_name_buffer) {
371 fprintf(irp->f, "fieldptr ");426 fprintf(irp->f, "fieldptr ");
...@@ -618,6 +673,13 @@ static void ir_print_ref(IrPrint *irp, IrInstructionRef *instruction) {...@@ -618,6 +673,13 @@ static void ir_print_ref(IrPrint *irp, IrInstructionRef *instruction) {
618 ir_print_other_instruction(irp, instruction->value);673 ir_print_other_instruction(irp, instruction->value);
619}674}
620675
676static void ir_print_ref_gen(IrPrint *irp, IrInstructionRefGen *instruction) {
677 fprintf(irp->f, "@ref(");
678 ir_print_other_instruction(irp, instruction->operand);
679 fprintf(irp->f, ")result=");
680 ir_print_other_instruction(irp, instruction->result_loc);
681}
682
621static void ir_print_compile_err(IrPrint *irp, IrInstructionCompileErr *instruction) {683static void ir_print_compile_err(IrPrint *irp, IrInstructionCompileErr *instruction) {
622 fprintf(irp->f, "@compileError(");684 fprintf(irp->f, "@compileError(");
623 ir_print_other_instruction(irp, instruction->msg);685 ir_print_other_instruction(irp, instruction->msg);
...@@ -682,7 +744,8 @@ static void ir_print_cmpxchg_src(IrPrint *irp, IrInstructionCmpxchgSrc *instruct...@@ -682,7 +744,8 @@ static void ir_print_cmpxchg_src(IrPrint *irp, IrInstructionCmpxchgSrc *instruct
682 ir_print_other_instruction(irp, instruction->success_order_value);744 ir_print_other_instruction(irp, instruction->success_order_value);
683 fprintf(irp->f, ", ");745 fprintf(irp->f, ", ");
684 ir_print_other_instruction(irp, instruction->failure_order_value);746 ir_print_other_instruction(irp, instruction->failure_order_value);
685 fprintf(irp->f, ")");747 fprintf(irp->f, ")result=");
748 ir_print_result_loc(irp, instruction->result_loc);
686}749}
687750
688static void ir_print_cmpxchg_gen(IrPrint *irp, IrInstructionCmpxchgGen *instruction) {751static void ir_print_cmpxchg_gen(IrPrint *irp, IrInstructionCmpxchgGen *instruction) {
...@@ -692,7 +755,8 @@ static void ir_print_cmpxchg_gen(IrPrint *irp, IrInstructionCmpxchgGen *instruct...@@ -692,7 +755,8 @@ static void ir_print_cmpxchg_gen(IrPrint *irp, IrInstructionCmpxchgGen *instruct
692 ir_print_other_instruction(irp, instruction->cmp_value);755 ir_print_other_instruction(irp, instruction->cmp_value);
693 fprintf(irp->f, ", ");756 fprintf(irp->f, ", ");
694 ir_print_other_instruction(irp, instruction->new_value);757 ir_print_other_instruction(irp, instruction->new_value);
695 fprintf(irp->f, ", TODO print atomic orders)");758 fprintf(irp->f, ", TODO print atomic orders)result=");
759 ir_print_other_instruction(irp, instruction->result_loc);
696}760}
697761
698static void ir_print_fence(IrPrint *irp, IrInstructionFence *instruction) {762static void ir_print_fence(IrPrint *irp, IrInstructionFence *instruction) {
...@@ -810,14 +874,26 @@ static void ir_print_memcpy(IrPrint *irp, IrInstructionMemcpy *instruction) {...@@ -810,14 +874,26 @@ static void ir_print_memcpy(IrPrint *irp, IrInstructionMemcpy *instruction) {
810 fprintf(irp->f, ")");874 fprintf(irp->f, ")");
811}875}
812876
813static void ir_print_slice(IrPrint *irp, IrInstructionSlice *instruction) {877static void ir_print_slice_src(IrPrint *irp, IrInstructionSliceSrc *instruction) {
814 ir_print_other_instruction(irp, instruction->ptr);878 ir_print_other_instruction(irp, instruction->ptr);
815 fprintf(irp->f, "[");879 fprintf(irp->f, "[");
816 ir_print_other_instruction(irp, instruction->start);880 ir_print_other_instruction(irp, instruction->start);
817 fprintf(irp->f, "..");881 fprintf(irp->f, "..");
818 if (instruction->end)882 if (instruction->end)
819 ir_print_other_instruction(irp, instruction->end);883 ir_print_other_instruction(irp, instruction->end);
820 fprintf(irp->f, "]");884 fprintf(irp->f, "]result=");
885 ir_print_result_loc(irp, instruction->result_loc);
886}
887
888static void ir_print_slice_gen(IrPrint *irp, IrInstructionSliceGen *instruction) {
889 ir_print_other_instruction(irp, instruction->ptr);
890 fprintf(irp->f, "[");
891 ir_print_other_instruction(irp, instruction->start);
892 fprintf(irp->f, "..");
893 if (instruction->end)
894 ir_print_other_instruction(irp, instruction->end);
895 fprintf(irp->f, "]result=");
896 ir_print_other_instruction(irp, instruction->result_loc);
821}897}
822898
823static void ir_print_member_count(IrPrint *irp, IrInstructionMemberCount *instruction) {899static void ir_print_member_count(IrPrint *irp, IrInstructionMemberCount *instruction) {
...@@ -889,43 +965,49 @@ static void ir_print_overflow_op(IrPrint *irp, IrInstructionOverflowOp *instruct...@@ -889,43 +965,49 @@ static void ir_print_overflow_op(IrPrint *irp, IrInstructionOverflowOp *instruct
889 fprintf(irp->f, ")");965 fprintf(irp->f, ")");
890}966}
891967
892static void ir_print_test_err(IrPrint *irp, IrInstructionTestErr *instruction) {968static void ir_print_test_err_src(IrPrint *irp, IrInstructionTestErrSrc *instruction) {
893 fprintf(irp->f, "@testError(");969 fprintf(irp->f, "@testError(");
894 ir_print_other_instruction(irp, instruction->value);970 ir_print_other_instruction(irp, instruction->base_ptr);
971 fprintf(irp->f, ")");
972}
973
974static void ir_print_test_err_gen(IrPrint *irp, IrInstructionTestErrGen *instruction) {
975 fprintf(irp->f, "@testError(");
976 ir_print_other_instruction(irp, instruction->err_union);
895 fprintf(irp->f, ")");977 fprintf(irp->f, ")");
896}978}
897979
898static void ir_print_unwrap_err_code(IrPrint *irp, IrInstructionUnwrapErrCode *instruction) {980static void ir_print_unwrap_err_code(IrPrint *irp, IrInstructionUnwrapErrCode *instruction) {
899 fprintf(irp->f, "UnwrapErrorCode(");981 fprintf(irp->f, "UnwrapErrorCode(");
900 ir_print_other_instruction(irp, instruction->err_union);982 ir_print_other_instruction(irp, instruction->err_union_ptr);
901 fprintf(irp->f, ")");983 fprintf(irp->f, ")");
902}984}
903985
904static void ir_print_unwrap_err_payload(IrPrint *irp, IrInstructionUnwrapErrPayload *instruction) {986static void ir_print_unwrap_err_payload(IrPrint *irp, IrInstructionUnwrapErrPayload *instruction) {
905 fprintf(irp->f, "ErrorUnionFieldPayload(");987 fprintf(irp->f, "ErrorUnionFieldPayload(");
906 ir_print_other_instruction(irp, instruction->value);988 ir_print_other_instruction(irp, instruction->value);
907 fprintf(irp->f, ")");989 fprintf(irp->f, ")safety=%d,init=%d",instruction->safety_check_on, instruction->initializing);
908 if (!instruction->safety_check_on) {
909 fprintf(irp->f, " // no safety");
910 }
911}990}
912991
913static void ir_print_maybe_wrap(IrPrint *irp, IrInstructionOptionalWrap *instruction) {992static void ir_print_optional_wrap(IrPrint *irp, IrInstructionOptionalWrap *instruction) {
914 fprintf(irp->f, "@maybeWrap(");993 fprintf(irp->f, "@optionalWrap(");
915 ir_print_other_instruction(irp, instruction->value);994 ir_print_other_instruction(irp, instruction->operand);
916 fprintf(irp->f, ")");995 fprintf(irp->f, ")result=");
996 ir_print_other_instruction(irp, instruction->result_loc);
917}997}
918998
919static void ir_print_err_wrap_code(IrPrint *irp, IrInstructionErrWrapCode *instruction) {999static void ir_print_err_wrap_code(IrPrint *irp, IrInstructionErrWrapCode *instruction) {
920 fprintf(irp->f, "@errWrapCode(");1000 fprintf(irp->f, "@errWrapCode(");
921 ir_print_other_instruction(irp, instruction->value);1001 ir_print_other_instruction(irp, instruction->operand);
922 fprintf(irp->f, ")");1002 fprintf(irp->f, ")result=");
1003 ir_print_other_instruction(irp, instruction->result_loc);
923}1004}
9241005
925static void ir_print_err_wrap_payload(IrPrint *irp, IrInstructionErrWrapPayload *instruction) {1006static void ir_print_err_wrap_payload(IrPrint *irp, IrInstructionErrWrapPayload *instruction) {
926 fprintf(irp->f, "@errWrapPayload(");1007 fprintf(irp->f, "@errWrapPayload(");
927 ir_print_other_instruction(irp, instruction->value);1008 ir_print_other_instruction(irp, instruction->operand);
928 fprintf(irp->f, ")");1009 fprintf(irp->f, ")result=");
1010 ir_print_other_instruction(irp, instruction->result_loc);
929}1011}
9301012
931static void ir_print_fn_proto(IrPrint *irp, IrInstructionFnProto *instruction) {1013static void ir_print_fn_proto(IrPrint *irp, IrInstructionFnProto *instruction) {
...@@ -971,12 +1053,11 @@ static void ir_print_ptr_cast_gen(IrPrint *irp, IrInstructionPtrCastGen *instruc...@@ -971,12 +1053,11 @@ static void ir_print_ptr_cast_gen(IrPrint *irp, IrInstructionPtrCastGen *instruc
971 fprintf(irp->f, ")");1053 fprintf(irp->f, ")");
972}1054}
9731055
974static void ir_print_bit_cast(IrPrint *irp, IrInstructionBitCast *instruction) {1056static void ir_print_bit_cast_src(IrPrint *irp, IrInstructionBitCastSrc *instruction) {
975 fprintf(irp->f, "@bitCast(");1057 fprintf(irp->f, "@bitCast(");
976 ir_print_other_instruction(irp, instruction->dest_type);1058 ir_print_other_instruction(irp, instruction->operand);
977 fprintf(irp->f, ",");1059 fprintf(irp->f, ")result=");
978 ir_print_other_instruction(irp, instruction->value);1060 ir_print_result_loc(irp, &instruction->result_loc_bit_cast->base);
979 fprintf(irp->f, ")");
980}1061}
9811062
982static void ir_print_bit_cast_gen(IrPrint *irp, IrInstructionBitCastGen *instruction) {1063static void ir_print_bit_cast_gen(IrPrint *irp, IrInstructionBitCastGen *instruction) {
...@@ -1043,7 +1124,15 @@ static void ir_print_array_to_vector(IrPrint *irp, IrInstructionArrayToVector *i...@@ -1043,7 +1124,15 @@ static void ir_print_array_to_vector(IrPrint *irp, IrInstructionArrayToVector *i
1043static void ir_print_vector_to_array(IrPrint *irp, IrInstructionVectorToArray *instruction) {1124static void ir_print_vector_to_array(IrPrint *irp, IrInstructionVectorToArray *instruction) {
1044 fprintf(irp->f, "VectorToArray(");1125 fprintf(irp->f, "VectorToArray(");
1045 ir_print_other_instruction(irp, instruction->vector);1126 ir_print_other_instruction(irp, instruction->vector);
1046 fprintf(irp->f, ")");1127 fprintf(irp->f, ")result=");
1128 ir_print_other_instruction(irp, instruction->result_loc);
1129}
1130
1131static void ir_print_ptr_of_array_to_slice(IrPrint *irp, IrInstructionPtrOfArrayToSlice *instruction) {
1132 fprintf(irp->f, "PtrOfArrayToSlice(");
1133 ir_print_other_instruction(irp, instruction->operand);
1134 fprintf(irp->f, ")result=");
1135 ir_print_other_instruction(irp, instruction->result_loc);
1047}1136}
10481137
1049static void ir_print_assert_zero(IrPrint *irp, IrInstructionAssertZero *instruction) {1138static void ir_print_assert_zero(IrPrint *irp, IrInstructionAssertZero *instruction) {
...@@ -1061,6 +1150,25 @@ static void ir_print_assert_non_null(IrPrint *irp, IrInstructionAssertNonNull *i...@@ -1061,6 +1150,25 @@ static void ir_print_assert_non_null(IrPrint *irp, IrInstructionAssertNonNull *i
1061static void ir_print_resize_slice(IrPrint *irp, IrInstructionResizeSlice *instruction) {1150static void ir_print_resize_slice(IrPrint *irp, IrInstructionResizeSlice *instruction) {
1062 fprintf(irp->f, "@resizeSlice(");1151 fprintf(irp->f, "@resizeSlice(");
1063 ir_print_other_instruction(irp, instruction->operand);1152 ir_print_other_instruction(irp, instruction->operand);
1153 fprintf(irp->f, ")result=");
1154 ir_print_other_instruction(irp, instruction->result_loc);
1155}
1156
1157static void ir_print_alloca_src(IrPrint *irp, IrInstructionAllocaSrc *instruction) {
1158 fprintf(irp->f, "Alloca(align=");
1159 ir_print_other_instruction(irp, instruction->align);
1160 fprintf(irp->f, ",name=%s)", instruction->name_hint);
1161}
1162
1163static void ir_print_alloca_gen(IrPrint *irp, IrInstructionAllocaGen *instruction) {
1164 fprintf(irp->f, "Alloca(align=%" PRIu32 ",name=%s)", instruction->align, instruction->name_hint);
1165}
1166
1167static void ir_print_end_expr(IrPrint *irp, IrInstructionEndExpr *instruction) {
1168 fprintf(irp->f, "EndExpr(result=");
1169 ir_print_result_loc(irp, instruction->result_loc);
1170 fprintf(irp->f, ",value=");
1171 ir_print_other_instruction(irp, instruction->value);
1064 fprintf(irp->f, ")");1172 fprintf(irp->f, ")");
1065}1173}
10661174
...@@ -1186,6 +1294,34 @@ static void ir_print_align_cast(IrPrint *irp, IrInstructionAlignCast *instructio...@@ -1186,6 +1294,34 @@ static void ir_print_align_cast(IrPrint *irp, IrInstructionAlignCast *instructio
1186 fprintf(irp->f, ")");1294 fprintf(irp->f, ")");
1187}1295}
11881296
1297static void ir_print_implicit_cast(IrPrint *irp, IrInstructionImplicitCast *instruction) {
1298 fprintf(irp->f, "@implicitCast(");
1299 ir_print_other_instruction(irp, instruction->dest_type);
1300 fprintf(irp->f, ",");
1301 ir_print_other_instruction(irp, instruction->target);
1302 fprintf(irp->f, ")");
1303}
1304
1305static void ir_print_resolve_result(IrPrint *irp, IrInstructionResolveResult *instruction) {
1306 fprintf(irp->f, "ResolveResult(");
1307 ir_print_result_loc(irp, instruction->result_loc);
1308 fprintf(irp->f, ")");
1309}
1310
1311static void ir_print_reset_result(IrPrint *irp, IrInstructionResetResult *instruction) {
1312 fprintf(irp->f, "ResetResult(");
1313 ir_print_result_loc(irp, instruction->result_loc);
1314 fprintf(irp->f, ")");
1315}
1316
1317static void ir_print_result_ptr(IrPrint *irp, IrInstructionResultPtr *instruction) {
1318 fprintf(irp->f, "ResultPtr(");
1319 ir_print_result_loc(irp, instruction->result_loc);
1320 fprintf(irp->f, ",");
1321 ir_print_other_instruction(irp, instruction->result);
1322 fprintf(irp->f, ")");
1323}
1324
1189static void ir_print_opaque_type(IrPrint *irp, IrInstructionOpaqueType *instruction) {1325static void ir_print_opaque_type(IrPrint *irp, IrInstructionOpaqueType *instruction) {
1190 fprintf(irp->f, "@OpaqueType()");1326 fprintf(irp->f, "@OpaqueType()");
1191}1327}
...@@ -1463,7 +1599,7 @@ static void ir_print_decl_var_gen(IrPrint *irp, IrInstructionDeclVarGen *decl_va...@@ -1463,7 +1599,7 @@ static void ir_print_decl_var_gen(IrPrint *irp, IrInstructionDeclVarGen *decl_va
1463 fprintf(irp->f, "%s %s: %s align(%u) = ", var_or_const, name, buf_ptr(&var->var_type->name),1599 fprintf(irp->f, "%s %s: %s align(%u) = ", var_or_const, name, buf_ptr(&var->var_type->name),
1464 var->align_bytes);1600 var->align_bytes);
14651601
1466 ir_print_other_instruction(irp, decl_var_instruction->init_value);1602 ir_print_other_instruction(irp, decl_var_instruction->var_ptr);
1467 if (decl_var_instruction->var->is_comptime != nullptr) {1603 if (decl_var_instruction->var->is_comptime != nullptr) {
1468 fprintf(irp->f, " // comptime = ");1604 fprintf(irp->f, " // comptime = ");
1469 ir_print_other_instruction(irp, decl_var_instruction->var->is_comptime);1605 ir_print_other_instruction(irp, decl_var_instruction->var->is_comptime);
...@@ -1502,8 +1638,11 @@ static void ir_print_instruction(IrPrint *irp, IrInstruction *instruction) {...@@ -1502,8 +1638,11 @@ static void ir_print_instruction(IrPrint *irp, IrInstruction *instruction) {
1502 case IrInstructionIdCast:1638 case IrInstructionIdCast:
1503 ir_print_cast(irp, (IrInstructionCast *)instruction);1639 ir_print_cast(irp, (IrInstructionCast *)instruction);
1504 break;1640 break;
1505 case IrInstructionIdCall:1641 case IrInstructionIdCallSrc:
1506 ir_print_call(irp, (IrInstructionCall *)instruction);1642 ir_print_call_src(irp, (IrInstructionCallSrc *)instruction);
1643 break;
1644 case IrInstructionIdCallGen:
1645 ir_print_call_gen(irp, (IrInstructionCallGen *)instruction);
1507 break;1646 break;
1508 case IrInstructionIdUnOp:1647 case IrInstructionIdUnOp:
1509 ir_print_un_op(irp, (IrInstructionUnOp *)instruction);1648 ir_print_un_op(irp, (IrInstructionUnOp *)instruction);
...@@ -1523,12 +1662,6 @@ static void ir_print_instruction(IrPrint *irp, IrInstruction *instruction) {...@@ -1523,12 +1662,6 @@ static void ir_print_instruction(IrPrint *irp, IrInstruction *instruction) {
1523 case IrInstructionIdContainerInitFields:1662 case IrInstructionIdContainerInitFields:
1524 ir_print_container_init_fields(irp, (IrInstructionContainerInitFields *)instruction);1663 ir_print_container_init_fields(irp, (IrInstructionContainerInitFields *)instruction);
1525 break;1664 break;
1526 case IrInstructionIdStructInit:
1527 ir_print_struct_init(irp, (IrInstructionStructInit *)instruction);
1528 break;
1529 case IrInstructionIdUnionInit:
1530 ir_print_union_init(irp, (IrInstructionUnionInit *)instruction);
1531 break;
1532 case IrInstructionIdUnreachable:1665 case IrInstructionIdUnreachable:
1533 ir_print_unreachable(irp, (IrInstructionUnreachable *)instruction);1666 ir_print_unreachable(irp, (IrInstructionUnreachable *)instruction);
1534 break;1667 break;
...@@ -1538,6 +1671,9 @@ static void ir_print_instruction(IrPrint *irp, IrInstruction *instruction) {...@@ -1538,6 +1671,9 @@ static void ir_print_instruction(IrPrint *irp, IrInstruction *instruction) {
1538 case IrInstructionIdVarPtr:1671 case IrInstructionIdVarPtr:
1539 ir_print_var_ptr(irp, (IrInstructionVarPtr *)instruction);1672 ir_print_var_ptr(irp, (IrInstructionVarPtr *)instruction);
1540 break;1673 break;
1674 case IrInstructionIdReturnPtr:
1675 ir_print_return_ptr(irp, (IrInstructionReturnPtr *)instruction);
1676 break;
1541 case IrInstructionIdLoadPtr:1677 case IrInstructionIdLoadPtr:
1542 ir_print_load_ptr(irp, (IrInstructionLoadPtr *)instruction);1678 ir_print_load_ptr(irp, (IrInstructionLoadPtr *)instruction);
1543 break;1679 break;
...@@ -1550,12 +1686,6 @@ static void ir_print_instruction(IrPrint *irp, IrInstruction *instruction) {...@@ -1550,12 +1686,6 @@ static void ir_print_instruction(IrPrint *irp, IrInstruction *instruction) {
1550 case IrInstructionIdTypeOf:1686 case IrInstructionIdTypeOf:
1551 ir_print_typeof(irp, (IrInstructionTypeOf *)instruction);1687 ir_print_typeof(irp, (IrInstructionTypeOf *)instruction);
1552 break;1688 break;
1553 case IrInstructionIdToPtrType:
1554 ir_print_to_ptr_type(irp, (IrInstructionToPtrType *)instruction);
1555 break;
1556 case IrInstructionIdPtrTypeChild:
1557 ir_print_ptr_type_child(irp, (IrInstructionPtrTypeChild *)instruction);
1558 break;
1559 case IrInstructionIdFieldPtr:1689 case IrInstructionIdFieldPtr:
1560 ir_print_field_ptr(irp, (IrInstructionFieldPtr *)instruction);1690 ir_print_field_ptr(irp, (IrInstructionFieldPtr *)instruction);
1561 break;1691 break;
...@@ -1634,6 +1764,9 @@ static void ir_print_instruction(IrPrint *irp, IrInstruction *instruction) {...@@ -1634,6 +1764,9 @@ static void ir_print_instruction(IrPrint *irp, IrInstruction *instruction) {
1634 case IrInstructionIdRef:1764 case IrInstructionIdRef:
1635 ir_print_ref(irp, (IrInstructionRef *)instruction);1765 ir_print_ref(irp, (IrInstructionRef *)instruction);
1636 break;1766 break;
1767 case IrInstructionIdRefGen:
1768 ir_print_ref_gen(irp, (IrInstructionRefGen *)instruction);
1769 break;
1637 case IrInstructionIdCompileErr:1770 case IrInstructionIdCompileErr:
1638 ir_print_compile_err(irp, (IrInstructionCompileErr *)instruction);1771 ir_print_compile_err(irp, (IrInstructionCompileErr *)instruction);
1639 break;1772 break;
...@@ -1709,8 +1842,11 @@ static void ir_print_instruction(IrPrint *irp, IrInstruction *instruction) {...@@ -1709,8 +1842,11 @@ static void ir_print_instruction(IrPrint *irp, IrInstruction *instruction) {
1709 case IrInstructionIdMemcpy:1842 case IrInstructionIdMemcpy:
1710 ir_print_memcpy(irp, (IrInstructionMemcpy *)instruction);1843 ir_print_memcpy(irp, (IrInstructionMemcpy *)instruction);
1711 break;1844 break;
1712 case IrInstructionIdSlice:1845 case IrInstructionIdSliceSrc:
1713 ir_print_slice(irp, (IrInstructionSlice *)instruction);1846 ir_print_slice_src(irp, (IrInstructionSliceSrc *)instruction);
1847 break;
1848 case IrInstructionIdSliceGen:
1849 ir_print_slice_gen(irp, (IrInstructionSliceGen *)instruction);
1714 break;1850 break;
1715 case IrInstructionIdMemberCount:1851 case IrInstructionIdMemberCount:
1716 ir_print_member_count(irp, (IrInstructionMemberCount *)instruction);1852 ir_print_member_count(irp, (IrInstructionMemberCount *)instruction);
...@@ -1739,8 +1875,11 @@ static void ir_print_instruction(IrPrint *irp, IrInstruction *instruction) {...@@ -1739,8 +1875,11 @@ static void ir_print_instruction(IrPrint *irp, IrInstruction *instruction) {
1739 case IrInstructionIdOverflowOp:1875 case IrInstructionIdOverflowOp:
1740 ir_print_overflow_op(irp, (IrInstructionOverflowOp *)instruction);1876 ir_print_overflow_op(irp, (IrInstructionOverflowOp *)instruction);
1741 break;1877 break;
1742 case IrInstructionIdTestErr:1878 case IrInstructionIdTestErrSrc:
1743 ir_print_test_err(irp, (IrInstructionTestErr *)instruction);1879 ir_print_test_err_src(irp, (IrInstructionTestErrSrc *)instruction);
1880 break;
1881 case IrInstructionIdTestErrGen:
1882 ir_print_test_err_gen(irp, (IrInstructionTestErrGen *)instruction);
1744 break;1883 break;
1745 case IrInstructionIdUnwrapErrCode:1884 case IrInstructionIdUnwrapErrCode:
1746 ir_print_unwrap_err_code(irp, (IrInstructionUnwrapErrCode *)instruction);1885 ir_print_unwrap_err_code(irp, (IrInstructionUnwrapErrCode *)instruction);
...@@ -1749,7 +1888,7 @@ static void ir_print_instruction(IrPrint *irp, IrInstruction *instruction) {...@@ -1749,7 +1888,7 @@ static void ir_print_instruction(IrPrint *irp, IrInstruction *instruction) {
1749 ir_print_unwrap_err_payload(irp, (IrInstructionUnwrapErrPayload *)instruction);1888 ir_print_unwrap_err_payload(irp, (IrInstructionUnwrapErrPayload *)instruction);
1750 break;1889 break;
1751 case IrInstructionIdOptionalWrap:1890 case IrInstructionIdOptionalWrap:
1752 ir_print_maybe_wrap(irp, (IrInstructionOptionalWrap *)instruction);1891 ir_print_optional_wrap(irp, (IrInstructionOptionalWrap *)instruction);
1753 break;1892 break;
1754 case IrInstructionIdErrWrapCode:1893 case IrInstructionIdErrWrapCode:
1755 ir_print_err_wrap_code(irp, (IrInstructionErrWrapCode *)instruction);1894 ir_print_err_wrap_code(irp, (IrInstructionErrWrapCode *)instruction);
...@@ -1769,8 +1908,8 @@ static void ir_print_instruction(IrPrint *irp, IrInstruction *instruction) {...@@ -1769,8 +1908,8 @@ static void ir_print_instruction(IrPrint *irp, IrInstruction *instruction) {
1769 case IrInstructionIdPtrCastGen:1908 case IrInstructionIdPtrCastGen:
1770 ir_print_ptr_cast_gen(irp, (IrInstructionPtrCastGen *)instruction);1909 ir_print_ptr_cast_gen(irp, (IrInstructionPtrCastGen *)instruction);
1771 break;1910 break;
1772 case IrInstructionIdBitCast:1911 case IrInstructionIdBitCastSrc:
1773 ir_print_bit_cast(irp, (IrInstructionBitCast *)instruction);1912 ir_print_bit_cast_src(irp, (IrInstructionBitCastSrc *)instruction);
1774 break;1913 break;
1775 case IrInstructionIdBitCastGen:1914 case IrInstructionIdBitCastGen:
1776 ir_print_bit_cast_gen(irp, (IrInstructionBitCastGen *)instruction);1915 ir_print_bit_cast_gen(irp, (IrInstructionBitCastGen *)instruction);
...@@ -1835,6 +1974,18 @@ static void ir_print_instruction(IrPrint *irp, IrInstruction *instruction) {...@@ -1835,6 +1974,18 @@ static void ir_print_instruction(IrPrint *irp, IrInstruction *instruction) {
1835 case IrInstructionIdAlignCast:1974 case IrInstructionIdAlignCast:
1836 ir_print_align_cast(irp, (IrInstructionAlignCast *)instruction);1975 ir_print_align_cast(irp, (IrInstructionAlignCast *)instruction);
1837 break;1976 break;
1977 case IrInstructionIdImplicitCast:
1978 ir_print_implicit_cast(irp, (IrInstructionImplicitCast *)instruction);
1979 break;
1980 case IrInstructionIdResolveResult:
1981 ir_print_resolve_result(irp, (IrInstructionResolveResult *)instruction);
1982 break;
1983 case IrInstructionIdResetResult:
1984 ir_print_reset_result(irp, (IrInstructionResetResult *)instruction);
1985 break;
1986 case IrInstructionIdResultPtr:
1987 ir_print_result_ptr(irp, (IrInstructionResultPtr *)instruction);
1988 break;
1838 case IrInstructionIdOpaqueType:1989 case IrInstructionIdOpaqueType:
1839 ir_print_opaque_type(irp, (IrInstructionOpaqueType *)instruction);1990 ir_print_opaque_type(irp, (IrInstructionOpaqueType *)instruction);
1840 break;1991 break;
...@@ -1943,6 +2094,9 @@ static void ir_print_instruction(IrPrint *irp, IrInstruction *instruction) {...@@ -1943,6 +2094,9 @@ static void ir_print_instruction(IrPrint *irp, IrInstruction *instruction) {
1943 case IrInstructionIdVectorToArray:2094 case IrInstructionIdVectorToArray:
1944 ir_print_vector_to_array(irp, (IrInstructionVectorToArray *)instruction);2095 ir_print_vector_to_array(irp, (IrInstructionVectorToArray *)instruction);
1945 break;2096 break;
2097 case IrInstructionIdPtrOfArrayToSlice:
2098 ir_print_ptr_of_array_to_slice(irp, (IrInstructionPtrOfArrayToSlice *)instruction);
2099 break;
1946 case IrInstructionIdAssertZero:2100 case IrInstructionIdAssertZero:
1947 ir_print_assert_zero(irp, (IrInstructionAssertZero *)instruction);2101 ir_print_assert_zero(irp, (IrInstructionAssertZero *)instruction);
1948 break;2102 break;
...@@ -1958,6 +2112,15 @@ static void ir_print_instruction(IrPrint *irp, IrInstruction *instruction) {...@@ -1958,6 +2112,15 @@ static void ir_print_instruction(IrPrint *irp, IrInstruction *instruction) {
1958 case IrInstructionIdUndeclaredIdent:2112 case IrInstructionIdUndeclaredIdent:
1959 ir_print_undeclared_ident(irp, (IrInstructionUndeclaredIdent *)instruction);2113 ir_print_undeclared_ident(irp, (IrInstructionUndeclaredIdent *)instruction);
1960 break;2114 break;
2115 case IrInstructionIdAllocaSrc:
2116 ir_print_alloca_src(irp, (IrInstructionAllocaSrc *)instruction);
2117 break;
2118 case IrInstructionIdAllocaGen:
2119 ir_print_alloca_gen(irp, (IrInstructionAllocaGen *)instruction);
2120 break;
2121 case IrInstructionIdEndExpr:
2122 ir_print_end_expr(irp, (IrInstructionEndExpr *)instruction);
2123 break;
1961 }2124 }
1962 fprintf(irp->f, "\n");2125 fprintf(irp->f, "\n");
1963}2126}
src/parser.cpp+3-3
...@@ -344,7 +344,7 @@ static AstNode *ast_parse_bin_op_expr(...@@ -344,7 +344,7 @@ static AstNode *ast_parse_bin_op_expr(
344 op->data.bin_op_expr.op1 = left;344 op->data.bin_op_expr.op1 = left;
345 op->data.bin_op_expr.op2 = right;345 op->data.bin_op_expr.op2 = right;
346 break;346 break;
347 case NodeTypeUnwrapErrorExpr:347 case NodeTypeCatchExpr:
348 op->data.unwrap_err_expr.op1 = left;348 op->data.unwrap_err_expr.op1 = left;
349 op->data.unwrap_err_expr.op2 = right;349 op->data.unwrap_err_expr.op2 = right;
350 break;350 break;
...@@ -2404,7 +2404,7 @@ static AstNode *ast_parse_bitwise_op(ParseContext *pc) {...@@ -2404,7 +2404,7 @@ static AstNode *ast_parse_bitwise_op(ParseContext *pc) {
2404 Token *catch_token = eat_token_if(pc, TokenIdKeywordCatch);2404 Token *catch_token = eat_token_if(pc, TokenIdKeywordCatch);
2405 if (catch_token != nullptr) {2405 if (catch_token != nullptr) {
2406 Token *payload = ast_parse_payload(pc);2406 Token *payload = ast_parse_payload(pc);
2407 AstNode *res = ast_create_node(pc, NodeTypeUnwrapErrorExpr, catch_token);2407 AstNode *res = ast_create_node(pc, NodeTypeCatchExpr, catch_token);
2408 if (payload != nullptr)2408 if (payload != nullptr)
2409 res->data.unwrap_err_expr.symbol = token_symbol(pc, payload);2409 res->data.unwrap_err_expr.symbol = token_symbol(pc, payload);
24102410
...@@ -2897,7 +2897,7 @@ void ast_visit_node_children(AstNode *node, void (*visit)(AstNode **, void *cont...@@ -2897,7 +2897,7 @@ void ast_visit_node_children(AstNode *node, void (*visit)(AstNode **, void *cont
2897 visit_field(&node->data.bin_op_expr.op1, visit, context);2897 visit_field(&node->data.bin_op_expr.op1, visit, context);
2898 visit_field(&node->data.bin_op_expr.op2, visit, context);2898 visit_field(&node->data.bin_op_expr.op2, visit, context);
2899 break;2899 break;
2900 case NodeTypeUnwrapErrorExpr:2900 case NodeTypeCatchExpr:
2901 visit_field(&node->data.unwrap_err_expr.op1, visit, context);2901 visit_field(&node->data.unwrap_err_expr.op1, visit, context);
2902 visit_field(&node->data.unwrap_err_expr.symbol, visit, context);2902 visit_field(&node->data.unwrap_err_expr.symbol, visit, context);
2903 visit_field(&node->data.unwrap_err_expr.op2, visit, context);2903 visit_field(&node->data.unwrap_err_expr.op2, visit, context);
std/event/fs.zig+1-2
...@@ -1290,10 +1290,9 @@ pub fn Watch(comptime V: type) type {...@@ -1290,10 +1290,9 @@ pub fn Watch(comptime V: type) type {
1290 error.FileDescriptorAlreadyPresentInSet => unreachable,1290 error.FileDescriptorAlreadyPresentInSet => unreachable,
1291 error.OperationCausesCircularLoop => unreachable,1291 error.OperationCausesCircularLoop => unreachable,
1292 error.FileDescriptorNotRegistered => unreachable,1292 error.FileDescriptorNotRegistered => unreachable,
1293 error.SystemResources => error.SystemResources,
1294 error.UserResourceLimitReached => error.UserResourceLimitReached,
1295 error.FileDescriptorIncompatibleWithEpoll => unreachable,1293 error.FileDescriptorIncompatibleWithEpoll => unreachable,
1296 error.Unexpected => unreachable,1294 error.Unexpected => unreachable,
1295 else => |e| e,
1297 };1296 };
1298 await (async channel.put(transformed_err) catch unreachable);1297 await (async channel.put(transformed_err) catch unreachable);
1299 };1298 };
std/event/lock.zig-1
...@@ -123,7 +123,6 @@ pub const Lock = struct {...@@ -123,7 +123,6 @@ pub const Lock = struct {
123};123};
124124
125test "std.event.Lock" {125test "std.event.Lock" {
126 // https://github.com/ziglang/zig/issues/1908
127 if (builtin.single_threaded) return error.SkipZigTest;126 if (builtin.single_threaded) return error.SkipZigTest;
128127
129 const allocator = std.heap.direct_allocator;128 const allocator = std.heap.direct_allocator;
std/event/net.zig+2-2
...@@ -263,8 +263,8 @@ pub async fn connect(loop: *Loop, _address: *const std.net.Address) !File {...@@ -263,8 +263,8 @@ pub async fn connect(loop: *Loop, _address: *const std.net.Address) !File {
263}263}
264264
265test "listen on a port, send bytes, receive bytes" {265test "listen on a port, send bytes, receive bytes" {
266 // https://github.com/ziglang/zig/issues/1908266 // https://github.com/ziglang/zig/issues/2377
267 if (builtin.single_threaded) return error.SkipZigTest;267 if (true) return error.SkipZigTest;
268268
269 if (builtin.os != builtin.Os.linux) {269 if (builtin.os != builtin.Os.linux) {
270 // TODO build abstractions for other operating systems270 // TODO build abstractions for other operating systems
std/event/rwlock.zig+2-2
...@@ -212,8 +212,8 @@ pub const RwLock = struct {...@@ -212,8 +212,8 @@ pub const RwLock = struct {
212};212};
213213
214test "std.event.RwLock" {214test "std.event.RwLock" {
215 // https://github.com/ziglang/zig/issues/1908215 // https://github.com/ziglang/zig/issues/2377
216 if (builtin.single_threaded or builtin.os != builtin.Os.linux) return error.SkipZigTest;216 if (true) return error.SkipZigTest;
217217
218 const allocator = std.heap.direct_allocator;218 const allocator = std.heap.direct_allocator;
219219
std/heap.zig+2-2
...@@ -360,9 +360,9 @@ pub const ArenaAllocator = struct {...@@ -360,9 +360,9 @@ pub const ArenaAllocator = struct {
360 var it = self.buffer_list.first;360 var it = self.buffer_list.first;
361 while (it) |node| {361 while (it) |node| {
362 // this has to occur before the free because the free frees node362 // this has to occur before the free because the free frees node
363 it = node.next;363 const next_it = node.next;
364
365 self.child_allocator.free(node.data);364 self.child_allocator.free(node.data);
365 it = next_it;
366 }366 }
367 }367 }
368368
std/io.zig+10-10
...@@ -164,32 +164,32 @@ pub fn InStream(comptime ReadError: type) type {...@@ -164,32 +164,32 @@ pub fn InStream(comptime ReadError: type) type {
164164
165 /// Reads a native-endian integer165 /// Reads a native-endian integer
166 pub fn readIntNative(self: *Self, comptime T: type) !T {166 pub fn readIntNative(self: *Self, comptime T: type) !T {
167 var bytes: [(T.bit_count + 7 )/ 8]u8 = undefined;167 var bytes: [(T.bit_count + 7) / 8]u8 = undefined;
168 try self.readNoEof(bytes[0..]);168 try self.readNoEof(bytes[0..]);
169 return mem.readIntNative(T, &bytes);169 return mem.readIntNative(T, &bytes);
170 }170 }
171171
172 /// Reads a foreign-endian integer172 /// Reads a foreign-endian integer
173 pub fn readIntForeign(self: *Self, comptime T: type) !T {173 pub fn readIntForeign(self: *Self, comptime T: type) !T {
174 var bytes: [(T.bit_count + 7 )/ 8]u8 = undefined;174 var bytes: [(T.bit_count + 7) / 8]u8 = undefined;
175 try self.readNoEof(bytes[0..]);175 try self.readNoEof(bytes[0..]);
176 return mem.readIntForeign(T, &bytes);176 return mem.readIntForeign(T, &bytes);
177 }177 }
178178
179 pub fn readIntLittle(self: *Self, comptime T: type) !T {179 pub fn readIntLittle(self: *Self, comptime T: type) !T {
180 var bytes: [(T.bit_count + 7 )/ 8]u8 = undefined;180 var bytes: [(T.bit_count + 7) / 8]u8 = undefined;
181 try self.readNoEof(bytes[0..]);181 try self.readNoEof(bytes[0..]);
182 return mem.readIntLittle(T, &bytes);182 return mem.readIntLittle(T, &bytes);
183 }183 }
184184
185 pub fn readIntBig(self: *Self, comptime T: type) !T {185 pub fn readIntBig(self: *Self, comptime T: type) !T {
186 var bytes: [(T.bit_count + 7 )/ 8]u8 = undefined;186 var bytes: [(T.bit_count + 7) / 8]u8 = undefined;
187 try self.readNoEof(bytes[0..]);187 try self.readNoEof(bytes[0..]);
188 return mem.readIntBig(T, &bytes);188 return mem.readIntBig(T, &bytes);
189 }189 }
190190
191 pub fn readInt(self: *Self, comptime T: type, endian: builtin.Endian) !T {191 pub fn readInt(self: *Self, comptime T: type, endian: builtin.Endian) !T {
192 var bytes: [(T.bit_count + 7 )/ 8]u8 = undefined;192 var bytes: [(T.bit_count + 7) / 8]u8 = undefined;
193 try self.readNoEof(bytes[0..]);193 try self.readNoEof(bytes[0..]);
194 return mem.readInt(T, &bytes, endian);194 return mem.readInt(T, &bytes, endian);
195 }195 }
...@@ -249,32 +249,32 @@ pub fn OutStream(comptime WriteError: type) type {...@@ -249,32 +249,32 @@ pub fn OutStream(comptime WriteError: type) type {
249249
250 /// Write a native-endian integer.250 /// Write a native-endian integer.
251 pub fn writeIntNative(self: *Self, comptime T: type, value: T) Error!void {251 pub fn writeIntNative(self: *Self, comptime T: type, value: T) Error!void {
252 var bytes: [(T.bit_count + 7 )/ 8]u8 = undefined;252 var bytes: [(T.bit_count + 7) / 8]u8 = undefined;
253 mem.writeIntNative(T, &bytes, value);253 mem.writeIntNative(T, &bytes, value);
254 return self.writeFn(self, bytes);254 return self.writeFn(self, bytes);
255 }255 }
256256
257 /// Write a foreign-endian integer.257 /// Write a foreign-endian integer.
258 pub fn writeIntForeign(self: *Self, comptime T: type, value: T) Error!void {258 pub fn writeIntForeign(self: *Self, comptime T: type, value: T) Error!void {
259 var bytes: [(T.bit_count + 7 )/ 8]u8 = undefined;259 var bytes: [(T.bit_count + 7) / 8]u8 = undefined;
260 mem.writeIntForeign(T, &bytes, value);260 mem.writeIntForeign(T, &bytes, value);
261 return self.writeFn(self, bytes);261 return self.writeFn(self, bytes);
262 }262 }
263263
264 pub fn writeIntLittle(self: *Self, comptime T: type, value: T) Error!void {264 pub fn writeIntLittle(self: *Self, comptime T: type, value: T) Error!void {
265 var bytes: [(T.bit_count + 7 )/ 8]u8 = undefined;265 var bytes: [(T.bit_count + 7) / 8]u8 = undefined;
266 mem.writeIntLittle(T, &bytes, value);266 mem.writeIntLittle(T, &bytes, value);
267 return self.writeFn(self, bytes);267 return self.writeFn(self, bytes);
268 }268 }
269269
270 pub fn writeIntBig(self: *Self, comptime T: type, value: T) Error!void {270 pub fn writeIntBig(self: *Self, comptime T: type, value: T) Error!void {
271 var bytes: [(T.bit_count + 7 )/ 8]u8 = undefined;271 var bytes: [(T.bit_count + 7) / 8]u8 = undefined;
272 mem.writeIntBig(T, &bytes, value);272 mem.writeIntBig(T, &bytes, value);
273 return self.writeFn(self, bytes);273 return self.writeFn(self, bytes);
274 }274 }
275275
276 pub fn writeInt(self: *Self, comptime T: type, value: T, endian: builtin.Endian) Error!void {276 pub fn writeInt(self: *Self, comptime T: type, value: T, endian: builtin.Endian) Error!void {
277 var bytes: [(T.bit_count + 7 )/ 8]u8 = undefined;277 var bytes: [(T.bit_count + 7) / 8]u8 = undefined;
278 mem.writeInt(T, &bytes, value, endian);278 mem.writeInt(T, &bytes, value, endian);
279 return self.writeFn(self, bytes);279 return self.writeFn(self, bytes);
280 }280 }
std/io/test.zig+4-1
...@@ -597,7 +597,10 @@ test "c out stream" {...@@ -597,7 +597,10 @@ test "c out stream" {
597597
598 const filename = c"tmp_io_test_file.txt";598 const filename = c"tmp_io_test_file.txt";
599 const out_file = std.c.fopen(filename, c"w") orelse return error.UnableToOpenTestFile;599 const out_file = std.c.fopen(filename, c"w") orelse return error.UnableToOpenTestFile;
600 defer fs.deleteFileC(filename) catch {};600 defer {
601 _ = std.c.fclose(out_file);
602 fs.deleteFileC(filename) catch {};
603 }
601604
602 const out_stream = &io.COutStream.init(out_file).stream;605 const out_stream = &io.COutStream.init(out_file).stream;
603 try out_stream.print("hi: {}\n", i32(123));606 try out_stream.print("hi: {}\n", i32(123));
std/json.zig+2-1
...@@ -876,8 +876,9 @@ pub const TokenStream = struct {...@@ -876,8 +876,9 @@ pub const TokenStream = struct {
876876
877 pub fn next(self: *TokenStream) !?Token {877 pub fn next(self: *TokenStream) !?Token {
878 if (self.token) |token| {878 if (self.token) |token| {
879 const copy = token;
879 self.token = null;880 self.token = null;
880 return token;881 return copy;
881 }882 }
882883
883 var t1: ?Token = undefined;884 var t1: ?Token = undefined;
std/os/windows.zig+2
...@@ -348,6 +348,7 @@ pub const DeleteFileError = error{...@@ -348,6 +348,7 @@ pub const DeleteFileError = error{
348 FileNotFound,348 FileNotFound,
349 AccessDenied,349 AccessDenied,
350 NameTooLong,350 NameTooLong,
351 FileBusy,
351 Unexpected,352 Unexpected,
352};353};
353354
...@@ -363,6 +364,7 @@ pub fn DeleteFileW(filename: [*]const u16) DeleteFileError!void {...@@ -363,6 +364,7 @@ pub fn DeleteFileW(filename: [*]const u16) DeleteFileError!void {
363 ERROR.ACCESS_DENIED => return error.AccessDenied,364 ERROR.ACCESS_DENIED => return error.AccessDenied,
364 ERROR.FILENAME_EXCED_RANGE => return error.NameTooLong,365 ERROR.FILENAME_EXCED_RANGE => return error.NameTooLong,
365 ERROR.INVALID_PARAMETER => return error.NameTooLong,366 ERROR.INVALID_PARAMETER => return error.NameTooLong,
367 ERROR.SHARING_VIOLATION => return error.FileBusy,
366 else => |err| return unexpectedError(err),368 else => |err| return unexpectedError(err),
367 }369 }
368 }370 }
std/special/bootstrap.zig+4-4
...@@ -114,20 +114,20 @@ extern fn main(c_argc: i32, c_argv: [*][*]u8, c_envp: [*]?[*]u8) i32 {...@@ -114,20 +114,20 @@ extern fn main(c_argc: i32, c_argv: [*][*]u8, c_envp: [*]?[*]u8) i32 {
114// and we want fewer call frames in stack traces.114// and we want fewer call frames in stack traces.
115inline fn callMain() u8 {115inline fn callMain() u8 {
116 switch (@typeId(@typeOf(root.main).ReturnType)) {116 switch (@typeId(@typeOf(root.main).ReturnType)) {
117 builtin.TypeId.NoReturn => {117 .NoReturn => {
118 root.main();118 root.main();
119 },119 },
120 builtin.TypeId.Void => {120 .Void => {
121 root.main();121 root.main();
122 return 0;122 return 0;
123 },123 },
124 builtin.TypeId.Int => {124 .Int => {
125 if (@typeOf(root.main).ReturnType.bit_count != 8) {125 if (@typeOf(root.main).ReturnType.bit_count != 8) {
126 @compileError("expected return type of main to be 'u8', 'noreturn', 'void', or '!void'");126 @compileError("expected return type of main to be 'u8', 'noreturn', 'void', or '!void'");
127 }127 }
128 return root.main();128 return root.main();
129 },129 },
130 builtin.TypeId.ErrorUnion => {130 .ErrorUnion => {
131 root.main() catch |err| {131 root.main() catch |err| {
132 std.debug.warn("error: {}\n", @errorName(err));132 std.debug.warn("error: {}\n", @errorName(err));
133 if (builtin.os != builtin.Os.zen) {133 if (builtin.os != builtin.Os.zen) {
std/special/compiler_rt/comparetf2.zig+9-6
...@@ -73,12 +73,15 @@ pub extern fn __getf2(a: f128, b: f128) c_int {...@@ -73,12 +73,15 @@ pub extern fn __getf2(a: f128, b: f128) c_int {
7373
74 if (aAbs > infRep or bAbs > infRep) return GE_UNORDERED;74 if (aAbs > infRep or bAbs > infRep) return GE_UNORDERED;
75 if ((aAbs | bAbs) == 0) return GE_EQUAL;75 if ((aAbs | bAbs) == 0) return GE_EQUAL;
76 return if ((aInt & bInt) >= 0) if (aInt < bInt)76 // zig fmt issue here, see https://github.com/ziglang/zig/issues/2661
77 GE_LESS77 return if ((aInt & bInt) >= 0)
78 else if (aInt == bInt)78 if (aInt < bInt)
79 GE_EQUAL79 GE_LESS
80 else80 else if (aInt == bInt)
81 GE_GREATER else if (aInt > bInt)81 GE_EQUAL
82 else
83 GE_GREATER
84 else if (aInt > bInt)
82 GE_LESS85 GE_LESS
83 else if (aInt == bInt)86 else if (aInt == bInt)
84 GE_EQUAL87 GE_EQUAL
std/special/panic.zig+3-4
...@@ -9,16 +9,15 @@ const std = @import("std");...@@ -9,16 +9,15 @@ const std = @import("std");
9pub fn panic(msg: []const u8, error_return_trace: ?*builtin.StackTrace) noreturn {9pub fn panic(msg: []const u8, error_return_trace: ?*builtin.StackTrace) noreturn {
10 @setCold(true);10 @setCold(true);
11 switch (builtin.os) {11 switch (builtin.os) {
12 // TODO: fix panic in zen12 .freestanding => {
13 builtin.Os.freestanding, builtin.Os.zen => {
14 while (true) {}13 while (true) {}
15 },14 },
16 builtin.Os.wasi => {15 .wasi => {
17 std.debug.warn("{}", msg);16 std.debug.warn("{}", msg);
18 _ = std.os.wasi.proc_raise(std.os.wasi.SIGABRT);17 _ = std.os.wasi.proc_raise(std.os.wasi.SIGABRT);
19 unreachable;18 unreachable;
20 },19 },
21 builtin.Os.uefi => {20 .uefi => {
22 // TODO look into using the debug info and logging helpful messages21 // TODO look into using the debug info and logging helpful messages
23 std.os.abort();22 std.os.abort();
24 },23 },
std/zig/parser_test.zig+2-2
...@@ -1,4 +1,4 @@...@@ -1,4 +1,4 @@
1// TODO remove `use` keyword eventually1// TODO remove `use` keyword eventually: https://github.com/ziglang/zig/issues/2591
2test "zig fmt: change use to usingnamespace" {2test "zig fmt: change use to usingnamespace" {
3 try testTransform(3 try testTransform(
4 \\use @import("std");4 \\use @import("std");
...@@ -1105,7 +1105,7 @@ test "zig fmt: first line comment in struct initializer" {...@@ -1105,7 +1105,7 @@ test "zig fmt: first line comment in struct initializer" {
1105 try testCanonical(1105 try testCanonical(
1106 \\pub async fn acquire(self: *Self) HeldLock {1106 \\pub async fn acquire(self: *Self) HeldLock {
1107 \\ return HeldLock{1107 \\ return HeldLock{
1108 \\ // TODO guaranteed allocation elision1108 \\ // guaranteed allocation elision
1109 \\ .held = await (async self.lock.acquire() catch unreachable),1109 \\ .held = await (async self.lock.acquire() catch unreachable),
1110 \\ .value = &self.private_data,1110 \\ .value = &self.private_data,
1111 \\ };1111 \\ };
std/zig/render.zig+3-3
...@@ -939,10 +939,10 @@ fn renderExpression(...@@ -939,10 +939,10 @@ fn renderExpression(
939 }939 }
940940
941 switch (container_decl.init_arg_expr) {941 switch (container_decl.init_arg_expr) {
942 ast.Node.ContainerDecl.InitArg.None => {942 .None => {
943 try renderToken(tree, stream, container_decl.kind_token, indent, start_col, Space.Space); // union943 try renderToken(tree, stream, container_decl.kind_token, indent, start_col, Space.Space); // union
944 },944 },
945 ast.Node.ContainerDecl.InitArg.Enum => |enum_tag_type| {945 .Enum => |enum_tag_type| {
946 try renderToken(tree, stream, container_decl.kind_token, indent, start_col, Space.None); // union946 try renderToken(tree, stream, container_decl.kind_token, indent, start_col, Space.None); // union
947947
948 const lparen = tree.nextToken(container_decl.kind_token);948 const lparen = tree.nextToken(container_decl.kind_token);
...@@ -962,7 +962,7 @@ fn renderExpression(...@@ -962,7 +962,7 @@ fn renderExpression(
962 try renderToken(tree, stream, tree.nextToken(enum_token), indent, start_col, Space.Space); // )962 try renderToken(tree, stream, tree.nextToken(enum_token), indent, start_col, Space.Space); // )
963 }963 }
964 },964 },
965 ast.Node.ContainerDecl.InitArg.Type => |type_expr| {965 .Type => |type_expr| {
966 try renderToken(tree, stream, container_decl.kind_token, indent, start_col, Space.None); // union966 try renderToken(tree, stream, container_decl.kind_token, indent, start_col, Space.None); // union
967967
968 const lparen = tree.nextToken(container_decl.kind_token);968 const lparen = tree.nextToken(container_decl.kind_token);
test/compile_errors.zig+75-40
...@@ -49,16 +49,11 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {...@@ -49,16 +49,11 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {
49 \\const Foo = struct {49 \\const Foo = struct {
50 \\ a: undefined,50 \\ a: undefined,
51 \\};51 \\};
52 \\const Bar = union {52 \\export fn entry1() void {
53 \\ a: undefined,
54 \\};
55 \\pub fn main() void {
56 \\ const foo: Foo = undefined;53 \\ const foo: Foo = undefined;
57 \\ const bar: Bar = undefined;
58 \\}54 \\}
59 ,55 ,
60 "tmp.zig:2:8: error: expected type 'type', found '(undefined)'",56 "tmp.zig:2:8: error: expected type 'type', found '(undefined)'",
61 "tmp.zig:5:8: error: expected type 'type', found '(undefined)'",
62 );57 );
6358
64 cases.add(59 cases.add(
...@@ -461,13 +456,25 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {...@@ -461,13 +456,25 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {
461 \\const G = packed struct {456 \\const G = packed struct {
462 \\ x: Enum,457 \\ x: Enum,
463 \\};458 \\};
464 \\export fn entry() void {459 \\export fn entry1() void {
465 \\ var a: A = undefined;460 \\ var a: A = undefined;
461 \\}
462 \\export fn entry2() void {
466 \\ var b: B = undefined;463 \\ var b: B = undefined;
464 \\}
465 \\export fn entry3() void {
467 \\ var r: C = undefined;466 \\ var r: C = undefined;
467 \\}
468 \\export fn entry4() void {
468 \\ var d: D = undefined;469 \\ var d: D = undefined;
470 \\}
471 \\export fn entry5() void {
469 \\ var e: E = undefined;472 \\ var e: E = undefined;
473 \\}
474 \\export fn entry6() void {
470 \\ var f: F = undefined;475 \\ var f: F = undefined;
476 \\}
477 \\export fn entry7() void {
471 \\ var g: G = undefined;478 \\ var g: G = undefined;
472 \\}479 \\}
473 \\const S = struct {480 \\const S = struct {
...@@ -489,7 +496,7 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {...@@ -489,7 +496,7 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {
489 "tmp.zig:14:5: error: non-packed, non-extern struct 'U' not allowed in packed struct; no guaranteed in-memory representation",496 "tmp.zig:14:5: error: non-packed, non-extern struct 'U' not allowed in packed struct; no guaranteed in-memory representation",
490 "tmp.zig:17:5: error: type '?anyerror' not allowed in packed struct; no guaranteed in-memory representation",497 "tmp.zig:17:5: error: type '?anyerror' not allowed in packed struct; no guaranteed in-memory representation",
491 "tmp.zig:20:5: error: type 'Enum' not allowed in packed struct; no guaranteed in-memory representation",498 "tmp.zig:20:5: error: type 'Enum' not allowed in packed struct; no guaranteed in-memory representation",
492 "tmp.zig:38:14: note: enum declaration does not specify an integer tag type",499 "tmp.zig:50:14: note: enum declaration does not specify an integer tag type",
493 );500 );
494501
495 cases.addCase(x: {502 cases.addCase(x: {
...@@ -721,7 +728,7 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {...@@ -721,7 +728,7 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {
721 \\ var oops = @bitCast(u7, byte);728 \\ var oops = @bitCast(u7, byte);
722 \\}729 \\}
723 ,730 ,
724 "tmp.zig:2:16: error: destination type 'u7' has 7 bits but source type 'u8' has 8 bits",731 "tmp.zig:2:25: error: destination type 'u7' has 7 bits but source type 'u8' has 8 bits",
725 );732 );
726733
727 cases.add(734 cases.add(
...@@ -1381,7 +1388,7 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {...@@ -1381,7 +1388,7 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {
1381 \\ for (xx) |f| {}1388 \\ for (xx) |f| {}
1382 \\}1389 \\}
1383 ,1390 ,
1384 "tmp.zig:7:15: error: variable of type 'Foo' must be const or comptime",1391 "tmp.zig:7:5: error: values of type 'Foo' must be comptime known, but index value is runtime known",
1385 );1392 );
13861393
1387 cases.add(1394 cases.add(
...@@ -2250,6 +2257,9 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {...@@ -2250,6 +2257,9 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {
2250 \\}2257 \\}
2251 \\2258 \\
2252 \\extern fn bar(x: *void) void { }2259 \\extern fn bar(x: *void) void { }
2260 \\export fn entry2() void {
2261 \\ bar(&{});
2262 \\}
2253 ,2263 ,
2254 "tmp.zig:1:30: error: parameter of type '*void' has 0 bits; not allowed in function with calling convention 'ccc'",2264 "tmp.zig:1:30: error: parameter of type '*void' has 0 bits; not allowed in function with calling convention 'ccc'",
2255 "tmp.zig:7:18: error: parameter of type '*void' has 0 bits; not allowed in function with calling convention 'ccc'",2265 "tmp.zig:7:18: error: parameter of type '*void' has 0 bits; not allowed in function with calling convention 'ccc'",
...@@ -2576,7 +2586,7 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {...@@ -2576,7 +2586,7 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {
2576 \\2586 \\
2577 \\fn b() void {}2587 \\fn b() void {}
2578 ,2588 ,
2579 "tmp.zig:3:5: error: unreachable code",2589 "tmp.zig:3:6: error: unreachable code",
2580 );2590 );
25812591
2582 cases.add(2592 cases.add(
...@@ -2596,7 +2606,6 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {...@@ -2596,7 +2606,6 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {
2596 \\}2606 \\}
2597 ,2607 ,
2598 "tmp.zig:3:5: error: use of undeclared identifier 'b'",2608 "tmp.zig:3:5: error: use of undeclared identifier 'b'",
2599 "tmp.zig:4:5: error: use of undeclared identifier 'c'",
2600 );2609 );
26012610
2602 cases.add(2611 cases.add(
...@@ -2662,7 +2671,7 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {...@@ -2662,7 +2671,7 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {
2662 \\ const a: noreturn = {};2671 \\ const a: noreturn = {};
2663 \\}2672 \\}
2664 ,2673 ,
2665 "tmp.zig:2:14: error: variable of type 'noreturn' not allowed",2674 "tmp.zig:2:25: error: expected type 'noreturn', found 'void'",
2666 );2675 );
26672676
2668 cases.add(2677 cases.add(
...@@ -2725,9 +2734,13 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {...@@ -2725,9 +2734,13 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {
2725 \\ var bad : bool = undefined;2734 \\ var bad : bool = undefined;
2726 \\ bad[bad] = bad[bad];2735 \\ bad[bad] = bad[bad];
2727 \\}2736 \\}
2737 \\export fn g() void {
2738 \\ var bad : bool = undefined;
2739 \\ _ = bad[bad];
2740 \\}
2728 ,2741 ,
2729 "tmp.zig:3:8: error: array access of non-array type 'bool'",2742 "tmp.zig:3:8: error: array access of non-array type 'bool'",
2730 "tmp.zig:3:19: error: array access of non-array type 'bool'",2743 "tmp.zig:7:12: error: array access of non-array type 'bool'",
2731 );2744 );
27322745
2733 cases.add(2746 cases.add(
...@@ -2737,9 +2750,14 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {...@@ -2737,9 +2750,14 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {
2737 \\ var bad = false;2750 \\ var bad = false;
2738 \\ array[bad] = array[bad];2751 \\ array[bad] = array[bad];
2739 \\}2752 \\}
2753 \\export fn g() void {
2754 \\ var array = "aoeu";
2755 \\ var bad = false;
2756 \\ _ = array[bad];
2757 \\}
2740 ,2758 ,
2741 "tmp.zig:4:11: error: expected type 'usize', found 'bool'",2759 "tmp.zig:4:11: error: expected type 'usize', found 'bool'",
2742 "tmp.zig:4:24: error: expected type 'usize', found 'bool'",2760 "tmp.zig:9:15: error: expected type 'usize', found 'bool'",
2743 );2761 );
27442762
2745 cases.add(2763 cases.add(
...@@ -2757,12 +2775,14 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {...@@ -2757,12 +2775,14 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {
2757 "missing else clause",2775 "missing else clause",
2758 \\fn f(b: bool) void {2776 \\fn f(b: bool) void {
2759 \\ const x : i32 = if (b) h: { break :h 1; };2777 \\ const x : i32 = if (b) h: { break :h 1; };
2778 \\}
2779 \\fn g(b: bool) void {
2760 \\ const y = if (b) h: { break :h i32(1); };2780 \\ const y = if (b) h: { break :h i32(1); };
2761 \\}2781 \\}
2762 \\export fn entry() void { f(true); }2782 \\export fn entry() void { f(true); g(true); }
2763 ,2783 ,
2764 "tmp.zig:2:42: error: integer value 1 cannot be implicitly casted to type 'void'",2784 "tmp.zig:2:42: error: integer value 1 cannot be implicitly casted to type 'void'",
2765 "tmp.zig:3:15: error: incompatible types: 'i32' and 'void'",2785 "tmp.zig:5:15: error: incompatible types: 'i32' and 'void'",
2766 );2786 );
27672787
2768 cases.add(2788 cases.add(
...@@ -2773,9 +2793,13 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {...@@ -2773,9 +2793,13 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {
2773 \\ a.foo = 1;2793 \\ a.foo = 1;
2774 \\ const y = a.bar;2794 \\ const y = a.bar;
2775 \\}2795 \\}
2796 \\export fn g() void {
2797 \\ var a : A = undefined;
2798 \\ const y = a.bar;
2799 \\}
2776 ,2800 ,
2777 "tmp.zig:4:6: error: no member named 'foo' in struct 'A'",2801 "tmp.zig:4:6: error: no member named 'foo' in struct 'A'",
2778 "tmp.zig:5:16: error: no member named 'bar' in struct 'A'",2802 "tmp.zig:9:16: error: no member named 'bar' in struct 'A'",
2779 );2803 );
27802804
2781 cases.add(2805 cases.add(
...@@ -2920,7 +2944,7 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {...@@ -2920,7 +2944,7 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {
2920 \\ _ = foo;2944 \\ _ = foo;
2921 \\}2945 \\}
2922 ,2946 ,
2923 "tmp.zig:1:19: error: type '[3]u16' does not support struct initialization syntax",2947 "tmp.zig:1:21: error: type '[3]u16' does not support struct initialization syntax",
2924 );2948 );
29252949
2926 cases.add(2950 cases.add(
...@@ -3239,7 +3263,7 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {...@@ -3239,7 +3263,7 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {
3239 \\3263 \\
3240 \\export fn entry() usize { return @sizeOf(@typeOf(Foo)); }3264 \\export fn entry() usize { return @sizeOf(@typeOf(Foo)); }
3241 ,3265 ,
3242 "tmp.zig:5:25: error: unable to evaluate constant expression",3266 "tmp.zig:5:18: error: unable to evaluate constant expression",
3243 "tmp.zig:2:12: note: called from here",3267 "tmp.zig:2:12: note: called from here",
3244 "tmp.zig:2:8: note: called from here",3268 "tmp.zig:2:8: note: called from here",
3245 );3269 );
...@@ -3856,7 +3880,7 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {...@@ -3856,7 +3880,7 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {
3856 \\ return 2;3880 \\ return 2;
3857 \\}3881 \\}
3858 ,3882 ,
3859 "tmp.zig:2:15: error: values of type 'comptime_int' must be comptime known",3883 "tmp.zig:5:17: error: cannot store runtime value in type 'comptime_int'",
3860 );3884 );
38613885
3862 cases.add(3886 cases.add(
...@@ -5108,7 +5132,7 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {...@@ -5108,7 +5132,7 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {
5108 \\ const array = [2]u8{1, 2, 3};5132 \\ const array = [2]u8{1, 2, 3};
5109 \\}5133 \\}
5110 ,5134 ,
5111 "tmp.zig:2:24: error: expected [2]u8 literal, found [3]u8 literal",5135 "tmp.zig:2:31: error: index 2 outside array of size 2",
5112 );5136 );
51135137
5114 cases.add(5138 cases.add(
...@@ -5125,36 +5149,47 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {...@@ -5125,36 +5149,47 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {
51255149
5126 cases.add(5150 cases.add(
5127 "non-const variables of things that require const variables",5151 "non-const variables of things that require const variables",
5128 \\const Opaque = @OpaqueType();5152 \\export fn entry1() void {
5129 \\
5130 \\export fn entry(opaque: *Opaque) void {
5131 \\ var m2 = &2;5153 \\ var m2 = &2;
5132 \\ const y: u32 = m2.*;5154 \\}
5133 \\5155 \\export fn entry2() void {
5134 \\ var a = undefined;5156 \\ var a = undefined;
5157 \\}
5158 \\export fn entry3() void {
5135 \\ var b = 1;5159 \\ var b = 1;
5160 \\}
5161 \\export fn entry4() void {
5136 \\ var c = 1.0;5162 \\ var c = 1.0;
5163 \\}
5164 \\export fn entry5() void {
5137 \\ var d = null;5165 \\ var d = null;
5166 \\}
5167 \\export fn entry6(opaque: *Opaque) void {
5138 \\ var e = opaque.*;5168 \\ var e = opaque.*;
5169 \\}
5170 \\export fn entry7() void {
5139 \\ var f = i32;5171 \\ var f = i32;
5172 \\}
5173 \\export fn entry8() void {
5140 \\ var h = (Foo {}).bar;5174 \\ var h = (Foo {}).bar;
5141 \\5175 \\}
5176 \\export fn entry9() void {
5142 \\ var z: noreturn = return;5177 \\ var z: noreturn = return;
5143 \\}5178 \\}
5144 \\5179 \\const Opaque = @OpaqueType();
5145 \\const Foo = struct {5180 \\const Foo = struct {
5146 \\ fn bar(self: *const Foo) void {}5181 \\ fn bar(self: *const Foo) void {}
5147 \\};5182 \\};
5148 ,5183 ,
5149 "tmp.zig:4:4: error: variable of type '*comptime_int' must be const or comptime",5184 "tmp.zig:2:4: error: variable of type '*comptime_int' must be const or comptime",
5150 "tmp.zig:7:4: error: variable of type '(undefined)' must be const or comptime",5185 "tmp.zig:5:4: error: variable of type '(undefined)' must be const or comptime",
5151 "tmp.zig:8:4: error: variable of type 'comptime_int' must be const or comptime",5186 "tmp.zig:8:4: error: variable of type 'comptime_int' must be const or comptime",
5152 "tmp.zig:9:4: error: variable of type 'comptime_float' must be const or comptime",5187 "tmp.zig:11:4: error: variable of type 'comptime_float' must be const or comptime",
5153 "tmp.zig:10:4: error: variable of type '(null)' must be const or comptime",5188 "tmp.zig:14:4: error: variable of type '(null)' must be const or comptime",
5154 "tmp.zig:11:4: error: variable of type 'Opaque' not allowed",5189 "tmp.zig:17:4: error: variable of type 'Opaque' not allowed",
5155 "tmp.zig:12:4: error: variable of type 'type' must be const or comptime",5190 "tmp.zig:20:4: error: variable of type 'type' must be const or comptime",
5156 "tmp.zig:13:4: error: variable of type '(bound fn(*const Foo) void)' must be const or comptime",5191 "tmp.zig:23:4: error: variable of type '(bound fn(*const Foo) void)' must be const or comptime",
5157 "tmp.zig:15:4: error: unreachable code",5192 "tmp.zig:26:4: error: unreachable code",
5158 );5193 );
51595194
5160 cases.add(5195 cases.add(
...@@ -5300,7 +5335,7 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {...@@ -5300,7 +5335,7 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {
5300 \\ }5335 \\ }
5301 \\}5336 \\}
5302 ,5337 ,
5303 "tmp.zig:37:16: error: cannot store runtime value in compile time variable",5338 "tmp.zig:37:29: error: cannot store runtime value in compile time variable",
5304 );5339 );
53055340
5306 cases.add(5341 cases.add(
...@@ -5924,7 +5959,7 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {...@@ -5924,7 +5959,7 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {
5924 \\ const foo = Foo { .Bar = x, .Baz = u8 };5959 \\ const foo = Foo { .Bar = x, .Baz = u8 };
5925 \\}5960 \\}
5926 ,5961 ,
5927 "tmp.zig:7:30: error: unable to evaluate constant expression",5962 "tmp.zig:7:23: error: unable to evaluate constant expression",
5928 );5963 );
59295964
5930 cases.add(5965 cases.add(
...@@ -5938,7 +5973,7 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {...@@ -5938,7 +5973,7 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {
5938 \\ const foo = Foo { .Bar = x };5973 \\ const foo = Foo { .Bar = x };
5939 \\}5974 \\}
5940 ,5975 ,
5941 "tmp.zig:7:30: error: unable to evaluate constant expression",5976 "tmp.zig:7:23: error: unable to evaluate constant expression",
5942 );5977 );
59435978
5944 cases.addTest(5979 cases.addTest(
test/stage1/behavior/array.zig+8-2
...@@ -172,6 +172,12 @@ fn plusOne(x: u32) u32 {...@@ -172,6 +172,12 @@ fn plusOne(x: u32) u32 {
172 return x + 1;172 return x + 1;
173}173}
174174
175test "runtime initialize array elem and then implicit cast to slice" {
176 var two: i32 = 2;
177 const x: []const i32 = [_]i32{two};
178 expect(x[0] == 2);
179}
180
175test "array literal as argument to function" {181test "array literal as argument to function" {
176 const S = struct {182 const S = struct {
177 fn entry(two: i32) void {183 fn entry(two: i32) void {
...@@ -227,7 +233,7 @@ test "double nested array to const slice cast in array literal" {...@@ -227,7 +233,7 @@ test "double nested array to const slice cast in array literal" {
227233
228 const cases2 = [_][]const i32{234 const cases2 = [_][]const i32{
229 [_]i32{1},235 [_]i32{1},
230 [_]i32{ two, 3 },236 &[_]i32{ two, 3 },
231 };237 };
232 expect(cases2.len == 2);238 expect(cases2.len == 2);
233 expect(cases2[0].len == 1);239 expect(cases2[0].len == 1);
...@@ -238,7 +244,7 @@ test "double nested array to const slice cast in array literal" {...@@ -238,7 +244,7 @@ test "double nested array to const slice cast in array literal" {
238244
239 const cases3 = [_][]const []const i32{245 const cases3 = [_][]const []const i32{
240 [_][]const i32{[_]i32{1}},246 [_][]const i32{[_]i32{1}},
241 [_][]const i32{[_]i32{ two, 3 }},247 &[_][]const i32{&[_]i32{ two, 3 }},
242 [_][]const i32{248 [_][]const i32{
243 [_]i32{4},249 [_]i32{4},
244 [_]i32{ 5, 6, 7 },250 [_]i32{ 5, 6, 7 },
test/stage1/behavior/bitcast.zig+13
...@@ -112,3 +112,16 @@ test "bitcast packed struct to integer and back" {...@@ -112,3 +112,16 @@ test "bitcast packed struct to integer and back" {
112 S.doTheTest();112 S.doTheTest();
113 comptime S.doTheTest();113 comptime S.doTheTest();
114}114}
115
116test "implicit cast to error union by returning" {
117 const S = struct {
118 fn entry() void {
119 expect((func(-1) catch unreachable) == maxInt(u64));
120 }
121 pub fn func(sz: i64) anyerror!u64 {
122 return @bitCast(u64, sz);
123 }
124 };
125 S.entry();
126 comptime S.entry();
127}
test/stage1/behavior/cast.zig+37
...@@ -482,3 +482,40 @@ test "@intCast to u0 and use the result" {...@@ -482,3 +482,40 @@ test "@intCast to u0 and use the result" {
482 S.doTheTest(0, 1, 0);482 S.doTheTest(0, 1, 0);
483 comptime S.doTheTest(0, 1, 0);483 comptime S.doTheTest(0, 1, 0);
484}484}
485
486test "peer type resolution: unreachable, null, slice" {
487 const S = struct {
488 fn doTheTest(num: usize, word: []const u8) void {
489 const result = switch (num) {
490 0 => null,
491 1 => word,
492 else => unreachable,
493 };
494 expect(mem.eql(u8, result.?, "hi"));
495 }
496 };
497 S.doTheTest(1, "hi");
498}
499
500test "peer type resolution: unreachable, error set, unreachable" {
501 const Error = error {
502 FileDescriptorAlreadyPresentInSet,
503 OperationCausesCircularLoop,
504 FileDescriptorNotRegistered,
505 SystemResources,
506 UserResourceLimitReached,
507 FileDescriptorIncompatibleWithEpoll,
508 Unexpected,
509 };
510 var err = Error.SystemResources;
511 const transformed_err = switch (err) {
512 error.FileDescriptorAlreadyPresentInSet => unreachable,
513 error.OperationCausesCircularLoop => unreachable,
514 error.FileDescriptorNotRegistered => unreachable,
515 error.SystemResources => error.SystemResources,
516 error.UserResourceLimitReached => error.UserResourceLimitReached,
517 error.FileDescriptorIncompatibleWithEpoll => unreachable,
518 error.Unexpected => unreachable,
519 };
520 expect(transformed_err == error.SystemResources);
521}
test/stage1/behavior/error.zig+40
...@@ -335,3 +335,43 @@ test "debug info for optional error set" {...@@ -335,3 +335,43 @@ test "debug info for optional error set" {
335 const SomeError = error{Hello};335 const SomeError = error{Hello};
336 var a_local_variable: ?SomeError = null;336 var a_local_variable: ?SomeError = null;
337}337}
338
339test "nested catch" {
340 const S = struct {
341 fn entry() void {
342 expectError(error.Bad, func());
343 }
344 fn fail() anyerror!Foo {
345 return error.Wrong;
346 }
347 fn func() anyerror!Foo {
348 const x = fail() catch
349 fail() catch
350 return error.Bad;
351 unreachable;
352 }
353 const Foo = struct {
354 field: i32,
355 };
356 };
357 S.entry();
358 comptime S.entry();
359}
360
361test "implicit cast to optional to error union to return result loc" {
362 const S = struct {
363 fn entry() void {
364 if (func(undefined)) |opt| {
365 expect(opt != null);
366 } else |_| @panic("expected non error");
367 }
368 fn func(f: *Foo) anyerror!?*Foo {
369 return f;
370 }
371 const Foo = struct {
372 field: i32,
373 };
374 };
375 S.entry();
376 //comptime S.entry(); TODO
377}
test/stage1/behavior/eval.zig+12-2
...@@ -190,6 +190,17 @@ fn testTryToTrickEvalWithRuntimeIf(b: bool) usize {...@@ -190,6 +190,17 @@ fn testTryToTrickEvalWithRuntimeIf(b: bool) usize {
190 }190 }
191}191}
192192
193test "inlined loop has array literal with elided runtime scope on first iteration but not second iteration" {
194 var runtime = [1]i32{3};
195 comptime var i: usize = 0;
196 inline while (i < 2) : (i += 1) {
197 const result = if (i == 0) [1]i32{2} else runtime;
198 }
199 comptime {
200 expect(i == 2);
201 }
202}
203
193fn max(comptime T: type, a: T, b: T) T {204fn max(comptime T: type, a: T, b: T) T {
194 if (T == bool) {205 if (T == bool) {
195 return a or b;206 return a or b;
...@@ -756,8 +767,7 @@ test "comptime bitwise operators" {...@@ -756,8 +767,7 @@ test "comptime bitwise operators" {
756test "*align(1) u16 is the same as *align(1:0:2) u16" {767test "*align(1) u16 is the same as *align(1:0:2) u16" {
757 comptime {768 comptime {
758 expect(*align(1:0:2) u16 == *align(1) u16);769 expect(*align(1:0:2) u16 == *align(1) u16);
759 // TODO add parsing support for this syntax770 expect(*align(:0:2) u16 == *u16);
760 //expect(*align(:0:2) u16 == *u16);
761 }771 }
762}772}
763773
test/stage1/behavior/fn.zig+23
...@@ -205,3 +205,26 @@ test "extern struct with stdcallcc fn pointer" {...@@ -205,3 +205,26 @@ test "extern struct with stdcallcc fn pointer" {
205 s.ptr = S.foo;205 s.ptr = S.foo;
206 expect(s.ptr() == 1234);206 expect(s.ptr() == 1234);
207}207}
208
209test "implicit cast fn call result to optional in field result" {
210 const S = struct {
211 fn entry() void {
212 var x = Foo{
213 .field = optionalPtr(),
214 };
215 expect(x.field.?.* == 999);
216 }
217
218 const glob: i32 = 999;
219
220 fn optionalPtr() *const i32 {
221 return &glob;
222 }
223
224 const Foo = struct {
225 field: ?*const i32,
226 };
227 };
228 S.entry();
229 comptime S.entry();
230}
test/stage1/behavior/for.zig+16
...@@ -110,3 +110,19 @@ fn testContinueOuter() void {...@@ -110,3 +110,19 @@ fn testContinueOuter() void {
110 }110 }
111 expect(counter == array.len);111 expect(counter == array.len);
112}112}
113
114test "2 break statements and an else" {
115 const S = struct {
116 fn entry(t: bool, f: bool) void {
117 var buf: [10]u8 = undefined;
118 var ok = false;
119 ok = for (buf) |item| {
120 if (f) break false;
121 if (t) break true;
122 } else false;
123 expect(ok);
124 }
125 };
126 S.entry(true, false);
127 comptime S.entry(true, false);
128}
test/stage1/behavior/if.zig+11
...@@ -52,3 +52,14 @@ test "unwrap mutable global var" {...@@ -52,3 +52,14 @@ test "unwrap mutable global var" {
52 expect(e == error.SomeError);52 expect(e == error.SomeError);
53 }53 }
54}54}
55
56test "labeled break inside comptime if inside runtime if" {
57 var answer: i32 = 0;
58 var c = true;
59 if (c) {
60 answer = if (true) blk: {
61 break :blk i32(42);
62 };
63 }
64 expect(answer == 42);
65}
test/stage1/behavior/misc.zig+8
...@@ -698,3 +698,11 @@ test "unicode escape in character literal" {...@@ -698,3 +698,11 @@ test "unicode escape in character literal" {
698 var a: u24 = '\U01f4a9';698 var a: u24 = '\U01f4a9';
699 expect(a == 128169);699 expect(a == 128169);
700}700}
701
702test "result location zero sized array inside struct field implicit cast to slice" {
703 const E = struct {
704 entries: []u32,
705 };
706 var foo = E{ .entries = [_]u32{} };
707 expect(foo.entries.len == 0);
708}
test/stage1/behavior/optional.zig+23-2
...@@ -76,6 +76,27 @@ test "unwrap function call with optional pointer return value" {...@@ -76,6 +76,27 @@ test "unwrap function call with optional pointer return value" {
76 }76 }
77 };77 };
78 S.entry();78 S.entry();
79 // TODO https://github.com/ziglang/zig/issues/190179 comptime S.entry();
80 //comptime S.entry();80}
81
82test "nested orelse" {
83 const S = struct {
84 fn entry() void {
85 expect(func() == null);
86 }
87 fn maybe() ?Foo {
88 return null;
89 }
90 fn func() ?Foo {
91 const x = maybe() orelse
92 maybe() orelse
93 return null;
94 unreachable;
95 }
96 const Foo = struct {
97 field: i32,
98 };
99 };
100 S.entry();
101 comptime S.entry();
81}102}
test/stage1/behavior/struct.zig+21
...@@ -578,3 +578,24 @@ test "default struct initialization fields" {...@@ -578,3 +578,24 @@ test "default struct initialization fields" {
578 };578 };
579 expectEqual(1239, x.a + x.b);579 expectEqual(1239, x.a + x.b);
580}580}
581
582test "extern fn returns struct by value" {
583 const S = struct {
584 fn entry() void {
585 var x = makeBar(10);
586 expectEqual(i32(10), x.handle);
587 }
588
589 const ExternBar = extern struct {
590 handle: i32,
591 };
592
593 extern fn makeBar(t: i32) ExternBar {
594 return ExternBar{
595 .handle = t,
596 };
597 }
598 };
599 S.entry();
600 comptime S.entry();
601}
test/stage1/behavior/switch.zig+16
...@@ -360,3 +360,19 @@ test "switch prongs with error set cases make a new error set type for capture v...@@ -360,3 +360,19 @@ test "switch prongs with error set cases make a new error set type for capture v
360 S.doTheTest();360 S.doTheTest();
361 comptime S.doTheTest();361 comptime S.doTheTest();
362}362}
363
364test "return result loc and then switch with range implicit casted to error union" {
365 const S = struct {
366 fn doTheTest() void {
367 expect((func(0xb) catch unreachable) == 0xb);
368 }
369 fn func(d: u8) anyerror!u8 {
370 return switch (d) {
371 0xa...0xf => d,
372 else => unreachable,
373 };
374 }
375 };
376 S.doTheTest();
377 comptime S.doTheTest();
378}
test/stage1/behavior/union.zig+20
...@@ -402,3 +402,23 @@ test "comptime union field value equality" {...@@ -402,3 +402,23 @@ test "comptime union field value equality" {
402 expect(a0 != a1);402 expect(a0 != a1);
403 expect(b0 != b1);403 expect(b0 != b1);
404}404}
405
406test "return union init with void payload" {
407 const S = struct {
408 fn entry() void {
409 expect(func().state == State.one);
410 }
411 const Outer = union(enum) {
412 state: State,
413 };
414 const State = union(enum) {
415 one: void,
416 two: u32,
417 };
418 fn func() Outer {
419 return Outer{ .state = State{ .one = {} }};
420 }
421 };
422 S.entry();
423 comptime S.entry();
424}
test/stage1/behavior/vector.zig+13
...@@ -61,3 +61,16 @@ test "vector bit operators" {...@@ -61,3 +61,16 @@ test "vector bit operators" {
61 S.doTheTest();61 S.doTheTest();
62 comptime S.doTheTest();62 comptime S.doTheTest();
63}63}
64
65test "implicit cast vector to array" {
66 const S = struct {
67 fn doTheTest() void {
68 var a: @Vector(4, i32) = [_]i32{ 1, 2, 3, 4 };
69 var result_array: [4]i32 = a;
70 result_array = a;
71 expect(mem.eql(i32, result_array, [4]i32{ 1, 2, 3, 4 }));
72 }
73 };
74 S.doTheTest();
75 comptime S.doTheTest();
76}
test/stage1/behavior/while.zig+45
...@@ -226,3 +226,48 @@ fn returnFalse() bool {...@@ -226,3 +226,48 @@ fn returnFalse() bool {
226fn returnTrue() bool {226fn returnTrue() bool {
227 return true;227 return true;
228}228}
229
230test "while bool 2 break statements and an else" {
231 const S = struct {
232 fn entry(t: bool, f: bool) void {
233 var ok = false;
234 ok = while (t) {
235 if (f) break false;
236 if (t) break true;
237 } else false;
238 expect(ok);
239 }
240 };
241 S.entry(true, false);
242 comptime S.entry(true, false);
243}
244
245test "while optional 2 break statements and an else" {
246 const S = struct {
247 fn entry(opt_t: ?bool, f: bool) void {
248 var ok = false;
249 ok = while (opt_t) |t| {
250 if (f) break false;
251 if (t) break true;
252 } else false;
253 expect(ok);
254 }
255 };
256 S.entry(true, false);
257 comptime S.entry(true, false);
258}
259
260test "while error 2 break statements and an else" {
261 const S = struct {
262 fn entry(opt_t: anyerror!bool, f: bool) void {
263 var ok = false;
264 ok = while (opt_t) |t| {
265 if (f) break false;
266 if (t) break true;
267 } else |_| false;
268 expect(ok);
269 }
270 };
271 S.entry(true, false);
272 comptime S.entry(true, false);
273}
test/tests.zig+13-15
...@@ -811,23 +811,21 @@ pub const CompileErrorContext = struct {...@@ -811,23 +811,21 @@ pub const CompileErrorContext = struct {
811 pub fn addCase(self: *CompileErrorContext, case: *const TestCase) void {811 pub fn addCase(self: *CompileErrorContext, case: *const TestCase) void {
812 const b = self.b;812 const b = self.b;
813813
814 for (self.modes) |mode| {814 const annotated_case_name = fmt.allocPrint(self.b.allocator, "compile-error {}", case.name) catch unreachable;
815 const annotated_case_name = fmt.allocPrint(self.b.allocator, "compile-error {} ({})", case.name, @tagName(mode)) catch unreachable;815 if (self.test_filter) |filter| {
816 if (self.test_filter) |filter| {816 if (mem.indexOf(u8, annotated_case_name, filter) == null) return;
817 if (mem.indexOf(u8, annotated_case_name, filter) == null) continue;817 }
818 }
819818
820 const compile_and_cmp_errors = CompileCmpOutputStep.create(self, annotated_case_name, case, mode);819 const compile_and_cmp_errors = CompileCmpOutputStep.create(self, annotated_case_name, case, .Debug);
821 self.step.dependOn(&compile_and_cmp_errors.step);820 self.step.dependOn(&compile_and_cmp_errors.step);
822821
823 for (case.sources.toSliceConst()) |src_file| {822 for (case.sources.toSliceConst()) |src_file| {
824 const expanded_src_path = fs.path.join(823 const expanded_src_path = fs.path.join(
825 b.allocator,824 b.allocator,
826 [_][]const u8{ b.cache_root, src_file.filename },825 [_][]const u8{ b.cache_root, src_file.filename },
827 ) catch unreachable;826 ) catch unreachable;
828 const write_src = b.addWriteFile(expanded_src_path, src_file.source);827 const write_src = b.addWriteFile(expanded_src_path, src_file.source);
829 compile_and_cmp_errors.step.dependOn(&write_src.step);828 compile_and_cmp_errors.step.dependOn(&write_src.step);
830 }
831 }829 }
832 }830 }
833};831};