authorgravatar for codroid@gmail.comhryx <codroid@gmail.com> 2019-06-27 22:12:34-07:00
committergravatar for codroid@gmail.comhryx <codroid@gmail.com> 2019-06-27 22:12:34-07:00
log2060c7c39b5c33fd6379a785b9beb921a22d1a6a
tree706903c47f96ea2b3b2e66b2ae62d05acf078f72
parent3e0ff32bd84102e4ea892bfdab6cd20daab83897
parentae72a982242fbd46f389f933c18b036e919093bc
signature Commit is signed but in an unrecognized format.

Merge branch 'master' into translate-c-userland


63 files changed, 6649 insertions(+), 2716 deletions(-)

CMakeLists.txt+12-3
......@@ -389,6 +389,8 @@ set(EMBEDDED_SOFTFLOAT_SOURCES
389389 "${CMAKE_SOURCE_DIR}/deps/SoftFloat-3e/source/s_subMagsF32.c"
390390 "${CMAKE_SOURCE_DIR}/deps/SoftFloat-3e/source/s_subMagsF64.c"
391391 "${CMAKE_SOURCE_DIR}/deps/SoftFloat-3e/source/s_tryPropagateNaNF128M.c"
392 "${CMAKE_SOURCE_DIR}/deps/SoftFloat-3e/source/f16_mulAdd.c"
393 "${CMAKE_SOURCE_DIR}/deps/SoftFloat-3e/source/f128M_mulAdd.c"
392394 "${CMAKE_SOURCE_DIR}/deps/SoftFloat-3e/source/softfloat_state.c"
393395 "${CMAKE_SOURCE_DIR}/deps/SoftFloat-3e/source/ui32_to_f128M.c"
394396 "${CMAKE_SOURCE_DIR}/deps/SoftFloat-3e/source/ui64_to_f128M.c"
......@@ -522,6 +524,9 @@ set(ZIG_STD_FILES
522524 "hash/siphash.zig"
523525 "hash_map.zig"
524526 "heap.zig"
527 "heap/logging_allocator.zig"
528 "http.zig"
529 "http/headers.zig"
525530 "io.zig"
526531 "io/c_out_stream.zig"
527532 "io/seekable_stream.zig"
......@@ -6653,15 +6658,18 @@ set(OPTIMIZED_C_FLAGS "-std=c99 -O3")
66536658set(EXE_LDFLAGS " ")
66546659if(MSVC)
66556660 set(EXE_LDFLAGS "/STACK:16777216")
6656elseif(ZIG_STATIC)
6661elseif(MINGW)
6662 set(EXE_LDFLAGS "${EXE_LDFLAGS} -Wl,--stack,16777216")
6663endif()
6664
6665if(ZIG_STATIC)
66576666 if(APPLE)
66586667 set(EXE_LDFLAGS "-static-libgcc -static-libstdc++")
66596668 else()
66606669 set(EXE_LDFLAGS "-static")
66616670 endif()
6662else()
6663 set(EXE_LDFLAGS " ")
66646671endif()
6672
66656673if(ZIG_TEST_COVERAGE)
66666674 set(EXE_CFLAGS "${EXE_CFLAGS} -fprofile-arcs -ftest-coverage")
66676675 set(EXE_LDFLAGS "${EXE_LDFLAGS} -fprofile-arcs -ftest-coverage")
......@@ -6729,6 +6737,7 @@ add_custom_command(
67296737 "-Doutput-dir=${CMAKE_BINARY_DIR}"
67306738 WORKING_DIRECTORY "${CMAKE_SOURCE_DIR}"
67316739 DEPENDS
6740 zig0
67326741 "${CMAKE_SOURCE_DIR}/src-self-hosted/dep_tokenizer.zig"
67336742 "${CMAKE_SOURCE_DIR}/src-self-hosted/stage1.zig"
67346743 "${CMAKE_SOURCE_DIR}/src-self-hosted/translate_c.zig"
build.zig+2-1
......@@ -74,7 +74,8 @@ pub fn build(b: *Builder) !void {
7474 const skip_non_native = b.option(bool, "skip-non-native", "Main test suite skips non-native builds") orelse false;
7575 const skip_self_hosted = b.option(bool, "skip-self-hosted", "Main test suite skips building self hosted compiler") orelse false;
7676 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);
7879 }
7980 const verbose_link_exe = b.option(bool, "verbose-link", "Print link command for self hosted compiler") orelse false;
8081 exe.setVerboseLink(verbose_link_exe);
doc/langref.html.in+91-3
......@@ -5096,7 +5096,7 @@ fn gimmeTheBiggerInteger(a: u64, b: u64) u64 {
50965096 <p>
50975097 For example, if we were to introduce another function to the above snippet:
50985098 </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'#}
51005100fn max(comptime T: type, a: T, b: T) T {
51015101 return if (a > b) a else b;
51025102}
......@@ -6259,6 +6259,13 @@ comptime {
62596259 This function is only valid within function scope.
62606260 </p>
62616261
6262 {#header_close#}
6263 {#header_open|@mulAdd#}
6264 <pre>{#syntax#}@mulAdd(comptime T: type, a: T, b: T, c: T) T{#endsyntax#}</pre>
6265 <p>
6266 Fused multiply add (for floats), similar to {#syntax#}(a * b) + c{#endsyntax#}, except
6267 only rounds once, and is thus more accurate.
6268 </p>
62626269 {#header_close#}
62636270
62646271 {#header_open|@byteSwap#}
......@@ -7347,10 +7354,91 @@ test "@setRuntimeSafety" {
73477354 <pre>{#syntax#}@sqrt(comptime T: type, value: T) T{#endsyntax#}</pre>
73487355 <p>
73497356 Performs the square root of a floating point number. Uses a dedicated hardware instruction
7350 when available. Currently only supports f32 and f64 at runtime. f128 at runtime is TODO.
7357 when available. Supports f16, f32, f64, and f128, as well as vectors.
7358 </p>
7359 {#header_close#}
7360 {#header_open|@sin#}
7361 <pre>{#syntax#}@sin(comptime T: type, value: T) T{#endsyntax#}</pre>
7362 <p>
7363 Sine trigometric function on a floating point number. Uses a dedicated hardware instruction
7364 when available. Currently supports f32 and f64.
73517365 </p>
7366 {#header_close#}
7367 {#header_open|@cos#}
7368 <pre>{#syntax#}@cos(comptime T: type, value: T) T{#endsyntax#}</pre>
7369 <p>
7370 Cosine trigometric function on a floating point number. Uses a dedicated hardware instruction
7371 when available. Currently supports f32 and f64.
7372 </p>
7373 {#header_close#}
7374 {#header_open|@exp#}
7375 <pre>{#syntax#}@exp(comptime T: type, value: T) T{#endsyntax#}</pre>
7376 <p>
7377 Base-e exponential function on a floating point number. Uses a dedicated hardware instruction
7378 when available. Currently supports f32 and f64.
7379 </p>
7380 {#header_close#}
7381 {#header_open|@exp2#}
7382 <pre>{#syntax#}@exp2(comptime T: type, value: T) T{#endsyntax#}</pre>
7383 <p>
7384 Base-2 exponential function on a floating point number. Uses a dedicated hardware instruction
7385 when available. Currently supports f32 and f64.
7386 </p>
7387 {#header_close#}
7388 {#header_open|@ln#}
7389 <pre>{#syntax#}@ln(comptime T: type, value: T) T{#endsyntax#}</pre>
7390 <p>
7391 Returns the natural logarithm of a floating point number. Uses a dedicated hardware instruction
7392 when available. Currently supports f32 and f64.
7393 </p>
7394 {#header_close#}
7395 {#header_open|@log2#}
7396 <pre>{#syntax#}@log2(comptime T: type, value: T) T{#endsyntax#}</pre>
7397 <p>
7398 Returns the logarithm to the base 2 of a floating point number. Uses a dedicated hardware instruction
7399 when available. Currently supports f32 and f64.
7400 </p>
7401 {#header_close#}
7402 {#header_open|@log10#}
7403 <pre>{#syntax#}@log10(comptime T: type, value: T) T{#endsyntax#}</pre>
7404 <p>
7405 Returns the logarithm to the base 10 of a floating point number. Uses a dedicated hardware instruction
7406 when available. Currently supports f32 and f64.
7407 </p>
7408 {#header_close#}
7409 {#header_open|@fabs#}
7410 <pre>{#syntax#}@fabs(comptime T: type, value: T) T{#endsyntax#}</pre>
7411 <p>
7412 Returns the absolute value of a floating point number. Uses a dedicated hardware instruction
7413 when available. Currently supports f32 and f64.
7414 </p>
7415 {#header_close#}
7416 {#header_open|@floor#}
7417 <pre>{#syntax#}@floor(comptime T: type, value: T) T{#endsyntax#}</pre>
7418 <p>
7419 Returns the largest integral value not greater than the given floating point number. Uses a dedicated hardware instruction
7420 when available. Currently supports f32 and f64.
7421 </p>
7422 {#header_close#}
7423 {#header_open|@ceil#}
7424 <pre>{#syntax#}@ceil(comptime T: type, value: T) T{#endsyntax#}</pre>
7425 <p>
7426 Returns the largest integral value not less than the given floating point number. Uses a dedicated hardware instruction
7427 when available. Currently supports f32 and f64.
7428 </p>
7429 {#header_close#}
7430 {#header_open|@trunc#}
7431 <pre>{#syntax#}@trunc(comptime T: type, value: T) T{#endsyntax#}</pre>
7432 <p>
7433 Rounds the given floating point number to an integer, towards zero. Uses a dedicated hardware instruction
7434 when available. Currently supports f32 and f64.
7435 </p>
7436 {#header_close#}
7437 {#header_open|@round#}
7438 <pre>{#syntax#}@round(comptime T: type, value: T) T{#endsyntax#}</pre>
73527439 <p>
7353 This is a low-level intrinsic. Most code can use {#syntax#}std.math.sqrt{#endsyntax#} instead.
7440 Rounds the given floating point number to an integer, away from zero. Uses a dedicated hardware instruction
7441 when available. Currently supports f32 and f64.
73547442 </p>
73557443 {#header_close#}
73567444
src-self-hosted/dep_tokenizer.zig+1-1
......@@ -998,7 +998,7 @@ fn printCharValues(out: var, bytes: []const u8) !void {
998998
999999fn printUnderstandableChar(out: var, char: u8) !void {
10001000 if (!std.ascii.isPrint(char) or char == ' ') {
1001 std.fmt.format(out.context, anyerror, out.output, "\\x{X2}", char) catch {};
1001 std.fmt.format(out.context, anyerror, out.output, "\\x{X:2}", char) catch {};
10021002 } else {
10031003 try out.write("'");
10041004 try out.write([_]u8{printable_char_tab[char]});
src/all_types.hpp+311-98
......@@ -34,12 +34,17 @@ struct CodeGen;
3434struct ConstExprValue;
3535struct IrInstruction;
3636struct IrInstructionCast;
37struct IrInstructionAllocaGen;
3738struct IrBasicBlock;
3839struct ScopeDecls;
3940struct ZigWindowsSDK;
4041struct Tld;
4142struct TldExport;
4243struct IrAnalyze;
44struct ResultLoc;
45struct ResultLocPeer;
46struct ResultLocPeerParent;
47struct ResultLocBitCast;
4348
4449enum X64CABIClass {
4550 X64CABIClass_Unknown,
......@@ -198,6 +203,9 @@ enum ConstPtrMut {
198203 // The pointer points to memory that is known only at runtime.
199204 // For example it may point to the initializer value of a variable.
200205 ConstPtrMutRuntimeVar,
206 // The pointer points to memory for which it must be inferred whether the
207 // value is comptime known or not.
208 ConstPtrMutInfer,
201209};
202210
203211struct ConstPtrValue {
......@@ -289,6 +297,7 @@ struct RuntimeHintSlice {
289297struct ConstGlobalRefs {
290298 LLVMValueRef llvm_value;
291299 LLVMValueRef llvm_global;
300 uint32_t align;
292301};
293302
294303struct ConstExprValue {
......@@ -325,6 +334,10 @@ struct ConstExprValue {
325334 RuntimeHintPtr rh_ptr;
326335 RuntimeHintSlice rh_slice;
327336 } 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
328341};
329342
330343enum ReturnKnowledge {
......@@ -426,7 +439,7 @@ enum NodeType {
426439 NodeTypeVariableDeclaration,
427440 NodeTypeTestDecl,
428441 NodeTypeBinOpExpr,
429 NodeTypeUnwrapErrorExpr,
442 NodeTypeCatchExpr,
430443 NodeTypeFloatLiteral,
431444 NodeTypeIntLiteral,
432445 NodeTypeStringLiteral,
......@@ -1097,6 +1110,8 @@ struct ZigPackage {
10971110
10981111 // reminder: hash tables must be initialized before use
10991112 HashMap<Buf *, ZigPackage *, buf_hash, buf_eql_buf> package_table;
1113
1114 bool added_to_cache;
11001115};
11011116
11021117// Stuff that only applies to a struct which is the implicit root struct of a file
......@@ -1364,7 +1379,7 @@ struct ZigFn {
13641379 AstNode *fn_no_inline_set_node;
13651380 AstNode *fn_static_eval_set_node;
13661381
1367 ZigList<IrInstruction *> alloca_list;
1382 ZigList<IrInstructionAllocaGen *> alloca_gen_list;
13681383 ZigList<ZigVar *> variable_list;
13691384
13701385 Buf *section_name;
......@@ -1406,6 +1421,7 @@ enum BuiltinFnId {
14061421 BuiltinFnIdSubWithOverflow,
14071422 BuiltinFnIdMulWithOverflow,
14081423 BuiltinFnIdShlWithOverflow,
1424 BuiltinFnIdMulAdd,
14091425 BuiltinFnIdCInclude,
14101426 BuiltinFnIdCDefine,
14111427 BuiltinFnIdCUndef,
......@@ -1433,6 +1449,19 @@ enum BuiltinFnId {
14331449 BuiltinFnIdRem,
14341450 BuiltinFnIdMod,
14351451 BuiltinFnIdSqrt,
1452 BuiltinFnIdSin,
1453 BuiltinFnIdCos,
1454 BuiltinFnIdExp,
1455 BuiltinFnIdExp2,
1456 BuiltinFnIdLn,
1457 BuiltinFnIdLog2,
1458 BuiltinFnIdLog10,
1459 BuiltinFnIdFabs,
1460 BuiltinFnIdFloor,
1461 BuiltinFnIdCeil,
1462 BuiltinFnIdTrunc,
1463 BuiltinFnIdNearbyInt,
1464 BuiltinFnIdRound,
14361465 BuiltinFnIdTruncate,
14371466 BuiltinFnIdIntCast,
14381467 BuiltinFnIdFloatCast,
......@@ -1554,9 +1583,8 @@ enum ZigLLVMFnId {
15541583 ZigLLVMFnIdClz,
15551584 ZigLLVMFnIdPopCount,
15561585 ZigLLVMFnIdOverflowArithmetic,
1557 ZigLLVMFnIdFloor,
1558 ZigLLVMFnIdCeil,
1559 ZigLLVMFnIdSqrt,
1586 ZigLLVMFnIdFMA,
1587 ZigLLVMFnIdFloatOp,
15601588 ZigLLVMFnIdBswap,
15611589 ZigLLVMFnIdBitReverse,
15621590};
......@@ -1583,7 +1611,9 @@ struct ZigLLVMFnKey {
15831611 uint32_t bit_count;
15841612 } pop_count;
15851613 struct {
1614 BuiltinFnId op;
15861615 uint32_t bit_count;
1616 uint32_t vector_len; // 0 means not a vector
15871617 } floating;
15881618 struct {
15891619 AddSubMul add_sub_mul;
......@@ -1984,6 +2014,11 @@ struct ScopeDecls {
19842014 bool any_imports_failed;
19852015};
19862016
2017enum LVal {
2018 LValNone,
2019 LValPtr,
2020};
2021
19872022// This scope comes from a block expression in user code.
19882023// NodeTypeBlock
19892024struct ScopeBlock {
......@@ -1992,12 +2027,14 @@ struct ScopeBlock {
19922027 Buf *name;
19932028 IrBasicBlock *end_block;
19942029 IrInstruction *is_comptime;
2030 ResultLocPeerParent *peer_parent;
19952031 ZigList<IrInstruction *> *incoming_values;
19962032 ZigList<IrBasicBlock *> *incoming_blocks;
19972033
19982034 AstNode *safety_set_node;
19992035 AstNode *fast_math_set_node;
20002036
2037 LVal lval;
20012038 bool safety_off;
20022039 bool fast_math_on;
20032040};
......@@ -2041,12 +2078,14 @@ struct ScopeCImport {
20412078struct ScopeLoop {
20422079 Scope base;
20432080
2081 LVal lval;
20442082 Buf *name;
20452083 IrBasicBlock *break_block;
20462084 IrBasicBlock *continue_block;
20472085 IrInstruction *is_comptime;
20482086 ZigList<IrInstruction *> *incoming_values;
20492087 ZigList<IrBasicBlock *> *incoming_blocks;
2088 ResultLocPeerParent *peer_parent;
20502089};
20512090
20522091// This scope blocks certain things from working such as comptime continue
......@@ -2123,6 +2162,8 @@ struct IrBasicBlock {
21232162 const char *name_hint;
21242163 size_t debug_id;
21252164 size_t ref_count;
2165 // index into the basic block list
2166 size_t index;
21262167 LLVMBasicBlockRef llvm_block;
21272168 LLVMBasicBlockRef llvm_exit_block;
21282169 // The instruction that referenced this basic block and caused us to
......@@ -2133,11 +2174,10 @@ struct IrBasicBlock {
21332174 // if the branch is comptime. The instruction points to the reason
21342175 // the basic block must be comptime.
21352176 IrInstruction *must_be_comptime_source_instr;
2136};
2137
2138enum LVal {
2139 LValNone,
2140 LValPtr,
2177 IrInstruction *suspend_instruction_ref;
2178 bool already_appended;
2179 bool suspended;
2180 bool in_resume_stack;
21412181};
21422182
21432183// These instructions are in transition to having "pass 1" instructions
......@@ -2170,19 +2210,17 @@ enum IrInstructionId {
21702210 IrInstructionIdUnionFieldPtr,
21712211 IrInstructionIdElemPtr,
21722212 IrInstructionIdVarPtr,
2173 IrInstructionIdCall,
2213 IrInstructionIdReturnPtr,
2214 IrInstructionIdCallSrc,
2215 IrInstructionIdCallGen,
21742216 IrInstructionIdConst,
21752217 IrInstructionIdReturn,
21762218 IrInstructionIdCast,
21772219 IrInstructionIdResizeSlice,
21782220 IrInstructionIdContainerInitList,
21792221 IrInstructionIdContainerInitFields,
2180 IrInstructionIdStructInit,
2181 IrInstructionIdUnionInit,
21822222 IrInstructionIdUnreachable,
21832223 IrInstructionIdTypeOf,
2184 IrInstructionIdToPtrType,
2185 IrInstructionIdPtrTypeChild,
21862224 IrInstructionIdSetCold,
21872225 IrInstructionIdSetRuntimeSafety,
21882226 IrInstructionIdSetFloatMode,
......@@ -2207,6 +2245,7 @@ enum IrInstructionId {
22072245 IrInstructionIdCDefine,
22082246 IrInstructionIdCUndef,
22092247 IrInstructionIdRef,
2248 IrInstructionIdRefGen,
22102249 IrInstructionIdCompileErr,
22112250 IrInstructionIdCompileLog,
22122251 IrInstructionIdErrName,
......@@ -2225,7 +2264,8 @@ enum IrInstructionId {
22252264 IrInstructionIdBoolNot,
22262265 IrInstructionIdMemset,
22272266 IrInstructionIdMemcpy,
2228 IrInstructionIdSlice,
2267 IrInstructionIdSliceSrc,
2268 IrInstructionIdSliceGen,
22292269 IrInstructionIdMemberCount,
22302270 IrInstructionIdMemberType,
22312271 IrInstructionIdMemberName,
......@@ -2235,7 +2275,10 @@ enum IrInstructionId {
22352275 IrInstructionIdHandle,
22362276 IrInstructionIdAlignOf,
22372277 IrInstructionIdOverflowOp,
2238 IrInstructionIdTestErr,
2278 IrInstructionIdTestErrSrc,
2279 IrInstructionIdTestErrGen,
2280 IrInstructionIdMulAdd,
2281 IrInstructionIdFloatOp,
22392282 IrInstructionIdUnwrapErrCode,
22402283 IrInstructionIdUnwrapErrPayload,
22412284 IrInstructionIdErrWrapCode,
......@@ -2244,7 +2287,7 @@ enum IrInstructionId {
22442287 IrInstructionIdTestComptime,
22452288 IrInstructionIdPtrCastSrc,
22462289 IrInstructionIdPtrCastGen,
2247 IrInstructionIdBitCast,
2290 IrInstructionIdBitCastSrc,
22482291 IrInstructionIdBitCastGen,
22492292 IrInstructionIdWidenOrShorten,
22502293 IrInstructionIdIntToPtr,
......@@ -2268,6 +2311,10 @@ enum IrInstructionId {
22682311 IrInstructionIdSetEvalBranchQuota,
22692312 IrInstructionIdPtrType,
22702313 IrInstructionIdAlignCast,
2314 IrInstructionIdImplicitCast,
2315 IrInstructionIdResolveResult,
2316 IrInstructionIdResetResult,
2317 IrInstructionIdResultPtr,
22712318 IrInstructionIdOpaqueType,
22722319 IrInstructionIdSetAlignStack,
22732320 IrInstructionIdArgType,
......@@ -2296,7 +2343,6 @@ enum IrInstructionId {
22962343 IrInstructionIdAddImplicitReturnType,
22972344 IrInstructionIdMergeErrRetTraces,
22982345 IrInstructionIdMarkErrRetTracePtr,
2299 IrInstructionIdSqrt,
23002346 IrInstructionIdErrSetCast,
23012347 IrInstructionIdToBytes,
23022348 IrInstructionIdFromBytes,
......@@ -2307,10 +2353,13 @@ enum IrInstructionId {
23072353 IrInstructionIdAssertNonNull,
23082354 IrInstructionIdHasDecl,
23092355 IrInstructionIdUndeclaredIdent,
2356 IrInstructionIdAllocaSrc,
2357 IrInstructionIdAllocaGen,
2358 IrInstructionIdEndExpr,
2359 IrInstructionIdPtrOfArrayToSlice,
23102360};
23112361
23122362struct IrInstruction {
2313 IrInstructionId id;
23142363 Scope *scope;
23152364 AstNode *source_node;
23162365 ConstExprValue value;
......@@ -2324,6 +2373,7 @@ struct IrInstruction {
23242373 // with this child field.
23252374 IrInstruction *child;
23262375 IrBasicBlock *owner_bb;
2376 IrInstructionId id;
23272377 // true if this instruction was generated by zig and not from user code
23282378 bool is_gen;
23292379};
......@@ -2334,14 +2384,14 @@ struct IrInstructionDeclVarSrc {
23342384 ZigVar *var;
23352385 IrInstruction *var_type;
23362386 IrInstruction *align_value;
2337 IrInstruction *init_value;
2387 IrInstruction *ptr;
23382388};
23392389
23402390struct IrInstructionDeclVarGen {
23412391 IrInstruction base;
23422392
23432393 ZigVar *var;
2344 IrInstruction *init_value;
2394 IrInstruction *var_ptr;
23452395};
23462396
23472397struct IrInstructionCondBr {
......@@ -2351,6 +2401,7 @@ struct IrInstructionCondBr {
23512401 IrBasicBlock *then_block;
23522402 IrBasicBlock *else_block;
23532403 IrInstruction *is_comptime;
2404 ResultLoc *result_loc;
23542405};
23552406
23562407struct IrInstructionBr {
......@@ -2403,6 +2454,7 @@ struct IrInstructionPhi {
24032454 size_t incoming_count;
24042455 IrBasicBlock **incoming_blocks;
24052456 IrInstruction **incoming_values;
2457 ResultLocPeerParent *peer_parent;
24062458};
24072459
24082460enum IrUnOp {
......@@ -2418,8 +2470,9 @@ struct IrInstructionUnOp {
24182470 IrInstruction base;
24192471
24202472 IrUnOp op_id;
2421 IrInstruction *value;
24222473 LVal lval;
2474 IrInstruction *value;
2475 ResultLoc *result_loc;
24232476};
24242477
24252478enum IrBinOp {
......@@ -2476,7 +2529,7 @@ struct IrInstructionLoadPtrGen {
24762529 IrInstruction base;
24772530
24782531 IrInstruction *ptr;
2479 LLVMValueRef tmp_ptr;
2532 IrInstruction *result_loc;
24802533};
24812534
24822535struct IrInstructionStorePtr {
......@@ -2489,6 +2542,7 @@ struct IrInstructionStorePtr {
24892542struct IrInstructionFieldPtr {
24902543 IrInstruction base;
24912544
2545 bool initializing;
24922546 IrInstruction *container_ptr;
24932547 Buf *field_name_buffer;
24942548 IrInstruction *field_name_expr;
......@@ -2505,9 +2559,10 @@ struct IrInstructionStructFieldPtr {
25052559struct IrInstructionUnionFieldPtr {
25062560 IrInstruction base;
25072561
2562 bool safety_check_on;
2563 bool initializing;
25082564 IrInstruction *union_ptr;
25092565 TypeUnionField *field;
2510 bool is_const;
25112566};
25122567
25132568struct IrInstructionElemPtr {
......@@ -2515,8 +2570,8 @@ struct IrInstructionElemPtr {
25152570
25162571 IrInstruction *array_ptr;
25172572 IrInstruction *elem_index;
2573 IrInstruction *init_array_type;
25182574 PtrLen ptr_len;
2519 bool is_const;
25202575 bool safety_check_on;
25212576};
25222577
......@@ -2527,14 +2582,21 @@ struct IrInstructionVarPtr {
25272582 ScopeFnDef *crossed_fndef_scope;
25282583};
25292584
2530struct IrInstructionCall {
2585// For functions that have a return type for which handle_is_ptr is true, a
2586// result location pointer is the secret first parameter ("sret"). This
2587// instruction returns that pointer.
2588struct IrInstructionReturnPtr {
2589 IrInstruction base;
2590};
2591
2592struct IrInstructionCallSrc {
25312593 IrInstruction base;
25322594
25332595 IrInstruction *fn_ref;
25342596 ZigFn *fn_entry;
25352597 size_t arg_count;
25362598 IrInstruction **args;
2537 LLVMValueRef tmp_ptr;
2599 ResultLoc *result_loc;
25382600
25392601 IrInstruction *async_allocator;
25402602 IrInstruction *new_stack;
......@@ -2543,6 +2605,21 @@ struct IrInstructionCall {
25432605 bool is_comptime;
25442606};
25452607
2608struct IrInstructionCallGen {
2609 IrInstruction base;
2610
2611 IrInstruction *fn_ref;
2612 ZigFn *fn_entry;
2613 size_t arg_count;
2614 IrInstruction **args;
2615 IrInstruction *result_loc;
2616
2617 IrInstruction *async_allocator;
2618 IrInstruction *new_stack;
2619 FnInline fn_inline;
2620 bool is_async;
2621};
2622
25462623struct IrInstructionConst {
25472624 IrInstruction base;
25482625};
......@@ -2565,7 +2642,6 @@ enum CastOp {
25652642 CastOpNumLitToConcrete,
25662643 CastOpErrSet,
25672644 CastOpBitCast,
2568 CastOpPtrOfArrayToSlice,
25692645};
25702646
25712647// TODO get rid of this instruction, replace with instructions for each op code
......@@ -2575,14 +2651,13 @@ struct IrInstructionCast {
25752651 IrInstruction *value;
25762652 ZigType *dest_type;
25772653 CastOp cast_op;
2578 LLVMValueRef tmp_ptr;
25792654};
25802655
25812656struct IrInstructionResizeSlice {
25822657 IrInstruction base;
25832658
25842659 IrInstruction *operand;
2585 LLVMValueRef tmp_ptr;
2660 IrInstruction *result_loc;
25862661};
25872662
25882663struct IrInstructionContainerInitList {
......@@ -2591,15 +2666,15 @@ struct IrInstructionContainerInitList {
25912666 IrInstruction *container_type;
25922667 IrInstruction *elem_type;
25932668 size_t item_count;
2594 IrInstruction **items;
2595 LLVMValueRef tmp_ptr;
2669 IrInstruction **elem_result_loc_list;
2670 IrInstruction *result_loc;
25962671};
25972672
25982673struct IrInstructionContainerInitFieldsField {
25992674 Buf *name;
2600 IrInstruction *value;
26012675 AstNode *source_node;
26022676 TypeStructField *type_struct_field;
2677 IrInstruction *result_loc;
26032678};
26042679
26052680struct IrInstructionContainerInitFields {
......@@ -2608,29 +2683,7 @@ struct IrInstructionContainerInitFields {
26082683 IrInstruction *container_type;
26092684 size_t field_count;
26102685 IrInstructionContainerInitFieldsField *fields;
2611};
2612
2613struct IrInstructionStructInitField {
2614 IrInstruction *value;
2615 TypeStructField *type_struct_field;
2616};
2617
2618struct IrInstructionStructInit {
2619 IrInstruction base;
2620
2621 ZigType *struct_type;
2622 size_t field_count;
2623 IrInstructionStructInitField *fields;
2624 LLVMValueRef tmp_ptr;
2625};
2626
2627struct IrInstructionUnionInit {
2628 IrInstruction base;
2629
2630 ZigType *union_type;
2631 TypeUnionField *field;
2632 IrInstruction *init_value;
2633 LLVMValueRef tmp_ptr;
2686 IrInstruction *result_loc;
26342687};
26352688
26362689struct IrInstructionUnreachable {
......@@ -2643,18 +2696,6 @@ struct IrInstructionTypeOf {
26432696 IrInstruction *value;
26442697};
26452698
2646struct IrInstructionToPtrType {
2647 IrInstruction base;
2648
2649 IrInstruction *ptr;
2650};
2651
2652struct IrInstructionPtrTypeChild {
2653 IrInstruction base;
2654
2655 IrInstruction *value;
2656};
2657
26582699struct IrInstructionSetCold {
26592700 IrInstruction base;
26602701
......@@ -2748,8 +2789,9 @@ struct IrInstructionTestNonNull {
27482789struct IrInstructionOptionalUnwrapPtr {
27492790 IrInstruction base;
27502791
2751 IrInstruction *base_ptr;
27522792 bool safety_check_on;
2793 bool initializing;
2794 IrInstruction *base_ptr;
27532795};
27542796
27552797struct IrInstructionCtz {
......@@ -2789,11 +2831,17 @@ struct IrInstructionRef {
27892831 IrInstruction base;
27902832
27912833 IrInstruction *value;
2792 LLVMValueRef tmp_ptr;
27932834 bool is_const;
27942835 bool is_volatile;
27952836};
27962837
2838struct IrInstructionRefGen {
2839 IrInstruction base;
2840
2841 IrInstruction *operand;
2842 IrInstruction *result_loc;
2843};
2844
27972845struct IrInstructionCompileErr {
27982846 IrInstruction base;
27992847
......@@ -2845,26 +2893,26 @@ struct IrInstructionEmbedFile {
28452893struct IrInstructionCmpxchgSrc {
28462894 IrInstruction base;
28472895
2896 bool is_weak;
28482897 IrInstruction *type_value;
28492898 IrInstruction *ptr;
28502899 IrInstruction *cmp_value;
28512900 IrInstruction *new_value;
28522901 IrInstruction *success_order_value;
28532902 IrInstruction *failure_order_value;
2854
2855 bool is_weak;
2903 ResultLoc *result_loc;
28562904};
28572905
28582906struct IrInstructionCmpxchgGen {
28592907 IrInstruction base;
28602908
2909 bool is_weak;
2910 AtomicOrder success_order;
2911 AtomicOrder failure_order;
28612912 IrInstruction *ptr;
28622913 IrInstruction *cmp_value;
28632914 IrInstruction *new_value;
2864 LLVMValueRef tmp_ptr;
2865 AtomicOrder success_order;
2866 AtomicOrder failure_order;
2867 bool is_weak;
2915 IrInstruction *result_loc;
28682916};
28692917
28702918struct IrInstructionFence {
......@@ -2908,6 +2956,7 @@ struct IrInstructionToBytes {
29082956 IrInstruction base;
29092957
29102958 IrInstruction *target;
2959 ResultLoc *result_loc;
29112960};
29122961
29132962struct IrInstructionFromBytes {
......@@ -2915,6 +2964,7 @@ struct IrInstructionFromBytes {
29152964
29162965 IrInstruction *dest_child_type;
29172966 IrInstruction *target;
2967 ResultLoc *result_loc;
29182968};
29192969
29202970struct IrInstructionIntToFloat {
......@@ -2973,14 +3023,24 @@ struct IrInstructionMemcpy {
29733023 IrInstruction *count;
29743024};
29753025
2976struct IrInstructionSlice {
3026struct IrInstructionSliceSrc {
29773027 IrInstruction base;
29783028
3029 bool safety_check_on;
29793030 IrInstruction *ptr;
29803031 IrInstruction *start;
29813032 IrInstruction *end;
3033 ResultLoc *result_loc;
3034};
3035
3036struct IrInstructionSliceGen {
3037 IrInstruction base;
3038
29823039 bool safety_check_on;
2983 LLVMValueRef tmp_ptr;
3040 IrInstruction *ptr;
3041 IrInstruction *start;
3042 IrInstruction *end;
3043 IrInstruction *result_loc;
29843044};
29853045
29863046struct IrInstructionMemberCount {
......@@ -3038,6 +3098,15 @@ struct IrInstructionOverflowOp {
30383098 ZigType *result_ptr_type;
30393099};
30403100
3101struct IrInstructionMulAdd {
3102 IrInstruction base;
3103
3104 IrInstruction *type_value;
3105 IrInstruction *op1;
3106 IrInstruction *op2;
3107 IrInstruction *op3;
3108};
3109
30413110struct IrInstructionAlignOf {
30423111 IrInstruction base;
30433112
......@@ -3045,44 +3114,54 @@ struct IrInstructionAlignOf {
30453114};
30463115
30473116// returns true if error, returns false if not error
3048struct IrInstructionTestErr {
3117struct IrInstructionTestErrSrc {
30493118 IrInstruction base;
30503119
3051 IrInstruction *value;
3120 bool resolve_err_set;
3121 IrInstruction *base_ptr;
30523122};
30533123
3054struct IrInstructionUnwrapErrCode {
3124struct IrInstructionTestErrGen {
30553125 IrInstruction base;
30563126
30573127 IrInstruction *err_union;
30583128};
30593129
3130// Takes an error union pointer, returns a pointer to the error code.
3131struct IrInstructionUnwrapErrCode {
3132 IrInstruction base;
3133
3134 bool initializing;
3135 IrInstruction *err_union_ptr;
3136};
3137
30603138struct IrInstructionUnwrapErrPayload {
30613139 IrInstruction base;
30623140
3063 IrInstruction *value;
30643141 bool safety_check_on;
3142 bool initializing;
3143 IrInstruction *value;
30653144};
30663145
30673146struct IrInstructionOptionalWrap {
30683147 IrInstruction base;
30693148
3070 IrInstruction *value;
3071 LLVMValueRef tmp_ptr;
3149 IrInstruction *operand;
3150 IrInstruction *result_loc;
30723151};
30733152
30743153struct IrInstructionErrWrapPayload {
30753154 IrInstruction base;
30763155
3077 IrInstruction *value;
3078 LLVMValueRef tmp_ptr;
3156 IrInstruction *operand;
3157 IrInstruction *result_loc;
30793158};
30803159
30813160struct IrInstructionErrWrapCode {
30823161 IrInstruction base;
30833162
3084 IrInstruction *value;
3085 LLVMValueRef tmp_ptr;
3163 IrInstruction *operand;
3164 IrInstruction *result_loc;
30863165};
30873166
30883167struct IrInstructionFnProto {
......@@ -3117,18 +3196,17 @@ struct IrInstructionPtrCastGen {
31173196 bool safety_check_on;
31183197};
31193198
3120struct IrInstructionBitCast {
3199struct IrInstructionBitCastSrc {
31213200 IrInstruction base;
31223201
3123 IrInstruction *dest_type;
3124 IrInstruction *value;
3202 IrInstruction *operand;
3203 ResultLocBitCast *result_loc_bit_cast;
31253204};
31263205
31273206struct IrInstructionBitCastGen {
31283207 IrInstruction base;
31293208
31303209 IrInstruction *operand;
3131 LLVMValueRef tmp_ptr;
31323210};
31333211
31343212struct IrInstructionWidenOrShorten {
......@@ -3204,8 +3282,8 @@ struct IrInstructionTypeName {
32043282struct IrInstructionDeclRef {
32053283 IrInstruction base;
32063284
3207 Tld *tld;
32083285 LVal lval;
3286 Tld *tld;
32093287};
32103288
32113289struct IrInstructionPanic {
......@@ -3461,11 +3539,13 @@ struct IrInstructionMarkErrRetTracePtr {
34613539 IrInstruction *err_ret_trace_ptr;
34623540};
34633541
3464struct IrInstructionSqrt {
3542// For float ops which take a single argument
3543struct IrInstructionFloatOp {
34653544 IrInstruction base;
34663545
3546 BuiltinFnId op;
34673547 IrInstruction *type;
3468 IrInstruction *op;
3548 IrInstruction *op1;
34693549};
34703550
34713551struct IrInstructionCheckRuntimeScope {
......@@ -3499,7 +3579,7 @@ struct IrInstructionVectorToArray {
34993579 IrInstruction base;
35003580
35013581 IrInstruction *vector;
3502 LLVMValueRef tmp_ptr;
3582 IrInstruction *result_loc;
35033583};
35043584
35053585struct IrInstructionAssertZero {
......@@ -3527,6 +3607,139 @@ struct IrInstructionUndeclaredIdent {
35273607 Buf *name;
35283608};
35293609
3610struct IrInstructionAllocaSrc {
3611 IrInstruction base;
3612
3613 IrInstruction *align;
3614 IrInstruction *is_comptime;
3615 const char *name_hint;
3616};
3617
3618struct IrInstructionAllocaGen {
3619 IrInstruction base;
3620
3621 uint32_t align;
3622 const char *name_hint;
3623};
3624
3625struct IrInstructionEndExpr {
3626 IrInstruction base;
3627
3628 IrInstruction *value;
3629 ResultLoc *result_loc;
3630};
3631
3632struct IrInstructionImplicitCast {
3633 IrInstruction base;
3634
3635 IrInstruction *dest_type;
3636 IrInstruction *target;
3637 ResultLoc *result_loc;
3638};
3639
3640// This one is for writing through the result pointer.
3641struct IrInstructionResolveResult {
3642 IrInstruction base;
3643
3644 ResultLoc *result_loc;
3645 IrInstruction *ty;
3646};
3647
3648// This one is when you want to read the value of the result.
3649// You have to give the value in case it is comptime.
3650struct IrInstructionResultPtr {
3651 IrInstruction base;
3652
3653 ResultLoc *result_loc;
3654 IrInstruction *result;
3655};
3656
3657struct IrInstructionResetResult {
3658 IrInstruction base;
3659
3660 ResultLoc *result_loc;
3661};
3662
3663struct IrInstructionPtrOfArrayToSlice {
3664 IrInstruction base;
3665
3666 IrInstruction *operand;
3667 IrInstruction *result_loc;
3668};
3669
3670enum ResultLocId {
3671 ResultLocIdInvalid,
3672 ResultLocIdNone,
3673 ResultLocIdVar,
3674 ResultLocIdReturn,
3675 ResultLocIdPeer,
3676 ResultLocIdPeerParent,
3677 ResultLocIdInstruction,
3678 ResultLocIdBitCast,
3679};
3680
3681// Additions to this struct may need to be handled in
3682// ir_reset_result
3683struct ResultLoc {
3684 ResultLocId id;
3685 bool written;
3686 IrInstruction *resolved_loc; // result ptr
3687 IrInstruction *source_instruction;
3688 IrInstruction *gen_instruction; // value to store to the result loc
3689 ZigType *implicit_elem_type;
3690};
3691
3692struct ResultLocNone {
3693 ResultLoc base;
3694};
3695
3696struct ResultLocVar {
3697 ResultLoc base;
3698
3699 ZigVar *var;
3700};
3701
3702struct ResultLocReturn {
3703 ResultLoc base;
3704};
3705
3706struct IrSuspendPosition {
3707 size_t basic_block_index;
3708 size_t instruction_index;
3709};
3710
3711struct ResultLocPeerParent {
3712 ResultLoc base;
3713
3714 bool skipped;
3715 bool done_resuming;
3716 IrBasicBlock *end_bb;
3717 ResultLoc *parent;
3718 ZigList<ResultLocPeer *> peers;
3719 ZigType *resolved_type;
3720 IrInstruction *is_comptime;
3721};
3722
3723struct ResultLocPeer {
3724 ResultLoc base;
3725
3726 ResultLocPeerParent *parent;
3727 IrBasicBlock *next_bb;
3728 IrSuspendPosition suspend_pos;
3729};
3730
3731// The result location is the source instruction
3732struct ResultLocInstruction {
3733 ResultLoc base;
3734};
3735
3736// The source_instruction is the destination type
3737struct ResultLocBitCast {
3738 ResultLoc base;
3739
3740 ResultLoc *parent;
3741};
3742
35303743static const size_t slice_ptr_index = 0;
35313744static const size_t slice_len_index = 1;
35323745
......@@ -3574,7 +3787,7 @@ struct FnWalkAttrs {
35743787
35753788struct FnWalkCall {
35763789 ZigList<LLVMValueRef> *gen_param_values;
3577 IrInstructionCall *inst;
3790 IrInstructionCallGen *inst;
35783791 bool is_var_args;
35793792};
35803793
src/analyze.cpp+23-24
......@@ -2995,7 +2995,7 @@ void scan_decls(CodeGen *g, ScopeDecls *decls_scope, AstNode *node) {
29952995 case NodeTypeBlock:
29962996 case NodeTypeGroupedExpr:
29972997 case NodeTypeBinOpExpr:
2998 case NodeTypeUnwrapErrorExpr:
2998 case NodeTypeCatchExpr:
29992999 case NodeTypeFnCallExpr:
30003000 case NodeTypeArrayAccessExpr:
30013001 case NodeTypeSliceExpr:
......@@ -4181,6 +4181,7 @@ static uint32_t hash_const_val_ptr(ConstExprValue *const_val) {
41814181 case ConstPtrMutComptimeConst:
41824182 hash_val += (uint32_t)4214318515;
41834183 break;
4184 case ConstPtrMutInfer:
41844185 case ConstPtrMutComptimeVar:
41854186 hash_val += (uint32_t)1103195694;
41864187 break;
......@@ -4511,6 +4512,8 @@ bool fn_eval_cacheable(Scope *scope, ZigType *return_type) {
45114512 ScopeVarDecl *var_scope = (ScopeVarDecl *)scope;
45124513 if (type_is_invalid(var_scope->var->var_type))
45134514 return false;
4515 if (var_scope->var->const_value->special == ConstValSpecialUndef)
4516 return false;
45144517 if (can_mutate_comptime_var_state(var_scope->var->const_value))
45154518 return false;
45164519 } else if (scope->id == ScopeIdFnDef) {
......@@ -4710,7 +4713,7 @@ ReqCompTime type_requires_comptime(CodeGen *g, ZigType *type_entry) {
47104713void init_const_str_lit(CodeGen *g, ConstExprValue *const_val, Buf *str) {
47114714 auto entry = g->string_literals_table.maybe_get(str);
47124715 if (entry != nullptr) {
4713 *const_val = *entry->value;
4716 memcpy(const_val, entry->value, sizeof(ConstExprValue));
47144717 return;
47154718 }
47164719
......@@ -4998,12 +5001,9 @@ void init_const_undefined(CodeGen *g, ConstExprValue *const_val) {
49985001 field_val->type = wanted_type->data.structure.fields[i].type_entry;
49995002 assert(field_val->type);
50005003 init_const_undefined(g, field_val);
5001 ConstParent *parent = get_const_val_parent(g, field_val);
5002 if (parent != nullptr) {
5003 parent->id = ConstParentIdStruct;
5004 parent->data.p_struct.struct_val = const_val;
5005 parent->data.p_struct.field_index = i;
5006 }
5004 field_val->parent.id = ConstParentIdStruct;
5005 field_val->parent.data.p_struct.struct_val = const_val;
5006 field_val->parent.data.p_struct.field_index = i;
50075007 }
50085008 } else {
50095009 const_val->special = ConstValSpecialUndef;
......@@ -5736,12 +5736,13 @@ uint32_t zig_llvm_fn_key_hash(ZigLLVMFnKey x) {
57365736 return (uint32_t)(x.data.clz.bit_count) * (uint32_t)2428952817;
57375737 case ZigLLVMFnIdPopCount:
57385738 return (uint32_t)(x.data.clz.bit_count) * (uint32_t)101195049;
5739 case ZigLLVMFnIdFloor:
5740 return (uint32_t)(x.data.floating.bit_count) * (uint32_t)1899859168;
5741 case ZigLLVMFnIdCeil:
5742 return (uint32_t)(x.data.floating.bit_count) * (uint32_t)1953839089;
5743 case ZigLLVMFnIdSqrt:
5744 return (uint32_t)(x.data.floating.bit_count) * (uint32_t)2225366385;
5739 case ZigLLVMFnIdFloatOp:
5740 return (uint32_t)(x.data.floating.bit_count) * ((uint32_t)x.id + 1025) +
5741 (uint32_t)(x.data.floating.vector_len) * (((uint32_t)x.id << 5) + 1025) +
5742 (uint32_t)(x.data.floating.op) * (uint32_t)43789879;
5743 case ZigLLVMFnIdFMA:
5744 return (uint32_t)(x.data.floating.bit_count) * ((uint32_t)x.id + 1025) +
5745 (uint32_t)(x.data.floating.vector_len) * (((uint32_t)x.id << 5) + 1025);
57455746 case ZigLLVMFnIdBswap:
57465747 return (uint32_t)(x.data.bswap.bit_count) * (uint32_t)3661994335;
57475748 case ZigLLVMFnIdBitReverse:
......@@ -5769,10 +5770,13 @@ bool zig_llvm_fn_key_eql(ZigLLVMFnKey a, ZigLLVMFnKey b) {
57695770 return a.data.bswap.bit_count == b.data.bswap.bit_count;
57705771 case ZigLLVMFnIdBitReverse:
57715772 return a.data.bit_reverse.bit_count == b.data.bit_reverse.bit_count;
5772 case ZigLLVMFnIdFloor:
5773 case ZigLLVMFnIdCeil:
5774 case ZigLLVMFnIdSqrt:
5775 return a.data.floating.bit_count == b.data.floating.bit_count;
5773 case ZigLLVMFnIdFloatOp:
5774 return a.data.floating.bit_count == b.data.floating.bit_count &&
5775 a.data.floating.vector_len == b.data.floating.vector_len &&
5776 a.data.floating.op == b.data.floating.op;
5777 case ZigLLVMFnIdFMA:
5778 return a.data.floating.bit_count == b.data.floating.bit_count &&
5779 a.data.floating.vector_len == b.data.floating.vector_len;
57765780 case ZigLLVMFnIdOverflowArithmetic:
57775781 return (a.data.overflow_arithmetic.bit_count == b.data.overflow_arithmetic.bit_count) &&
57785782 (a.data.overflow_arithmetic.add_sub_mul == b.data.overflow_arithmetic.add_sub_mul) &&
......@@ -5839,11 +5843,6 @@ void expand_undef_array(CodeGen *g, ConstExprValue *const_val) {
58395843 zig_unreachable();
58405844}
58415845
5842// Deprecated. Reference the parent field directly.
5843ConstParent *get_const_val_parent(CodeGen *g, ConstExprValue *value) {
5844 return &value->parent;
5845}
5846
58475846static const ZigTypeId all_type_ids[] = {
58485847 ZigTypeIdMetaType,
58495848 ZigTypeIdVoid,
......@@ -7277,6 +7276,6 @@ void src_assert(bool ok, AstNode *source_node) {
72777276 buf_ptr(source_node->owner->data.structure.root_struct->path),
72787277 (unsigned)source_node->line + 1, (unsigned)source_node->column + 1);
72797278 }
7280 const char *msg = "assertion failed";
7279 const char *msg = "assertion failed. This is a bug in the Zig compiler.";
72817280 stage2_panic(msg, strlen(msg));
72827281}
src/analyze.hpp-1
......@@ -180,7 +180,6 @@ void init_const_undefined(CodeGen *g, ConstExprValue *const_val);
180180ConstExprValue *create_const_vals(size_t count);
181181
182182ZigType *make_int_type(CodeGen *g, bool is_signed, uint32_t size_in_bits);
183ConstParent *get_const_val_parent(CodeGen *g, ConstExprValue *value);
184183void expand_undef_array(CodeGen *g, ConstExprValue *const_val);
185184void 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) {
165165 return "Parens";
166166 case NodeTypeBinOpExpr:
167167 return "BinOpExpr";
168 case NodeTypeUnwrapErrorExpr:
169 return "UnwrapErrorExpr";
168 case NodeTypeCatchExpr:
169 return "CatchExpr";
170170 case NodeTypeFnCallExpr:
171171 return "FnCallExpr";
172172 case NodeTypeArrayAccessExpr:
......@@ -1107,7 +1107,7 @@ static void render_node_extra(AstRender *ar, AstNode *node, bool grouped) {
11071107 fprintf(ar->f, "]");
11081108 break;
11091109 }
1110 case NodeTypeUnwrapErrorExpr:
1110 case NodeTypeCatchExpr:
11111111 {
11121112 render_node_ungrouped(ar, node->data.unwrap_err_expr.op1);
11131113 fprintf(ar->f, " catch ");
src/codegen.cpp+364-360
......@@ -180,6 +180,8 @@ CodeGen *codegen_create(Buf *main_pkg_path, Buf *root_src_path, const ZigTarget
180180 g->root_package = new_package(".", "", "");
181181 }
182182
183 g->root_package->package_table.put(buf_create_from_str("root"), g->root_package);
184
183185 g->zig_std_special_dir = buf_alloc();
184186 os_path_join(g->zig_std_dir, buf_sprintf("special"), g->zig_std_special_dir);
185187
......@@ -691,7 +693,9 @@ static ZigLLVMDIScope *get_di_scope(CodeGen *g, Scope *scope) {
691693 is_definition, scope_line, flags, is_optimized, nullptr);
692694
693695 scope->di_scope = ZigLLVMSubprogramToScope(subprogram);
694 ZigLLVMFnSetSubprogram(fn_llvm_value(g, fn_table_entry), subprogram);
696 if (!g->strip_debug_symbols) {
697 ZigLLVMFnSetSubprogram(fn_llvm_value(g, fn_table_entry), subprogram);
698 }
695699 return scope->di_scope;
696700 }
697701 case ScopeIdDecls:
......@@ -806,32 +810,47 @@ static LLVMValueRef get_int_overflow_fn(CodeGen *g, ZigType *operand_type, AddSu
806810 return fn_val;
807811}
808812
809static LLVMValueRef get_float_fn(CodeGen *g, ZigType *type_entry, ZigLLVMFnId fn_id) {
810 assert(type_entry->id == ZigTypeIdFloat);
813static LLVMValueRef get_float_fn(CodeGen *g, ZigType *type_entry, ZigLLVMFnId fn_id, BuiltinFnId op) {
814 assert(type_entry->id == ZigTypeIdFloat ||
815 type_entry->id == ZigTypeIdVector);
816
817 bool is_vector = (type_entry->id == ZigTypeIdVector);
818 ZigType *float_type = is_vector ? type_entry->data.vector.elem_type : type_entry;
811819
812820 ZigLLVMFnKey key = {};
813821 key.id = fn_id;
814 key.data.floating.bit_count = (uint32_t)type_entry->data.floating.bit_count;
822 key.data.floating.bit_count = (uint32_t)float_type->data.floating.bit_count;
823 key.data.floating.vector_len = is_vector ? (uint32_t)type_entry->data.vector.len : 0;
824 key.data.floating.op = op;
815825
816826 auto existing_entry = g->llvm_fn_table.maybe_get(key);
817827 if (existing_entry)
818828 return existing_entry->value;
819829
820830 const char *name;
821 if (fn_id == ZigLLVMFnIdFloor) {
822 name = "floor";
823 } else if (fn_id == ZigLLVMFnIdCeil) {
824 name = "ceil";
825 } else if (fn_id == ZigLLVMFnIdSqrt) {
826 name = "sqrt";
831 uint32_t num_args;
832 if (fn_id == ZigLLVMFnIdFMA) {
833 name = "fma";
834 num_args = 3;
835 } else if (fn_id == ZigLLVMFnIdFloatOp) {
836 name = float_op_to_name(op, true);
837 num_args = 1;
827838 } else {
828839 zig_unreachable();
829840 }
830841
831842 char fn_name[64];
832 sprintf(fn_name, "llvm.%s.f%" ZIG_PRI_usize "", name, type_entry->data.floating.bit_count);
843 if (is_vector)
844 sprintf(fn_name, "llvm.%s.v%" PRIu32 "f%" PRIu32, name, key.data.floating.vector_len, key.data.floating.bit_count);
845 else
846 sprintf(fn_name, "llvm.%s.f%" PRIu32, name, key.data.floating.bit_count);
833847 LLVMTypeRef float_type_ref = get_llvm_type(g, type_entry);
834 LLVMTypeRef fn_type = LLVMFunctionType(float_type_ref, &float_type_ref, 1, false);
848 LLVMTypeRef return_elem_types[3] = {
849 float_type_ref,
850 float_type_ref,
851 float_type_ref,
852 };
853 LLVMTypeRef fn_type = LLVMFunctionType(float_type_ref, return_elem_types, num_args, false);
835854 LLVMValueRef fn_val = LLVMAddFunction(g->module, fn_name, fn_type);
836855 assert(LLVMGetIntrinsicID(fn_val));
837856
......@@ -844,9 +863,7 @@ static LLVMValueRef gen_store_untyped(CodeGen *g, LLVMValueRef value, LLVMValueR
844863{
845864 LLVMValueRef instruction = LLVMBuildStore(g->builder, value, ptr);
846865 if (is_volatile) LLVMSetVolatile(instruction, true);
847 if (alignment == 0) {
848 LLVMSetAlignment(instruction, LLVMABIAlignmentOfType(g->target_data_ref, LLVMTypeOf(value)));
849 } else {
866 if (alignment != 0) {
850867 LLVMSetAlignment(instruction, alignment);
851868 }
852869 return instruction;
......@@ -1324,7 +1341,9 @@ static LLVMValueRef get_add_error_return_trace_addr_fn(CodeGen *g) {
13241341 LLVMBuildRetVoid(g->builder);
13251342
13261343 LLVMPositionBuilderAtEnd(g->builder, prev_block);
1327 LLVMSetCurrentDebugLocation(g->builder, prev_debug_location);
1344 if (!g->strip_debug_symbols) {
1345 LLVMSetCurrentDebugLocation(g->builder, prev_debug_location);
1346 }
13281347
13291348 g->add_error_return_trace_addr_fn_val = fn_val;
13301349 return fn_val;
......@@ -1455,7 +1474,9 @@ static LLVMValueRef get_merge_err_ret_traces_fn_val(CodeGen *g) {
14551474 LLVMBuildBr(g->builder, loop_block);
14561475
14571476 LLVMPositionBuilderAtEnd(g->builder, prev_block);
1458 LLVMSetCurrentDebugLocation(g->builder, prev_debug_location);
1477 if (!g->strip_debug_symbols) {
1478 LLVMSetCurrentDebugLocation(g->builder, prev_debug_location);
1479 }
14591480
14601481 g->merge_err_ret_traces_fn_val = fn_val;
14611482 return fn_val;
......@@ -1511,7 +1532,9 @@ static LLVMValueRef get_return_err_fn(CodeGen *g) {
15111532 LLVMBuildRetVoid(g->builder);
15121533
15131534 LLVMPositionBuilderAtEnd(g->builder, prev_block);
1514 LLVMSetCurrentDebugLocation(g->builder, prev_debug_location);
1535 if (!g->strip_debug_symbols) {
1536 LLVMSetCurrentDebugLocation(g->builder, prev_debug_location);
1537 }
15151538
15161539 g->return_err_fn = fn_val;
15171540 return fn_val;
......@@ -1639,7 +1662,9 @@ static LLVMValueRef get_safety_crash_err_fn(CodeGen *g) {
16391662 gen_panic(g, msg_slice, err_ret_trace_arg);
16401663
16411664 LLVMPositionBuilderAtEnd(g->builder, prev_block);
1642 LLVMSetCurrentDebugLocation(g->builder, prev_debug_location);
1665 if (!g->strip_debug_symbols) {
1666 LLVMSetCurrentDebugLocation(g->builder, prev_debug_location);
1667 }
16431668
16441669 g->safety_crash_err_fn = fn_val;
16451670 return fn_val;
......@@ -1989,6 +2014,7 @@ static LLVMValueRef gen_assign_raw(CodeGen *g, LLVMValueRef ptr, ZigType *ptr_ty
19892014}
19902015
19912016static void gen_var_debug_decl(CodeGen *g, ZigVar *var) {
2017 if (g->strip_debug_symbols) return;
19922018 assert(var->di_loc_var != nullptr);
19932019 AstNode *source_node = var->decl_node;
19942020 ZigLLVMDILocation *debug_loc = ZigLLVMGetDebugLoc((unsigned)source_node->line + 1,
......@@ -2001,7 +2027,7 @@ static LLVMValueRef ir_llvm_value(CodeGen *g, IrInstruction *instruction) {
20012027 if (!type_has_bits(instruction->value.type))
20022028 return nullptr;
20032029 if (!instruction->llvm_value) {
2004 assert(instruction->value.special != ConstValSpecialRuntime);
2030 src_assert(instruction->value.special != ConstValSpecialRuntime, instruction->source_node);
20052031 assert(instruction->value.type);
20062032 render_const_val(g, &instruction->value, "");
20072033 // we might have to do some pointer casting here due to the way union
......@@ -2010,11 +2036,9 @@ static LLVMValueRef ir_llvm_value(CodeGen *g, IrInstruction *instruction) {
20102036 render_const_val_global(g, &instruction->value, "");
20112037 ZigType *ptr_type = get_pointer_to_type(g, instruction->value.type, true);
20122038 instruction->llvm_value = LLVMBuildBitCast(g->builder, instruction->value.global_refs->llvm_global, get_llvm_type(g, ptr_type), "");
2013 } else if (get_codegen_ptr_type(instruction->value.type) != nullptr) {
2039 } else {
20142040 instruction->llvm_value = LLVMBuildBitCast(g->builder, instruction->value.global_refs->llvm_value,
20152041 get_llvm_type(g, instruction->value.type), "");
2016 } else {
2017 instruction->llvm_value = instruction->value.global_refs->llvm_value;
20182042 }
20192043 assert(instruction->llvm_value);
20202044 }
......@@ -2295,7 +2319,7 @@ void walk_function_params(CodeGen *g, ZigType *fn_type, FnWalk *fn_walk) {
22952319 return;
22962320 }
22972321 if (fn_walk->id == FnWalkIdCall) {
2298 IrInstructionCall *instruction = fn_walk->data.call.inst;
2322 IrInstructionCallGen *instruction = fn_walk->data.call.inst;
22992323 bool is_var_args = fn_walk->data.call.is_var_args;
23002324 for (size_t call_i = 0; call_i < instruction->arg_count; call_i += 1) {
23012325 IrInstruction *param_instruction = instruction->args[call_i];
......@@ -2389,17 +2413,33 @@ static LLVMValueRef ir_render_save_err_ret_addr(CodeGen *g, IrExecutable *execut
23892413}
23902414
23912415static LLVMValueRef ir_render_return(CodeGen *g, IrExecutable *executable, IrInstructionReturn *return_instruction) {
2392 LLVMValueRef value = ir_llvm_value(g, return_instruction->value);
2393 ZigType *return_type = return_instruction->value->value.type;
2394
23952416 if (want_first_arg_sret(g, &g->cur_fn->type_entry->data.fn.fn_type_id)) {
2417 if (return_instruction->value == nullptr) {
2418 LLVMBuildRetVoid(g->builder);
2419 return nullptr;
2420 }
23962421 assert(g->cur_ret_ptr);
2422 src_assert(return_instruction->value->value.special != ConstValSpecialRuntime,
2423 return_instruction->base.source_node);
2424 LLVMValueRef value = ir_llvm_value(g, return_instruction->value);
2425 ZigType *return_type = return_instruction->value->value.type;
23972426 gen_assign_raw(g, g->cur_ret_ptr, get_pointer_to_type(g, return_type, false), value);
23982427 LLVMBuildRetVoid(g->builder);
2399 } else if (handle_is_ptr(return_type)) {
2400 LLVMValueRef by_val_value = gen_load_untyped(g, value, 0, false, "");
2401 LLVMBuildRet(g->builder, by_val_value);
2428 } else if (g->cur_fn->type_entry->data.fn.fn_type_id.cc != CallingConventionAsync &&
2429 handle_is_ptr(g->cur_fn->type_entry->data.fn.fn_type_id.return_type))
2430 {
2431 if (return_instruction->value == nullptr) {
2432 LLVMValueRef by_val_value = gen_load_untyped(g, g->cur_ret_ptr, 0, false, "");
2433 LLVMBuildRet(g->builder, by_val_value);
2434 } else {
2435 LLVMValueRef value = ir_llvm_value(g, return_instruction->value);
2436 LLVMValueRef by_val_value = gen_load_untyped(g, value, 0, false, "");
2437 LLVMBuildRet(g->builder, by_val_value);
2438 }
2439 } else if (return_instruction->value == nullptr) {
2440 LLVMBuildRetVoid(g->builder);
24022441 } else {
2442 LLVMValueRef value = ir_llvm_value(g, return_instruction->value);
24032443 LLVMBuildRet(g->builder, value);
24042444 }
24052445 return nullptr;
......@@ -2460,22 +2500,17 @@ static LLVMValueRef gen_overflow_shr_op(CodeGen *g, ZigType *type_entry,
24602500 return result;
24612501}
24622502
2463static LLVMValueRef gen_floor(CodeGen *g, LLVMValueRef val, ZigType *type_entry) {
2464 if (type_entry->id == ZigTypeIdInt)
2503static LLVMValueRef gen_float_op(CodeGen *g, LLVMValueRef val, ZigType *type_entry, BuiltinFnId op) {
2504 if ((op == BuiltinFnIdCeil ||
2505 op == BuiltinFnIdFloor) &&
2506 type_entry->id == ZigTypeIdInt)
24652507 return val;
2508 assert(type_entry->id == ZigTypeIdFloat);
24662509
2467 LLVMValueRef floor_fn = get_float_fn(g, type_entry, ZigLLVMFnIdFloor);
2510 LLVMValueRef floor_fn = get_float_fn(g, type_entry, ZigLLVMFnIdFloatOp, op);
24682511 return LLVMBuildCall(g->builder, floor_fn, &val, 1, "");
24692512}
24702513
2471static LLVMValueRef gen_ceil(CodeGen *g, LLVMValueRef val, ZigType *type_entry) {
2472 if (type_entry->id == ZigTypeIdInt)
2473 return val;
2474
2475 LLVMValueRef ceil_fn = get_float_fn(g, type_entry, ZigLLVMFnIdCeil);
2476 return LLVMBuildCall(g->builder, ceil_fn, &val, 1, "");
2477}
2478
24792514enum DivKind {
24802515 DivKindFloat,
24812516 DivKindTrunc,
......@@ -2551,7 +2586,7 @@ static LLVMValueRef gen_div(CodeGen *g, bool want_runtime_safety, bool want_fast
25512586 return result;
25522587 case DivKindExact:
25532588 if (want_runtime_safety) {
2554 LLVMValueRef floored = gen_floor(g, result, type_entry);
2589 LLVMValueRef floored = gen_float_op(g, result, type_entry, BuiltinFnIdFloor);
25552590 LLVMBasicBlockRef ok_block = LLVMAppendBasicBlock(g->cur_fn_val, "DivExactOk");
25562591 LLVMBasicBlockRef fail_block = LLVMAppendBasicBlock(g->cur_fn_val, "DivExactFail");
25572592 LLVMValueRef ok_bit = LLVMBuildFCmp(g->builder, LLVMRealOEQ, floored, result, "");
......@@ -2573,12 +2608,12 @@ static LLVMValueRef gen_div(CodeGen *g, bool want_runtime_safety, bool want_fast
25732608 LLVMBuildCondBr(g->builder, ltz, ltz_block, gez_block);
25742609
25752610 LLVMPositionBuilderAtEnd(g->builder, ltz_block);
2576 LLVMValueRef ceiled = gen_ceil(g, result, type_entry);
2611 LLVMValueRef ceiled = gen_float_op(g, result, type_entry, BuiltinFnIdCeil);
25772612 LLVMBasicBlockRef ceiled_end_block = LLVMGetInsertBlock(g->builder);
25782613 LLVMBuildBr(g->builder, end_block);
25792614
25802615 LLVMPositionBuilderAtEnd(g->builder, gez_block);
2581 LLVMValueRef floored = gen_floor(g, result, type_entry);
2616 LLVMValueRef floored = gen_float_op(g, result, type_entry, BuiltinFnIdFloor);
25822617 LLVMBasicBlockRef floored_end_block = LLVMGetInsertBlock(g->builder);
25832618 LLVMBuildBr(g->builder, end_block);
25842619
......@@ -2590,7 +2625,7 @@ static LLVMValueRef gen_div(CodeGen *g, bool want_runtime_safety, bool want_fast
25902625 return phi;
25912626 }
25922627 case DivKindFloor:
2593 return gen_floor(g, result, type_entry);
2628 return gen_float_op(g, result, type_entry, BuiltinFnIdFloor);
25942629 }
25952630 zig_unreachable();
25962631 }
......@@ -2942,7 +2977,7 @@ static LLVMValueRef ir_render_resize_slice(CodeGen *g, IrExecutable *executable,
29422977 LLVMValueRef expr_val = ir_llvm_value(g, instruction->operand);
29432978 assert(expr_val);
29442979
2945 assert(instruction->tmp_ptr);
2980 LLVMValueRef result_loc = ir_llvm_value(g, instruction->result_loc);
29462981 assert(wanted_type->id == ZigTypeIdStruct);
29472982 assert(wanted_type->data.structure.is_slice);
29482983 assert(actual_type->id == ZigTypeIdStruct);
......@@ -2963,7 +2998,7 @@ static LLVMValueRef ir_render_resize_slice(CodeGen *g, IrExecutable *executable,
29632998 LLVMValueRef src_ptr = gen_load_untyped(g, src_ptr_ptr, 0, false, "");
29642999 LLVMValueRef src_ptr_casted = LLVMBuildBitCast(g->builder, src_ptr,
29653000 get_llvm_type(g, wanted_type->data.structure.fields[0].type_entry), "");
2966 LLVMValueRef dest_ptr_ptr = LLVMBuildStructGEP(g->builder, instruction->tmp_ptr,
3001 LLVMValueRef dest_ptr_ptr = LLVMBuildStructGEP(g->builder, result_loc,
29673002 (unsigned)wanted_ptr_index, "");
29683003 gen_store_untyped(g, src_ptr_casted, dest_ptr_ptr, 0, false);
29693004
......@@ -2996,12 +3031,10 @@ static LLVMValueRef ir_render_resize_slice(CodeGen *g, IrExecutable *executable,
29963031 zig_unreachable();
29973032 }
29983033
2999 LLVMValueRef dest_len_ptr = LLVMBuildStructGEP(g->builder, instruction->tmp_ptr,
3000 (unsigned)wanted_len_index, "");
3034 LLVMValueRef dest_len_ptr = LLVMBuildStructGEP(g->builder, result_loc, (unsigned)wanted_len_index, "");
30013035 gen_store_untyped(g, new_len, dest_len_ptr, 0, false);
30023036
3003
3004 return instruction->tmp_ptr;
3037 return result_loc;
30053038}
30063039
30073040static LLVMValueRef ir_render_cast(CodeGen *g, IrExecutable *executable,
......@@ -3071,33 +3104,39 @@ static LLVMValueRef ir_render_cast(CodeGen *g, IrExecutable *executable,
30713104 return expr_val;
30723105 case CastOpBitCast:
30733106 return LLVMBuildBitCast(g->builder, expr_val, get_llvm_type(g, wanted_type), "");
3074 case CastOpPtrOfArrayToSlice: {
3075 assert(cast_instruction->tmp_ptr);
3076 assert(actual_type->id == ZigTypeIdPointer);
3077 ZigType *array_type = actual_type->data.pointer.child_type;
3078 assert(array_type->id == ZigTypeIdArray);
3079
3080 LLVMValueRef ptr_field_ptr = LLVMBuildStructGEP(g->builder, cast_instruction->tmp_ptr,
3081 slice_ptr_index, "");
3082 LLVMValueRef indices[] = {
3083 LLVMConstNull(g->builtin_types.entry_usize->llvm_type),
3084 LLVMConstInt(g->builtin_types.entry_usize->llvm_type, 0, false),
3085 };
3086 LLVMValueRef slice_start_ptr = LLVMBuildInBoundsGEP(g->builder, expr_val, indices, 2, "");
3087 gen_store_untyped(g, slice_start_ptr, ptr_field_ptr, 0, false);
3088
3089 LLVMValueRef len_field_ptr = LLVMBuildStructGEP(g->builder, cast_instruction->tmp_ptr,
3090 slice_len_index, "");
3091 LLVMValueRef len_value = LLVMConstInt(g->builtin_types.entry_usize->llvm_type,
3092 array_type->data.array.len, false);
3093 gen_store_untyped(g, len_value, len_field_ptr, 0, false);
3094
3095 return cast_instruction->tmp_ptr;
3096 }
30973107 }
30983108 zig_unreachable();
30993109}
31003110
3111static LLVMValueRef ir_render_ptr_of_array_to_slice(CodeGen *g, IrExecutable *executable,
3112 IrInstructionPtrOfArrayToSlice *instruction)
3113{
3114 ZigType *actual_type = instruction->operand->value.type;
3115 LLVMValueRef expr_val = ir_llvm_value(g, instruction->operand);
3116 assert(expr_val);
3117
3118 LLVMValueRef result_loc = ir_llvm_value(g, instruction->result_loc);
3119
3120 assert(actual_type->id == ZigTypeIdPointer);
3121 ZigType *array_type = actual_type->data.pointer.child_type;
3122 assert(array_type->id == ZigTypeIdArray);
3123
3124 LLVMValueRef ptr_field_ptr = LLVMBuildStructGEP(g->builder, result_loc, slice_ptr_index, "");
3125 LLVMValueRef indices[] = {
3126 LLVMConstNull(g->builtin_types.entry_usize->llvm_type),
3127 LLVMConstInt(g->builtin_types.entry_usize->llvm_type, 0, false),
3128 };
3129 LLVMValueRef slice_start_ptr = LLVMBuildInBoundsGEP(g->builder, expr_val, indices, 2, "");
3130 gen_store_untyped(g, slice_start_ptr, ptr_field_ptr, 0, false);
3131
3132 LLVMValueRef len_field_ptr = LLVMBuildStructGEP(g->builder, result_loc, slice_len_index, "");
3133 LLVMValueRef len_value = LLVMConstInt(g->builtin_types.entry_usize->llvm_type,
3134 array_type->data.array.len, false);
3135 gen_store_untyped(g, len_value, len_field_ptr, 0, false);
3136
3137 return result_loc;
3138}
3139
31013140static LLVMValueRef ir_render_ptr_cast(CodeGen *g, IrExecutable *executable,
31023141 IrInstructionPtrCastGen *instruction)
31033142{
......@@ -3144,12 +3183,7 @@ static LLVMValueRef ir_render_bit_cast(CodeGen *g, IrExecutable *executable,
31443183 uint32_t alignment = get_abi_alignment(g, actual_type);
31453184 return gen_load_untyped(g, bitcasted_ptr, alignment, false, "");
31463185 } else {
3147 assert(instruction->tmp_ptr != nullptr);
3148 LLVMTypeRef wanted_ptr_type_ref = LLVMPointerType(get_llvm_type(g, actual_type), 0);
3149 LLVMValueRef bitcasted_ptr = LLVMBuildBitCast(g->builder, instruction->tmp_ptr, wanted_ptr_type_ref, "");
3150 uint32_t alignment = get_abi_alignment(g, wanted_type);
3151 gen_store_untyped(g, value, bitcasted_ptr, alignment, false);
3152 return instruction->tmp_ptr;
3186 zig_unreachable();
31533187 }
31543188}
31553189
......@@ -3335,31 +3369,13 @@ static LLVMValueRef ir_render_bool_not(CodeGen *g, IrExecutable *executable, IrI
33353369 return LLVMBuildICmp(g->builder, LLVMIntEQ, value, zero, "");
33363370}
33373371
3338static LLVMValueRef ir_render_decl_var(CodeGen *g, IrExecutable *executable,
3339 IrInstructionDeclVarGen *decl_var_instruction)
3340{
3341 ZigVar *var = decl_var_instruction->var;
3372static LLVMValueRef ir_render_decl_var(CodeGen *g, IrExecutable *executable, IrInstructionDeclVarGen *instruction) {
3373 ZigVar *var = instruction->var;
33423374
33433375 if (!type_has_bits(var->var_type))
33443376 return nullptr;
33453377
3346 if (var->ref_count == 0 && g->build_mode != BuildModeDebug)
3347 return nullptr;
3348
3349 IrInstruction *init_value = decl_var_instruction->init_value;
3350
3351 bool have_init_expr = !value_is_all_undef(&init_value->value);
3352
3353 if (have_init_expr) {
3354 ZigType *var_ptr_type = get_pointer_to_type_extra(g, var->var_type, false, false,
3355 PtrLenSingle, var->align_bytes, 0, 0, false);
3356 LLVMValueRef llvm_init_val = ir_llvm_value(g, init_value);
3357 gen_assign_raw(g, var->value_ref, var_ptr_type, llvm_init_val);
3358 } else if (ir_want_runtime_safety(g, &decl_var_instruction->base)) {
3359 uint32_t align_bytes = (var->align_bytes == 0) ? get_abi_alignment(g, var->var_type) : var->align_bytes;
3360 gen_undef_init(g, align_bytes, var->var_type, var->value_ref);
3361 }
3362
3378 var->value_ref = ir_llvm_value(g, instruction->var_ptr);
33633379 gen_var_debug_decl(g, var);
33643380 return nullptr;
33653381}
......@@ -3391,13 +3407,13 @@ static LLVMValueRef ir_render_load_ptr(CodeGen *g, IrExecutable *executable, IrI
33913407 LLVMValueRef shifted_value = LLVMBuildLShr(g->builder, containing_int, shift_amt_val, "");
33923408
33933409 if (handle_is_ptr(child_type)) {
3394 assert(instruction->tmp_ptr != nullptr);
3410 LLVMValueRef result_loc = ir_llvm_value(g, instruction->result_loc);
33953411 LLVMTypeRef same_size_int = LLVMIntType(size_in_bits);
33963412 LLVMValueRef truncated_int = LLVMBuildTrunc(g->builder, shifted_value, same_size_int, "");
3397 LLVMValueRef bitcasted_ptr = LLVMBuildBitCast(g->builder, instruction->tmp_ptr,
3413 LLVMValueRef bitcasted_ptr = LLVMBuildBitCast(g->builder, result_loc,
33983414 LLVMPointerType(same_size_int, 0), "");
33993415 LLVMBuildStore(g->builder, truncated_int, bitcasted_ptr);
3400 return instruction->tmp_ptr;
3416 return result_loc;
34013417 }
34023418
34033419 if (child_type->id == ZigTypeIdFloat) {
......@@ -3575,6 +3591,14 @@ static LLVMValueRef ir_render_var_ptr(CodeGen *g, IrExecutable *executable, IrIn
35753591 }
35763592}
35773593
3594static LLVMValueRef ir_render_return_ptr(CodeGen *g, IrExecutable *executable,
3595 IrInstructionReturnPtr *instruction)
3596{
3597 src_assert(g->cur_ret_ptr != nullptr || !type_has_bits(instruction->base.value.type),
3598 instruction->base.source_node);
3599 return g->cur_ret_ptr;
3600}
3601
35783602static LLVMValueRef ir_render_elem_ptr(CodeGen *g, IrExecutable *executable, IrInstructionElemPtr *instruction) {
35793603 LLVMValueRef array_ptr_ptr = ir_llvm_value(g, instruction->array_ptr);
35803604 ZigType *array_ptr_type = instruction->array_ptr->value.type;
......@@ -3726,7 +3750,7 @@ static void set_call_instr_sret(CodeGen *g, LLVMValueRef call_instr) {
37263750 LLVMAddCallSiteAttribute(call_instr, 1, sret_attr);
37273751}
37283752
3729static LLVMValueRef ir_render_call(CodeGen *g, IrExecutable *executable, IrInstructionCall *instruction) {
3753static LLVMValueRef ir_render_call(CodeGen *g, IrExecutable *executable, IrInstructionCallGen *instruction) {
37303754 LLVMValueRef fn_val;
37313755 ZigType *fn_type;
37323756 if (instruction->fn_entry) {
......@@ -3749,8 +3773,9 @@ static LLVMValueRef ir_render_call(CodeGen *g, IrExecutable *executable, IrInstr
37493773 bool prefix_arg_err_ret_stack = get_prefix_arg_err_ret_stack(g, fn_type_id);
37503774 bool is_var_args = fn_type_id->is_var_args;
37513775 ZigList<LLVMValueRef> gen_param_values = {};
3776 LLVMValueRef result_loc = instruction->result_loc ? ir_llvm_value(g, instruction->result_loc) : nullptr;
37523777 if (first_arg_ret) {
3753 gen_param_values.append(instruction->tmp_ptr);
3778 gen_param_values.append(result_loc);
37543779 }
37553780 if (prefix_arg_err_ret_stack) {
37563781 gen_param_values.append(get_cur_err_ret_trace_val(g, instruction->base.scope));
......@@ -3758,7 +3783,7 @@ static LLVMValueRef ir_render_call(CodeGen *g, IrExecutable *executable, IrInstr
37583783 if (instruction->is_async) {
37593784 gen_param_values.append(ir_llvm_value(g, instruction->async_allocator));
37603785
3761 LLVMValueRef err_val_ptr = LLVMBuildStructGEP(g->builder, instruction->tmp_ptr, err_union_err_index, "");
3786 LLVMValueRef err_val_ptr = LLVMBuildStructGEP(g->builder, result_loc, err_union_err_index, "");
37623787 gen_param_values.append(err_val_ptr);
37633788 }
37643789 FnWalk fn_walk = {};
......@@ -3801,9 +3826,9 @@ static LLVMValueRef ir_render_call(CodeGen *g, IrExecutable *executable, IrInstr
38013826
38023827
38033828 if (instruction->is_async) {
3804 LLVMValueRef payload_ptr = LLVMBuildStructGEP(g->builder, instruction->tmp_ptr, err_union_payload_index, "");
3829 LLVMValueRef payload_ptr = LLVMBuildStructGEP(g->builder, result_loc, err_union_payload_index, "");
38053830 LLVMBuildStore(g->builder, result, payload_ptr);
3806 return instruction->tmp_ptr;
3831 return result_loc;
38073832 }
38083833
38093834 if (src_return_type->id == ZigTypeIdUnreachable) {
......@@ -3812,11 +3837,11 @@ static LLVMValueRef ir_render_call(CodeGen *g, IrExecutable *executable, IrInstr
38123837 return nullptr;
38133838 } else if (first_arg_ret) {
38143839 set_call_instr_sret(g, result);
3815 return instruction->tmp_ptr;
3840 return result_loc;
38163841 } else if (handle_is_ptr(src_return_type)) {
3817 auto store_instr = LLVMBuildStore(g->builder, result, instruction->tmp_ptr);
3818 LLVMSetAlignment(store_instr, LLVMGetAlignment(instruction->tmp_ptr));
3819 return instruction->tmp_ptr;
3842 LLVMValueRef store_instr = LLVMBuildStore(g->builder, result, result_loc);
3843 LLVMSetAlignment(store_instr, LLVMGetAlignment(result_loc));
3844 return result_loc;
38203845 } else {
38213846 return result;
38223847 }
......@@ -3825,6 +3850,9 @@ static LLVMValueRef ir_render_call(CodeGen *g, IrExecutable *executable, IrInstr
38253850static LLVMValueRef ir_render_struct_field_ptr(CodeGen *g, IrExecutable *executable,
38263851 IrInstructionStructFieldPtr *instruction)
38273852{
3853 if (instruction->base.value.special != ConstValSpecialRuntime)
3854 return nullptr;
3855
38283856 LLVMValueRef struct_ptr = ir_llvm_value(g, instruction->struct_ptr);
38293857 // not necessarily a pointer. could be ZigTypeIdStruct
38303858 ZigType *struct_ptr_type = instruction->struct_ptr->value.type;
......@@ -3846,6 +3874,9 @@ static LLVMValueRef ir_render_struct_field_ptr(CodeGen *g, IrExecutable *executa
38463874static LLVMValueRef ir_render_union_field_ptr(CodeGen *g, IrExecutable *executable,
38473875 IrInstructionUnionFieldPtr *instruction)
38483876{
3877 if (instruction->base.value.special != ConstValSpecialRuntime)
3878 return nullptr;
3879
38493880 ZigType *union_ptr_type = instruction->union_ptr->value.type;
38503881 assert(union_ptr_type->id == ZigTypeIdPointer);
38513882 ZigType *union_type = union_ptr_type->data.pointer.child_type;
......@@ -3853,8 +3884,20 @@ static LLVMValueRef ir_render_union_field_ptr(CodeGen *g, IrExecutable *executab
38533884
38543885 TypeUnionField *field = instruction->field;
38553886
3856 if (!type_has_bits(field->type_entry))
3887 if (!type_has_bits(field->type_entry)) {
3888 if (union_type->data.unionation.gen_tag_index == SIZE_MAX) {
3889 return nullptr;
3890 }
3891 if (instruction->initializing) {
3892 LLVMValueRef union_ptr = ir_llvm_value(g, instruction->union_ptr);
3893 LLVMValueRef tag_field_ptr = LLVMBuildStructGEP(g->builder, union_ptr,
3894 union_type->data.unionation.gen_tag_index, "");
3895 LLVMValueRef tag_value = bigint_to_llvm_const(get_llvm_type(g, union_type->data.unionation.tag_type),
3896 &field->enum_field->value);
3897 gen_store_untyped(g, tag_value, tag_field_ptr, 0, false);
3898 }
38573899 return nullptr;
3900 }
38583901
38593902 LLVMValueRef union_ptr = ir_llvm_value(g, instruction->union_ptr);
38603903 LLVMTypeRef field_type_ref = LLVMPointerType(get_llvm_type(g, field->type_entry), 0);
......@@ -3865,7 +3908,12 @@ static LLVMValueRef ir_render_union_field_ptr(CodeGen *g, IrExecutable *executab
38653908 return bitcasted_union_field_ptr;
38663909 }
38673910
3868 if (ir_want_runtime_safety(g, &instruction->base)) {
3911 if (instruction->initializing) {
3912 LLVMValueRef tag_field_ptr = LLVMBuildStructGEP(g->builder, union_ptr, union_type->data.unionation.gen_tag_index, "");
3913 LLVMValueRef tag_value = bigint_to_llvm_const(get_llvm_type(g, union_type->data.unionation.tag_type),
3914 &field->enum_field->value);
3915 gen_store_untyped(g, tag_value, tag_field_ptr, 0, false);
3916 } else if (instruction->safety_check_on && ir_want_runtime_safety(g, &instruction->base)) {
38693917 LLVMValueRef tag_field_ptr = LLVMBuildStructGEP(g->builder, union_ptr, union_type->data.unionation.gen_tag_index, "");
38703918 LLVMValueRef tag_value = gen_load_untyped(g, tag_field_ptr, 0, false, "");
38713919
......@@ -4065,14 +4113,17 @@ static LLVMValueRef ir_render_test_non_null(CodeGen *g, IrExecutable *executable
40654113static LLVMValueRef ir_render_optional_unwrap_ptr(CodeGen *g, IrExecutable *executable,
40664114 IrInstructionOptionalUnwrapPtr *instruction)
40674115{
4116 if (instruction->base.value.special != ConstValSpecialRuntime)
4117 return nullptr;
4118
40684119 ZigType *ptr_type = instruction->base_ptr->value.type;
40694120 assert(ptr_type->id == ZigTypeIdPointer);
40704121 ZigType *maybe_type = ptr_type->data.pointer.child_type;
40714122 assert(maybe_type->id == ZigTypeIdOptional);
40724123 ZigType *child_type = maybe_type->data.maybe.child_type;
4073 LLVMValueRef maybe_ptr = ir_llvm_value(g, instruction->base_ptr);
4074 if (ir_want_runtime_safety(g, &instruction->base) && instruction->safety_check_on) {
4075 LLVMValueRef maybe_handle = get_handle_value(g, maybe_ptr, maybe_type, ptr_type);
4124 LLVMValueRef base_ptr = ir_llvm_value(g, instruction->base_ptr);
4125 if (instruction->safety_check_on && ir_want_runtime_safety(g, &instruction->base)) {
4126 LLVMValueRef maybe_handle = get_handle_value(g, base_ptr, maybe_type, ptr_type);
40764127 LLVMValueRef non_null_bit = gen_non_null_bit(g, maybe_type, maybe_handle);
40774128 LLVMBasicBlockRef fail_block = LLVMAppendBasicBlock(g->cur_fn_val, "UnwrapOptionalFail");
40784129 LLVMBasicBlockRef ok_block = LLVMAppendBasicBlock(g->cur_fn_val, "UnwrapOptionalOk");
......@@ -4088,10 +4139,16 @@ static LLVMValueRef ir_render_optional_unwrap_ptr(CodeGen *g, IrExecutable *exec
40884139 } else {
40894140 bool is_scalar = !handle_is_ptr(maybe_type);
40904141 if (is_scalar) {
4091 return maybe_ptr;
4142 return base_ptr;
40924143 } else {
4093 LLVMValueRef maybe_struct_ref = get_handle_value(g, maybe_ptr, maybe_type, ptr_type);
4094 return LLVMBuildStructGEP(g->builder, maybe_struct_ref, maybe_child_index, "");
4144 LLVMValueRef optional_struct_ref = get_handle_value(g, base_ptr, maybe_type, ptr_type);
4145 if (instruction->initializing) {
4146 LLVMValueRef non_null_bit_ptr = LLVMBuildStructGEP(g->builder, optional_struct_ref,
4147 maybe_null_index, "");
4148 LLVMValueRef non_null_bit = LLVMConstInt(LLVMInt1Type(), 1, false);
4149 gen_store_untyped(g, non_null_bit, non_null_bit_ptr, 0, false);
4150 }
4151 return LLVMBuildStructGEP(g->builder, optional_struct_ref, maybe_child_index, "");
40954152 }
40964153 }
40974154}
......@@ -4214,17 +4271,17 @@ static LLVMValueRef ir_render_phi(CodeGen *g, IrExecutable *executable, IrInstru
42144271 return phi;
42154272}
42164273
4217static LLVMValueRef ir_render_ref(CodeGen *g, IrExecutable *executable, IrInstructionRef *instruction) {
4274static LLVMValueRef ir_render_ref(CodeGen *g, IrExecutable *executable, IrInstructionRefGen *instruction) {
42184275 if (!type_has_bits(instruction->base.value.type)) {
42194276 return nullptr;
42204277 }
4221 LLVMValueRef value = ir_llvm_value(g, instruction->value);
4222 if (handle_is_ptr(instruction->value->value.type)) {
4278 LLVMValueRef value = ir_llvm_value(g, instruction->operand);
4279 if (handle_is_ptr(instruction->operand->value.type)) {
42234280 return value;
42244281 } else {
4225 assert(instruction->tmp_ptr);
4226 gen_store_untyped(g, value, instruction->tmp_ptr, 0, false);
4227 return instruction->tmp_ptr;
4282 LLVMValueRef result_loc = ir_llvm_value(g, instruction->result_loc);
4283 gen_store_untyped(g, value, result_loc, 0, false);
4284 return result_loc;
42284285 }
42294286}
42304287
......@@ -4340,7 +4397,9 @@ static LLVMValueRef get_enum_tag_name_function(CodeGen *g, ZigType *enum_type) {
43404397 g->cur_fn = prev_cur_fn;
43414398 g->cur_fn_val = prev_cur_fn_val;
43424399 LLVMPositionBuilderAtEnd(g->builder, prev_block);
4343 LLVMSetCurrentDebugLocation(g->builder, prev_debug_location);
4400 if (!g->strip_debug_symbols) {
4401 LLVMSetCurrentDebugLocation(g->builder, prev_debug_location);
4402 }
43444403
43454404 enum_type->data.enumeration.name_function = fn_val;
43464405 return fn_val;
......@@ -4516,28 +4575,28 @@ static LLVMValueRef ir_render_cmpxchg(CodeGen *g, IrExecutable *executable, IrIn
45164575 LLVMValueRef result_val = ZigLLVMBuildCmpXchg(g->builder, ptr_val, cmp_val, new_val,
45174576 success_order, failure_order, instruction->is_weak);
45184577
4519 ZigType *maybe_type = instruction->base.value.type;
4520 assert(maybe_type->id == ZigTypeIdOptional);
4521 ZigType *child_type = maybe_type->data.maybe.child_type;
4578 ZigType *optional_type = instruction->base.value.type;
4579 assert(optional_type->id == ZigTypeIdOptional);
4580 ZigType *child_type = optional_type->data.maybe.child_type;
45224581
4523 if (!handle_is_ptr(maybe_type)) {
4582 if (!handle_is_ptr(optional_type)) {
45244583 LLVMValueRef payload_val = LLVMBuildExtractValue(g->builder, result_val, 0, "");
45254584 LLVMValueRef success_bit = LLVMBuildExtractValue(g->builder, result_val, 1, "");
45264585 return LLVMBuildSelect(g->builder, success_bit, LLVMConstNull(get_llvm_type(g, child_type)), payload_val, "");
45274586 }
45284587
4529 assert(instruction->tmp_ptr != nullptr);
4588 LLVMValueRef result_loc = ir_llvm_value(g, instruction->result_loc);
45304589 assert(type_has_bits(child_type));
45314590
45324591 LLVMValueRef payload_val = LLVMBuildExtractValue(g->builder, result_val, 0, "");
4533 LLVMValueRef val_ptr = LLVMBuildStructGEP(g->builder, instruction->tmp_ptr, maybe_child_index, "");
4592 LLVMValueRef val_ptr = LLVMBuildStructGEP(g->builder, result_loc, maybe_child_index, "");
45344593 gen_assign_raw(g, val_ptr, get_pointer_to_type(g, child_type, false), payload_val);
45354594
45364595 LLVMValueRef success_bit = LLVMBuildExtractValue(g->builder, result_val, 1, "");
45374596 LLVMValueRef nonnull_bit = LLVMBuildNot(g->builder, success_bit, "");
4538 LLVMValueRef maybe_ptr = LLVMBuildStructGEP(g->builder, instruction->tmp_ptr, maybe_null_index, "");
4597 LLVMValueRef maybe_ptr = LLVMBuildStructGEP(g->builder, result_loc, maybe_null_index, "");
45394598 gen_store_untyped(g, nonnull_bit, maybe_ptr, 0, false);
4540 return instruction->tmp_ptr;
4599 return result_loc;
45414600}
45424601
45434602static LLVMValueRef ir_render_fence(CodeGen *g, IrExecutable *executable, IrInstructionFence *instruction) {
......@@ -4609,16 +4668,14 @@ static LLVMValueRef ir_render_memcpy(CodeGen *g, IrExecutable *executable, IrIns
46094668 return nullptr;
46104669}
46114670
4612static LLVMValueRef ir_render_slice(CodeGen *g, IrExecutable *executable, IrInstructionSlice *instruction) {
4613 assert(instruction->tmp_ptr);
4614
4671static LLVMValueRef ir_render_slice(CodeGen *g, IrExecutable *executable, IrInstructionSliceGen *instruction) {
46154672 LLVMValueRef array_ptr_ptr = ir_llvm_value(g, instruction->ptr);
46164673 ZigType *array_ptr_type = instruction->ptr->value.type;
46174674 assert(array_ptr_type->id == ZigTypeIdPointer);
46184675 ZigType *array_type = array_ptr_type->data.pointer.child_type;
46194676 LLVMValueRef array_ptr = get_handle_value(g, array_ptr_ptr, array_type, array_ptr_type);
46204677
4621 LLVMValueRef tmp_struct_ptr = instruction->tmp_ptr;
4678 LLVMValueRef tmp_struct_ptr = ir_llvm_value(g, instruction->result_loc);
46224679
46234680 bool want_runtime_safety = instruction->safety_check_on && ir_want_runtime_safety(g, &instruction->base);
46244681
......@@ -4636,7 +4693,9 @@ static LLVMValueRef ir_render_slice(CodeGen *g, IrExecutable *executable, IrInst
46364693 end_val = LLVMConstInt(g->builtin_types.entry_usize->llvm_type, array_type->data.array.len, false);
46374694 }
46384695 if (want_runtime_safety) {
4639 add_bounds_check(g, start_val, LLVMIntEQ, nullptr, LLVMIntULE, end_val);
4696 if (instruction->start->value.special == ConstValSpecialRuntime || instruction->end) {
4697 add_bounds_check(g, start_val, LLVMIntEQ, nullptr, LLVMIntULE, end_val);
4698 }
46404699 if (instruction->end) {
46414700 LLVMValueRef array_end = LLVMConstInt(g->builtin_types.entry_usize->llvm_type,
46424701 array_type->data.array.len, false);
......@@ -4867,10 +4926,10 @@ static LLVMValueRef ir_render_overflow_op(CodeGen *g, IrExecutable *executable,
48674926 return overflow_bit;
48684927}
48694928
4870static LLVMValueRef ir_render_test_err(CodeGen *g, IrExecutable *executable, IrInstructionTestErr *instruction) {
4871 ZigType *err_union_type = instruction->value->value.type;
4929static LLVMValueRef ir_render_test_err(CodeGen *g, IrExecutable *executable, IrInstructionTestErrGen *instruction) {
4930 ZigType *err_union_type = instruction->err_union->value.type;
48724931 ZigType *payload_type = err_union_type->data.error_union.payload_type;
4873 LLVMValueRef err_union_handle = ir_llvm_value(g, instruction->value);
4932 LLVMValueRef err_union_handle = ir_llvm_value(g, instruction->err_union);
48744933
48754934 LLVMValueRef err_val;
48764935 if (type_has_bits(payload_type)) {
......@@ -4887,25 +4946,30 @@ static LLVMValueRef ir_render_test_err(CodeGen *g, IrExecutable *executable, IrI
48874946static LLVMValueRef ir_render_unwrap_err_code(CodeGen *g, IrExecutable *executable,
48884947 IrInstructionUnwrapErrCode *instruction)
48894948{
4890 ZigType *ptr_type = instruction->err_union->value.type;
4949 if (instruction->base.value.special != ConstValSpecialRuntime)
4950 return nullptr;
4951
4952 ZigType *ptr_type = instruction->err_union_ptr->value.type;
48914953 assert(ptr_type->id == ZigTypeIdPointer);
48924954 ZigType *err_union_type = ptr_type->data.pointer.child_type;
48934955 ZigType *payload_type = err_union_type->data.error_union.payload_type;
4894 LLVMValueRef err_union_ptr = ir_llvm_value(g, instruction->err_union);
4895 LLVMValueRef err_union_handle = get_handle_value(g, err_union_ptr, err_union_type, ptr_type);
4896
4897 if (type_has_bits(payload_type)) {
4898 LLVMValueRef err_val_ptr = LLVMBuildStructGEP(g->builder, err_union_handle, err_union_err_index, "");
4899 return gen_load_untyped(g, err_val_ptr, 0, false, "");
4956 LLVMValueRef err_union_ptr = ir_llvm_value(g, instruction->err_union_ptr);
4957 if (!type_has_bits(payload_type)) {
4958 return err_union_ptr;
49004959 } else {
4901 return err_union_handle;
4960 // TODO assign undef to the payload
4961 LLVMValueRef err_union_handle = get_handle_value(g, err_union_ptr, err_union_type, ptr_type);
4962 return LLVMBuildStructGEP(g->builder, err_union_handle, err_union_err_index, "");
49024963 }
49034964}
49044965
49054966static LLVMValueRef ir_render_unwrap_err_payload(CodeGen *g, IrExecutable *executable,
49064967 IrInstructionUnwrapErrPayload *instruction)
49074968{
4908 bool want_safety = ir_want_runtime_safety(g, &instruction->base) && instruction->safety_check_on &&
4969 if (instruction->base.value.special != ConstValSpecialRuntime)
4970 return nullptr;
4971
4972 bool want_safety = instruction->safety_check_on && ir_want_runtime_safety(g, &instruction->base) &&
49094973 g->errors_by_index.length > 1;
49104974 if (!want_safety && !type_has_bits(instruction->base.value.type))
49114975 return nullptr;
......@@ -4941,13 +5005,18 @@ static LLVMValueRef ir_render_unwrap_err_payload(CodeGen *g, IrExecutable *execu
49415005 }
49425006
49435007 if (type_has_bits(payload_type)) {
5008 if (instruction->initializing) {
5009 LLVMValueRef err_tag_ptr = LLVMBuildStructGEP(g->builder, err_union_handle, err_union_err_index, "");
5010 LLVMValueRef ok_err_val = LLVMConstNull(get_llvm_type(g, g->err_tag_type));
5011 gen_store_untyped(g, ok_err_val, err_tag_ptr, 0, false);
5012 }
49445013 return LLVMBuildStructGEP(g->builder, err_union_handle, err_union_payload_index, "");
49455014 } else {
49465015 return nullptr;
49475016 }
49485017}
49495018
4950static LLVMValueRef ir_render_maybe_wrap(CodeGen *g, IrExecutable *executable, IrInstructionOptionalWrap *instruction) {
5019static LLVMValueRef ir_render_optional_wrap(CodeGen *g, IrExecutable *executable, IrInstructionOptionalWrap *instruction) {
49515020 ZigType *wanted_type = instruction->base.value.type;
49525021
49535022 assert(wanted_type->id == ZigTypeIdOptional);
......@@ -4955,23 +5024,32 @@ static LLVMValueRef ir_render_maybe_wrap(CodeGen *g, IrExecutable *executable, I
49555024 ZigType *child_type = wanted_type->data.maybe.child_type;
49565025
49575026 if (!type_has_bits(child_type)) {
4958 return LLVMConstInt(LLVMInt1Type(), 1, false);
5027 LLVMValueRef result = LLVMConstAllOnes(LLVMInt1Type());
5028 if (instruction->result_loc != nullptr) {
5029 LLVMValueRef result_loc = ir_llvm_value(g, instruction->result_loc);
5030 gen_store_untyped(g, result, result_loc, 0, false);
5031 }
5032 return result;
49595033 }
49605034
4961 LLVMValueRef payload_val = ir_llvm_value(g, instruction->value);
5035 LLVMValueRef payload_val = ir_llvm_value(g, instruction->operand);
49625036 if (!handle_is_ptr(wanted_type)) {
5037 if (instruction->result_loc != nullptr) {
5038 LLVMValueRef result_loc = ir_llvm_value(g, instruction->result_loc);
5039 gen_store_untyped(g, payload_val, result_loc, 0, false);
5040 }
49635041 return payload_val;
49645042 }
49655043
4966 assert(instruction->tmp_ptr);
5044 LLVMValueRef result_loc = ir_llvm_value(g, instruction->result_loc);
49675045
4968 LLVMValueRef val_ptr = LLVMBuildStructGEP(g->builder, instruction->tmp_ptr, maybe_child_index, "");
5046 LLVMValueRef val_ptr = LLVMBuildStructGEP(g->builder, result_loc, maybe_child_index, "");
49695047 // child_type and instruction->value->value.type may differ by constness
49705048 gen_assign_raw(g, val_ptr, get_pointer_to_type(g, child_type, false), payload_val);
4971 LLVMValueRef maybe_ptr = LLVMBuildStructGEP(g->builder, instruction->tmp_ptr, maybe_null_index, "");
5049 LLVMValueRef maybe_ptr = LLVMBuildStructGEP(g->builder, result_loc, maybe_null_index, "");
49725050 gen_store_untyped(g, LLVMConstAllOnes(LLVMInt1Type()), maybe_ptr, 0, false);
49735051
4974 return instruction->tmp_ptr;
5052 return result_loc;
49755053}
49765054
49775055static LLVMValueRef ir_render_err_wrap_code(CodeGen *g, IrExecutable *executable, IrInstructionErrWrapCode *instruction) {
......@@ -4979,20 +5057,19 @@ static LLVMValueRef ir_render_err_wrap_code(CodeGen *g, IrExecutable *executable
49795057
49805058 assert(wanted_type->id == ZigTypeIdErrorUnion);
49815059
4982 ZigType *payload_type = wanted_type->data.error_union.payload_type;
4983 ZigType *err_set_type = wanted_type->data.error_union.err_set_type;
4984
4985 LLVMValueRef err_val = ir_llvm_value(g, instruction->value);
5060 LLVMValueRef err_val = ir_llvm_value(g, instruction->operand);
49865061
4987 if (!type_has_bits(payload_type) || !type_has_bits(err_set_type))
5062 if (!handle_is_ptr(wanted_type))
49885063 return err_val;
49895064
4990 assert(instruction->tmp_ptr);
5065 LLVMValueRef result_loc = ir_llvm_value(g, instruction->result_loc);
49915066
4992 LLVMValueRef err_tag_ptr = LLVMBuildStructGEP(g->builder, instruction->tmp_ptr, err_union_err_index, "");
5067 LLVMValueRef err_tag_ptr = LLVMBuildStructGEP(g->builder, result_loc, err_union_err_index, "");
49935068 gen_store_untyped(g, err_val, err_tag_ptr, 0, false);
49945069
4995 return instruction->tmp_ptr;
5070 // TODO store undef to the payload
5071
5072 return result_loc;
49965073}
49975074
49985075static LLVMValueRef ir_render_err_wrap_payload(CodeGen *g, IrExecutable *executable, IrInstructionErrWrapPayload *instruction) {
......@@ -5004,7 +5081,7 @@ static LLVMValueRef ir_render_err_wrap_payload(CodeGen *g, IrExecutable *executa
50045081 ZigType *err_set_type = wanted_type->data.error_union.err_set_type;
50055082
50065083 if (!type_has_bits(err_set_type)) {
5007 return ir_llvm_value(g, instruction->value);
5084 return ir_llvm_value(g, instruction->operand);
50085085 }
50095086
50105087 LLVMValueRef ok_err_val = LLVMConstNull(get_llvm_type(g, g->err_tag_type));
......@@ -5012,17 +5089,18 @@ static LLVMValueRef ir_render_err_wrap_payload(CodeGen *g, IrExecutable *executa
50125089 if (!type_has_bits(payload_type))
50135090 return ok_err_val;
50145091
5015 assert(instruction->tmp_ptr);
50165092
5017 LLVMValueRef payload_val = ir_llvm_value(g, instruction->value);
5093 LLVMValueRef result_loc = ir_llvm_value(g, instruction->result_loc);
50185094
5019 LLVMValueRef err_tag_ptr = LLVMBuildStructGEP(g->builder, instruction->tmp_ptr, err_union_err_index, "");
5095 LLVMValueRef payload_val = ir_llvm_value(g, instruction->operand);
5096
5097 LLVMValueRef err_tag_ptr = LLVMBuildStructGEP(g->builder, result_loc, err_union_err_index, "");
50205098 gen_store_untyped(g, ok_err_val, err_tag_ptr, 0, false);
50215099
5022 LLVMValueRef payload_ptr = LLVMBuildStructGEP(g->builder, instruction->tmp_ptr, err_union_payload_index, "");
5100 LLVMValueRef payload_ptr = LLVMBuildStructGEP(g->builder, result_loc, err_union_payload_index, "");
50235101 gen_assign_raw(g, payload_ptr, get_pointer_to_type(g, payload_type, false), payload_val);
50245102
5025 return instruction->tmp_ptr;
5103 return result_loc;
50265104}
50275105
50285106static LLVMValueRef ir_render_union_tag(CodeGen *g, IrExecutable *executable, IrInstructionUnionTag *instruction) {
......@@ -5043,90 +5121,6 @@ static LLVMValueRef ir_render_union_tag(CodeGen *g, IrExecutable *executable, Ir
50435121 return get_handle_value(g, tag_field_ptr, tag_type, ptr_type);
50445122}
50455123
5046static LLVMValueRef ir_render_struct_init(CodeGen *g, IrExecutable *executable, IrInstructionStructInit *instruction) {
5047 for (size_t i = 0; i < instruction->field_count; i += 1) {
5048 IrInstructionStructInitField *field = &instruction->fields[i];
5049 TypeStructField *type_struct_field = field->type_struct_field;
5050 if (!type_has_bits(type_struct_field->type_entry))
5051 continue;
5052
5053 LLVMValueRef field_ptr = LLVMBuildStructGEP(g->builder, instruction->tmp_ptr,
5054 (unsigned)type_struct_field->gen_index, "");
5055 LLVMValueRef value = ir_llvm_value(g, field->value);
5056
5057 uint32_t field_align_bytes = get_abi_alignment(g, type_struct_field->type_entry);
5058 uint32_t host_int_bytes = get_host_int_bytes(g, instruction->struct_type, type_struct_field);
5059
5060 ZigType *ptr_type = get_pointer_to_type_extra(g, type_struct_field->type_entry,
5061 false, false, PtrLenSingle, field_align_bytes,
5062 (uint32_t)type_struct_field->bit_offset_in_host, host_int_bytes, false);
5063
5064 gen_assign_raw(g, field_ptr, ptr_type, value);
5065 }
5066 return instruction->tmp_ptr;
5067}
5068
5069static LLVMValueRef ir_render_union_init(CodeGen *g, IrExecutable *executable, IrInstructionUnionInit *instruction) {
5070 TypeUnionField *type_union_field = instruction->field;
5071
5072 if (!type_has_bits(type_union_field->type_entry))
5073 return nullptr;
5074
5075 uint32_t field_align_bytes = get_abi_alignment(g, type_union_field->type_entry);
5076 ZigType *ptr_type = get_pointer_to_type_extra(g, type_union_field->type_entry,
5077 false, false, PtrLenSingle, field_align_bytes,
5078 0, 0, false);
5079
5080 LLVMValueRef uncasted_union_ptr;
5081 // Even if safety is off in this block, if the union type has the safety field, we have to populate it
5082 // correctly. Otherwise safety code somewhere other than here could fail.
5083 ZigType *union_type = instruction->union_type;
5084 if (union_type->data.unionation.gen_tag_index != SIZE_MAX) {
5085 LLVMValueRef tag_field_ptr = LLVMBuildStructGEP(g->builder, instruction->tmp_ptr,
5086 union_type->data.unionation.gen_tag_index, "");
5087
5088 LLVMValueRef tag_value = bigint_to_llvm_const(get_llvm_type(g, union_type->data.unionation.tag_type),
5089 &type_union_field->enum_field->value);
5090 gen_store_untyped(g, tag_value, tag_field_ptr, 0, false);
5091
5092 uncasted_union_ptr = LLVMBuildStructGEP(g->builder, instruction->tmp_ptr,
5093 (unsigned)union_type->data.unionation.gen_union_index, "");
5094 } else {
5095 uncasted_union_ptr = LLVMBuildStructGEP(g->builder, instruction->tmp_ptr, (unsigned)0, "");
5096 }
5097
5098 LLVMValueRef field_ptr = LLVMBuildBitCast(g->builder, uncasted_union_ptr, get_llvm_type(g, ptr_type), "");
5099 LLVMValueRef value = ir_llvm_value(g, instruction->init_value);
5100
5101 gen_assign_raw(g, field_ptr, ptr_type, value);
5102
5103 return instruction->tmp_ptr;
5104}
5105
5106static LLVMValueRef ir_render_container_init_list(CodeGen *g, IrExecutable *executable,
5107 IrInstructionContainerInitList *instruction)
5108{
5109 ZigType *array_type = instruction->base.value.type;
5110 assert(array_type->id == ZigTypeIdArray);
5111 LLVMValueRef tmp_array_ptr = instruction->tmp_ptr;
5112 assert(tmp_array_ptr);
5113
5114 size_t field_count = instruction->item_count;
5115
5116 ZigType *child_type = array_type->data.array.child_type;
5117 for (size_t i = 0; i < field_count; i += 1) {
5118 LLVMValueRef elem_val = ir_llvm_value(g, instruction->items[i]);
5119 LLVMValueRef indices[] = {
5120 LLVMConstNull(g->builtin_types.entry_usize->llvm_type),
5121 LLVMConstInt(g->builtin_types.entry_usize->llvm_type, i, false),
5122 };
5123 LLVMValueRef elem_ptr = LLVMBuildInBoundsGEP(g->builder, tmp_array_ptr, indices, 2, "");
5124 gen_assign_raw(g, elem_ptr, get_pointer_to_type(g, child_type, false), elem_val);
5125 }
5126
5127 return tmp_array_ptr;
5128}
5129
51305124static LLVMValueRef ir_render_panic(CodeGen *g, IrExecutable *executable, IrInstructionPanic *instruction) {
51315125 gen_panic(g, ir_llvm_value(g, instruction->msg), get_cur_err_ret_trace_val(g, instruction->base.scope));
51325126 return nullptr;
......@@ -5343,7 +5337,9 @@ static LLVMValueRef get_coro_alloc_helper_fn_val(CodeGen *g, LLVMTypeRef alloc_f
53435337 g->cur_fn = prev_cur_fn;
53445338 g->cur_fn_val = prev_cur_fn_val;
53455339 LLVMPositionBuilderAtEnd(g->builder, prev_block);
5346 LLVMSetCurrentDebugLocation(g->builder, prev_debug_location);
5340 if (!g->strip_debug_symbols) {
5341 LLVMSetCurrentDebugLocation(g->builder, prev_debug_location);
5342 }
53475343
53485344 g->coro_alloc_helper_fn_val = fn_val;
53495345 return fn_val;
......@@ -5430,13 +5426,28 @@ static LLVMValueRef ir_render_mark_err_ret_trace_ptr(CodeGen *g, IrExecutable *e
54305426 return nullptr;
54315427}
54325428
5433static LLVMValueRef ir_render_sqrt(CodeGen *g, IrExecutable *executable, IrInstructionSqrt *instruction) {
5434 LLVMValueRef op = ir_llvm_value(g, instruction->op);
5429static LLVMValueRef ir_render_float_op(CodeGen *g, IrExecutable *executable, IrInstructionFloatOp *instruction) {
5430 LLVMValueRef op = ir_llvm_value(g, instruction->op1);
54355431 assert(instruction->base.value.type->id == ZigTypeIdFloat);
5436 LLVMValueRef fn_val = get_float_fn(g, instruction->base.value.type, ZigLLVMFnIdSqrt);
5432 LLVMValueRef fn_val = get_float_fn(g, instruction->base.value.type, ZigLLVMFnIdFloatOp, instruction->op);
54375433 return LLVMBuildCall(g->builder, fn_val, &op, 1, "");
54385434}
54395435
5436static LLVMValueRef ir_render_mul_add(CodeGen *g, IrExecutable *executable, IrInstructionMulAdd *instruction) {
5437 LLVMValueRef op1 = ir_llvm_value(g, instruction->op1);
5438 LLVMValueRef op2 = ir_llvm_value(g, instruction->op2);
5439 LLVMValueRef op3 = ir_llvm_value(g, instruction->op3);
5440 assert(instruction->base.value.type->id == ZigTypeIdFloat ||
5441 instruction->base.value.type->id == ZigTypeIdVector);
5442 LLVMValueRef fn_val = get_float_fn(g, instruction->base.value.type, ZigLLVMFnIdFMA, BuiltinFnIdMulAdd);
5443 LLVMValueRef args[3] = {
5444 op1,
5445 op2,
5446 op3,
5447 };
5448 return LLVMBuildCall(g->builder, fn_val, args, 3, "");
5449}
5450
54405451static LLVMValueRef ir_render_bswap(CodeGen *g, IrExecutable *executable, IrInstructionBswap *instruction) {
54415452 LLVMValueRef op = ir_llvm_value(g, instruction->op);
54425453 ZigType *int_type = instruction->base.value.type;
......@@ -5474,12 +5485,12 @@ static LLVMValueRef ir_render_vector_to_array(CodeGen *g, IrExecutable *executab
54745485 ZigType *array_type = instruction->base.value.type;
54755486 assert(array_type->id == ZigTypeIdArray);
54765487 assert(handle_is_ptr(array_type));
5477 assert(instruction->tmp_ptr);
5488 LLVMValueRef result_loc = ir_llvm_value(g, instruction->result_loc);
54785489 LLVMValueRef vector = ir_llvm_value(g, instruction->vector);
5479 LLVMValueRef casted_ptr = LLVMBuildBitCast(g->builder, instruction->tmp_ptr,
5490 LLVMValueRef casted_ptr = LLVMBuildBitCast(g->builder, result_loc,
54805491 LLVMPointerType(get_llvm_type(g, instruction->vector->value.type), 0), "");
5481 gen_store_untyped(g, vector, casted_ptr, 0, false);
5482 return instruction->tmp_ptr;
5492 gen_store_untyped(g, vector, casted_ptr, get_ptr_align(g, instruction->result_loc->value.type), false);
5493 return result_loc;
54835494}
54845495
54855496static LLVMValueRef ir_render_array_to_vector(CodeGen *g, IrExecutable *executable,
......@@ -5542,14 +5553,10 @@ static void set_debug_location(CodeGen *g, IrInstruction *instruction) {
55425553}
55435554
55445555static LLVMValueRef ir_render_instruction(CodeGen *g, IrExecutable *executable, IrInstruction *instruction) {
5545 set_debug_location(g, instruction);
5546
55475556 switch (instruction->id) {
55485557 case IrInstructionIdInvalid:
55495558 case IrInstructionIdConst:
55505559 case IrInstructionIdTypeOf:
5551 case IrInstructionIdToPtrType:
5552 case IrInstructionIdPtrTypeChild:
55535560 case IrInstructionIdFieldPtr:
55545561 case IrInstructionIdSetCold:
55555562 case IrInstructionIdSetRuntimeSafety:
......@@ -5611,10 +5618,22 @@ static LLVMValueRef ir_render_instruction(CodeGen *g, IrExecutable *executable,
56115618 case IrInstructionIdPtrCastSrc:
56125619 case IrInstructionIdCmpxchgSrc:
56135620 case IrInstructionIdLoadPtr:
5614 case IrInstructionIdBitCast:
56155621 case IrInstructionIdGlobalAsm:
56165622 case IrInstructionIdHasDecl:
56175623 case IrInstructionIdUndeclaredIdent:
5624 case IrInstructionIdCallSrc:
5625 case IrInstructionIdAllocaSrc:
5626 case IrInstructionIdEndExpr:
5627 case IrInstructionIdAllocaGen:
5628 case IrInstructionIdImplicitCast:
5629 case IrInstructionIdResolveResult:
5630 case IrInstructionIdResetResult:
5631 case IrInstructionIdResultPtr:
5632 case IrInstructionIdContainerInitList:
5633 case IrInstructionIdSliceSrc:
5634 case IrInstructionIdRef:
5635 case IrInstructionIdBitCastSrc:
5636 case IrInstructionIdTestErrSrc:
56185637 zig_unreachable();
56195638
56205639 case IrInstructionIdDeclVarGen:
......@@ -5639,10 +5658,12 @@ static LLVMValueRef ir_render_instruction(CodeGen *g, IrExecutable *executable,
56395658 return ir_render_store_ptr(g, executable, (IrInstructionStorePtr *)instruction);
56405659 case IrInstructionIdVarPtr:
56415660 return ir_render_var_ptr(g, executable, (IrInstructionVarPtr *)instruction);
5661 case IrInstructionIdReturnPtr:
5662 return ir_render_return_ptr(g, executable, (IrInstructionReturnPtr *)instruction);
56425663 case IrInstructionIdElemPtr:
56435664 return ir_render_elem_ptr(g, executable, (IrInstructionElemPtr *)instruction);
5644 case IrInstructionIdCall:
5645 return ir_render_call(g, executable, (IrInstructionCall *)instruction);
5665 case IrInstructionIdCallGen:
5666 return ir_render_call(g, executable, (IrInstructionCallGen *)instruction);
56465667 case IrInstructionIdStructFieldPtr:
56475668 return ir_render_struct_field_ptr(g, executable, (IrInstructionStructFieldPtr *)instruction);
56485669 case IrInstructionIdUnionFieldPtr:
......@@ -5667,8 +5688,8 @@ static LLVMValueRef ir_render_instruction(CodeGen *g, IrExecutable *executable,
56675688 return ir_render_bit_reverse(g, executable, (IrInstructionBitReverse *)instruction);
56685689 case IrInstructionIdPhi:
56695690 return ir_render_phi(g, executable, (IrInstructionPhi *)instruction);
5670 case IrInstructionIdRef:
5671 return ir_render_ref(g, executable, (IrInstructionRef *)instruction);
5691 case IrInstructionIdRefGen:
5692 return ir_render_ref(g, executable, (IrInstructionRefGen *)instruction);
56725693 case IrInstructionIdErrName:
56735694 return ir_render_err_name(g, executable, (IrInstructionErrName *)instruction);
56745695 case IrInstructionIdCmpxchgGen:
......@@ -5683,8 +5704,8 @@ static LLVMValueRef ir_render_instruction(CodeGen *g, IrExecutable *executable,
56835704 return ir_render_memset(g, executable, (IrInstructionMemset *)instruction);
56845705 case IrInstructionIdMemcpy:
56855706 return ir_render_memcpy(g, executable, (IrInstructionMemcpy *)instruction);
5686 case IrInstructionIdSlice:
5687 return ir_render_slice(g, executable, (IrInstructionSlice *)instruction);
5707 case IrInstructionIdSliceGen:
5708 return ir_render_slice(g, executable, (IrInstructionSliceGen *)instruction);
56885709 case IrInstructionIdBreakpoint:
56895710 return ir_render_breakpoint(g, executable, (IrInstructionBreakpoint *)instruction);
56905711 case IrInstructionIdReturnAddress:
......@@ -5695,24 +5716,20 @@ static LLVMValueRef ir_render_instruction(CodeGen *g, IrExecutable *executable,
56955716 return ir_render_handle(g, executable, (IrInstructionHandle *)instruction);
56965717 case IrInstructionIdOverflowOp:
56975718 return ir_render_overflow_op(g, executable, (IrInstructionOverflowOp *)instruction);
5698 case IrInstructionIdTestErr:
5699 return ir_render_test_err(g, executable, (IrInstructionTestErr *)instruction);
5719 case IrInstructionIdTestErrGen:
5720 return ir_render_test_err(g, executable, (IrInstructionTestErrGen *)instruction);
57005721 case IrInstructionIdUnwrapErrCode:
57015722 return ir_render_unwrap_err_code(g, executable, (IrInstructionUnwrapErrCode *)instruction);
57025723 case IrInstructionIdUnwrapErrPayload:
57035724 return ir_render_unwrap_err_payload(g, executable, (IrInstructionUnwrapErrPayload *)instruction);
57045725 case IrInstructionIdOptionalWrap:
5705 return ir_render_maybe_wrap(g, executable, (IrInstructionOptionalWrap *)instruction);
5726 return ir_render_optional_wrap(g, executable, (IrInstructionOptionalWrap *)instruction);
57065727 case IrInstructionIdErrWrapCode:
57075728 return ir_render_err_wrap_code(g, executable, (IrInstructionErrWrapCode *)instruction);
57085729 case IrInstructionIdErrWrapPayload:
57095730 return ir_render_err_wrap_payload(g, executable, (IrInstructionErrWrapPayload *)instruction);
57105731 case IrInstructionIdUnionTag:
57115732 return ir_render_union_tag(g, executable, (IrInstructionUnionTag *)instruction);
5712 case IrInstructionIdStructInit:
5713 return ir_render_struct_init(g, executable, (IrInstructionStructInit *)instruction);
5714 case IrInstructionIdUnionInit:
5715 return ir_render_union_init(g, executable, (IrInstructionUnionInit *)instruction);
57165733 case IrInstructionIdPtrCastGen:
57175734 return ir_render_ptr_cast(g, executable, (IrInstructionPtrCastGen *)instruction);
57185735 case IrInstructionIdBitCastGen:
......@@ -5729,8 +5746,6 @@ static LLVMValueRef ir_render_instruction(CodeGen *g, IrExecutable *executable,
57295746 return ir_render_int_to_err(g, executable, (IrInstructionIntToErr *)instruction);
57305747 case IrInstructionIdErrToInt:
57315748 return ir_render_err_to_int(g, executable, (IrInstructionErrToInt *)instruction);
5732 case IrInstructionIdContainerInitList:
5733 return ir_render_container_init_list(g, executable, (IrInstructionContainerInitList *)instruction);
57345749 case IrInstructionIdPanic:
57355750 return ir_render_panic(g, executable, (IrInstructionPanic *)instruction);
57365751 case IrInstructionIdTagName:
......@@ -5779,8 +5794,10 @@ static LLVMValueRef ir_render_instruction(CodeGen *g, IrExecutable *executable,
57795794 return ir_render_merge_err_ret_traces(g, executable, (IrInstructionMergeErrRetTraces *)instruction);
57805795 case IrInstructionIdMarkErrRetTracePtr:
57815796 return ir_render_mark_err_ret_trace_ptr(g, executable, (IrInstructionMarkErrRetTracePtr *)instruction);
5782 case IrInstructionIdSqrt:
5783 return ir_render_sqrt(g, executable, (IrInstructionSqrt *)instruction);
5797 case IrInstructionIdFloatOp:
5798 return ir_render_float_op(g, executable, (IrInstructionFloatOp *)instruction);
5799 case IrInstructionIdMulAdd:
5800 return ir_render_mul_add(g, executable, (IrInstructionMulAdd *)instruction);
57845801 case IrInstructionIdArrayToVector:
57855802 return ir_render_array_to_vector(g, executable, (IrInstructionArrayToVector *)instruction);
57865803 case IrInstructionIdVectorToArray:
......@@ -5791,6 +5808,8 @@ static LLVMValueRef ir_render_instruction(CodeGen *g, IrExecutable *executable,
57915808 return ir_render_assert_non_null(g, executable, (IrInstructionAssertNonNull *)instruction);
57925809 case IrInstructionIdResizeSlice:
57935810 return ir_render_resize_slice(g, executable, (IrInstructionResizeSlice *)instruction);
5811 case IrInstructionIdPtrOfArrayToSlice:
5812 return ir_render_ptr_of_array_to_slice(g, executable, (IrInstructionPtrOfArrayToSlice *)instruction);
57945813 }
57955814 zig_unreachable();
57965815}
......@@ -5802,7 +5821,6 @@ static void ir_render(CodeGen *g, ZigFn *fn_entry) {
58025821 assert(executable->basic_block_list.length > 0);
58035822 for (size_t block_i = 0; block_i < executable->basic_block_list.length; block_i += 1) {
58045823 IrBasicBlock *current_block = executable->basic_block_list.at(block_i);
5805 //assert(current_block->ref_count > 0);
58065824 assert(current_block->llvm_block);
58075825 LLVMPositionBuilderAtEnd(g->builder, current_block->llvm_block);
58085826 for (size_t instr_i = 0; instr_i < current_block->instruction_list.length; instr_i += 1) {
......@@ -5810,6 +5828,9 @@ static void ir_render(CodeGen *g, ZigFn *fn_entry) {
58105828 if (instruction->ref_count == 0 && !ir_has_side_effects(instruction))
58115829 continue;
58125830
5831 if (!g->strip_debug_symbols) {
5832 set_debug_location(g, instruction);
5833 }
58135834 instruction->llvm_value = ir_render_instruction(g, executable, instruction);
58145835 }
58155836 current_block->llvm_exit_block = LLVMGetInsertBlock(g->builder);
......@@ -6599,7 +6620,8 @@ static void render_const_val_global(CodeGen *g, ConstExprValue *const_val, const
65996620 LLVMSetLinkage(global_value, LLVMInternalLinkage);
66006621 LLVMSetGlobalConstant(global_value, true);
66016622 LLVMSetUnnamedAddr(global_value, true);
6602 LLVMSetAlignment(global_value, get_abi_alignment(g, const_val->type));
6623 LLVMSetAlignment(global_value, (const_val->global_refs->align == 0) ?
6624 get_abi_alignment(g, const_val->type) : const_val->global_refs->align);
66036625
66046626 const_val->global_refs->llvm_global = global_value;
66056627 }
......@@ -6724,7 +6746,7 @@ static void do_code_gen(CodeGen *g) {
67246746 zig_panic("TODO debug info for var with ptr casted value");
67256747 }
67266748 ZigType *var_type = g->builtin_types.entry_f128;
6727 ConstExprValue coerced_value;
6749 ConstExprValue coerced_value = {};
67286750 coerced_value.special = ConstValSpecialStatic;
67296751 coerced_value.type = var_type;
67306752 coerced_value.data.x_f128 = bigfloat_to_f128(&const_val->data.x_bigfloat);
......@@ -6829,20 +6851,24 @@ static void do_code_gen(CodeGen *g) {
68296851 FnTypeId *fn_type_id = &fn_table_entry->type_entry->data.fn.fn_type_id;
68306852 CallingConvention cc = fn_type_id->cc;
68316853 bool is_c_abi = cc == CallingConventionC;
6854 bool want_sret = want_first_arg_sret(g, fn_type_id);
68326855
68336856 LLVMValueRef fn = fn_llvm_value(g, fn_table_entry);
68346857 g->cur_fn = fn_table_entry;
68356858 g->cur_fn_val = fn;
6836 ZigType *return_type = fn_type_id->return_type;
6837 if (handle_is_ptr(return_type)) {
6859
6860 build_all_basic_blocks(g, fn_table_entry);
6861 clear_debug_source_node(g);
6862
6863 if (want_sret) {
68386864 g->cur_ret_ptr = LLVMGetParam(fn, 0);
6865 } else if (handle_is_ptr(fn_type_id->return_type)) {
6866 g->cur_ret_ptr = build_alloca(g, fn_type_id->return_type, "result", 0);
6867 // TODO add debug info variable for this
68396868 } else {
68406869 g->cur_ret_ptr = nullptr;
68416870 }
68426871
6843 build_all_basic_blocks(g, fn_table_entry);
6844 clear_debug_source_node(g);
6845
68466872 uint32_t err_ret_trace_arg_index = get_err_ret_trace_arg_index(g, fn_table_entry);
68476873 bool have_err_ret_trace_arg = err_ret_trace_arg_index != UINT32_MAX;
68486874 if (have_err_ret_trace_arg) {
......@@ -6867,68 +6893,28 @@ static void do_code_gen(CodeGen *g) {
68676893 }
68686894
68696895 // allocate temporary stack data
6870 for (size_t alloca_i = 0; alloca_i < fn_table_entry->alloca_list.length; alloca_i += 1) {
6871 IrInstruction *instruction = fn_table_entry->alloca_list.at(alloca_i);
6872 LLVMValueRef *slot;
6873 ZigType *slot_type = instruction->value.type;
6874 uint32_t alignment_bytes = 0;
6875 if (instruction->id == IrInstructionIdCast) {
6876 IrInstructionCast *cast_instruction = (IrInstructionCast *)instruction;
6877 slot = &cast_instruction->tmp_ptr;
6878 } else if (instruction->id == IrInstructionIdRef) {
6879 IrInstructionRef *ref_instruction = (IrInstructionRef *)instruction;
6880 slot = &ref_instruction->tmp_ptr;
6881 assert(instruction->value.type->id == ZigTypeIdPointer);
6882 slot_type = instruction->value.type->data.pointer.child_type;
6883 } else if (instruction->id == IrInstructionIdContainerInitList) {
6884 IrInstructionContainerInitList *container_init_list_instruction = (IrInstructionContainerInitList *)instruction;
6885 slot = &container_init_list_instruction->tmp_ptr;
6886 } else if (instruction->id == IrInstructionIdStructInit) {
6887 IrInstructionStructInit *struct_init_instruction = (IrInstructionStructInit *)instruction;
6888 slot = &struct_init_instruction->tmp_ptr;
6889 } else if (instruction->id == IrInstructionIdUnionInit) {
6890 IrInstructionUnionInit *union_init_instruction = (IrInstructionUnionInit *)instruction;
6891 slot = &union_init_instruction->tmp_ptr;
6892 } else if (instruction->id == IrInstructionIdCall) {
6893 IrInstructionCall *call_instruction = (IrInstructionCall *)instruction;
6894 slot = &call_instruction->tmp_ptr;
6895 } else if (instruction->id == IrInstructionIdSlice) {
6896 IrInstructionSlice *slice_instruction = (IrInstructionSlice *)instruction;
6897 slot = &slice_instruction->tmp_ptr;
6898 } else if (instruction->id == IrInstructionIdOptionalWrap) {
6899 IrInstructionOptionalWrap *maybe_wrap_instruction = (IrInstructionOptionalWrap *)instruction;
6900 slot = &maybe_wrap_instruction->tmp_ptr;
6901 } else if (instruction->id == IrInstructionIdErrWrapPayload) {
6902 IrInstructionErrWrapPayload *err_wrap_payload_instruction = (IrInstructionErrWrapPayload *)instruction;
6903 slot = &err_wrap_payload_instruction->tmp_ptr;
6904 } else if (instruction->id == IrInstructionIdErrWrapCode) {
6905 IrInstructionErrWrapCode *err_wrap_code_instruction = (IrInstructionErrWrapCode *)instruction;
6906 slot = &err_wrap_code_instruction->tmp_ptr;
6907 } else if (instruction->id == IrInstructionIdCmpxchgGen) {
6908 IrInstructionCmpxchgGen *cmpxchg_instruction = (IrInstructionCmpxchgGen *)instruction;
6909 slot = &cmpxchg_instruction->tmp_ptr;
6910 } else if (instruction->id == IrInstructionIdResizeSlice) {
6911 IrInstructionResizeSlice *resize_slice_instruction = (IrInstructionResizeSlice *)instruction;
6912 slot = &resize_slice_instruction->tmp_ptr;
6913 } else if (instruction->id == IrInstructionIdLoadPtrGen) {
6914 IrInstructionLoadPtrGen *load_ptr_inst = (IrInstructionLoadPtrGen *)instruction;
6915 slot = &load_ptr_inst->tmp_ptr;
6916 } else if (instruction->id == IrInstructionIdBitCastGen) {
6917 IrInstructionBitCastGen *bit_cast_inst = (IrInstructionBitCastGen *)instruction;
6918 slot = &bit_cast_inst->tmp_ptr;
6919 } else if (instruction->id == IrInstructionIdVectorToArray) {
6920 IrInstructionVectorToArray *vector_to_array_instruction = (IrInstructionVectorToArray *)instruction;
6921 alignment_bytes = get_abi_alignment(g, vector_to_array_instruction->vector->value.type);
6922 slot = &vector_to_array_instruction->tmp_ptr;
6923 } else {
6924 zig_unreachable();
6896 for (size_t alloca_i = 0; alloca_i < fn_table_entry->alloca_gen_list.length; alloca_i += 1) {
6897 IrInstructionAllocaGen *instruction = fn_table_entry->alloca_gen_list.at(alloca_i);
6898 ZigType *ptr_type = instruction->base.value.type;
6899 assert(ptr_type->id == ZigTypeIdPointer);
6900 ZigType *child_type = ptr_type->data.pointer.child_type;
6901 if (!type_has_bits(child_type))
6902 continue;
6903 if (instruction->base.ref_count == 0)
6904 continue;
6905 if (instruction->base.value.special != ConstValSpecialRuntime) {
6906 if (const_ptr_pointee(nullptr, g, &instruction->base.value, nullptr)->special !=
6907 ConstValSpecialRuntime)
6908 {
6909 continue;
6910 }
69256911 }
6926 *slot = build_alloca(g, slot_type, "", alignment_bytes);
6912 instruction->base.llvm_value = build_alloca(g, child_type, instruction->name_hint,
6913 get_ptr_align(g, ptr_type));
69276914 }
69286915
69296916 ZigType *import = get_scope_import(&fn_table_entry->fndef_scope->base);
6930
6931 unsigned gen_i_init = want_first_arg_sret(g, fn_type_id) ? 1 : 0;
6917 unsigned gen_i_init = want_sret ? 1 : 0;
69326918
69336919 // create debug variable declarations for variables and allocate all local variables
69346920 FnWalk fn_walk_var = {};
......@@ -6955,8 +6941,6 @@ static void do_code_gen(CodeGen *g) {
69556941 }
69566942
69576943 if (var->src_arg_index == SIZE_MAX) {
6958 var->value_ref = build_alloca(g, var->var_type, buf_ptr(&var->name), var->align_bytes);
6959
69606944 var->di_loc_var = ZigLLVMCreateAutoVariable(g->dbuilder, get_di_scope(g, var->parent_scope),
69616945 buf_ptr(&var->name), import->data.structure.root_struct->di_file, (unsigned)(var->decl_node->line + 1),
69626946 get_llvm_di_type(g, var->var_type), !g->strip_debug_symbols, 0);
......@@ -7398,6 +7382,21 @@ static void define_builtin_fns(CodeGen *g) {
73987382 create_builtin_fn(g, BuiltinFnIdRem, "rem", 2);
73997383 create_builtin_fn(g, BuiltinFnIdMod, "mod", 2);
74007384 create_builtin_fn(g, BuiltinFnIdSqrt, "sqrt", 2);
7385 create_builtin_fn(g, BuiltinFnIdSin, "sin", 2);
7386 create_builtin_fn(g, BuiltinFnIdCos, "cos", 2);
7387 create_builtin_fn(g, BuiltinFnIdExp, "exp", 2);
7388 create_builtin_fn(g, BuiltinFnIdExp2, "exp2", 2);
7389 create_builtin_fn(g, BuiltinFnIdLn, "ln", 2);
7390 create_builtin_fn(g, BuiltinFnIdLog2, "log2", 2);
7391 create_builtin_fn(g, BuiltinFnIdLog10, "log10", 2);
7392 create_builtin_fn(g, BuiltinFnIdFabs, "fabs", 2);
7393 create_builtin_fn(g, BuiltinFnIdFloor, "floor", 2);
7394 create_builtin_fn(g, BuiltinFnIdCeil, "ceil", 2);
7395 create_builtin_fn(g, BuiltinFnIdTrunc, "trunc", 2);
7396 //Needs library support on Windows
7397 //create_builtin_fn(g, BuiltinFnIdNearbyInt, "nearbyInt", 2);
7398 create_builtin_fn(g, BuiltinFnIdRound, "round", 2);
7399 create_builtin_fn(g, BuiltinFnIdMulAdd, "mulAdd", 4);
74017400 create_builtin_fn(g, BuiltinFnIdInlineCall, "inlineCall", SIZE_MAX);
74027401 create_builtin_fn(g, BuiltinFnIdNoInlineCall, "noInlineCall", SIZE_MAX);
74037402 create_builtin_fn(g, BuiltinFnIdNewStackCall, "newStackCall", SIZE_MAX);
......@@ -8056,6 +8055,8 @@ static Error define_builtin_compile_vars(CodeGen *g) {
80568055 g->root_package->package_table.put(buf_create_from_str("builtin"), g->compile_var_package);
80578056 g->std_package->package_table.put(buf_create_from_str("builtin"), g->compile_var_package);
80588057 g->std_package->package_table.put(buf_create_from_str("std"), g->std_package);
8058 g->std_package->package_table.put(buf_create_from_str("root"),
8059 g->is_test_build ? g->test_runner_package : g->root_package);
80598060 g->compile_var_import = add_source_file(g, g->compile_var_package, builtin_zig_path, contents,
80608061 SourceKindPkgMain);
80618062
......@@ -8525,7 +8526,7 @@ static ZigType *add_special_code(CodeGen *g, ZigPackage *package, const char *ba
85258526
85268527static ZigPackage *create_bootstrap_pkg(CodeGen *g, ZigPackage *pkg_with_main) {
85278528 ZigPackage *package = codegen_create_package(g, buf_ptr(g->zig_std_special_dir), "bootstrap.zig", "std.special");
8528 package->package_table.put(buf_create_from_str("@root"), pkg_with_main);
8529 package->package_table.put(buf_create_from_str("root"), pkg_with_main);
85298530 return package;
85308531}
85318532
......@@ -9378,6 +9379,7 @@ void codegen_add_time_event(CodeGen *g, const char *name) {
93789379static void add_cache_pkg(CodeGen *g, CacheHash *ch, ZigPackage *pkg) {
93799380 if (buf_len(&pkg->root_src_path) == 0)
93809381 return;
9382 pkg->added_to_cache = true;
93819383
93829384 Buf *rel_full_path = buf_alloc();
93839385 os_path_join(&pkg->root_src_dir, &pkg->root_src_path, rel_full_path);
......@@ -9389,9 +9391,7 @@ static void add_cache_pkg(CodeGen *g, CacheHash *ch, ZigPackage *pkg) {
93899391 if (!entry)
93909392 break;
93919393
9392 // TODO: I think we need a more sophisticated detection of
9393 // packages we have already seen
9394 if (entry->value != pkg) {
9394 if (!pkg->added_to_cache) {
93959395 cache_buf(ch, entry->key);
93969396 add_cache_pkg(g, ch, entry->value);
93979397 }
......@@ -9648,6 +9648,10 @@ ZigPackage *codegen_create_package(CodeGen *g, const char *root_src_dir, const c
96489648 if (g->std_package != nullptr) {
96499649 assert(g->compile_var_package != nullptr);
96509650 pkg->package_table.put(buf_create_from_str("std"), g->std_package);
9651
9652 ZigPackage *main_pkg = g->is_test_build ? g->test_runner_package : g->root_package;
9653 pkg->package_table.put(buf_create_from_str("root"), main_pkg);
9654
96519655 pkg->package_table.put(buf_create_from_str("builtin"), g->compile_var_package);
96529656 }
96539657 return pkg;
src/ir.cpp+3608-1624
......@@ -38,6 +38,7 @@ struct IrAnalyze {
3838 ZigType *explicit_return_type;
3939 AstNode *explicit_return_type_source_node;
4040 ZigList<IrInstruction *> src_implicit_return_type_list;
41 ZigList<IrSuspendPosition> resume_stack;
4142 IrBasicBlock *const_predecessor_bb;
4243};
4344
......@@ -157,16 +158,19 @@ enum UndefAllowed {
157158};
158159
159160static 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_analyze_instruction(IrAnalyze *ira, IrInstruction *instruction);
161static IrInstruction *ir_gen_node_extra(IrBuilder *irb, AstNode *node, Scope *scope, LVal lval,
162 ResultLoc *result_loc);
162163static 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);
164166static ErrorMsg *exec_add_error_node(CodeGen *codegen, IrExecutable *exec, AstNode *source_node, Buf *msg);
165167static 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);
167170static IrInstruction *ir_get_var_ptr(IrAnalyze *ira, IrInstruction *instruction, ZigVar *var);
168171static 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);
170174static ZigType *adjust_ptr_align(CodeGen *g, ZigType *ptr_type, uint32_t new_align);
171175static ZigType *adjust_slice_align(CodeGen *g, ZigType *slice_type, uint32_t new_align);
172176static 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_
178182static ConstExprValue *ir_resolve_const(IrAnalyze *ira, IrInstruction *value, UndefAllowed undef_allowed);
179183static void copy_const_val(ConstExprValue *dest, ConstExprValue *src, bool same_global_refs);
180184static Error resolve_ptr_align(IrAnalyze *ira, ZigType *ty, uint32_t *result_align);
181static void ir_add_alloca(IrAnalyze *ira, IrInstruction *instruction, ZigType *type_entry);
182185static IrInstruction *ir_analyze_int_to_ptr(IrAnalyze *ira, IrInstruction *source_instr, IrInstruction *target,
183186 ZigType *ptr_type);
184187static IrInstruction *ir_analyze_bit_cast(IrAnalyze *ira, IrInstruction *source_instr, IrInstruction *value,
185188 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
187202static ConstExprValue *const_ptr_pointee_unchecked(CodeGen *g, ConstExprValue *const_val) {
188203 assert(get_src_ptr_type(const_val->type) != nullptr);
189204 assert(const_val->special == ConstValSpecialStatic);
190205 ConstExprValue *result;
191
206
192207 switch (type_has_one_possible_value(g, const_val->type->data.pointer.child_type)) {
193208 case OnePossibleValueInvalid:
194209 zig_unreachable();
......@@ -200,7 +215,7 @@ static ConstExprValue *const_ptr_pointee_unchecked(CodeGen *g, ConstExprValue *c
200215 case OnePossibleValueNo:
201216 break;
202217 }
203
218
204219 switch (const_val->data.x_ptr.special) {
205220 case ConstPtrSpecialInvalid:
206221 zig_unreachable();
......@@ -246,6 +261,15 @@ static bool is_opt_err_set(ZigType *ty) {
246261 (ty->id == ZigTypeIdOptional && ty->data.maybe.child_type->id == ZigTypeIdErrorSet);
247262}
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
249273// This function returns true when you can change the type of a ConstExprValue and the
250274// value remains meaningful.
251275static 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) {
282306 return a->data.floating.bit_count == b->data.floating.bit_count;
283307 case ZigTypeIdInt:
284308 return a->data.integral.is_signed == b->data.integral.is_signed;
285 case ZigTypeIdArray:
286309 case ZigTypeIdStruct:
310 return is_slice(a) && is_slice(b);
311 case ZigTypeIdArray:
287312 case ZigTypeIdOptional:
288313 case ZigTypeIdErrorUnion:
289314 case ZigTypeIdEnum:
......@@ -386,6 +411,7 @@ static IrBasicBlock *ir_create_basic_block(IrBuilder *irb, Scope *scope, const c
386411 result->scope = scope;
387412 result->name_hint = name_hint;
388413 result->debug_id = exec_next_debug_id(irb->exec);
414 result->index = SIZE_MAX; // set later
389415 return result;
390416}
391417
......@@ -475,8 +501,16 @@ static constexpr IrInstructionId ir_instruction_id(IrInstructionVarPtr *) {
475501 return IrInstructionIdVarPtr;
476502}
477503
478static constexpr IrInstructionId ir_instruction_id(IrInstructionCall *) {
479 return IrInstructionIdCall;
504static constexpr IrInstructionId ir_instruction_id(IrInstructionReturnPtr *) {
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;
480514}
481515
482516static constexpr IrInstructionId ir_instruction_id(IrInstructionConst *) {
......@@ -511,14 +545,6 @@ static constexpr IrInstructionId ir_instruction_id(IrInstructionTypeOf *) {
511545 return IrInstructionIdTypeOf;
512546}
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
522548static constexpr IrInstructionId ir_instruction_id(IrInstructionSetCold *) {
523549 return IrInstructionIdSetCold;
524550}
......@@ -611,12 +637,8 @@ static constexpr IrInstructionId ir_instruction_id(IrInstructionRef *) {
611637 return IrInstructionIdRef;
612638}
613639
614static constexpr IrInstructionId ir_instruction_id(IrInstructionStructInit *) {
615 return IrInstructionIdStructInit;
616}
617
618static constexpr IrInstructionId ir_instruction_id(IrInstructionUnionInit *) {
619 return IrInstructionIdUnionInit;
640static constexpr IrInstructionId ir_instruction_id(IrInstructionRefGen *) {
641 return IrInstructionIdRefGen;
620642}
621643
622644static constexpr IrInstructionId ir_instruction_id(IrInstructionCompileErr *) {
......@@ -703,8 +725,12 @@ static constexpr IrInstructionId ir_instruction_id(IrInstructionMemcpy *) {
703725 return IrInstructionIdMemcpy;
704726}
705727
706static constexpr IrInstructionId ir_instruction_id(IrInstructionSlice *) {
707 return IrInstructionIdSlice;
728static constexpr IrInstructionId ir_instruction_id(IrInstructionSliceSrc *) {
729 return IrInstructionIdSliceSrc;
730}
731
732static constexpr IrInstructionId ir_instruction_id(IrInstructionSliceGen *) {
733 return IrInstructionIdSliceGen;
708734}
709735
710736static constexpr IrInstructionId ir_instruction_id(IrInstructionMemberCount *) {
......@@ -743,8 +769,16 @@ static constexpr IrInstructionId ir_instruction_id(IrInstructionOverflowOp *) {
743769 return IrInstructionIdOverflowOp;
744770}
745771
746static constexpr IrInstructionId ir_instruction_id(IrInstructionTestErr *) {
747 return IrInstructionIdTestErr;
772static constexpr IrInstructionId ir_instruction_id(IrInstructionTestErrSrc *) {
773 return IrInstructionIdTestErrSrc;
774}
775
776static constexpr IrInstructionId ir_instruction_id(IrInstructionTestErrGen *) {
777 return IrInstructionIdTestErrGen;
778}
779
780static constexpr IrInstructionId ir_instruction_id(IrInstructionMulAdd *) {
781 return IrInstructionIdMulAdd;
748782}
749783
750784static constexpr IrInstructionId ir_instruction_id(IrInstructionUnwrapErrCode *) {
......@@ -783,8 +817,8 @@ static constexpr IrInstructionId ir_instruction_id(IrInstructionPtrCastGen *) {
783817 return IrInstructionIdPtrCastGen;
784818}
785819
786static constexpr IrInstructionId ir_instruction_id(IrInstructionBitCast *) {
787 return IrInstructionIdBitCast;
820static constexpr IrInstructionId ir_instruction_id(IrInstructionBitCastSrc *) {
821 return IrInstructionIdBitCastSrc;
788822}
789823
790824static constexpr IrInstructionId ir_instruction_id(IrInstructionBitCastGen *) {
......@@ -879,6 +913,26 @@ static constexpr IrInstructionId ir_instruction_id(IrInstructionAlignCast *) {
879913 return IrInstructionIdAlignCast;
880914}
881915
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
882936static constexpr IrInstructionId ir_instruction_id(IrInstructionOpaqueType *) {
883937 return IrInstructionIdOpaqueType;
884938}
......@@ -987,8 +1041,8 @@ static constexpr IrInstructionId ir_instruction_id(IrInstructionMarkErrRetTraceP
9871041 return IrInstructionIdMarkErrRetTracePtr;
9881042}
9891043
990static constexpr IrInstructionId ir_instruction_id(IrInstructionSqrt *) {
991 return IrInstructionIdSqrt;
1044static constexpr IrInstructionId ir_instruction_id(IrInstructionFloatOp *) {
1045 return IrInstructionIdFloatOp;
9921046}
9931047
9941048static constexpr IrInstructionId ir_instruction_id(IrInstructionCheckRuntimeScope *) {
......@@ -1019,6 +1073,18 @@ static constexpr IrInstructionId ir_instruction_id(IrInstructionUndeclaredIdent
10191073 return IrInstructionIdUndeclaredIdent;
10201074}
10211075
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
10221088template<typename T>
10231089static T *ir_create_instruction(IrBuilder *irb, Scope *scope, AstNode *source_node) {
10241090 T *special_instruction = allocate<T>(1);
......@@ -1070,13 +1136,15 @@ static IrInstruction *ir_build_cond_br(IrBuilder *irb, Scope *scope, AstNode *so
10701136 return &cond_br_instruction->base;
10711137}
10721138
1073static 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{
10741142 IrInstructionReturn *return_instruction = ir_build_instruction<IrInstructionReturn>(irb, scope, source_node);
10751143 return_instruction->base.value.type = irb->codegen->builtin_types.entry_unreachable;
10761144 return_instruction->base.value.special = ConstValSpecialStatic;
10771145 return_instruction->value = return_value;
10781146
1079 ir_ref_instruction(return_value, irb->current_basic_block);
1147 if (return_value != nullptr) ir_ref_instruction(return_value, irb->current_basic_block);
10801148
10811149 return &return_instruction->base;
10821150}
......@@ -1254,17 +1322,27 @@ static IrInstruction *ir_build_var_ptr(IrBuilder *irb, Scope *scope, AstNode *so
12541322 return ir_build_var_ptr_x(irb, scope, source_node, var, nullptr);
12551323}
12561324
1257static IrInstruction *ir_build_elem_ptr(IrBuilder *irb, Scope *scope, AstNode *source_node, IrInstruction *array_ptr,
1258 IrInstruction *elem_index, bool safety_check_on, PtrLen ptr_len)
1325static IrInstruction *ir_build_return_ptr(IrAnalyze *ira, IrInstruction *source_instruction, ZigType *ty) {
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)
12591335{
12601336 IrInstructionElemPtr *instruction = ir_build_instruction<IrInstructionElemPtr>(irb, scope, source_node);
12611337 instruction->array_ptr = array_ptr;
12621338 instruction->elem_index = elem_index;
12631339 instruction->safety_check_on = safety_check_on;
12641340 instruction->ptr_len = ptr_len;
1341 instruction->init_array_type = init_array_type;
12651342
12661343 ir_ref_instruction(array_ptr, irb->current_basic_block);
12671344 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);
12681346
12691347 return &instruction->base;
12701348}
......@@ -1284,12 +1362,13 @@ static IrInstruction *ir_build_field_ptr_instruction(IrBuilder *irb, Scope *scop
12841362}
12851363
12861364static IrInstruction *ir_build_field_ptr(IrBuilder *irb, Scope *scope, AstNode *source_node,
1287 IrInstruction *container_ptr, Buf *field_name)
1365 IrInstruction *container_ptr, Buf *field_name, bool initializing)
12881366{
12891367 IrInstructionFieldPtr *instruction = ir_build_instruction<IrInstructionFieldPtr>(irb, scope, source_node);
12901368 instruction->container_ptr = container_ptr;
12911369 instruction->field_name_buffer = field_name;
12921370 instruction->field_name_expr = nullptr;
1371 instruction->initializing = initializing;
12931372
12941373 ir_ref_instruction(container_ptr, irb->current_basic_block);
12951374
......@@ -1309,9 +1388,11 @@ static IrInstruction *ir_build_struct_field_ptr(IrBuilder *irb, Scope *scope, As
13091388}
13101389
13111390static IrInstruction *ir_build_union_field_ptr(IrBuilder *irb, Scope *scope, AstNode *source_node,
1312 IrInstruction *union_ptr, TypeUnionField *field)
1391 IrInstruction *union_ptr, TypeUnionField *field, bool safety_check_on, bool initializing)
13131392{
13141393 IrInstructionUnionFieldPtr *instruction = ir_build_instruction<IrInstructionUnionFieldPtr>(irb, scope, source_node);
1394 instruction->initializing = initializing;
1395 instruction->safety_check_on = safety_check_on;
13151396 instruction->union_ptr = union_ptr;
13161397 instruction->field = field;
13171398
......@@ -1320,12 +1401,12 @@ static IrInstruction *ir_build_union_field_ptr(IrBuilder *irb, Scope *scope, Ast
13201401 return &instruction->base;
13211402}
13221403
1323static IrInstruction *ir_build_call(IrBuilder *irb, Scope *scope, AstNode *source_node,
1404static IrInstruction *ir_build_call_src(IrBuilder *irb, Scope *scope, AstNode *source_node,
13241405 ZigFn *fn_entry, IrInstruction *fn_ref, size_t arg_count, IrInstruction **args,
13251406 bool is_comptime, FnInline fn_inline, bool is_async, IrInstruction *async_allocator,
1326 IrInstruction *new_stack)
1407 IrInstruction *new_stack, ResultLoc *result_loc)
13271408{
1328 IrInstructionCall *call_instruction = ir_build_instruction<IrInstructionCall>(irb, scope, source_node);
1409 IrInstructionCallSrc *call_instruction = ir_build_instruction<IrInstructionCallSrc>(irb, scope, source_node);
13291410 call_instruction->fn_entry = fn_entry;
13301411 call_instruction->fn_ref = fn_ref;
13311412 call_instruction->is_comptime = is_comptime;
......@@ -1335,6 +1416,7 @@ static IrInstruction *ir_build_call(IrBuilder *irb, Scope *scope, AstNode *sourc
13351416 call_instruction->is_async = is_async;
13361417 call_instruction->async_allocator = async_allocator;
13371418 call_instruction->new_stack = new_stack;
1419 call_instruction->result_loc = result_loc;
13381420
13391421 if (fn_ref != nullptr) ir_ref_instruction(fn_ref, irb->current_basic_block);
13401422 for (size_t i = 0; i < arg_count; i += 1)
......@@ -1345,8 +1427,37 @@ static IrInstruction *ir_build_call(IrBuilder *irb, Scope *scope, AstNode *sourc
13451427 return &call_instruction->base;
13461428}
13471429
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
13481458static IrInstruction *ir_build_phi(IrBuilder *irb, Scope *scope, AstNode *source_node,
1349 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)
13501461{
13511462 assert(incoming_count != 0);
13521463 assert(incoming_count != SIZE_MAX);
......@@ -1355,6 +1466,7 @@ static IrInstruction *ir_build_phi(IrBuilder *irb, Scope *scope, AstNode *source
13551466 phi_instruction->incoming_count = incoming_count;
13561467 phi_instruction->incoming_blocks = incoming_blocks;
13571468 phi_instruction->incoming_values = incoming_values;
1469 phi_instruction->peer_parent = peer_parent;
13581470
13591471 for (size_t i = 0; i < incoming_count; i += 1) {
13601472 ir_ref_bb(incoming_blocks[i]);
......@@ -1408,12 +1520,13 @@ static IrInstruction *ir_build_ptr_type(IrBuilder *irb, Scope *scope, AstNode *s
14081520}
14091521
14101522static IrInstruction *ir_build_un_op_lval(IrBuilder *irb, Scope *scope, AstNode *source_node, IrUnOp op_id,
1411 IrInstruction *value, LVal lval)
1523 IrInstruction *value, LVal lval, ResultLoc *result_loc)
14121524{
14131525 IrInstructionUnOp *instruction = ir_build_instruction<IrInstructionUnOp>(irb, scope, source_node);
14141526 instruction->op_id = op_id;
14151527 instruction->value = value;
14161528 instruction->lval = lval;
1529 instruction->result_loc = result_loc;
14171530
14181531 ir_ref_instruction(value, irb->current_basic_block);
14191532
......@@ -1423,72 +1536,49 @@ static IrInstruction *ir_build_un_op_lval(IrBuilder *irb, Scope *scope, AstNode
14231536static IrInstruction *ir_build_un_op(IrBuilder *irb, Scope *scope, AstNode *source_node, IrUnOp op_id,
14241537 IrInstruction *value)
14251538{
1426 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);
14271540}
14281541
14291542static IrInstruction *ir_build_container_init_list(IrBuilder *irb, Scope *scope, AstNode *source_node,
1430 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)
14311545{
14321546 IrInstructionContainerInitList *container_init_list_instruction =
14331547 ir_build_instruction<IrInstructionContainerInitList>(irb, scope, source_node);
14341548 container_init_list_instruction->container_type = container_type;
1435 container_init_list_instruction->elem_type = elem_type;
14361549 container_init_list_instruction->item_count = item_count;
1437 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;
14381552
1439 if (container_type != nullptr) ir_ref_instruction(container_type, irb->current_basic_block);
1440 if (elem_type != nullptr) ir_ref_instruction(elem_type, irb->current_basic_block);
1553 ir_ref_instruction(container_type, irb->current_basic_block);
14411554 for (size_t i = 0; i < item_count; i += 1) {
1442 ir_ref_instruction(items[i], irb->current_basic_block);
1555 ir_ref_instruction(elem_result_loc_list[i], irb->current_basic_block);
14431556 }
1557 if (result_loc != nullptr) ir_ref_instruction(result_loc, irb->current_basic_block);
14441558
14451559 return &container_init_list_instruction->base;
14461560}
14471561
14481562static IrInstruction *ir_build_container_init_fields(IrBuilder *irb, Scope *scope, AstNode *source_node,
1449 IrInstruction *container_type, size_t field_count, IrInstructionContainerInitFieldsField *fields)
1563 IrInstruction *container_type, size_t field_count, IrInstructionContainerInitFieldsField *fields,
1564 IrInstruction *result_loc)
14501565{
14511566 IrInstructionContainerInitFields *container_init_fields_instruction =
14521567 ir_build_instruction<IrInstructionContainerInitFields>(irb, scope, source_node);
14531568 container_init_fields_instruction->container_type = container_type;
14541569 container_init_fields_instruction->field_count = field_count;
14551570 container_init_fields_instruction->fields = fields;
1571 container_init_fields_instruction->result_loc = result_loc;
14561572
14571573 ir_ref_instruction(container_type, irb->current_basic_block);
14581574 for (size_t i = 0; i < field_count; i += 1) {
1459 ir_ref_instruction(fields[i].value, irb->current_basic_block);
1575 ir_ref_instruction(fields[i].result_loc, irb->current_basic_block);
14601576 }
1577 if (result_loc != nullptr) ir_ref_instruction(result_loc, irb->current_basic_block);
14611578
14621579 return &container_init_fields_instruction->base;
14631580}
14641581
1465static IrInstruction *ir_build_struct_init(IrBuilder *irb, Scope *scope, AstNode *source_node,
1466 ZigType *struct_type, size_t field_count, IrInstructionStructInitField *fields)
1467{
1468 IrInstructionStructInit *struct_init_instruction = ir_build_instruction<IrInstructionStructInit>(irb, scope, source_node);
1469 struct_init_instruction->struct_type = struct_type;
1470 struct_init_instruction->field_count = field_count;
1471 struct_init_instruction->fields = fields;
1472
1473 for (size_t i = 0; i < field_count; i += 1)
1474 ir_ref_instruction(fields[i].value, irb->current_basic_block);
1475
1476 return &struct_init_instruction->base;
1477}
1478
1479static IrInstruction *ir_build_union_init(IrBuilder *irb, Scope *scope, AstNode *source_node,
1480 ZigType *union_type, TypeUnionField *field, IrInstruction *init_value)
1481{
1482 IrInstructionUnionInit *union_init_instruction = ir_build_instruction<IrInstructionUnionInit>(irb, scope, source_node);
1483 union_init_instruction->union_type = union_type;
1484 union_init_instruction->field = field;
1485 union_init_instruction->init_value = init_value;
1486
1487 ir_ref_instruction(init_value, irb->current_basic_block);
1488
1489 return &union_init_instruction->base;
1490}
1491
14921582static IrInstruction *ir_build_unreachable(IrBuilder *irb, Scope *scope, AstNode *source_node) {
14931583 IrInstructionUnreachable *unreachable_instruction =
14941584 ir_build_instruction<IrInstructionUnreachable>(irb, scope, source_node);
......@@ -1513,47 +1603,47 @@ static IrInstruction *ir_build_store_ptr(IrBuilder *irb, Scope *scope, AstNode *
15131603}
15141604
15151605static IrInstruction *ir_build_var_decl_src(IrBuilder *irb, Scope *scope, AstNode *source_node,
1516 ZigVar *var, IrInstruction *var_type, IrInstruction *align_value, IrInstruction *init_value)
1606 ZigVar *var, IrInstruction *align_value, IrInstruction *ptr)
15171607{
15181608 IrInstructionDeclVarSrc *decl_var_instruction = ir_build_instruction<IrInstructionDeclVarSrc>(irb, scope, source_node);
15191609 decl_var_instruction->base.value.special = ConstValSpecialStatic;
15201610 decl_var_instruction->base.value.type = irb->codegen->builtin_types.entry_void;
15211611 decl_var_instruction->var = var;
1522 decl_var_instruction->var_type = var_type;
15231612 decl_var_instruction->align_value = align_value;
1524 decl_var_instruction->init_value = init_value;
1613 decl_var_instruction->ptr = ptr;
15251614
1526 if (var_type != nullptr) ir_ref_instruction(var_type, irb->current_basic_block);
15271615 if (align_value != nullptr) ir_ref_instruction(align_value, irb->current_basic_block);
1528 ir_ref_instruction(init_value, irb->current_basic_block);
1616 ir_ref_instruction(ptr, irb->current_basic_block);
15291617
15301618 return &decl_var_instruction->base;
15311619}
15321620
15331621static IrInstruction *ir_build_var_decl_gen(IrAnalyze *ira, IrInstruction *source_instruction,
1534 ZigVar *var, IrInstruction *init_value)
1622 ZigVar *var, IrInstruction *var_ptr)
15351623{
15361624 IrInstructionDeclVarGen *decl_var_instruction = ir_build_instruction<IrInstructionDeclVarGen>(&ira->new_irb,
15371625 source_instruction->scope, source_instruction->source_node);
15381626 decl_var_instruction->base.value.special = ConstValSpecialStatic;
15391627 decl_var_instruction->base.value.type = ira->codegen->builtin_types.entry_void;
15401628 decl_var_instruction->var = var;
1541 decl_var_instruction->init_value = init_value;
1629 decl_var_instruction->var_ptr = var_ptr;
15421630
1543 ir_ref_instruction(init_value, ira->new_irb.current_basic_block);
1631 ir_ref_instruction(var_ptr, ira->new_irb.current_basic_block);
15441632
15451633 return &decl_var_instruction->base;
15461634}
15471635
15481636static IrInstruction *ir_build_resize_slice(IrAnalyze *ira, IrInstruction *source_instruction,
1549 IrInstruction *operand, ZigType *ty)
1637 IrInstruction *operand, ZigType *ty, IrInstruction *result_loc)
15501638{
15511639 IrInstructionResizeSlice *instruction = ir_build_instruction<IrInstructionResizeSlice>(&ira->new_irb,
15521640 source_instruction->scope, source_instruction->source_node);
15531641 instruction->base.value.type = ty;
15541642 instruction->operand = operand;
1643 instruction->result_loc = result_loc;
15551644
15561645 ir_ref_instruction(operand, ira->new_irb.current_basic_block);
1646 ir_ref_instruction(result_loc, ira->new_irb.current_basic_block);
15571647
15581648 return &instruction->base;
15591649}
......@@ -1594,27 +1684,6 @@ static IrInstruction *ir_build_typeof(IrBuilder *irb, Scope *scope, AstNode *sou
15941684 return &instruction->base;
15951685}
15961686
1597static IrInstruction *ir_build_to_ptr_type(IrBuilder *irb, Scope *scope, AstNode *source_node, IrInstruction *ptr) {
1598 IrInstructionToPtrType *instruction = ir_build_instruction<IrInstructionToPtrType>(irb, scope, source_node);
1599 instruction->ptr = ptr;
1600
1601 ir_ref_instruction(ptr, irb->current_basic_block);
1602
1603 return &instruction->base;
1604}
1605
1606static IrInstruction *ir_build_ptr_type_child(IrBuilder *irb, Scope *scope, AstNode *source_node,
1607 IrInstruction *value)
1608{
1609 IrInstructionPtrTypeChild *instruction = ir_build_instruction<IrInstructionPtrTypeChild>(
1610 irb, scope, source_node);
1611 instruction->value = value;
1612
1613 ir_ref_instruction(value, irb->current_basic_block);
1614
1615 return &instruction->base;
1616}
1617
16181687static IrInstruction *ir_build_set_cold(IrBuilder *irb, Scope *scope, AstNode *source_node, IrInstruction *is_cold) {
16191688 IrInstructionSetCold *instruction = ir_build_instruction<IrInstructionSetCold>(irb, scope, source_node);
16201689 instruction->is_cold = is_cold;
......@@ -1740,40 +1809,59 @@ static IrInstruction *ir_build_test_nonnull(IrBuilder *irb, Scope *scope, AstNod
17401809}
17411810
17421811static IrInstruction *ir_build_optional_unwrap_ptr(IrBuilder *irb, Scope *scope, AstNode *source_node,
1743 IrInstruction *base_ptr, bool safety_check_on)
1812 IrInstruction *base_ptr, bool safety_check_on, bool initializing)
17441813{
17451814 IrInstructionOptionalUnwrapPtr *instruction = ir_build_instruction<IrInstructionOptionalUnwrapPtr>(irb, scope, source_node);
17461815 instruction->base_ptr = base_ptr;
17471816 instruction->safety_check_on = safety_check_on;
1817 instruction->initializing = initializing;
17481818
17491819 ir_ref_instruction(base_ptr, irb->current_basic_block);
17501820
17511821 return &instruction->base;
17521822}
17531823
1754static IrInstruction *ir_build_maybe_wrap(IrBuilder *irb, Scope *scope, AstNode *source_node, IrInstruction *value) {
1755 IrInstructionOptionalWrap *instruction = ir_build_instruction<IrInstructionOptionalWrap>(irb, scope, source_node);
1756 instruction->value = value;
1824static IrInstruction *ir_build_optional_wrap(IrAnalyze *ira, IrInstruction *source_instruction, ZigType *result_ty,
1825 IrInstruction *operand, IrInstruction *result_loc)
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;
17571832
1758 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);
17591835
17601836 return &instruction->base;
17611837}
17621838
1763static IrInstruction *ir_build_err_wrap_payload(IrBuilder *irb, Scope *scope, AstNode *source_node, IrInstruction *value) {
1764 IrInstructionErrWrapPayload *instruction = ir_build_instruction<IrInstructionErrWrapPayload>(irb, scope, source_node);
1765 instruction->value = value;
1839static IrInstruction *ir_build_err_wrap_payload(IrAnalyze *ira, IrInstruction *source_instruction,
1840 ZigType *result_type, IrInstruction *operand, IrInstruction *result_loc)
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;
17661847
1767 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);
17681850
17691851 return &instruction->base;
17701852}
17711853
1772static IrInstruction *ir_build_err_wrap_code(IrBuilder *irb, Scope *scope, AstNode *source_node, IrInstruction *value) {
1773 IrInstructionErrWrapCode *instruction = ir_build_instruction<IrInstructionErrWrapCode>(irb, scope, source_node);
1774 instruction->value = value;
1854static IrInstruction *ir_build_err_wrap_code(IrAnalyze *ira, IrInstruction *source_instruction,
1855 ZigType *result_type, IrInstruction *operand, IrInstruction *result_loc)
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;
17751862
1776 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);
17771865
17781866 return &instruction->base;
17791867}
......@@ -1930,6 +2018,21 @@ static IrInstruction *ir_build_ref(IrBuilder *irb, Scope *scope, AstNode *source
19302018 return &instruction->base;
19312019}
19322020
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
19332036static IrInstruction *ir_build_compile_err(IrBuilder *irb, Scope *scope, AstNode *source_node, IrInstruction *msg) {
19342037 IrInstructionCompileErr *instruction = ir_build_instruction<IrInstructionCompileErr>(irb, scope, source_node);
19352038 instruction->msg = msg;
......@@ -2007,8 +2110,7 @@ static IrInstruction *ir_build_embed_file(IrBuilder *irb, Scope *scope, AstNode
20072110
20082111static IrInstruction *ir_build_cmpxchg_src(IrBuilder *irb, Scope *scope, AstNode *source_node,
20092112 IrInstruction *type_value, IrInstruction *ptr, IrInstruction *cmp_value, IrInstruction *new_value,
2010 IrInstruction *success_order_value, IrInstruction *failure_order_value,
2011 bool is_weak)
2113 IrInstruction *success_order_value, IrInstruction *failure_order_value, bool is_weak, ResultLoc *result_loc)
20122114{
20132115 IrInstructionCmpxchgSrc *instruction = ir_build_instruction<IrInstructionCmpxchgSrc>(irb, scope, source_node);
20142116 instruction->type_value = type_value;
......@@ -2018,6 +2120,7 @@ static IrInstruction *ir_build_cmpxchg_src(IrBuilder *irb, Scope *scope, AstNode
20182120 instruction->success_order_value = success_order_value;
20192121 instruction->failure_order_value = failure_order_value;
20202122 instruction->is_weak = is_weak;
2123 instruction->result_loc = result_loc;
20212124
20222125 ir_ref_instruction(type_value, irb->current_basic_block);
20232126 ir_ref_instruction(ptr, irb->current_basic_block);
......@@ -2029,22 +2132,25 @@ static IrInstruction *ir_build_cmpxchg_src(IrBuilder *irb, Scope *scope, AstNode
20292132 return &instruction->base;
20302133}
20312134
2032static IrInstruction *ir_build_cmpxchg_gen(IrAnalyze *ira, IrInstruction *source_instruction,
2135static IrInstruction *ir_build_cmpxchg_gen(IrAnalyze *ira, IrInstruction *source_instruction, ZigType *result_type,
20332136 IrInstruction *ptr, IrInstruction *cmp_value, IrInstruction *new_value,
2034 AtomicOrder success_order, AtomicOrder failure_order, bool is_weak)
2137 AtomicOrder success_order, AtomicOrder failure_order, bool is_weak, IrInstruction *result_loc)
20352138{
20362139 IrInstructionCmpxchgGen *instruction = ir_build_instruction<IrInstructionCmpxchgGen>(&ira->new_irb,
20372140 source_instruction->scope, source_instruction->source_node);
2141 instruction->base.value.type = result_type;
20382142 instruction->ptr = ptr;
20392143 instruction->cmp_value = cmp_value;
20402144 instruction->new_value = new_value;
20412145 instruction->success_order = success_order;
20422146 instruction->failure_order = failure_order;
20432147 instruction->is_weak = is_weak;
2148 instruction->result_loc = result_loc;
20442149
20452150 ir_ref_instruction(ptr, ira->new_irb.current_basic_block);
20462151 ir_ref_instruction(cmp_value, ira->new_irb.current_basic_block);
20472152 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);
20482154
20492155 return &instruction->base;
20502156}
......@@ -2103,19 +2209,25 @@ static IrInstruction *ir_build_err_set_cast(IrBuilder *irb, Scope *scope, AstNod
21032209 return &instruction->base;
21042210}
21052211
2106static 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{
21072215 IrInstructionToBytes *instruction = ir_build_instruction<IrInstructionToBytes>(irb, scope, source_node);
21082216 instruction->target = target;
2217 instruction->result_loc = result_loc;
21092218
21102219 ir_ref_instruction(target, irb->current_basic_block);
21112220
21122221 return &instruction->base;
21132222}
21142223
2115static 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{
21162227 IrInstructionFromBytes *instruction = ir_build_instruction<IrInstructionFromBytes>(irb, scope, source_node);
21172228 instruction->dest_child_type = dest_child_type;
21182229 instruction->target = target;
2230 instruction->result_loc = result_loc;
21192231
21202232 ir_ref_instruction(dest_child_type, irb->current_basic_block);
21212233 ir_ref_instruction(target, irb->current_basic_block);
......@@ -2217,14 +2329,15 @@ static IrInstruction *ir_build_memcpy(IrBuilder *irb, Scope *scope, AstNode *sou
22172329 return &instruction->base;
22182330}
22192331
2220static IrInstruction *ir_build_slice(IrBuilder *irb, Scope *scope, AstNode *source_node,
2221 IrInstruction *ptr, IrInstruction *start, IrInstruction *end, bool safety_check_on)
2332static IrInstruction *ir_build_slice_src(IrBuilder *irb, Scope *scope, AstNode *source_node,
2333 IrInstruction *ptr, IrInstruction *start, IrInstruction *end, bool safety_check_on, ResultLoc *result_loc)
22222334{
2223 IrInstructionSlice *instruction = ir_build_instruction<IrInstructionSlice>(irb, scope, source_node);
2335 IrInstructionSliceSrc *instruction = ir_build_instruction<IrInstructionSliceSrc>(irb, scope, source_node);
22242336 instruction->ptr = ptr;
22252337 instruction->start = start;
22262338 instruction->end = end;
22272339 instruction->safety_check_on = safety_check_on;
2340 instruction->result_loc = result_loc;
22282341
22292342 ir_ref_instruction(ptr, irb->current_basic_block);
22302343 ir_ref_instruction(start, irb->current_basic_block);
......@@ -2233,6 +2346,26 @@ static IrInstruction *ir_build_slice(IrBuilder *irb, Scope *scope, AstNode *sour
22332346 return &instruction->base;
22342347}
22352348
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
22362369static IrInstruction *ir_build_member_count(IrBuilder *irb, Scope *scope, AstNode *source_node, IrInstruction *container) {
22372370 IrInstructionMemberCount *instruction = ir_build_instruction<IrInstructionMemberCount>(irb, scope, source_node);
22382371 instruction->container = container;
......@@ -2308,6 +2441,75 @@ static IrInstruction *ir_build_overflow_op(IrBuilder *irb, Scope *scope, AstNode
23082441 return &instruction->base;
23092442}
23102443
2444
2445//TODO Powi, Pow, minnum, maxnum, maximum, minimum, copysign,
2446// lround, llround, lrint, llrint
2447// So far this is only non-complicated type functions.
2448const char *float_op_to_name(BuiltinFnId op, bool llvm_name) {
2449 const bool b = llvm_name;
2450
2451 switch (op) {
2452 case BuiltinFnIdSqrt:
2453 return "sqrt";
2454 case BuiltinFnIdSin:
2455 return "sin";
2456 case BuiltinFnIdCos:
2457 return "cos";
2458 case BuiltinFnIdExp:
2459 return "exp";
2460 case BuiltinFnIdExp2:
2461 return "exp2";
2462 case BuiltinFnIdLn:
2463 return b ? "log" : "ln";
2464 case BuiltinFnIdLog10:
2465 return "log10";
2466 case BuiltinFnIdLog2:
2467 return "log2";
2468 case BuiltinFnIdFabs:
2469 return "fabs";
2470 case BuiltinFnIdFloor:
2471 return "floor";
2472 case BuiltinFnIdCeil:
2473 return "ceil";
2474 case BuiltinFnIdTrunc:
2475 return "trunc";
2476 case BuiltinFnIdNearbyInt:
2477 return b ? "nearbyint" : "nearbyInt";
2478 case BuiltinFnIdRound:
2479 return "round";
2480 default:
2481 zig_unreachable();
2482 }
2483}
2484
2485static IrInstruction *ir_build_float_op(IrBuilder *irb, Scope *scope, AstNode *source_node, IrInstruction *type, IrInstruction *op1, BuiltinFnId op) {
2486 IrInstructionFloatOp *instruction = ir_build_instruction<IrInstructionFloatOp>(irb, scope, source_node);
2487 instruction->type = type;
2488 instruction->op1 = op1;
2489 instruction->op = op;
2490
2491 if (type != nullptr) ir_ref_instruction(type, irb->current_basic_block);
2492 ir_ref_instruction(op1, irb->current_basic_block);
2493
2494 return &instruction->base;
2495}
2496
2497static IrInstruction *ir_build_mul_add(IrBuilder *irb, Scope *scope, AstNode *source_node,
2498 IrInstruction *type_value, IrInstruction *op1, IrInstruction *op2, IrInstruction *op3) {
2499 IrInstructionMulAdd *instruction = ir_build_instruction<IrInstructionMulAdd>(irb, scope, source_node);
2500 instruction->type_value = type_value;
2501 instruction->op1 = op1;
2502 instruction->op2 = op2;
2503 instruction->op3 = op3;
2504
2505 ir_ref_instruction(type_value, irb->current_basic_block);
2506 ir_ref_instruction(op1, irb->current_basic_block);
2507 ir_ref_instruction(op2, irb->current_basic_block);
2508 ir_ref_instruction(op3, irb->current_basic_block);
2509
2510 return &instruction->base;
2511}
2512
23112513static IrInstruction *ir_build_align_of(IrBuilder *irb, Scope *scope, AstNode *source_node, IrInstruction *type_value) {
23122514 IrInstructionAlignOf *instruction = ir_build_instruction<IrInstructionAlignOf>(irb, scope, source_node);
23132515 instruction->type_value = type_value;
......@@ -2317,34 +2519,49 @@ static IrInstruction *ir_build_align_of(IrBuilder *irb, Scope *scope, AstNode *s
23172519 return &instruction->base;
23182520}
23192521
2320static IrInstruction *ir_build_test_err(IrBuilder *irb, Scope *scope, AstNode *source_node,
2321 IrInstruction *value)
2522static IrInstruction *ir_build_test_err_src(IrBuilder *irb, Scope *scope, AstNode *source_node,
2523 IrInstruction *base_ptr, bool resolve_err_set)
23222524{
2323 IrInstructionTestErr *instruction = ir_build_instruction<IrInstructionTestErr>(irb, scope, source_node);
2324 instruction->value = value;
2525 IrInstructionTestErrSrc *instruction = ir_build_instruction<IrInstructionTestErrSrc>(irb, scope, source_node);
2526 instruction->base_ptr = base_ptr;
2527 instruction->resolve_err_set = resolve_err_set;
23252528
2326 ir_ref_instruction(value, irb->current_basic_block);
2529 ir_ref_instruction(base_ptr, irb->current_basic_block);
23272530
23282531 return &instruction->base;
23292532}
23302533
2331static 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,
23322535 IrInstruction *err_union)
23332536{
2334 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;
23352540 instruction->err_union = err_union;
23362541
2337 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);
23382554
23392555 return &instruction->base;
23402556}
23412557
23422558static IrInstruction *ir_build_unwrap_err_payload(IrBuilder *irb, Scope *scope, AstNode *source_node,
2343 IrInstruction *value, bool safety_check_on)
2559 IrInstruction *value, bool safety_check_on, bool initializing)
23442560{
23452561 IrInstructionUnwrapErrPayload *instruction = ir_build_instruction<IrInstructionUnwrapErrPayload>(irb, scope, source_node);
23462562 instruction->value = value;
23472563 instruction->safety_check_on = safety_check_on;
2564 instruction->initializing = initializing;
23482565
23492566 ir_ref_instruction(value, irb->current_basic_block);
23502567
......@@ -2414,28 +2631,28 @@ static IrInstruction *ir_build_ptr_cast_gen(IrAnalyze *ira, IrInstruction *sourc
24142631}
24152632
24162633static IrInstruction *ir_build_load_ptr_gen(IrAnalyze *ira, IrInstruction *source_instruction,
2417 IrInstruction *ptr, ZigType *ty)
2634 IrInstruction *ptr, ZigType *ty, IrInstruction *result_loc)
24182635{
24192636 IrInstructionLoadPtrGen *instruction = ir_build_instruction<IrInstructionLoadPtrGen>(
24202637 &ira->new_irb, source_instruction->scope, source_instruction->source_node);
24212638 instruction->base.value.type = ty;
24222639 instruction->ptr = ptr;
2640 instruction->result_loc = result_loc;
24232641
24242642 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);
24252644
24262645 return &instruction->base;
24272646}
24282647
2429static IrInstruction *ir_build_bit_cast(IrBuilder *irb, Scope *scope, AstNode *source_node,
2430 IrInstruction *dest_type, IrInstruction *value)
2648static IrInstruction *ir_build_bit_cast_src(IrBuilder *irb, Scope *scope, AstNode *source_node,
2649 IrInstruction *operand, ResultLocBitCast *result_loc_bit_cast)
24312650{
2432 IrInstructionBitCast *instruction = ir_build_instruction<IrInstructionBitCast>(
2433 irb, scope, source_node);
2434 instruction->dest_type = dest_type;
2435 instruction->value = value;
2651 IrInstructionBitCastSrc *instruction = ir_build_instruction<IrInstructionBitCastSrc>(irb, scope, source_node);
2652 instruction->operand = operand;
2653 instruction->result_loc_bit_cast = result_loc_bit_cast;
24362654
2437 ir_ref_instruction(dest_type, irb->current_basic_block);
2438 ir_ref_instruction(value, irb->current_basic_block);
2655 ir_ref_instruction(operand, irb->current_basic_block);
24392656
24402657 return &instruction->base;
24412658}
......@@ -2587,11 +2804,8 @@ static IrInstruction *ir_build_type_name(IrBuilder *irb, Scope *scope, AstNode *
25872804 return &instruction->base;
25882805}
25892806
2590static IrInstruction *ir_build_decl_ref(IrBuilder *irb, Scope *scope, AstNode *source_node,
2591 Tld *tld, LVal lval)
2592{
2593 IrInstructionDeclRef *instruction = ir_build_instruction<IrInstructionDeclRef>(
2594 irb, scope, source_node);
2807static IrInstruction *ir_build_decl_ref(IrBuilder *irb, Scope *scope, AstNode *source_node, Tld *tld, LVal lval) {
2808 IrInstructionDeclRef *instruction = ir_build_instruction<IrInstructionDeclRef>(irb, scope, source_node);
25952809 instruction->tld = tld;
25962810 instruction->lval = lval;
25972811
......@@ -2719,6 +2933,53 @@ static IrInstruction *ir_build_align_cast(IrBuilder *irb, Scope *scope, AstNode
27192933 return &instruction->base;
27202934}
27212935
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
27222983static IrInstruction *ir_build_opaque_type(IrBuilder *irb, Scope *scope, AstNode *source_node) {
27232984 IrInstructionOpaqueType *instruction = ir_build_instruction<IrInstructionOpaqueType>(irb, scope, source_node);
27242985
......@@ -3013,17 +3274,6 @@ static IrInstruction *ir_build_mark_err_ret_trace_ptr(IrBuilder *irb, Scope *sco
30133274 return &instruction->base;
30143275}
30153276
3016static IrInstruction *ir_build_sqrt(IrBuilder *irb, Scope *scope, AstNode *source_node, IrInstruction *type, IrInstruction *op) {
3017 IrInstructionSqrt *instruction = ir_build_instruction<IrInstructionSqrt>(irb, scope, source_node);
3018 instruction->type = type;
3019 instruction->op = op;
3020
3021 if (type != nullptr) ir_ref_instruction(type, irb->current_basic_block);
3022 ir_ref_instruction(op, irb->current_basic_block);
3023
3024 return &instruction->base;
3025}
3026
30273277static IrInstruction *ir_build_has_decl(IrBuilder *irb, Scope *scope, AstNode *source_node,
30283278 IrInstruction *container, IrInstruction *name)
30293279{
......@@ -3058,16 +3308,31 @@ static IrInstruction *ir_build_check_runtime_scope(IrBuilder *irb, Scope *scope,
30583308}
30593309
30603310static IrInstruction *ir_build_vector_to_array(IrAnalyze *ira, IrInstruction *source_instruction,
3061 IrInstruction *vector, ZigType *result_type)
3311 ZigType *result_type, IrInstruction *vector, IrInstruction *result_loc)
30623312{
30633313 IrInstructionVectorToArray *instruction = ir_build_instruction<IrInstructionVectorToArray>(&ira->new_irb,
30643314 source_instruction->scope, source_instruction->source_node);
30653315 instruction->base.value.type = result_type;
30663316 instruction->vector = vector;
3317 instruction->result_loc = result_loc;
30673318
30683319 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;
30693333
3070 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);
30713336
30723337 return &instruction->base;
30733338}
......@@ -3111,18 +3376,57 @@ static IrInstruction *ir_build_assert_non_null(IrAnalyze *ira, IrInstruction *so
31113376 return &instruction->base;
31123377}
31133378
3114static void ir_count_defers(IrBuilder *irb, Scope *inner_scope, Scope *outer_scope, size_t *results) {
3115 results[ReturnKindUnconditional] = 0;
3116 results[ReturnKindError] = 0;
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;
31173387
3118 Scope *scope = inner_scope;
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);
31193390
3120 while (scope != outer_scope) {
3121 assert(scope);
3122 switch (scope->id) {
3123 case ScopeIdDefer: {
3124 AstNode *defer_node = scope->source_node;
3125 assert(defer_node->type == NodeTypeDefer);
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
3418static void ir_count_defers(IrBuilder *irb, Scope *inner_scope, Scope *outer_scope, size_t *results) {
3419 results[ReturnKindUnconditional] = 0;
3420 results[ReturnKindError] = 0;
3421
3422 Scope *scope = inner_scope;
3423
3424 while (scope != outer_scope) {
3425 assert(scope);
3426 switch (scope->id) {
3427 case ScopeIdDefer: {
3428 AstNode *defer_node = scope->source_node;
3429 assert(defer_node->type == NodeTypeDefer);
31263430 ReturnKind defer_kind = defer_node->data.defer.kind;
31273431 results[defer_kind] += 1;
31283432 scope = scope->parent;
......@@ -3211,6 +3515,7 @@ static void ir_set_cursor_at_end(IrBuilder *irb, IrBasicBlock *basic_block) {
32113515}
32123516
32133517static void ir_set_cursor_at_end_and_append_block(IrBuilder *irb, IrBasicBlock *basic_block) {
3518 basic_block->index = irb->exec->basic_block_list.length;
32143519 irb->exec->basic_block_list.append(basic_block);
32153520 ir_set_cursor_at_end(irb, basic_block);
32163521}
......@@ -3299,7 +3604,7 @@ static IrInstruction *ir_gen_async_return(IrBuilder *irb, Scope *scope, AstNode
32993604 return ir_build_cond_br(irb, scope, node, is_canceled_bool, irb->exec->coro_final_cleanup_block, irb->exec->coro_early_final, is_comptime);
33003605}
33013606
3302static 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) {
33033608 assert(node->type == NodeTypeReturnExpr);
33043609
33053610 ZigFn *fn_entry = exec_fn_entry(irb->exec);
......@@ -3323,12 +3628,16 @@ static IrInstruction *ir_gen_return(IrBuilder *irb, Scope *scope, AstNode *node,
33233628 switch (node->data.return_expr.kind) {
33243629 case ReturnKindUnconditional:
33253630 {
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
33263635 IrInstruction *return_value;
33273636 if (expr_node) {
33283637 // Temporarily set this so that if we return a type it gets the name of the function
33293638 ZigFn *prev_name_fn = irb->exec->name_fn;
33303639 irb->exec->name_fn = exec_fn_entry(irb->exec);
3331 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);
33323641 irb->exec->name_fn = prev_name_fn;
33333642 if (return_value == irb->codegen->invalid_instruction)
33343643 return irb->codegen->invalid_instruction;
......@@ -3346,7 +3655,9 @@ static IrInstruction *ir_gen_return(IrBuilder *irb, Scope *scope, AstNode *node,
33463655 ir_gen_defers_for_block(irb, scope, outer_scope, false);
33473656 }
33483657
3349 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);
33503661
33513662 bool should_inline = ir_should_inline(irb->exec, scope);
33523663 IrInstruction *is_comptime;
......@@ -3375,21 +3686,24 @@ static IrInstruction *ir_gen_return(IrBuilder *irb, Scope *scope, AstNode *node,
33753686 ir_build_br(irb, scope, node, ret_stmt_block, is_comptime);
33763687
33773688 ir_set_cursor_at_end_and_append_block(irb, ret_stmt_block);
3378 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;
33793692 } else {
33803693 // generate unconditional defers
33813694 ir_gen_defers_for_block(irb, scope, outer_scope, false);
3382 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;
33833698 }
33843699 }
33853700 case ReturnKindError:
33863701 {
33873702 assert(expr_node);
3388 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);
33893704 if (err_union_ptr == irb->codegen->invalid_instruction)
33903705 return irb->codegen->invalid_instruction;
3391 IrInstruction *err_union_val = ir_build_load_ptr(irb, scope, node, err_union_ptr);
3392 IrInstruction *is_err_val = ir_build_test_err(irb, scope, node, err_union_val);
3706 IrInstruction *is_err_val = ir_build_test_err_src(irb, scope, node, err_union_ptr, true);
33933707
33943708 IrBasicBlock *return_block = ir_create_basic_block(irb, scope, "ErrRetReturn");
33953709 IrBasicBlock *continue_block = ir_create_basic_block(irb, scope, "ErrRetContinue");
......@@ -3404,19 +3718,27 @@ static IrInstruction *ir_gen_return(IrBuilder *irb, Scope *scope, AstNode *node,
34043718
34053719 ir_set_cursor_at_end_and_append_block(irb, return_block);
34063720 if (!ir_gen_defers_for_block(irb, scope, outer_scope, true)) {
3407 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
34083729 if (irb->codegen->have_err_ret_tracing && !should_inline) {
34093730 ir_build_save_err_ret_addr(irb, scope, node);
34103731 }
3411 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;
34123734 }
34133735
34143736 ir_set_cursor_at_end_and_append_block(irb, continue_block);
3415 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);
34163738 if (lval == LValPtr)
34173739 return unwrapped_ptr;
34183740 else
3419 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);
34203742 }
34213743 }
34223744 zig_unreachable();
......@@ -3500,7 +3822,17 @@ static ZigVar *ir_create_var(IrBuilder *irb, AstNode *node, Scope *scope, Buf *n
35003822 return var;
35013823}
35023824
3503static 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{
35043836 assert(block_node->type == NodeTypeBlock);
35053837
35063838 ZigList<IrInstruction *> incoming_values = {0};
......@@ -3518,15 +3850,24 @@ static IrInstruction *ir_gen_block(IrBuilder *irb, Scope *parent_scope, AstNode
35183850
35193851 if (block_node->data.block.statements.length == 0) {
35203852 // {}
3521 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);
35223854 }
35233855
35243856 if (block_node->data.block.name != nullptr) {
3857 scope_block->lval = lval;
35253858 scope_block->incoming_blocks = &incoming_blocks;
35263859 scope_block->incoming_values = &incoming_values;
35273860 scope_block->end_block = ir_create_basic_block(irb, parent_scope, "BlockEnd");
35283861 scope_block->is_comptime = ir_build_const_bool(irb, parent_scope, block_node,
35293862 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);
35303871 }
35313872
35323873 bool is_continuation_unreachable = false;
......@@ -3540,6 +3881,8 @@ static IrInstruction *ir_gen_block(IrBuilder *irb, Scope *parent_scope, AstNode
35403881 // keep the last noreturn statement value around in case we need to return it
35413882 noreturn_return_value = statement_value;
35423883 }
3884 // This logic must be kept in sync with
3885 // [STMT_EXPR_TEST_THING] <--- (search this token)
35433886 if (statement_node->type == NodeTypeDefer && statement_value != irb->codegen->invalid_instruction) {
35443887 // defer starts a new scope
35453888 child_scope = statement_node->data.defer.child_scope;
......@@ -3560,21 +3903,41 @@ static IrInstruction *ir_gen_block(IrBuilder *irb, Scope *parent_scope, AstNode
35603903 return noreturn_return_value;
35613904 }
35623905
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 }
35633909 ir_set_cursor_at_end_and_append_block(irb, scope_block->end_block);
3564 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);
35653913 } else {
35663914 incoming_blocks.append(irb->current_basic_block);
3567 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);
35683928 }
35693929
35703930 if (block_node->data.block.name != nullptr) {
35713931 ir_gen_defers_for_block(irb, child_scope, outer_block_scope, false);
35723932 ir_mark_gen(ir_build_br(irb, parent_scope, block_node, scope_block->end_block, scope_block->is_comptime));
35733933 ir_set_cursor_at_end_and_append_block(irb, scope_block->end_block);
3574 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);
35753937 } else {
35763938 ir_gen_defers_for_block(irb, child_scope, outer_block_scope, false);
3577 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);
35783941 }
35793942}
35803943
......@@ -3594,7 +3957,7 @@ static IrInstruction *ir_gen_bin_op_id(IrBuilder *irb, Scope *scope, AstNode *no
35943957}
35953958
35963959static IrInstruction *ir_gen_assign(IrBuilder *irb, Scope *scope, AstNode *node) {
3597 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);
35983961 IrInstruction *rvalue = ir_gen_node(irb, node->data.bin_op_expr.op2, scope);
35993962
36003963 if (lvalue == irb->codegen->invalid_instruction || rvalue == irb->codegen->invalid_instruction)
......@@ -3605,7 +3968,7 @@ static IrInstruction *ir_gen_assign(IrBuilder *irb, Scope *scope, AstNode *node)
36053968}
36063969
36073970static IrInstruction *ir_gen_assign_op(IrBuilder *irb, Scope *scope, AstNode *node, IrBinOp op_id) {
3608 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);
36093972 if (lvalue == irb->codegen->invalid_instruction)
36103973 return lvalue;
36113974 IrInstruction *op1 = ir_build_load_ptr(irb, scope, node->data.bin_op_expr.op1, lvalue);
......@@ -3656,7 +4019,7 @@ static IrInstruction *ir_gen_bool_or(IrBuilder *irb, Scope *scope, AstNode *node
36564019 incoming_blocks[0] = post_val1_block;
36574020 incoming_blocks[1] = post_val2_block;
36584021
3659 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);
36604023}
36614024
36624025static IrInstruction *ir_gen_bool_and(IrBuilder *irb, Scope *scope, AstNode *node) {
......@@ -3698,16 +4061,51 @@ static IrInstruction *ir_gen_bool_and(IrBuilder *irb, Scope *scope, AstNode *nod
36984061 incoming_blocks[0] = post_val1_block;
36994062 incoming_blocks[1] = post_val2_block;
37004063
3701 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;
4084}
4085
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;
37024098}
37034099
3704static IrInstruction *ir_gen_orelse(IrBuilder *irb, Scope *parent_scope, AstNode *node) {
4100static IrInstruction *ir_gen_orelse(IrBuilder *irb, Scope *parent_scope, AstNode *node, LVal lval,
4101 ResultLoc *result_loc)
4102{
37054103 assert(node->type == NodeTypeBinOpExpr);
37064104
37074105 AstNode *op1_node = node->data.bin_op_expr.op1;
37084106 AstNode *op2_node = node->data.bin_op_expr.op2;
37094107
3710 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);
37114109 if (maybe_ptr == irb->codegen->invalid_instruction)
37124110 return irb->codegen->invalid_instruction;
37134111
......@@ -3724,10 +4122,14 @@ static IrInstruction *ir_gen_orelse(IrBuilder *irb, Scope *parent_scope, AstNode
37244122 IrBasicBlock *ok_block = ir_create_basic_block(irb, parent_scope, "OptionalNonNull");
37254123 IrBasicBlock *null_block = ir_create_basic_block(irb, parent_scope, "OptionalNull");
37264124 IrBasicBlock *end_block = ir_create_basic_block(irb, parent_scope, "OptionalEnd");
3727 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);
37284129
37294130 ir_set_cursor_at_end_and_append_block(irb, null_block);
3730 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);
37314133 if (null_result == irb->codegen->invalid_instruction)
37324134 return irb->codegen->invalid_instruction;
37334135 IrBasicBlock *after_null_block = irb->current_basic_block;
......@@ -3735,8 +4137,9 @@ static IrInstruction *ir_gen_orelse(IrBuilder *irb, Scope *parent_scope, AstNode
37354137 ir_mark_gen(ir_build_br(irb, parent_scope, node, end_block, is_comptime));
37364138
37374139 ir_set_cursor_at_end_and_append_block(irb, ok_block);
3738 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);
37394141 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);
37404143 IrBasicBlock *after_ok_block = irb->current_basic_block;
37414144 ir_build_br(irb, parent_scope, node, end_block, is_comptime);
37424145
......@@ -3747,7 +4150,8 @@ static IrInstruction *ir_gen_orelse(IrBuilder *irb, Scope *parent_scope, AstNode
37474150 IrBasicBlock **incoming_blocks = allocate<IrBasicBlock *>(2);
37484151 incoming_blocks[0] = after_null_block;
37494152 incoming_blocks[1] = after_ok_block;
3750 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);
37514155}
37524156
37534157static IrInstruction *ir_gen_error_union(IrBuilder *irb, Scope *parent_scope, AstNode *node) {
......@@ -3767,7 +4171,7 @@ static IrInstruction *ir_gen_error_union(IrBuilder *irb, Scope *parent_scope, As
37674171 return ir_build_error_union(irb, parent_scope, node, err_set, payload);
37684172}
37694173
3770static 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) {
37714175 assert(node->type == NodeTypeBinOpExpr);
37724176
37734177 BinOpType bin_op_type = node->data.bin_op_expr.bin_op;
......@@ -3775,87 +4179,87 @@ static IrInstruction *ir_gen_bin_op(IrBuilder *irb, Scope *scope, AstNode *node)
37754179 case BinOpTypeInvalid:
37764180 zig_unreachable();
37774181 case BinOpTypeAssign:
3778 return ir_gen_assign(irb, scope, node);
4182 return ir_lval_wrap(irb, scope, ir_gen_assign(irb, scope, node), lval, result_loc);
37794183 case BinOpTypeAssignTimes:
3780 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);
37814185 case BinOpTypeAssignTimesWrap:
3782 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);
37834187 case BinOpTypeAssignDiv:
3784 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);
37854189 case BinOpTypeAssignMod:
3786 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);
37874191 case BinOpTypeAssignPlus:
3788 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);
37894193 case BinOpTypeAssignPlusWrap:
3790 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);
37914195 case BinOpTypeAssignMinus:
3792 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);
37934197 case BinOpTypeAssignMinusWrap:
3794 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);
37954199 case BinOpTypeAssignBitShiftLeft:
3796 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);
37974201 case BinOpTypeAssignBitShiftRight:
3798 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);
37994203 case BinOpTypeAssignBitAnd:
3800 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);
38014205 case BinOpTypeAssignBitXor:
3802 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);
38034207 case BinOpTypeAssignBitOr:
3804 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);
38054209 case BinOpTypeAssignMergeErrorSets:
3806 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);
38074211 case BinOpTypeBoolOr:
3808 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);
38094213 case BinOpTypeBoolAnd:
3810 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);
38114215 case BinOpTypeCmpEq:
3812 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);
38134217 case BinOpTypeCmpNotEq:
3814 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);
38154219 case BinOpTypeCmpLessThan:
3816 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);
38174221 case BinOpTypeCmpGreaterThan:
3818 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);
38194223 case BinOpTypeCmpLessOrEq:
3820 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);
38214225 case BinOpTypeCmpGreaterOrEq:
3822 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);
38234227 case BinOpTypeBinOr:
3824 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);
38254229 case BinOpTypeBinXor:
3826 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);
38274231 case BinOpTypeBinAnd:
3828 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);
38294233 case BinOpTypeBitShiftLeft:
3830 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);
38314235 case BinOpTypeBitShiftRight:
3832 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);
38334237 case BinOpTypeAdd:
3834 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);
38354239 case BinOpTypeAddWrap:
3836 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);
38374241 case BinOpTypeSub:
3838 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);
38394243 case BinOpTypeSubWrap:
3840 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);
38414245 case BinOpTypeMult:
3842 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);
38434247 case BinOpTypeMultWrap:
3844 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);
38454249 case BinOpTypeDiv:
3846 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);
38474251 case BinOpTypeMod:
3848 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);
38494253 case BinOpTypeArrayCat:
3850 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);
38514255 case BinOpTypeArrayMult:
3852 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);
38534257 case BinOpTypeMergeErrorSets:
3854 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);
38554259 case BinOpTypeUnwrapOptional:
3856 return ir_gen_orelse(irb, scope, node);
4260 return ir_gen_orelse(irb, scope, node, lval, result_loc);
38574261 case BinOpTypeErrorUnion:
3858 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);
38594263 }
38604264 zig_unreachable();
38614265}
......@@ -3900,12 +4304,12 @@ static void populate_invalid_variable_in_scope(CodeGen *g, Scope *scope, AstNode
39004304 TldVar *tld_var = allocate<TldVar>(1);
39014305 init_tld(&tld_var->base, TldIdVar, var_name, VisibModPub, node, &scope_decls->base);
39024306 tld_var->base.resolution = TldResolutionInvalid;
3903 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,
39044308 &g->invalid_instruction->value, &tld_var->base, g->builtin_types.entry_invalid);
39054309 scope_decls->decl_table.put(var_name, &tld_var->base);
39064310}
39074311
3908static 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) {
39094313 Error err;
39104314 assert(node->type == NodeTypeSymbol);
39114315
......@@ -3939,7 +4343,7 @@ static IrInstruction *ir_gen_symbol(IrBuilder *irb, Scope *scope, AstNode *node,
39394343 if (lval == LValPtr) {
39404344 return ir_build_ref(irb, scope, node, value, false, false);
39414345 } else {
3942 return value;
4346 return ir_expr_wrap(irb, scope, value, result_loc);
39434347 }
39444348 }
39454349
......@@ -3947,15 +4351,22 @@ static IrInstruction *ir_gen_symbol(IrBuilder *irb, Scope *scope, AstNode *node,
39474351 ZigVar *var = find_variable(irb->codegen, scope, variable_name, &crossed_fndef_scope);
39484352 if (var) {
39494353 IrInstruction *var_ptr = ir_build_var_ptr_x(irb, scope, node, var, crossed_fndef_scope);
3950 if (lval == LValPtr)
4354 if (lval == LValPtr) {
39514355 return var_ptr;
3952 else
3953 return ir_build_load_ptr(irb, scope, node, var_ptr);
4356 } else {
4357 return ir_expr_wrap(irb, scope, ir_build_load_ptr(irb, scope, node, var_ptr), result_loc);
4358 }
39544359 }
39554360
39564361 Tld *tld = find_decl(irb->codegen, scope, variable_name);
3957 if (tld)
3958 return ir_build_decl_ref(irb, scope, node, tld, lval);
4362 if (tld) {
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 }
39594370
39604371 if (get_container_scope(node->owner)->any_imports_failed) {
39614372 // skip the error message since we had a failing import in this file
......@@ -3966,11 +4377,13 @@ static IrInstruction *ir_gen_symbol(IrBuilder *irb, Scope *scope, AstNode *node,
39664377 return ir_build_undeclared_identifier(irb, scope, node, variable_name);
39674378}
39684379
3969static 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{
39704383 assert(node->type == NodeTypeArrayAccessExpr);
39714384
39724385 AstNode *array_ref_node = node->data.array_access_expr.array_ref_expr;
3973 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);
39744387 if (array_ref_instruction == irb->codegen->invalid_instruction)
39754388 return array_ref_instruction;
39764389
......@@ -3980,11 +4393,12 @@ static IrInstruction *ir_gen_array_access(IrBuilder *irb, Scope *scope, AstNode
39804393 return subscript_instruction;
39814394
39824395 IrInstruction *ptr_instruction = ir_build_elem_ptr(irb, scope, node, array_ref_instruction,
3983 subscript_instruction, true, PtrLenSingle);
4396 subscript_instruction, true, PtrLenSingle, nullptr);
39844397 if (lval == LValPtr)
39854398 return ptr_instruction;
39864399
3987 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);
39884402}
39894403
39904404static IrInstruction *ir_gen_field_access(IrBuilder *irb, Scope *scope, AstNode *node) {
......@@ -3993,11 +4407,11 @@ static IrInstruction *ir_gen_field_access(IrBuilder *irb, Scope *scope, AstNode
39934407 AstNode *container_ref_node = node->data.field_access_expr.struct_expr;
39944408 Buf *field_name = node->data.field_access_expr.field_name;
39954409
3996 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);
39974411 if (container_ref_instruction == irb->codegen->invalid_instruction)
39984412 return container_ref_instruction;
39994413
4000 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);
40014415}
40024416
40034417static IrInstruction *ir_gen_overflow_op(IrBuilder *irb, Scope *scope, AstNode *node, IrOverflowOp op) {
......@@ -4028,6 +4442,33 @@ static IrInstruction *ir_gen_overflow_op(IrBuilder *irb, Scope *scope, AstNode *
40284442 return ir_build_overflow_op(irb, scope, node, op, type_value, op1, op2, result_ptr, nullptr);
40294443}
40304444
4445static IrInstruction *ir_gen_mul_add(IrBuilder *irb, Scope *scope, AstNode *node) {
4446 assert(node->type == NodeTypeFnCallExpr);
4447
4448 AstNode *type_node = node->data.fn_call_expr.params.at(0);
4449 AstNode *op1_node = node->data.fn_call_expr.params.at(1);
4450 AstNode *op2_node = node->data.fn_call_expr.params.at(2);
4451 AstNode *op3_node = node->data.fn_call_expr.params.at(3);
4452
4453 IrInstruction *type_value = ir_gen_node(irb, type_node, scope);
4454 if (type_value == irb->codegen->invalid_instruction)
4455 return irb->codegen->invalid_instruction;
4456
4457 IrInstruction *op1 = ir_gen_node(irb, op1_node, scope);
4458 if (op1 == irb->codegen->invalid_instruction)
4459 return irb->codegen->invalid_instruction;
4460
4461 IrInstruction *op2 = ir_gen_node(irb, op2_node, scope);
4462 if (op2 == irb->codegen->invalid_instruction)
4463 return irb->codegen->invalid_instruction;
4464
4465 IrInstruction *op3 = ir_gen_node(irb, op3_node, scope);
4466 if (op3 == irb->codegen->invalid_instruction)
4467 return irb->codegen->invalid_instruction;
4468
4469 return ir_build_mul_add(irb, scope, node, type_value, op1, op2, op3);
4470}
4471
40314472static IrInstruction *ir_gen_this(IrBuilder *irb, Scope *orig_scope, AstNode *node) {
40324473 for (Scope *it_scope = orig_scope; it_scope != nullptr; it_scope = it_scope->parent) {
40334474 if (it_scope->id == ScopeIdDecls) {
......@@ -4043,7 +4484,9 @@ static IrInstruction *ir_gen_this(IrBuilder *irb, Scope *orig_scope, AstNode *no
40434484 zig_unreachable();
40444485}
40454486
4046static 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{
40474490 assert(node->type == NodeTypeFnCallExpr);
40484491
40494492 AstNode *fn_ref_expr = node->data.fn_call_expr.fn_ref_expr;
......@@ -4079,7 +4522,7 @@ static IrInstruction *ir_gen_builtin_fn_call(IrBuilder *irb, Scope *scope, AstNo
40794522 return arg;
40804523
40814524 IrInstruction *type_of = ir_build_typeof(irb, scope, node, arg);
4082 return ir_lval_wrap(irb, scope, type_of, lval);
4525 return ir_lval_wrap(irb, scope, type_of, lval, result_loc);
40834526 }
40844527 case BuiltinFnIdSetCold:
40854528 {
......@@ -4089,7 +4532,7 @@ static IrInstruction *ir_gen_builtin_fn_call(IrBuilder *irb, Scope *scope, AstNo
40894532 return arg0_value;
40904533
40914534 IrInstruction *set_cold = ir_build_set_cold(irb, scope, node, arg0_value);
4092 return ir_lval_wrap(irb, scope, set_cold, lval);
4535 return ir_lval_wrap(irb, scope, set_cold, lval, result_loc);
40934536 }
40944537 case BuiltinFnIdSetRuntimeSafety:
40954538 {
......@@ -4099,7 +4542,7 @@ static IrInstruction *ir_gen_builtin_fn_call(IrBuilder *irb, Scope *scope, AstNo
40994542 return arg0_value;
41004543
41014544 IrInstruction *set_safety = ir_build_set_runtime_safety(irb, scope, node, arg0_value);
4102 return ir_lval_wrap(irb, scope, set_safety, lval);
4545 return ir_lval_wrap(irb, scope, set_safety, lval, result_loc);
41034546 }
41044547 case BuiltinFnIdSetFloatMode:
41054548 {
......@@ -4109,7 +4552,7 @@ static IrInstruction *ir_gen_builtin_fn_call(IrBuilder *irb, Scope *scope, AstNo
41094552 return arg0_value;
41104553
41114554 IrInstruction *set_float_mode = ir_build_set_float_mode(irb, scope, node, arg0_value);
4112 return ir_lval_wrap(irb, scope, set_float_mode, lval);
4555 return ir_lval_wrap(irb, scope, set_float_mode, lval, result_loc);
41134556 }
41144557 case BuiltinFnIdSizeof:
41154558 {
......@@ -4119,7 +4562,7 @@ static IrInstruction *ir_gen_builtin_fn_call(IrBuilder *irb, Scope *scope, AstNo
41194562 return arg0_value;
41204563
41214564 IrInstruction *size_of = ir_build_size_of(irb, scope, node, arg0_value);
4122 return ir_lval_wrap(irb, scope, size_of, lval);
4565 return ir_lval_wrap(irb, scope, size_of, lval, result_loc);
41234566 }
41244567 case BuiltinFnIdImport:
41254568 {
......@@ -4129,12 +4572,12 @@ static IrInstruction *ir_gen_builtin_fn_call(IrBuilder *irb, Scope *scope, AstNo
41294572 return arg0_value;
41304573
41314574 IrInstruction *import = ir_build_import(irb, scope, node, arg0_value);
4132 return ir_lval_wrap(irb, scope, import, lval);
4575 return ir_lval_wrap(irb, scope, import, lval, result_loc);
41334576 }
41344577 case BuiltinFnIdCImport:
41354578 {
41364579 IrInstruction *c_import = ir_build_c_import(irb, scope, node);
4137 return ir_lval_wrap(irb, scope, c_import, lval);
4580 return ir_lval_wrap(irb, scope, c_import, lval, result_loc);
41384581 }
41394582 case BuiltinFnIdCInclude:
41404583 {
......@@ -4149,7 +4592,7 @@ static IrInstruction *ir_gen_builtin_fn_call(IrBuilder *irb, Scope *scope, AstNo
41494592 }
41504593
41514594 IrInstruction *c_include = ir_build_c_include(irb, scope, node, arg0_value);
4152 return ir_lval_wrap(irb, scope, c_include, lval);
4595 return ir_lval_wrap(irb, scope, c_include, lval, result_loc);
41534596 }
41544597 case BuiltinFnIdCDefine:
41554598 {
......@@ -4169,7 +4612,7 @@ static IrInstruction *ir_gen_builtin_fn_call(IrBuilder *irb, Scope *scope, AstNo
41694612 }
41704613
41714614 IrInstruction *c_define = ir_build_c_define(irb, scope, node, arg0_value, arg1_value);
4172 return ir_lval_wrap(irb, scope, c_define, lval);
4615 return ir_lval_wrap(irb, scope, c_define, lval, result_loc);
41734616 }
41744617 case BuiltinFnIdCUndef:
41754618 {
......@@ -4184,7 +4627,7 @@ static IrInstruction *ir_gen_builtin_fn_call(IrBuilder *irb, Scope *scope, AstNo
41844627 }
41854628
41864629 IrInstruction *c_undef = ir_build_c_undef(irb, scope, node, arg0_value);
4187 return ir_lval_wrap(irb, scope, c_undef, lval);
4630 return ir_lval_wrap(irb, scope, c_undef, lval, result_loc);
41884631 }
41894632 case BuiltinFnIdCompileErr:
41904633 {
......@@ -4194,7 +4637,7 @@ static IrInstruction *ir_gen_builtin_fn_call(IrBuilder *irb, Scope *scope, AstNo
41944637 return arg0_value;
41954638
41964639 IrInstruction *compile_err = ir_build_compile_err(irb, scope, node, arg0_value);
4197 return ir_lval_wrap(irb, scope, compile_err, lval);
4640 return ir_lval_wrap(irb, scope, compile_err, lval, result_loc);
41984641 }
41994642 case BuiltinFnIdCompileLog:
42004643 {
......@@ -4208,7 +4651,7 @@ static IrInstruction *ir_gen_builtin_fn_call(IrBuilder *irb, Scope *scope, AstNo
42084651 }
42094652
42104653 IrInstruction *compile_log = ir_build_compile_log(irb, scope, node, actual_param_count, args);
4211 return ir_lval_wrap(irb, scope, compile_log, lval);
4654 return ir_lval_wrap(irb, scope, compile_log, lval, result_loc);
42124655 }
42134656 case BuiltinFnIdErrName:
42144657 {
......@@ -4218,7 +4661,7 @@ static IrInstruction *ir_gen_builtin_fn_call(IrBuilder *irb, Scope *scope, AstNo
42184661 return arg0_value;
42194662
42204663 IrInstruction *err_name = ir_build_err_name(irb, scope, node, arg0_value);
4221 return ir_lval_wrap(irb, scope, err_name, lval);
4664 return ir_lval_wrap(irb, scope, err_name, lval, result_loc);
42224665 }
42234666 case BuiltinFnIdEmbedFile:
42244667 {
......@@ -4228,7 +4671,7 @@ static IrInstruction *ir_gen_builtin_fn_call(IrBuilder *irb, Scope *scope, AstNo
42284671 return arg0_value;
42294672
42304673 IrInstruction *embed_file = ir_build_embed_file(irb, scope, node, arg0_value);
4231 return ir_lval_wrap(irb, scope, embed_file, lval);
4674 return ir_lval_wrap(irb, scope, embed_file, lval, result_loc);
42324675 }
42334676 case BuiltinFnIdCmpxchgWeak:
42344677 case BuiltinFnIdCmpxchgStrong:
......@@ -4264,8 +4707,9 @@ static IrInstruction *ir_gen_builtin_fn_call(IrBuilder *irb, Scope *scope, AstNo
42644707 return arg5_value;
42654708
42664709 IrInstruction *cmpxchg = ir_build_cmpxchg_src(irb, scope, node, arg0_value, arg1_value,
4267 arg2_value, arg3_value, arg4_value, arg5_value, (builtin_fn->id == BuiltinFnIdCmpxchgWeak));
4268 return ir_lval_wrap(irb, scope, cmpxchg, lval);
4710 arg2_value, arg3_value, arg4_value, arg5_value, (builtin_fn->id == BuiltinFnIdCmpxchgWeak),
4711 result_loc);
4712 return ir_lval_wrap(irb, scope, cmpxchg, lval, result_loc);
42694713 }
42704714 case BuiltinFnIdFence:
42714715 {
......@@ -4275,7 +4719,7 @@ static IrInstruction *ir_gen_builtin_fn_call(IrBuilder *irb, Scope *scope, AstNo
42754719 return arg0_value;
42764720
42774721 IrInstruction *fence = ir_build_fence(irb, scope, node, arg0_value, AtomicOrderUnordered);
4278 return ir_lval_wrap(irb, scope, fence, lval);
4722 return ir_lval_wrap(irb, scope, fence, lval, result_loc);
42794723 }
42804724 case BuiltinFnIdDivExact:
42814725 {
......@@ -4290,7 +4734,7 @@ static IrInstruction *ir_gen_builtin_fn_call(IrBuilder *irb, Scope *scope, AstNo
42904734 return arg1_value;
42914735
42924736 IrInstruction *bin_op = ir_build_bin_op(irb, scope, node, IrBinOpDivExact, arg0_value, arg1_value, true);
4293 return ir_lval_wrap(irb, scope, bin_op, lval);
4737 return ir_lval_wrap(irb, scope, bin_op, lval, result_loc);
42944738 }
42954739 case BuiltinFnIdDivTrunc:
42964740 {
......@@ -4305,7 +4749,7 @@ static IrInstruction *ir_gen_builtin_fn_call(IrBuilder *irb, Scope *scope, AstNo
43054749 return arg1_value;
43064750
43074751 IrInstruction *bin_op = ir_build_bin_op(irb, scope, node, IrBinOpDivTrunc, arg0_value, arg1_value, true);
4308 return ir_lval_wrap(irb, scope, bin_op, lval);
4752 return ir_lval_wrap(irb, scope, bin_op, lval, result_loc);
43094753 }
43104754 case BuiltinFnIdDivFloor:
43114755 {
......@@ -4320,7 +4764,7 @@ static IrInstruction *ir_gen_builtin_fn_call(IrBuilder *irb, Scope *scope, AstNo
43204764 return arg1_value;
43214765
43224766 IrInstruction *bin_op = ir_build_bin_op(irb, scope, node, IrBinOpDivFloor, arg0_value, arg1_value, true);
4323 return ir_lval_wrap(irb, scope, bin_op, lval);
4767 return ir_lval_wrap(irb, scope, bin_op, lval, result_loc);
43244768 }
43254769 case BuiltinFnIdRem:
43264770 {
......@@ -4335,7 +4779,7 @@ static IrInstruction *ir_gen_builtin_fn_call(IrBuilder *irb, Scope *scope, AstNo
43354779 return arg1_value;
43364780
43374781 IrInstruction *bin_op = ir_build_bin_op(irb, scope, node, IrBinOpRemRem, arg0_value, arg1_value, true);
4338 return ir_lval_wrap(irb, scope, bin_op, lval);
4782 return ir_lval_wrap(irb, scope, bin_op, lval, result_loc);
43394783 }
43404784 case BuiltinFnIdMod:
43414785 {
......@@ -4350,9 +4794,22 @@ static IrInstruction *ir_gen_builtin_fn_call(IrBuilder *irb, Scope *scope, AstNo
43504794 return arg1_value;
43514795
43524796 IrInstruction *bin_op = ir_build_bin_op(irb, scope, node, IrBinOpRemMod, arg0_value, arg1_value, true);
4353 return ir_lval_wrap(irb, scope, bin_op, lval);
4797 return ir_lval_wrap(irb, scope, bin_op, lval, result_loc);
43544798 }
43554799 case BuiltinFnIdSqrt:
4800 case BuiltinFnIdSin:
4801 case BuiltinFnIdCos:
4802 case BuiltinFnIdExp:
4803 case BuiltinFnIdExp2:
4804 case BuiltinFnIdLn:
4805 case BuiltinFnIdLog2:
4806 case BuiltinFnIdLog10:
4807 case BuiltinFnIdFabs:
4808 case BuiltinFnIdFloor:
4809 case BuiltinFnIdCeil:
4810 case BuiltinFnIdTrunc:
4811 case BuiltinFnIdNearbyInt:
4812 case BuiltinFnIdRound:
43564813 {
43574814 AstNode *arg0_node = node->data.fn_call_expr.params.at(0);
43584815 IrInstruction *arg0_value = ir_gen_node(irb, arg0_node, scope);
......@@ -4364,8 +4821,8 @@ static IrInstruction *ir_gen_builtin_fn_call(IrBuilder *irb, Scope *scope, AstNo
43644821 if (arg1_value == irb->codegen->invalid_instruction)
43654822 return arg1_value;
43664823
4367 IrInstruction *ir_sqrt = ir_build_sqrt(irb, scope, node, arg0_value, arg1_value);
4368 return ir_lval_wrap(irb, scope, ir_sqrt, lval);
4824 IrInstruction *ir_sqrt = ir_build_float_op(irb, scope, node, arg0_value, arg1_value, builtin_fn->id);
4825 return ir_lval_wrap(irb, scope, ir_sqrt, lval, result_loc);
43694826 }
43704827 case BuiltinFnIdTruncate:
43714828 {
......@@ -4380,7 +4837,7 @@ static IrInstruction *ir_gen_builtin_fn_call(IrBuilder *irb, Scope *scope, AstNo
43804837 return arg1_value;
43814838
43824839 IrInstruction *truncate = ir_build_truncate(irb, scope, node, arg0_value, arg1_value);
4383 return ir_lval_wrap(irb, scope, truncate, lval);
4840 return ir_lval_wrap(irb, scope, truncate, lval, result_loc);
43844841 }
43854842 case BuiltinFnIdIntCast:
43864843 {
......@@ -4395,7 +4852,7 @@ static IrInstruction *ir_gen_builtin_fn_call(IrBuilder *irb, Scope *scope, AstNo
43954852 return arg1_value;
43964853
43974854 IrInstruction *result = ir_build_int_cast(irb, scope, node, arg0_value, arg1_value);
4398 return ir_lval_wrap(irb, scope, result, lval);
4855 return ir_lval_wrap(irb, scope, result, lval, result_loc);
43994856 }
44004857 case BuiltinFnIdFloatCast:
44014858 {
......@@ -4410,7 +4867,7 @@ static IrInstruction *ir_gen_builtin_fn_call(IrBuilder *irb, Scope *scope, AstNo
44104867 return arg1_value;
44114868
44124869 IrInstruction *result = ir_build_float_cast(irb, scope, node, arg0_value, arg1_value);
4413 return ir_lval_wrap(irb, scope, result, lval);
4870 return ir_lval_wrap(irb, scope, result, lval, result_loc);
44144871 }
44154872 case BuiltinFnIdErrSetCast:
44164873 {
......@@ -4425,7 +4882,7 @@ static IrInstruction *ir_gen_builtin_fn_call(IrBuilder *irb, Scope *scope, AstNo
44254882 return arg1_value;
44264883
44274884 IrInstruction *result = ir_build_err_set_cast(irb, scope, node, arg0_value, arg1_value);
4428 return ir_lval_wrap(irb, scope, result, lval);
4885 return ir_lval_wrap(irb, scope, result, lval, result_loc);
44294886 }
44304887 case BuiltinFnIdFromBytes:
44314888 {
......@@ -4439,8 +4896,8 @@ static IrInstruction *ir_gen_builtin_fn_call(IrBuilder *irb, Scope *scope, AstNo
44394896 if (arg1_value == irb->codegen->invalid_instruction)
44404897 return arg1_value;
44414898
4442 IrInstruction *result = ir_build_from_bytes(irb, scope, node, arg0_value, arg1_value);
4443 return ir_lval_wrap(irb, scope, result, lval);
4899 IrInstruction *result = ir_build_from_bytes(irb, scope, node, arg0_value, arg1_value, result_loc);
4900 return ir_lval_wrap(irb, scope, result, lval, result_loc);
44444901 }
44454902 case BuiltinFnIdToBytes:
44464903 {
......@@ -4449,8 +4906,8 @@ static IrInstruction *ir_gen_builtin_fn_call(IrBuilder *irb, Scope *scope, AstNo
44494906 if (arg0_value == irb->codegen->invalid_instruction)
44504907 return arg0_value;
44514908
4452 IrInstruction *result = ir_build_to_bytes(irb, scope, node, arg0_value);
4453 return ir_lval_wrap(irb, scope, result, lval);
4909 IrInstruction *result = ir_build_to_bytes(irb, scope, node, arg0_value, result_loc);
4910 return ir_lval_wrap(irb, scope, result, lval, result_loc);
44544911 }
44554912 case BuiltinFnIdIntToFloat:
44564913 {
......@@ -4465,7 +4922,7 @@ static IrInstruction *ir_gen_builtin_fn_call(IrBuilder *irb, Scope *scope, AstNo
44654922 return arg1_value;
44664923
44674924 IrInstruction *result = ir_build_int_to_float(irb, scope, node, arg0_value, arg1_value);
4468 return ir_lval_wrap(irb, scope, result, lval);
4925 return ir_lval_wrap(irb, scope, result, lval, result_loc);
44694926 }
44704927 case BuiltinFnIdFloatToInt:
44714928 {
......@@ -4480,7 +4937,7 @@ static IrInstruction *ir_gen_builtin_fn_call(IrBuilder *irb, Scope *scope, AstNo
44804937 return arg1_value;
44814938
44824939 IrInstruction *result = ir_build_float_to_int(irb, scope, node, arg0_value, arg1_value);
4483 return ir_lval_wrap(irb, scope, result, lval);
4940 return ir_lval_wrap(irb, scope, result, lval, result_loc);
44844941 }
44854942 case BuiltinFnIdErrToInt:
44864943 {
......@@ -4490,7 +4947,7 @@ static IrInstruction *ir_gen_builtin_fn_call(IrBuilder *irb, Scope *scope, AstNo
44904947 return arg0_value;
44914948
44924949 IrInstruction *result = ir_build_err_to_int(irb, scope, node, arg0_value);
4493 return ir_lval_wrap(irb, scope, result, lval);
4950 return ir_lval_wrap(irb, scope, result, lval, result_loc);
44944951 }
44954952 case BuiltinFnIdIntToErr:
44964953 {
......@@ -4500,7 +4957,7 @@ static IrInstruction *ir_gen_builtin_fn_call(IrBuilder *irb, Scope *scope, AstNo
45004957 return arg0_value;
45014958
45024959 IrInstruction *result = ir_build_int_to_err(irb, scope, node, arg0_value);
4503 return ir_lval_wrap(irb, scope, result, lval);
4960 return ir_lval_wrap(irb, scope, result, lval, result_loc);
45044961 }
45054962 case BuiltinFnIdBoolToInt:
45064963 {
......@@ -4510,7 +4967,7 @@ static IrInstruction *ir_gen_builtin_fn_call(IrBuilder *irb, Scope *scope, AstNo
45104967 return arg0_value;
45114968
45124969 IrInstruction *result = ir_build_bool_to_int(irb, scope, node, arg0_value);
4513 return ir_lval_wrap(irb, scope, result, lval);
4970 return ir_lval_wrap(irb, scope, result, lval, result_loc);
45144971 }
45154972 case BuiltinFnIdIntType:
45164973 {
......@@ -4525,7 +4982,7 @@ static IrInstruction *ir_gen_builtin_fn_call(IrBuilder *irb, Scope *scope, AstNo
45254982 return arg1_value;
45264983
45274984 IrInstruction *int_type = ir_build_int_type(irb, scope, node, arg0_value, arg1_value);
4528 return ir_lval_wrap(irb, scope, int_type, lval);
4985 return ir_lval_wrap(irb, scope, int_type, lval, result_loc);
45294986 }
45304987 case BuiltinFnIdVectorType:
45314988 {
......@@ -4540,7 +4997,7 @@ static IrInstruction *ir_gen_builtin_fn_call(IrBuilder *irb, Scope *scope, AstNo
45404997 return arg1_value;
45414998
45424999 IrInstruction *vector_type = ir_build_vector_type(irb, scope, node, arg0_value, arg1_value);
4543 return ir_lval_wrap(irb, scope, vector_type, lval);
5000 return ir_lval_wrap(irb, scope, vector_type, lval, result_loc);
45445001 }
45455002 case BuiltinFnIdMemcpy:
45465003 {
......@@ -4560,7 +5017,7 @@ static IrInstruction *ir_gen_builtin_fn_call(IrBuilder *irb, Scope *scope, AstNo
45605017 return arg2_value;
45615018
45625019 IrInstruction *ir_memcpy = ir_build_memcpy(irb, scope, node, arg0_value, arg1_value, arg2_value);
4563 return ir_lval_wrap(irb, scope, ir_memcpy, lval);
5020 return ir_lval_wrap(irb, scope, ir_memcpy, lval, result_loc);
45645021 }
45655022 case BuiltinFnIdMemset:
45665023 {
......@@ -4580,7 +5037,7 @@ static IrInstruction *ir_gen_builtin_fn_call(IrBuilder *irb, Scope *scope, AstNo
45805037 return arg2_value;
45815038
45825039 IrInstruction *ir_memset = ir_build_memset(irb, scope, node, arg0_value, arg1_value, arg2_value);
4583 return ir_lval_wrap(irb, scope, ir_memset, lval);
5040 return ir_lval_wrap(irb, scope, ir_memset, lval, result_loc);
45845041 }
45855042 case BuiltinFnIdMemberCount:
45865043 {
......@@ -4590,7 +5047,7 @@ static IrInstruction *ir_gen_builtin_fn_call(IrBuilder *irb, Scope *scope, AstNo
45905047 return arg0_value;
45915048
45925049 IrInstruction *member_count = ir_build_member_count(irb, scope, node, arg0_value);
4593 return ir_lval_wrap(irb, scope, member_count, lval);
5050 return ir_lval_wrap(irb, scope, member_count, lval, result_loc);
45945051 }
45955052 case BuiltinFnIdMemberType:
45965053 {
......@@ -4606,7 +5063,7 @@ static IrInstruction *ir_gen_builtin_fn_call(IrBuilder *irb, Scope *scope, AstNo
46065063
46075064
46085065 IrInstruction *member_type = ir_build_member_type(irb, scope, node, arg0_value, arg1_value);
4609 return ir_lval_wrap(irb, scope, member_type, lval);
5066 return ir_lval_wrap(irb, scope, member_type, lval, result_loc);
46105067 }
46115068 case BuiltinFnIdMemberName:
46125069 {
......@@ -4622,12 +5079,12 @@ static IrInstruction *ir_gen_builtin_fn_call(IrBuilder *irb, Scope *scope, AstNo
46225079
46235080
46245081 IrInstruction *member_name = ir_build_member_name(irb, scope, node, arg0_value, arg1_value);
4625 return ir_lval_wrap(irb, scope, member_name, lval);
5082 return ir_lval_wrap(irb, scope, member_name, lval, result_loc);
46265083 }
46275084 case BuiltinFnIdField:
46285085 {
46295086 AstNode *arg0_node = node->data.fn_call_expr.params.at(0);
4630 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);
46315088 if (arg0_value == irb->codegen->invalid_instruction)
46325089 return arg0_value;
46335090
......@@ -4641,7 +5098,8 @@ static IrInstruction *ir_gen_builtin_fn_call(IrBuilder *irb, Scope *scope, AstNo
46415098 if (lval == LValPtr)
46425099 return ptr_instruction;
46435100
4644 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);
46455103 }
46465104 case BuiltinFnIdTypeInfo:
46475105 {
......@@ -4651,14 +5109,14 @@ static IrInstruction *ir_gen_builtin_fn_call(IrBuilder *irb, Scope *scope, AstNo
46515109 return arg0_value;
46525110
46535111 IrInstruction *type_info = ir_build_type_info(irb, scope, node, arg0_value);
4654 return ir_lval_wrap(irb, scope, type_info, lval);
5112 return ir_lval_wrap(irb, scope, type_info, lval, result_loc);
46555113 }
46565114 case BuiltinFnIdBreakpoint:
4657 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);
46585116 case BuiltinFnIdReturnAddress:
4659 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);
46605118 case BuiltinFnIdFrameAddress:
4661 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);
46625120 case BuiltinFnIdHandle:
46635121 if (!irb->exec->fn_entry) {
46645122 add_node_error(irb->codegen, node, buf_sprintf("@handle() called outside of function definition"));
......@@ -4668,7 +5126,7 @@ static IrInstruction *ir_gen_builtin_fn_call(IrBuilder *irb, Scope *scope, AstNo
46685126 add_node_error(irb->codegen, node, buf_sprintf("@handle() in non-async function"));
46695127 return irb->codegen->invalid_instruction;
46705128 }
4671 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);
46725130 case BuiltinFnIdAlignOf:
46735131 {
46745132 AstNode *arg0_node = node->data.fn_call_expr.params.at(0);
......@@ -4677,16 +5135,18 @@ static IrInstruction *ir_gen_builtin_fn_call(IrBuilder *irb, Scope *scope, AstNo
46775135 return arg0_value;
46785136
46795137 IrInstruction *align_of = ir_build_align_of(irb, scope, node, arg0_value);
4680 return ir_lval_wrap(irb, scope, align_of, lval);
5138 return ir_lval_wrap(irb, scope, align_of, lval, result_loc);
46815139 }
46825140 case BuiltinFnIdAddWithOverflow:
4683 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);
46845142 case BuiltinFnIdSubWithOverflow:
4685 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);
46865144 case BuiltinFnIdMulWithOverflow:
4687 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);
46885146 case BuiltinFnIdShlWithOverflow:
4689 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);
5148 case BuiltinFnIdMulAdd:
5149 return ir_lval_wrap(irb, scope, ir_gen_mul_add(irb, scope, node), lval, result_loc);
46905150 case BuiltinFnIdTypeName:
46915151 {
46925152 AstNode *arg0_node = node->data.fn_call_expr.params.at(0);
......@@ -4695,7 +5155,7 @@ static IrInstruction *ir_gen_builtin_fn_call(IrBuilder *irb, Scope *scope, AstNo
46955155 return arg0_value;
46965156
46975157 IrInstruction *type_name = ir_build_type_name(irb, scope, node, arg0_value);
4698 return ir_lval_wrap(irb, scope, type_name, lval);
5158 return ir_lval_wrap(irb, scope, type_name, lval, result_loc);
46995159 }
47005160 case BuiltinFnIdPanic:
47015161 {
......@@ -4705,7 +5165,7 @@ static IrInstruction *ir_gen_builtin_fn_call(IrBuilder *irb, Scope *scope, AstNo
47055165 return arg0_value;
47065166
47075167 IrInstruction *panic = ir_build_panic(irb, scope, node, arg0_value);
4708 return ir_lval_wrap(irb, scope, panic, lval);
5168 return ir_lval_wrap(irb, scope, panic, lval, result_loc);
47095169 }
47105170 case BuiltinFnIdPtrCast:
47115171 {
......@@ -4720,22 +5180,31 @@ static IrInstruction *ir_gen_builtin_fn_call(IrBuilder *irb, Scope *scope, AstNo
47205180 return arg1_value;
47215181
47225182 IrInstruction *ptr_cast = ir_build_ptr_cast_src(irb, scope, node, arg0_value, arg1_value, true);
4723 return ir_lval_wrap(irb, scope, ptr_cast, lval);
5183 return ir_lval_wrap(irb, scope, ptr_cast, lval, result_loc);
47245184 }
47255185 case BuiltinFnIdBitCast:
47265186 {
4727 AstNode *arg0_node = node->data.fn_call_expr.params.at(0);
4728 IrInstruction *arg0_value = ir_gen_node(irb, arg0_node, scope);
4729 if (arg0_value == irb->codegen->invalid_instruction)
4730 return arg0_value;
5187 AstNode *dest_type_node = node->data.fn_call_expr.params.at(0);
5188 IrInstruction *dest_type = ir_gen_node(irb, dest_type_node, scope);
5189 if (dest_type == irb->codegen->invalid_instruction)
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);
47315199
47325200 AstNode *arg1_node = node->data.fn_call_expr.params.at(1);
4733 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);
47345203 if (arg1_value == irb->codegen->invalid_instruction)
47355204 return arg1_value;
47365205
4737 IrInstruction *bit_cast = ir_build_bit_cast(irb, scope, node, arg0_value, arg1_value);
4738 return ir_lval_wrap(irb, scope, bit_cast, lval);
5206 IrInstruction *bitcast = ir_build_bit_cast_src(irb, scope, arg1_node, arg1_value, result_loc_bit_cast);
5207 return ir_lval_wrap(irb, scope, bitcast, lval, result_loc);
47395208 }
47405209 case BuiltinFnIdIntToPtr:
47415210 {
......@@ -4750,7 +5219,7 @@ static IrInstruction *ir_gen_builtin_fn_call(IrBuilder *irb, Scope *scope, AstNo
47505219 return arg1_value;
47515220
47525221 IrInstruction *int_to_ptr = ir_build_int_to_ptr(irb, scope, node, arg0_value, arg1_value);
4753 return ir_lval_wrap(irb, scope, int_to_ptr, lval);
5222 return ir_lval_wrap(irb, scope, int_to_ptr, lval, result_loc);
47545223 }
47555224 case BuiltinFnIdPtrToInt:
47565225 {
......@@ -4760,7 +5229,7 @@ static IrInstruction *ir_gen_builtin_fn_call(IrBuilder *irb, Scope *scope, AstNo
47605229 return arg0_value;
47615230
47625231 IrInstruction *ptr_to_int = ir_build_ptr_to_int(irb, scope, node, arg0_value);
4763 return ir_lval_wrap(irb, scope, ptr_to_int, lval);
5232 return ir_lval_wrap(irb, scope, ptr_to_int, lval, result_loc);
47645233 }
47655234 case BuiltinFnIdTagName:
47665235 {
......@@ -4771,7 +5240,7 @@ static IrInstruction *ir_gen_builtin_fn_call(IrBuilder *irb, Scope *scope, AstNo
47715240
47725241 IrInstruction *actual_tag = ir_build_union_tag(irb, scope, node, arg0_value);
47735242 IrInstruction *tag_name = ir_build_tag_name(irb, scope, node, actual_tag);
4774 return ir_lval_wrap(irb, scope, tag_name, lval);
5243 return ir_lval_wrap(irb, scope, tag_name, lval, result_loc);
47755244 }
47765245 case BuiltinFnIdTagType:
47775246 {
......@@ -4781,7 +5250,7 @@ static IrInstruction *ir_gen_builtin_fn_call(IrBuilder *irb, Scope *scope, AstNo
47815250 return arg0_value;
47825251
47835252 IrInstruction *tag_type = ir_build_tag_type(irb, scope, node, arg0_value);
4784 return ir_lval_wrap(irb, scope, tag_type, lval);
5253 return ir_lval_wrap(irb, scope, tag_type, lval, result_loc);
47855254 }
47865255 case BuiltinFnIdFieldParentPtr:
47875256 {
......@@ -4801,7 +5270,7 @@ static IrInstruction *ir_gen_builtin_fn_call(IrBuilder *irb, Scope *scope, AstNo
48015270 return arg2_value;
48025271
48035272 IrInstruction *field_parent_ptr = ir_build_field_parent_ptr(irb, scope, node, arg0_value, arg1_value, arg2_value, nullptr);
4804 return ir_lval_wrap(irb, scope, field_parent_ptr, lval);
5273 return ir_lval_wrap(irb, scope, field_parent_ptr, lval, result_loc);
48055274 }
48065275 case BuiltinFnIdByteOffsetOf:
48075276 {
......@@ -4816,7 +5285,7 @@ static IrInstruction *ir_gen_builtin_fn_call(IrBuilder *irb, Scope *scope, AstNo
48165285 return arg1_value;
48175286
48185287 IrInstruction *offset_of = ir_build_byte_offset_of(irb, scope, node, arg0_value, arg1_value);
4819 return ir_lval_wrap(irb, scope, offset_of, lval);
5288 return ir_lval_wrap(irb, scope, offset_of, lval, result_loc);
48205289 }
48215290 case BuiltinFnIdBitOffsetOf:
48225291 {
......@@ -4831,7 +5300,7 @@ static IrInstruction *ir_gen_builtin_fn_call(IrBuilder *irb, Scope *scope, AstNo
48315300 return arg1_value;
48325301
48335302 IrInstruction *offset_of = ir_build_bit_offset_of(irb, scope, node, arg0_value, arg1_value);
4834 return ir_lval_wrap(irb, scope, offset_of, lval);
5303 return ir_lval_wrap(irb, scope, offset_of, lval, result_loc);
48355304 }
48365305 case BuiltinFnIdInlineCall:
48375306 case BuiltinFnIdNoInlineCall:
......@@ -4857,8 +5326,9 @@ static IrInstruction *ir_gen_builtin_fn_call(IrBuilder *irb, Scope *scope, AstNo
48575326 }
48585327 FnInline fn_inline = (builtin_fn->id == BuiltinFnIdInlineCall) ? FnInlineAlways : FnInlineNever;
48595328
4860 IrInstruction *call = ir_build_call(irb, scope, node, nullptr, fn_ref, arg_count, args, false, fn_inline, false, nullptr, nullptr);
4861 return ir_lval_wrap(irb, scope, call, lval);
5329 IrInstruction *call = ir_build_call_src(irb, scope, node, nullptr, fn_ref, arg_count, args, false,
5330 fn_inline, false, nullptr, nullptr, result_loc);
5331 return ir_lval_wrap(irb, scope, call, lval, result_loc);
48625332 }
48635333 case BuiltinFnIdNewStackCall:
48645334 {
......@@ -4887,8 +5357,9 @@ static IrInstruction *ir_gen_builtin_fn_call(IrBuilder *irb, Scope *scope, AstNo
48875357 return args[i];
48885358 }
48895359
4890 IrInstruction *call = ir_build_call(irb, scope, node, nullptr, fn_ref, arg_count, args, false, FnInlineAuto, false, nullptr, new_stack);
4891 return ir_lval_wrap(irb, scope, call, lval);
5360 IrInstruction *call = ir_build_call_src(irb, scope, node, nullptr, fn_ref, arg_count, args, false,
5361 FnInlineAuto, false, nullptr, new_stack, result_loc);
5362 return ir_lval_wrap(irb, scope, call, lval, result_loc);
48925363 }
48935364 case BuiltinFnIdTypeId:
48945365 {
......@@ -4898,7 +5369,7 @@ static IrInstruction *ir_gen_builtin_fn_call(IrBuilder *irb, Scope *scope, AstNo
48985369 return arg0_value;
48995370
49005371 IrInstruction *type_id = ir_build_type_id(irb, scope, node, arg0_value);
4901 return ir_lval_wrap(irb, scope, type_id, lval);
5372 return ir_lval_wrap(irb, scope, type_id, lval, result_loc);
49025373 }
49035374 case BuiltinFnIdShlExact:
49045375 {
......@@ -4913,7 +5384,7 @@ static IrInstruction *ir_gen_builtin_fn_call(IrBuilder *irb, Scope *scope, AstNo
49135384 return arg1_value;
49145385
49155386 IrInstruction *bin_op = ir_build_bin_op(irb, scope, node, IrBinOpBitShiftLeftExact, arg0_value, arg1_value, true);
4916 return ir_lval_wrap(irb, scope, bin_op, lval);
5387 return ir_lval_wrap(irb, scope, bin_op, lval, result_loc);
49175388 }
49185389 case BuiltinFnIdShrExact:
49195390 {
......@@ -4928,7 +5399,7 @@ static IrInstruction *ir_gen_builtin_fn_call(IrBuilder *irb, Scope *scope, AstNo
49285399 return arg1_value;
49295400
49305401 IrInstruction *bin_op = ir_build_bin_op(irb, scope, node, IrBinOpBitShiftRightExact, arg0_value, arg1_value, true);
4931 return ir_lval_wrap(irb, scope, bin_op, lval);
5402 return ir_lval_wrap(irb, scope, bin_op, lval, result_loc);
49325403 }
49335404 case BuiltinFnIdSetEvalBranchQuota:
49345405 {
......@@ -4938,7 +5409,7 @@ static IrInstruction *ir_gen_builtin_fn_call(IrBuilder *irb, Scope *scope, AstNo
49385409 return arg0_value;
49395410
49405411 IrInstruction *set_eval_branch_quota = ir_build_set_eval_branch_quota(irb, scope, node, arg0_value);
4941 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);
49425413 }
49435414 case BuiltinFnIdAlignCast:
49445415 {
......@@ -4953,17 +5424,17 @@ static IrInstruction *ir_gen_builtin_fn_call(IrBuilder *irb, Scope *scope, AstNo
49535424 return arg1_value;
49545425
49555426 IrInstruction *align_cast = ir_build_align_cast(irb, scope, node, arg0_value, arg1_value);
4956 return ir_lval_wrap(irb, scope, align_cast, lval);
5427 return ir_lval_wrap(irb, scope, align_cast, lval, result_loc);
49575428 }
49585429 case BuiltinFnIdOpaqueType:
49595430 {
49605431 IrInstruction *opaque_type = ir_build_opaque_type(irb, scope, node);
4961 return ir_lval_wrap(irb, scope, opaque_type, lval);
5432 return ir_lval_wrap(irb, scope, opaque_type, lval, result_loc);
49625433 }
49635434 case BuiltinFnIdThis:
49645435 {
49655436 IrInstruction *this_inst = ir_gen_this(irb, scope, node);
4966 return ir_lval_wrap(irb, scope, this_inst, lval);
5437 return ir_lval_wrap(irb, scope, this_inst, lval, result_loc);
49675438 }
49685439 case BuiltinFnIdSetAlignStack:
49695440 {
......@@ -4973,7 +5444,7 @@ static IrInstruction *ir_gen_builtin_fn_call(IrBuilder *irb, Scope *scope, AstNo
49735444 return arg0_value;
49745445
49755446 IrInstruction *set_align_stack = ir_build_set_align_stack(irb, scope, node, arg0_value);
4976 return ir_lval_wrap(irb, scope, set_align_stack, lval);
5447 return ir_lval_wrap(irb, scope, set_align_stack, lval, result_loc);
49775448 }
49785449 case BuiltinFnIdArgType:
49795450 {
......@@ -4988,7 +5459,7 @@ static IrInstruction *ir_gen_builtin_fn_call(IrBuilder *irb, Scope *scope, AstNo
49885459 return arg1_value;
49895460
49905461 IrInstruction *arg_type = ir_build_arg_type(irb, scope, node, arg0_value, arg1_value);
4991 return ir_lval_wrap(irb, scope, arg_type, lval);
5462 return ir_lval_wrap(irb, scope, arg_type, lval, result_loc);
49925463 }
49935464 case BuiltinFnIdExport:
49945465 {
......@@ -5008,12 +5479,12 @@ static IrInstruction *ir_gen_builtin_fn_call(IrBuilder *irb, Scope *scope, AstNo
50085479 return arg2_value;
50095480
50105481 IrInstruction *ir_export = ir_build_export(irb, scope, node, arg0_value, arg1_value, arg2_value);
5011 return ir_lval_wrap(irb, scope, ir_export, lval);
5482 return ir_lval_wrap(irb, scope, ir_export, lval, result_loc);
50125483 }
50135484 case BuiltinFnIdErrorReturnTrace:
50145485 {
50155486 IrInstruction *error_return_trace = ir_build_error_return_trace(irb, scope, node, IrInstructionErrorReturnTrace::Null);
5016 return ir_lval_wrap(irb, scope, error_return_trace, lval);
5487 return ir_lval_wrap(irb, scope, error_return_trace, lval, result_loc);
50175488 }
50185489 case BuiltinFnIdAtomicRmw:
50195490 {
......@@ -5042,10 +5513,11 @@ static IrInstruction *ir_gen_builtin_fn_call(IrBuilder *irb, Scope *scope, AstNo
50425513 if (arg4_value == irb->codegen->invalid_instruction)
50435514 return arg4_value;
50445515
5045 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,
50465517 arg4_value,
50475518 // these 2 values don't mean anything since we passed non-null values for other args
50485519 AtomicRmwOp_xchg, AtomicOrderMonotonic);
5520 return ir_lval_wrap(irb, scope, inst, lval, result_loc);
50495521 }
50505522 case BuiltinFnIdAtomicLoad:
50515523 {
......@@ -5064,9 +5536,10 @@ static IrInstruction *ir_gen_builtin_fn_call(IrBuilder *irb, Scope *scope, AstNo
50645536 if (arg2_value == irb->codegen->invalid_instruction)
50655537 return arg2_value;
50665538
5067 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,
50685540 // this value does not mean anything since we passed non-null values for other arg
50695541 AtomicOrderMonotonic);
5542 return ir_lval_wrap(irb, scope, inst, lval, result_loc);
50705543 }
50715544 case BuiltinFnIdIntToEnum:
50725545 {
......@@ -5081,7 +5554,7 @@ static IrInstruction *ir_gen_builtin_fn_call(IrBuilder *irb, Scope *scope, AstNo
50815554 return arg1_value;
50825555
50835556 IrInstruction *result = ir_build_int_to_enum(irb, scope, node, arg0_value, arg1_value);
5084 return ir_lval_wrap(irb, scope, result, lval);
5557 return ir_lval_wrap(irb, scope, result, lval, result_loc);
50855558 }
50865559 case BuiltinFnIdEnumToInt:
50875560 {
......@@ -5091,7 +5564,7 @@ static IrInstruction *ir_gen_builtin_fn_call(IrBuilder *irb, Scope *scope, AstNo
50915564 return arg0_value;
50925565
50935566 IrInstruction *result = ir_build_enum_to_int(irb, scope, node, arg0_value);
5094 return ir_lval_wrap(irb, scope, result, lval);
5567 return ir_lval_wrap(irb, scope, result, lval, result_loc);
50955568 }
50965569 case BuiltinFnIdCtz:
50975570 case BuiltinFnIdPopCount:
......@@ -5129,7 +5602,7 @@ static IrInstruction *ir_gen_builtin_fn_call(IrBuilder *irb, Scope *scope, AstNo
51295602 default:
51305603 zig_unreachable();
51315604 }
5132 return ir_lval_wrap(irb, scope, result, lval);
5605 return ir_lval_wrap(irb, scope, result, lval, result_loc);
51335606 }
51345607 case BuiltinFnIdHasDecl:
51355608 {
......@@ -5144,17 +5617,19 @@ static IrInstruction *ir_gen_builtin_fn_call(IrBuilder *irb, Scope *scope, AstNo
51445617 return arg1_value;
51455618
51465619 IrInstruction *has_decl = ir_build_has_decl(irb, scope, node, arg0_value, arg1_value);
5147 return ir_lval_wrap(irb, scope, has_decl, lval);
5620 return ir_lval_wrap(irb, scope, has_decl, lval, result_loc);
51485621 }
51495622 }
51505623 zig_unreachable();
51515624}
51525625
5153static 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{
51545629 assert(node->type == NodeTypeFnCallExpr);
51555630
51565631 if (node->data.fn_call_expr.is_builtin)
5157 return ir_gen_builtin_fn_call(irb, scope, node, lval);
5632 return ir_gen_builtin_fn_call(irb, scope, node, lval, result_loc);
51585633
51595634 AstNode *fn_ref_node = node->data.fn_call_expr.fn_ref_expr;
51605635 IrInstruction *fn_ref = ir_gen_node(irb, fn_ref_node, scope);
......@@ -5180,12 +5655,14 @@ static IrInstruction *ir_gen_fn_call(IrBuilder *irb, Scope *scope, AstNode *node
51805655 }
51815656 }
51825657
5183 IrInstruction *fn_call = ir_build_call(irb, scope, node, nullptr, fn_ref, arg_count, args, false, FnInlineAuto,
5184 is_async, async_allocator, nullptr);
5185 return ir_lval_wrap(irb, scope, fn_call, lval);
5658 IrInstruction *fn_call = ir_build_call_src(irb, scope, node, nullptr, fn_ref, arg_count, args, false, FnInlineAuto,
5659 is_async, async_allocator, nullptr, result_loc);
5660 return ir_lval_wrap(irb, scope, fn_call, lval, result_loc);
51865661}
51875662
5188static 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{
51895666 assert(node->type == NodeTypeIfBoolExpr);
51905667
51915668 IrInstruction *condition = ir_gen_node(irb, node->data.if_bool_expr.condition, scope);
......@@ -5206,12 +5683,16 @@ static IrInstruction *ir_gen_if_bool_expr(IrBuilder *irb, Scope *scope, AstNode
52065683 IrBasicBlock *else_block = ir_create_basic_block(irb, scope, "Else");
52075684 IrBasicBlock *endif_block = ir_create_basic_block(irb, scope, "EndIf");
52085685
5209 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);
52105690
52115691 ir_set_cursor_at_end_and_append_block(irb, then_block);
52125692
52135693 Scope *subexpr_scope = create_runtime_scope(irb->codegen, node, scope, is_comptime);
5214 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);
52155696 if (then_expr_result == irb->codegen->invalid_instruction)
52165697 return irb->codegen->invalid_instruction;
52175698 IrBasicBlock *after_then_block = irb->current_basic_block;
......@@ -5221,11 +5702,12 @@ static IrInstruction *ir_gen_if_bool_expr(IrBuilder *irb, Scope *scope, AstNode
52215702 ir_set_cursor_at_end_and_append_block(irb, else_block);
52225703 IrInstruction *else_expr_result;
52235704 if (else_node) {
5224 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);
52255706 if (else_expr_result == irb->codegen->invalid_instruction)
52265707 return irb->codegen->invalid_instruction;
52275708 } else {
52285709 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);
52295711 }
52305712 IrBasicBlock *after_else_block = irb->current_basic_block;
52315713 if (!instr_is_unreachable(else_expr_result))
......@@ -5239,14 +5721,15 @@ static IrInstruction *ir_gen_if_bool_expr(IrBuilder *irb, Scope *scope, AstNode
52395721 incoming_blocks[0] = after_then_block;
52405722 incoming_blocks[1] = after_else_block;
52415723
5242 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);
52435726}
52445727
52455728static IrInstruction *ir_gen_prefix_op_id_lval(IrBuilder *irb, Scope *scope, AstNode *node, IrUnOp op_id, LVal lval) {
52465729 assert(node->type == NodeTypePrefixOpExpr);
52475730 AstNode *expr_node = node->data.prefix_op_expr.primary_expr;
52485731
5249 IrInstruction *value = ir_gen_node_extra(irb, expr_node, scope, lval);
5732 IrInstruction *value = ir_gen_node_extra(irb, expr_node, scope, lval, nullptr);
52505733 if (value == irb->codegen->invalid_instruction)
52515734 return value;
52525735
......@@ -5257,15 +5740,34 @@ static IrInstruction *ir_gen_prefix_op_id(IrBuilder *irb, Scope *scope, AstNode
52575740 return ir_gen_prefix_op_id_lval(irb, scope, node, op_id, LValNone);
52585741}
52595742
5260static IrInstruction *ir_lval_wrap(IrBuilder *irb, Scope *scope, IrInstruction *value, LVal lval) {
5261 if (lval != LValPtr)
5743static IrInstruction *ir_expr_wrap(IrBuilder *irb, Scope *scope, IrInstruction *inst, ResultLoc *result_loc) {
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 {
52625758 return value;
5263 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 {
52645768 return value;
5769 }
52655770
5266 // We needed a pointer to a value, but we got a value. So we create
5267 // an instruction which just makes a const pointer of it.
5268 return ir_build_ref(irb, scope, value->source_node, value, false, false);
52695771}
52705772
52715773static PtrLen star_token_to_ptr_len(TokenId token_id) {
......@@ -5338,21 +5840,22 @@ static IrInstruction *ir_gen_pointer_type(IrBuilder *irb, Scope *scope, AstNode
53385840 ptr_len, align_value, bit_offset_start, host_int_bytes, is_allow_zero);
53395841}
53405842
5341static IrInstruction *ir_gen_catch_unreachable(IrBuilder *irb, Scope *scope, AstNode *source_node, AstNode *expr_node,
5342 LVal lval)
5843static IrInstruction *ir_gen_catch_unreachable(IrBuilder *irb, Scope *scope, AstNode *source_node,
5844 AstNode *expr_node, LVal lval, ResultLoc *result_loc)
53435845{
5344 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);
53455847 if (err_union_ptr == irb->codegen->invalid_instruction)
53465848 return irb->codegen->invalid_instruction;
53475849
5348 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);
53495851 if (payload_ptr == irb->codegen->invalid_instruction)
53505852 return irb->codegen->invalid_instruction;
53515853
53525854 if (lval == LValPtr)
53535855 return payload_ptr;
53545856
5355 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);
53565859}
53575860
53585861static IrInstruction *ir_gen_bool_not(IrBuilder *irb, Scope *scope, AstNode *node) {
......@@ -5366,7 +5869,9 @@ static IrInstruction *ir_gen_bool_not(IrBuilder *irb, Scope *scope, AstNode *nod
53665869 return ir_build_bool_not(irb, scope, node, value);
53675870}
53685871
5369static 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{
53705875 assert(node->type == NodeTypePrefixOpExpr);
53715876
53725877 PrefixOp prefix_op = node->data.prefix_op_expr.prefix_op;
......@@ -5375,24 +5880,26 @@ static IrInstruction *ir_gen_prefix_op_expr(IrBuilder *irb, Scope *scope, AstNod
53755880 case PrefixOpInvalid:
53765881 zig_unreachable();
53775882 case PrefixOpBoolNot:
5378 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);
53795884 case PrefixOpBinNot:
5380 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);
53815886 case PrefixOpNegation:
5382 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);
53835888 case PrefixOpNegationWrap:
5384 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);
53855890 case PrefixOpOptional:
5386 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);
53875892 case PrefixOpAddrOf: {
53885893 AstNode *expr_node = node->data.prefix_op_expr.primary_expr;
5389 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);
53905895 }
53915896 }
53925897 zig_unreachable();
53935898}
53945899
5395static 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{
53965903 assert(node->type == NodeTypeContainerInitExpr);
53975904
53985905 AstNodeContainerInitExpr *container_init_expr = &node->data.container_init_expr;
......@@ -5410,45 +5917,104 @@ static IrInstruction *ir_gen_container_init_expr(IrBuilder *irb, Scope *scope, A
54105917 return container_type;
54115918 }
54125919
5413 if (kind == ContainerInitKindStruct) {
5414 if (elem_type != nullptr) {
5415 add_node_error(irb->codegen, container_init_expr->type,
5416 buf_sprintf("initializing array with struct syntax"));
5417 return irb->codegen->invalid_instruction;
5418 }
5920 switch (kind) {
5921 case ContainerInitKindStruct: {
5922 if (elem_type != nullptr) {
5923 add_node_error(irb->codegen, container_init_expr->type,
5924 buf_sprintf("initializing array with struct syntax"));
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);
54195936
5420 size_t field_count = container_init_expr->entries.length;
5421 IrInstructionContainerInitFieldsField *fields = allocate<IrInstructionContainerInitFieldsField>(field_count);
5422 for (size_t i = 0; i < field_count; i += 1) {
5423 AstNode *entry_node = container_init_expr->entries.at(i);
5424 assert(entry_node->type == NodeTypeStructValueField);
5937 Buf *name = entry_node->data.struct_val_field.name;
5938 AstNode *expr_node = entry_node->data.struct_val_field.expr;
54255939
5426 Buf *name = entry_node->data.struct_val_field.name;
5427 AstNode *expr_node = entry_node->data.struct_val_field.expr;
5428 IrInstruction *expr_value = ir_gen_node(irb, expr_node, scope);
5429 if (expr_value == irb->codegen->invalid_instruction)
5430 return expr_value;
5940 IrInstruction *field_ptr = ir_build_field_ptr(irb, scope, entry_node, container_ptr, name, true);
5941 ResultLocInstruction *result_loc_inst = allocate<ResultLocInstruction>(1);
5942 result_loc_inst->base.id = ResultLocIdInstruction;
5943 result_loc_inst->base.source_instruction = field_ptr;
5944 ir_ref_instruction(field_ptr, irb->current_basic_block);
5945 ir_build_reset_result(irb, scope, expr_node, &result_loc_inst->base);
54315946
5432 fields[i].name = name;
5433 fields[i].value = expr_value;
5434 fields[i].source_node = entry_node;
5947 IrInstruction *expr_value = ir_gen_node_extra(irb, expr_node, scope, LValNone,
5948 &result_loc_inst->base);
5949 if (expr_value == irb->codegen->invalid_instruction)
5950 return expr_value;
5951
5952 fields[i].name = name;
5953 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);
54355960 }
5436 return ir_build_container_init_fields(irb, scope, node, container_type, field_count, fields);
5437 } else if (kind == ContainerInitKindArray) {
5438 size_t item_count = container_init_expr->entries.length;
5439 IrInstruction **values = allocate<IrInstruction *>(item_count);
5440 for (size_t i = 0; i < item_count; i += 1) {
5441 AstNode *expr_node = container_init_expr->entries.at(i);
5442 IrInstruction *expr_value = ir_gen_node(irb, expr_node, scope);
5443 if (expr_value == irb->codegen->invalid_instruction)
5444 return expr_value;
5961 case ContainerInitKindArray: {
5962 size_t item_count = container_init_expr->entries.length;
5963
5964 if (container_type == nullptr) {
5965 IrInstruction *item_count_inst = ir_build_const_usize(irb, scope, node, item_count);
5966 container_type = ir_build_array_type(irb, scope, node, item_count_inst, elem_type);
5967 }
5968
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);
54455984
5446 values[i] = expr_value;
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);
54475995 }
5448 return ir_build_container_init_list(irb, scope, node, container_type, elem_type, item_count, values);
5449 } else {
5450 zig_unreachable();
54515996 }
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);
54526018}
54536019
54546020static IrInstruction *ir_gen_var_decl(IrBuilder *irb, Scope *scope, AstNode *node) {
......@@ -5461,9 +6027,12 @@ static IrInstruction *ir_gen_var_decl(IrBuilder *irb, Scope *scope, AstNode *nod
54616027 return irb->codegen->invalid_instruction;
54626028 }
54636029
6030 // Used for the type expr and the align expr
6031 Scope *comptime_scope = create_comptime_scope(irb->codegen, node, scope);
6032
54646033 IrInstruction *type_instruction;
54656034 if (variable_declaration->type != nullptr) {
5466 type_instruction = ir_gen_node(irb, variable_declaration->type, scope);
6035 type_instruction = ir_gen_node(irb, variable_declaration->type, comptime_scope);
54676036 if (type_instruction == irb->codegen->invalid_instruction)
54686037 return type_instruction;
54696038 } else {
......@@ -5474,8 +6043,8 @@ static IrInstruction *ir_gen_var_decl(IrBuilder *irb, Scope *scope, AstNode *nod
54746043 bool is_const = variable_declaration->is_const;
54756044 bool is_extern = variable_declaration->is_extern;
54766045
5477 IrInstruction *is_comptime = ir_build_const_bool(irb, scope, node,
5478 ir_should_inline(irb->exec, scope) || variable_declaration->is_comptime);
6046 bool is_comptime_scalar = ir_should_inline(irb->exec, scope) || variable_declaration->is_comptime;
6047 IrInstruction *is_comptime = ir_build_const_bool(irb, scope, node, is_comptime_scalar);
54796048 ZigVar *var = ir_create_var(irb, node, scope, variable_declaration->symbol,
54806049 is_const, is_const, is_shadowable, is_comptime);
54816050 // we detect IrInstructionIdDeclVarSrc in gen_block to make sure the next node
......@@ -5489,7 +6058,7 @@ static IrInstruction *ir_gen_var_decl(IrBuilder *irb, Scope *scope, AstNode *nod
54896058
54906059 IrInstruction *align_value = nullptr;
54916060 if (variable_declaration->align_expr != nullptr) {
5492 align_value = ir_gen_node(irb, variable_declaration->align_expr, scope);
6061 align_value = ir_gen_node(irb, variable_declaration->align_expr, comptime_scope);
54936062 if (align_value == irb->codegen->invalid_instruction)
54946063 return align_value;
54956064 }
......@@ -5502,20 +6071,39 @@ static IrInstruction *ir_gen_var_decl(IrBuilder *irb, Scope *scope, AstNode *nod
55026071 // Parser should ensure that this never happens
55036072 assert(variable_declaration->threadlocal_tok == nullptr);
55046073
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
55056084 // Temporarily set the name of the IrExecutable to the VariableDeclaration
55066085 // so that the struct or enum from the init expression inherits the name.
55076086 Buf *old_exec_name = irb->exec->name;
55086087 irb->exec->name = variable_declaration->symbol;
5509 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);
55106090 irb->exec->name = old_exec_name;
55116091
55126092 if (init_value == irb->codegen->invalid_instruction)
5513 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 }
55146100
5515 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);
55166102}
55176103
5518static 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{
55196107 assert(node->type == NodeTypeWhileExpr);
55206108
55216109 AstNode *continue_expr_node = node->data.while_expr.continue_expr;
......@@ -5550,25 +6138,33 @@ static IrInstruction *ir_gen_while_expr(IrBuilder *irb, Scope *scope, AstNode *n
55506138 } else {
55516139 payload_scope = subexpr_scope;
55526140 }
5553 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);
55546143 if (err_val_ptr == irb->codegen->invalid_instruction)
55556144 return err_val_ptr;
5556 IrInstruction *err_val = ir_build_load_ptr(irb, scope, node->data.while_expr.condition, err_val_ptr);
5557 IrInstruction *is_err = ir_build_test_err(irb, scope, node->data.while_expr.condition, err_val);
6145 IrInstruction *is_err = ir_build_test_err_src(irb, scope, node->data.while_expr.condition, err_val_ptr, true);
55586146 IrBasicBlock *after_cond_block = irb->current_basic_block;
55596147 IrInstruction *void_else_result = else_node ? nullptr : ir_mark_gen(ir_build_const_void(irb, scope, node));
6148 IrInstruction *cond_br_inst;
55606149 if (!instr_is_unreachable(is_err)) {
5561 ir_mark_gen(ir_build_cond_br(irb, scope, node->data.while_expr.condition, is_err,
5562 else_block, body_block, is_comptime));
6150 cond_br_inst = ir_build_cond_br(irb, scope, node->data.while_expr.condition, is_err,
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();
55636156 }
55646157
6158 ResultLocPeerParent *peer_parent = ir_build_result_peers(irb, cond_br_inst, end_block, result_loc,
6159 is_comptime);
6160
55656161 ir_set_cursor_at_end_and_append_block(irb, body_block);
55666162 if (var_symbol) {
5567 IrInstruction *var_ptr_value = ir_build_unwrap_err_payload(irb, payload_scope, symbol_node,
5568 err_val_ptr, false);
5569 IrInstruction *var_value = node->data.while_expr.var_is_ptr ?
5570 var_ptr_value : ir_build_load_ptr(irb, payload_scope, symbol_node, var_ptr_value);
5571 ir_build_var_decl_src(irb, payload_scope, symbol_node, payload_var, nullptr, nullptr, var_value);
6163 IrInstruction *payload_ptr = ir_build_unwrap_err_payload(irb, payload_scope, symbol_node,
6164 err_val_ptr, false, false);
6165 IrInstruction *var_ptr = node->data.while_expr.var_is_ptr ?
6166 ir_build_ref(irb, payload_scope, symbol_node, payload_ptr, true, false) : payload_ptr;
6167 ir_build_var_decl_src(irb, payload_scope, symbol_node, payload_var, nullptr, var_ptr);
55726168 }
55736169
55746170 ZigList<IrInstruction *> incoming_values = {0};
......@@ -5580,7 +6176,12 @@ static IrInstruction *ir_gen_while_expr(IrBuilder *irb, Scope *scope, AstNode *n
55806176 loop_scope->is_comptime = is_comptime;
55816177 loop_scope->incoming_blocks = &incoming_blocks;
55826178 loop_scope->incoming_values = &incoming_values;
6179 loop_scope->lval = lval;
6180 loop_scope->peer_parent = peer_parent;
55836181
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.
55846185 IrInstruction *body_result = ir_gen_node(irb, node->data.while_expr.body, &loop_scope->base);
55856186 if (body_result == irb->codegen->invalid_instruction)
55866187 return body_result;
......@@ -5609,10 +6210,15 @@ static IrInstruction *ir_gen_while_expr(IrBuilder *irb, Scope *scope, AstNode *n
56096210 ZigVar *err_var = ir_create_var(irb, err_symbol_node, scope, err_symbol,
56106211 true, false, false, is_comptime);
56116212 Scope *err_scope = err_var->child_scope;
5612 IrInstruction *err_var_value = ir_build_unwrap_err_code(irb, err_scope, err_symbol_node, err_val_ptr);
5613 ir_build_var_decl_src(irb, err_scope, symbol_node, err_var, nullptr, nullptr, err_var_value);
6213 IrInstruction *err_ptr = ir_build_unwrap_err_code(irb, err_scope, err_symbol_node, err_val_ptr);
6214 ir_build_var_decl_src(irb, err_scope, symbol_node, err_var, nullptr, err_ptr);
56146215
5615 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);
56166222 if (else_result == irb->codegen->invalid_instruction)
56176223 return else_result;
56186224 if (!instr_is_unreachable(else_result))
......@@ -5626,8 +6232,13 @@ static IrInstruction *ir_gen_while_expr(IrBuilder *irb, Scope *scope, AstNode *n
56266232 incoming_blocks.append(after_cond_block);
56276233 incoming_values.append(void_else_result);
56286234 }
6235 if (peer_parent->peers.length != 0) {
6236 peer_parent->peers.last()->next_bb = end_block;
6237 }
56296238
5630 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);
56316242 } else if (var_symbol != nullptr) {
56326243 ir_set_cursor_at_end_and_append_block(irb, cond_block);
56336244 Scope *subexpr_scope = create_runtime_scope(irb->codegen, node, scope, is_comptime);
......@@ -5637,23 +6248,32 @@ static IrInstruction *ir_gen_while_expr(IrBuilder *irb, Scope *scope, AstNode *n
56376248 ZigVar *payload_var = ir_create_var(irb, symbol_node, subexpr_scope, var_symbol,
56386249 true, false, false, is_comptime);
56396250 Scope *child_scope = payload_var->child_scope;
5640 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);
56416253 if (maybe_val_ptr == irb->codegen->invalid_instruction)
56426254 return maybe_val_ptr;
56436255 IrInstruction *maybe_val = ir_build_load_ptr(irb, scope, node->data.while_expr.condition, maybe_val_ptr);
56446256 IrInstruction *is_non_null = ir_build_test_nonnull(irb, scope, node->data.while_expr.condition, maybe_val);
56456257 IrBasicBlock *after_cond_block = irb->current_basic_block;
56466258 IrInstruction *void_else_result = else_node ? nullptr : ir_mark_gen(ir_build_const_void(irb, scope, node));
6259 IrInstruction *cond_br_inst;
56476260 if (!instr_is_unreachable(is_non_null)) {
5648 ir_mark_gen(ir_build_cond_br(irb, scope, node->data.while_expr.condition, is_non_null,
5649 body_block, else_block, is_comptime));
6261 cond_br_inst = ir_build_cond_br(irb, scope, node->data.while_expr.condition, is_non_null,
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();
56506267 }
56516268
6269 ResultLocPeerParent *peer_parent = ir_build_result_peers(irb, cond_br_inst, end_block, result_loc,
6270 is_comptime);
6271
56526272 ir_set_cursor_at_end_and_append_block(irb, body_block);
5653 IrInstruction *var_ptr_value = ir_build_optional_unwrap_ptr(irb, child_scope, symbol_node, maybe_val_ptr, false);
5654 IrInstruction *var_value = node->data.while_expr.var_is_ptr ?
5655 var_ptr_value : ir_build_load_ptr(irb, child_scope, symbol_node, var_ptr_value);
5656 ir_build_var_decl_src(irb, child_scope, symbol_node, payload_var, nullptr, nullptr, var_value);
6273 IrInstruction *payload_ptr = ir_build_optional_unwrap_ptr(irb, child_scope, symbol_node, maybe_val_ptr, false, false);
6274 IrInstruction *var_ptr = node->data.while_expr.var_is_ptr ?
6275 ir_build_ref(irb, child_scope, symbol_node, payload_ptr, true, false) : payload_ptr;
6276 ir_build_var_decl_src(irb, child_scope, symbol_node, payload_var, nullptr, var_ptr);
56576277
56586278 ZigList<IrInstruction *> incoming_values = {0};
56596279 ZigList<IrBasicBlock *> incoming_blocks = {0};
......@@ -5664,7 +6284,12 @@ static IrInstruction *ir_gen_while_expr(IrBuilder *irb, Scope *scope, AstNode *n
56646284 loop_scope->is_comptime = is_comptime;
56656285 loop_scope->incoming_blocks = &incoming_blocks;
56666286 loop_scope->incoming_values = &incoming_values;
6287 loop_scope->lval = lval;
6288 loop_scope->peer_parent = peer_parent;
56676289
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.
56686293 IrInstruction *body_result = ir_gen_node(irb, node->data.while_expr.body, &loop_scope->base);
56696294 if (body_result == irb->codegen->invalid_instruction)
56706295 return body_result;
......@@ -5689,7 +6314,12 @@ static IrInstruction *ir_gen_while_expr(IrBuilder *irb, Scope *scope, AstNode *n
56896314 if (else_node) {
56906315 ir_set_cursor_at_end_and_append_block(irb, else_block);
56916316
5692 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);
56936323 if (else_result == irb->codegen->invalid_instruction)
56946324 return else_result;
56956325 if (!instr_is_unreachable(else_result))
......@@ -5704,8 +6334,13 @@ static IrInstruction *ir_gen_while_expr(IrBuilder *irb, Scope *scope, AstNode *n
57046334 incoming_blocks.append(after_cond_block);
57056335 incoming_values.append(void_else_result);
57066336 }
6337 if (peer_parent->peers.length != 0) {
6338 peer_parent->peers.last()->next_bb = end_block;
6339 }
57076340
5708 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);
57096344 } else {
57106345 ir_set_cursor_at_end_and_append_block(irb, cond_block);
57116346 IrInstruction *cond_val = ir_gen_node(irb, node->data.while_expr.condition, scope);
......@@ -5713,11 +6348,18 @@ static IrInstruction *ir_gen_while_expr(IrBuilder *irb, Scope *scope, AstNode *n
57136348 return cond_val;
57146349 IrBasicBlock *after_cond_block = irb->current_basic_block;
57156350 IrInstruction *void_else_result = else_node ? nullptr : ir_mark_gen(ir_build_const_void(irb, scope, node));
6351 IrInstruction *cond_br_inst;
57166352 if (!instr_is_unreachable(cond_val)) {
5717 ir_mark_gen(ir_build_cond_br(irb, scope, node->data.while_expr.condition, cond_val,
5718 body_block, else_block, is_comptime));
6353 cond_br_inst = ir_build_cond_br(irb, scope, node->data.while_expr.condition, cond_val,
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();
57196359 }
57206360
6361 ResultLocPeerParent *peer_parent = ir_build_result_peers(irb, cond_br_inst, end_block, result_loc,
6362 is_comptime);
57216363 ir_set_cursor_at_end_and_append_block(irb, body_block);
57226364
57236365 ZigList<IrInstruction *> incoming_values = {0};
......@@ -5731,7 +6373,12 @@ static IrInstruction *ir_gen_while_expr(IrBuilder *irb, Scope *scope, AstNode *n
57316373 loop_scope->is_comptime = is_comptime;
57326374 loop_scope->incoming_blocks = &incoming_blocks;
57336375 loop_scope->incoming_values = &incoming_values;
6376 loop_scope->lval = lval;
6377 loop_scope->peer_parent = peer_parent;
57346378
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.
57356382 IrInstruction *body_result = ir_gen_node(irb, node->data.while_expr.body, &loop_scope->base);
57366383 if (body_result == irb->codegen->invalid_instruction)
57376384 return body_result;
......@@ -5756,7 +6403,13 @@ static IrInstruction *ir_gen_while_expr(IrBuilder *irb, Scope *scope, AstNode *n
57566403 if (else_node) {
57576404 ir_set_cursor_at_end_and_append_block(irb, else_block);
57586405
5759 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);
57606413 if (else_result == irb->codegen->invalid_instruction)
57616414 return else_result;
57626415 if (!instr_is_unreachable(else_result))
......@@ -5771,12 +6424,19 @@ static IrInstruction *ir_gen_while_expr(IrBuilder *irb, Scope *scope, AstNode *n
57716424 incoming_blocks.append(after_cond_block);
57726425 incoming_values.append(void_else_result);
57736426 }
6427 if (peer_parent->peers.length != 0) {
6428 peer_parent->peers.last()->next_bb = end_block;
6429 }
57746430
5775 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);
57766434 }
57776435}
57786436
5779static 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{
57806440 assert(node->type == NodeTypeForExpr);
57816441
57826442 AstNode *array_node = node->data.for_expr.array_expr;
......@@ -5791,76 +6451,67 @@ static IrInstruction *ir_gen_for_expr(IrBuilder *irb, Scope *parent_scope, AstNo
57916451 }
57926452 assert(elem_node->type == NodeTypeSymbol);
57936453
5794 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);
57956455 if (array_val_ptr == irb->codegen->invalid_instruction)
57966456 return array_val_ptr;
57976457
5798 IrInstruction *pointer_type = ir_build_to_ptr_type(irb, parent_scope, array_node, array_val_ptr);
5799 IrInstruction *elem_var_type;
5800 if (node->data.for_expr.elem_is_ptr) {
5801 elem_var_type = pointer_type;
5802 } else {
5803 elem_var_type = ir_build_ptr_type_child(irb, parent_scope, elem_node, pointer_type);
5804 }
5805
58066458 IrInstruction *is_comptime = ir_build_const_bool(irb, parent_scope, node,
58076459 ir_should_inline(irb->exec, parent_scope) || node->data.for_expr.is_inline);
58086460
5809 // TODO make it an error to write to element variable or i variable.
5810 Buf *elem_var_name = elem_node->data.symbol_expr.symbol;
5811 ZigVar *elem_var = ir_create_var(irb, elem_node, parent_scope, elem_var_name, true, false, false, is_comptime);
5812 Scope *child_scope = elem_var->child_scope;
5813
5814 IrInstruction *undefined_value = ir_build_const_undefined(irb, child_scope, elem_node);
5815 ir_build_var_decl_src(irb, child_scope, elem_node, elem_var, elem_var_type, nullptr, undefined_value);
5816 IrInstruction *elem_var_ptr = ir_build_var_ptr(irb, child_scope, node, elem_var);
5817
58186461 AstNode *index_var_source_node;
58196462 ZigVar *index_var;
6463 const char *index_var_name;
58206464 if (index_node) {
58216465 index_var_source_node = index_node;
5822 Buf *index_var_name = index_node->data.symbol_expr.symbol;
5823 index_var = ir_create_var(irb, index_node, child_scope, index_var_name, true, false, false, is_comptime);
6466 Buf *index_var_name_buf = index_node->data.symbol_expr.symbol;
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);
58246469 } else {
58256470 index_var_source_node = node;
5826 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";
58276473 }
5828 child_scope = index_var->child_scope;
58296474
5830 IrInstruction *usize = ir_build_const_type(irb, child_scope, node, irb->codegen->builtin_types.entry_usize);
5831 IrInstruction *zero = ir_build_const_usize(irb, child_scope, node, 0);
5832 IrInstruction *one = ir_build_const_usize(irb, child_scope, node, 1);
5833 ir_build_var_decl_src(irb, child_scope, index_var_source_node, index_var, usize, nullptr, zero);
5834 IrInstruction *index_ptr = ir_build_var_ptr(irb, child_scope, node, index_var);
6475 IrInstruction *zero = ir_build_const_usize(irb, parent_scope, node, 0);
6476 build_decl_var_and_init(irb, parent_scope, index_var_source_node, index_var, zero, index_var_name, is_comptime);
6477 parent_scope = index_var->child_scope;
6478
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);
58356481
58366482
5837 IrBasicBlock *cond_block = ir_create_basic_block(irb, child_scope, "ForCond");
5838 IrBasicBlock *body_block = ir_create_basic_block(irb, child_scope, "ForBody");
5839 IrBasicBlock *end_block = ir_create_basic_block(irb, child_scope, "ForEnd");
5840 IrBasicBlock *else_block = else_node ? ir_create_basic_block(irb, child_scope, "ForElse") : end_block;
5841 IrBasicBlock *continue_block = ir_create_basic_block(irb, child_scope, "ForContinue");
6483 IrBasicBlock *cond_block = ir_create_basic_block(irb, parent_scope, "ForCond");
6484 IrBasicBlock *body_block = ir_create_basic_block(irb, parent_scope, "ForBody");
6485 IrBasicBlock *end_block = ir_create_basic_block(irb, parent_scope, "ForEnd");
6486 IrBasicBlock *else_block = else_node ? ir_create_basic_block(irb, parent_scope, "ForElse") : end_block;
6487 IrBasicBlock *continue_block = ir_create_basic_block(irb, parent_scope, "ForContinue");
58426488
58436489 Buf *len_field_name = buf_create_from_str("len");
5844 IrInstruction *len_ref = ir_build_field_ptr(irb, child_scope, node, array_val_ptr, len_field_name);
5845 IrInstruction *len_val = ir_build_load_ptr(irb, child_scope, node, len_ref);
5846 ir_build_br(irb, child_scope, node, cond_block, is_comptime);
6490 IrInstruction *len_ref = ir_build_field_ptr(irb, parent_scope, node, array_val_ptr, len_field_name, false);
6491 IrInstruction *len_val = ir_build_load_ptr(irb, parent_scope, node, len_ref);
6492 ir_build_br(irb, parent_scope, node, cond_block, is_comptime);
58476493
58486494 ir_set_cursor_at_end_and_append_block(irb, cond_block);
5849 IrInstruction *index_val = ir_build_load_ptr(irb, child_scope, node, index_ptr);
5850 IrInstruction *cond = ir_build_bin_op(irb, child_scope, node, IrBinOpCmpLessThan, index_val, len_val, false);
6495 IrInstruction *index_val = ir_build_load_ptr(irb, parent_scope, node, index_ptr);
6496 IrInstruction *cond = ir_build_bin_op(irb, parent_scope, node, IrBinOpCmpLessThan, index_val, len_val, false);
58516497 IrBasicBlock *after_cond_block = irb->current_basic_block;
58526498 IrInstruction *void_else_value = else_node ? nullptr : ir_mark_gen(ir_build_const_void(irb, parent_scope, node));
5853 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);
58546503
58556504 ir_set_cursor_at_end_and_append_block(irb, body_block);
5856 IrInstruction *elem_ptr = ir_build_elem_ptr(irb, child_scope, node, array_val_ptr, index_val, false, PtrLenSingle);
5857 IrInstruction *elem_val;
5858 if (node->data.for_expr.elem_is_ptr) {
5859 elem_val = elem_ptr;
5860 } else {
5861 elem_val = ir_build_load_ptr(irb, child_scope, node, elem_ptr);
5862 }
5863 ir_mark_gen(ir_build_store_ptr(irb, child_scope, node, elem_var_ptr, elem_val));
6505 IrInstruction *elem_ptr = ir_build_elem_ptr(irb, parent_scope, node, array_val_ptr, index_val, false,
6506 PtrLenSingle, nullptr);
6507 // TODO make it an error to write to element variable or i variable.
6508 Buf *elem_var_name = elem_node->data.symbol_expr.symbol;
6509 ZigVar *elem_var = ir_create_var(irb, elem_node, parent_scope, elem_var_name, true, false, false, is_comptime);
6510 Scope *child_scope = elem_var->child_scope;
6511
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);
58646515
58656516 ZigList<IrInstruction *> incoming_values = {0};
58666517 ZigList<IrBasicBlock *> incoming_blocks = {0};
......@@ -5870,7 +6521,12 @@ static IrInstruction *ir_gen_for_expr(IrBuilder *irb, Scope *parent_scope, AstNo
58706521 loop_scope->is_comptime = is_comptime;
58716522 loop_scope->incoming_blocks = &incoming_blocks;
58726523 loop_scope->incoming_values = &incoming_values;
6524 loop_scope->lval = LValNone;
6525 loop_scope->peer_parent = peer_parent;
58736526
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.
58746530 IrInstruction *body_result = ir_gen_node(irb, body_node, &loop_scope->base);
58756531
58766532 if (!instr_is_unreachable(body_result)) {
......@@ -5887,7 +6543,12 @@ static IrInstruction *ir_gen_for_expr(IrBuilder *irb, Scope *parent_scope, AstNo
58876543 if (else_node) {
58886544 ir_set_cursor_at_end_and_append_block(irb, else_block);
58896545
5890 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, LValNone, &peer_result->base);
58916552 if (else_result == irb->codegen->invalid_instruction)
58926553 return else_result;
58936554 if (!instr_is_unreachable(else_result))
......@@ -5903,8 +6564,13 @@ static IrInstruction *ir_gen_for_expr(IrBuilder *irb, Scope *parent_scope, AstNo
59036564 incoming_blocks.append(after_cond_block);
59046565 incoming_values.append(void_else_value);
59056566 }
6567 if (peer_parent->peers.length != 0) {
6568 peer_parent->peers.last()->next_bb = end_block;
6569 }
59066570
5907 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_lval_wrap(irb, parent_scope, phi, lval, result_loc);
59086574}
59096575
59106576static IrInstruction *ir_gen_bool_literal(IrBuilder *irb, Scope *scope, AstNode *node) {
......@@ -6189,7 +6855,9 @@ static IrInstruction *ir_gen_asm_expr(IrBuilder *irb, Scope *scope, AstNode *nod
61896855 input_list, output_types, output_vars, return_count, is_volatile);
61906856}
61916857
6192static 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{
61936861 assert(node->type == NodeTypeIfOptional);
61946862
61956863 Buf *var_symbol = node->data.test_expr.var_symbol;
......@@ -6198,7 +6866,7 @@ static IrInstruction *ir_gen_if_optional_expr(IrBuilder *irb, Scope *scope, AstN
61986866 AstNode *else_node = node->data.test_expr.else_node;
61996867 bool var_is_ptr = node->data.test_expr.var_is_ptr;
62006868
6201 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);
62026870 if (maybe_val_ptr == irb->codegen->invalid_instruction)
62036871 return maybe_val_ptr;
62046872
......@@ -6215,27 +6883,31 @@ static IrInstruction *ir_gen_if_optional_expr(IrBuilder *irb, Scope *scope, AstN
62156883 } else {
62166884 is_comptime = ir_build_test_comptime(irb, scope, node, is_non_null);
62176885 }
6218 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);
62196891
62206892 ir_set_cursor_at_end_and_append_block(irb, then_block);
62216893
62226894 Scope *subexpr_scope = create_runtime_scope(irb->codegen, node, scope, is_comptime);
62236895 Scope *var_scope;
62246896 if (var_symbol) {
6225 IrInstruction *var_type = nullptr;
62266897 bool is_shadowable = false;
62276898 bool is_const = true;
62286899 ZigVar *var = ir_create_var(irb, node, subexpr_scope,
62296900 var_symbol, is_const, is_const, is_shadowable, is_comptime);
62306901
6231 IrInstruction *var_ptr_value = ir_build_optional_unwrap_ptr(irb, subexpr_scope, node, maybe_val_ptr, false);
6232 IrInstruction *var_value = var_is_ptr ? var_ptr_value : ir_build_load_ptr(irb, subexpr_scope, node, var_ptr_value);
6233 ir_build_var_decl_src(irb, subexpr_scope, node, var, var_type, nullptr, var_value);
6902 IrInstruction *payload_ptr = ir_build_optional_unwrap_ptr(irb, subexpr_scope, node, maybe_val_ptr, false, false);
6903 IrInstruction *var_ptr = var_is_ptr ? ir_build_ref(irb, subexpr_scope, node, payload_ptr, true, false) : payload_ptr;
6904 ir_build_var_decl_src(irb, subexpr_scope, node, var, nullptr, var_ptr);
62346905 var_scope = var->child_scope;
62356906 } else {
62366907 var_scope = subexpr_scope;
62376908 }
6238 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);
62396911 if (then_expr_result == irb->codegen->invalid_instruction)
62406912 return then_expr_result;
62416913 IrBasicBlock *after_then_block = irb->current_basic_block;
......@@ -6245,11 +6917,12 @@ static IrInstruction *ir_gen_if_optional_expr(IrBuilder *irb, Scope *scope, AstN
62456917 ir_set_cursor_at_end_and_append_block(irb, else_block);
62466918 IrInstruction *else_expr_result;
62476919 if (else_node) {
6248 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);
62496921 if (else_expr_result == irb->codegen->invalid_instruction)
62506922 return else_expr_result;
62516923 } else {
62526924 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);
62536926 }
62546927 IrBasicBlock *after_else_block = irb->current_basic_block;
62556928 if (!instr_is_unreachable(else_expr_result))
......@@ -6263,10 +6936,13 @@ static IrInstruction *ir_gen_if_optional_expr(IrBuilder *irb, Scope *scope, AstN
62636936 incoming_blocks[0] = after_then_block;
62646937 incoming_blocks[1] = after_else_block;
62656938
6266 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);
62676941}
62686942
6269static 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{
62706946 assert(node->type == NodeTypeIfErrorExpr);
62716947
62726948 AstNode *target_node = node->data.if_err_expr.target_node;
......@@ -6277,12 +6953,12 @@ static IrInstruction *ir_gen_if_err_expr(IrBuilder *irb, Scope *scope, AstNode *
62776953 Buf *var_symbol = node->data.if_err_expr.var_symbol;
62786954 Buf *err_symbol = node->data.if_err_expr.err_symbol;
62796955
6280 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);
62816957 if (err_val_ptr == irb->codegen->invalid_instruction)
62826958 return err_val_ptr;
62836959
62846960 IrInstruction *err_val = ir_build_load_ptr(irb, scope, node, err_val_ptr);
6285 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);
62866962
62876963 IrBasicBlock *ok_block = ir_create_basic_block(irb, scope, "TryOk");
62886964 IrBasicBlock *else_block = ir_create_basic_block(irb, scope, "TryElse");
......@@ -6290,27 +6966,31 @@ static IrInstruction *ir_gen_if_err_expr(IrBuilder *irb, Scope *scope, AstNode *
62906966
62916967 bool force_comptime = ir_should_inline(irb->exec, scope);
62926968 IrInstruction *is_comptime = force_comptime ? ir_build_const_bool(irb, scope, node, true) : ir_build_test_comptime(irb, scope, node, is_err);
6293 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);
62946973
62956974 ir_set_cursor_at_end_and_append_block(irb, ok_block);
62966975
62976976 Scope *subexpr_scope = create_runtime_scope(irb->codegen, node, scope, is_comptime);
62986977 Scope *var_scope;
62996978 if (var_symbol) {
6300 IrInstruction *var_type = nullptr;
63016979 bool is_shadowable = false;
63026980 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);
63036981 ZigVar *var = ir_create_var(irb, node, subexpr_scope,
63046982 var_symbol, var_is_const, var_is_const, is_shadowable, var_is_comptime);
63056983
6306 IrInstruction *var_ptr_value = ir_build_unwrap_err_payload(irb, subexpr_scope, node, err_val_ptr, false);
6307 IrInstruction *var_value = var_is_ptr ? var_ptr_value : ir_build_load_ptr(irb, subexpr_scope, node, var_ptr_value);
6308 ir_build_var_decl_src(irb, subexpr_scope, node, var, var_type, nullptr, var_value);
6984 IrInstruction *payload_ptr = ir_build_unwrap_err_payload(irb, subexpr_scope, node, err_val_ptr, false, false);
6985 IrInstruction *var_ptr = var_is_ptr ?
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);
63096988 var_scope = var->child_scope;
63106989 } else {
63116990 var_scope = subexpr_scope;
63126991 }
6313 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);
63146994 if (then_expr_result == irb->codegen->invalid_instruction)
63156995 return then_expr_result;
63166996 IrBasicBlock *after_then_block = irb->current_basic_block;
......@@ -6323,23 +7003,23 @@ static IrInstruction *ir_gen_if_err_expr(IrBuilder *irb, Scope *scope, AstNode *
63237003 if (else_node) {
63247004 Scope *err_var_scope;
63257005 if (err_symbol) {
6326 IrInstruction *var_type = nullptr;
63277006 bool is_shadowable = false;
63287007 bool is_const = true;
63297008 ZigVar *var = ir_create_var(irb, node, subexpr_scope,
63307009 err_symbol, is_const, is_const, is_shadowable, is_comptime);
63317010
6332 IrInstruction *var_value = ir_build_unwrap_err_code(irb, subexpr_scope, node, err_val_ptr);
6333 ir_build_var_decl_src(irb, subexpr_scope, node, var, var_type, nullptr, var_value);
7011 IrInstruction *err_ptr = ir_build_unwrap_err_code(irb, subexpr_scope, node, err_val_ptr);
7012 ir_build_var_decl_src(irb, subexpr_scope, node, var, nullptr, err_ptr);
63347013 err_var_scope = var->child_scope;
63357014 } else {
63367015 err_var_scope = subexpr_scope;
63377016 }
6338 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);
63397018 if (else_expr_result == irb->codegen->invalid_instruction)
63407019 return else_expr_result;
63417020 } else {
63427021 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);
63437023 }
63447024 IrBasicBlock *after_else_block = irb->current_basic_block;
63457025 if (!instr_is_unreachable(else_expr_result))
......@@ -6353,14 +7033,15 @@ static IrInstruction *ir_gen_if_err_expr(IrBuilder *irb, Scope *scope, AstNode *
63537033 incoming_blocks[0] = after_then_block;
63547034 incoming_blocks[1] = after_else_block;
63557035
6356 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);
63577038}
63587039
63597040static bool ir_gen_switch_prong_expr(IrBuilder *irb, Scope *scope, AstNode *switch_node, AstNode *prong_node,
63607041 IrBasicBlock *end_block, IrInstruction *is_comptime, IrInstruction *var_is_comptime,
63617042 IrInstruction *target_value_ptr, IrInstruction **prong_values, size_t prong_values_len,
63627043 ZigList<IrBasicBlock *> *incoming_blocks, ZigList<IrInstruction *> *incoming_values,
6363 IrInstructionSwitchElseVar **out_switch_else_var)
7044 IrInstructionSwitchElseVar **out_switch_else_var, LVal lval, ResultLoc *result_loc)
63647045{
63657046 assert(switch_node->type == NodeTypeSwitchExpr);
63667047 assert(prong_node->type == NodeTypeSwitchProng);
......@@ -6378,28 +7059,27 @@ static bool ir_gen_switch_prong_expr(IrBuilder *irb, Scope *scope, AstNode *swit
63787059 ZigVar *var = ir_create_var(irb, var_symbol_node, scope,
63797060 var_name, is_const, is_const, is_shadowable, var_is_comptime);
63807061 child_scope = var->child_scope;
6381 IrInstruction *var_value;
7062 IrInstruction *var_ptr;
63827063 if (out_switch_else_var != nullptr) {
63837064 IrInstructionSwitchElseVar *switch_else_var = ir_build_switch_else_var(irb, scope, var_symbol_node,
63847065 target_value_ptr);
63857066 *out_switch_else_var = switch_else_var;
6386 IrInstruction *var_ptr_value = &switch_else_var->base;
6387 var_value = var_is_ptr ? var_ptr_value : ir_build_load_ptr(irb, scope, var_symbol_node, var_ptr_value);
7067 IrInstruction *payload_ptr = &switch_else_var->base;
7068 var_ptr = var_is_ptr ? ir_build_ref(irb, scope, var_symbol_node, payload_ptr, true, false) : payload_ptr;
63887069 } else if (prong_values != nullptr) {
6389 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,
63907071 prong_values, prong_values_len);
6391 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;
63927073 } else {
6393 var_value = var_is_ptr ? target_value_ptr : ir_build_load_ptr(irb, scope, var_symbol_node,
6394target_value_ptr);
7074 var_ptr = var_is_ptr ?
7075 ir_build_ref(irb, scope, var_symbol_node, target_value_ptr, true, false) : target_value_ptr;
63957076 }
6396 IrInstruction *var_type = nullptr; // infer the type
6397 ir_build_var_decl_src(irb, scope, var_symbol_node, var, var_type, nullptr, var_value);
7077 ir_build_var_decl_src(irb, scope, var_symbol_node, var, nullptr, var_ptr);
63987078 } else {
63997079 child_scope = scope;
64007080 }
64017081
6402 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);
64037083 if (expr_result == irb->codegen->invalid_instruction)
64047084 return false;
64057085 if (!instr_is_unreachable(expr_result))
......@@ -6409,11 +7089,13 @@ target_value_ptr);
64097089 return true;
64107090}
64117091
6412static 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{
64137095 assert(node->type == NodeTypeSwitchExpr);
64147096
64157097 AstNode *target_node = node->data.switch_expr.expr;
6416 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);
64177099 if (target_value_ptr == irb->codegen->invalid_instruction)
64187100 return target_value_ptr;
64197101 IrInstruction *target_value = ir_build_switch_target(irb, scope, node, target_value_ptr);
......@@ -6440,6 +7122,14 @@ static IrInstruction *ir_gen_switch_expr(IrBuilder *irb, Scope *scope, AstNode *
64407122
64417123 IrInstructionSwitchElseVar *switch_else_var = nullptr;
64427124
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
64437133 // First do the else and the ranges
64447134 Scope *subexpr_scope = create_runtime_scope(irb->codegen, node, scope, is_comptime);
64457135 Scope *comptime_scope = create_comptime_scope(irb->codegen, node, scope);
......@@ -6448,6 +7138,7 @@ static IrInstruction *ir_gen_switch_expr(IrBuilder *irb, Scope *scope, AstNode *
64487138 AstNode *prong_node = node->data.switch_expr.prongs.at(prong_i);
64497139 size_t prong_item_count = prong_node->data.switch_prong.items.length;
64507140 if (prong_item_count == 0) {
7141 ResultLocPeer *this_peer_result_loc = create_peer_result(peer_parent);
64517142 if (else_prong) {
64527143 ErrorMsg *msg = add_node_error(irb->codegen, prong_node,
64537144 buf_sprintf("multiple else prongs in switch expression"));
......@@ -6458,15 +7149,21 @@ static IrInstruction *ir_gen_switch_expr(IrBuilder *irb, Scope *scope, AstNode *
64587149 else_prong = prong_node;
64597150
64607151 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);
64617156 ir_set_cursor_at_end_and_append_block(irb, else_block);
64627157 if (!ir_gen_switch_prong_expr(irb, subexpr_scope, node, prong_node, end_block,
64637158 is_comptime, var_is_comptime, target_value_ptr, nullptr, 0, &incoming_blocks, &incoming_values,
6464 &switch_else_var))
7159 &switch_else_var, LValNone, &this_peer_result_loc->base))
64657160 {
64667161 return irb->codegen->invalid_instruction;
64677162 }
64687163 ir_set_cursor_at_end(irb, prev_block);
64697164 } else if (prong_node->data.switch_prong.any_items_are_range) {
7165 ResultLocPeer *this_peer_result_loc = create_peer_result(peer_parent);
7166
64707167 IrInstruction *ok_bit = nullptr;
64717168 AstNode *last_item_node = nullptr;
64727169 for (size_t item_i = 0; item_i < prong_item_count; item_i += 1) {
......@@ -6523,13 +7220,20 @@ static IrInstruction *ir_gen_switch_expr(IrBuilder *irb, Scope *scope, AstNode *
65237220
65247221 assert(ok_bit);
65257222 assert(last_item_node);
6526 ir_mark_gen(ir_build_cond_br(irb, scope, last_item_node, ok_bit, range_block_yes,
6527 range_block_no, is_comptime));
7223 IrInstruction *br_inst = ir_mark_gen(ir_build_cond_br(irb, scope, last_item_node, ok_bit,
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 }
65287228
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);
65297233 ir_set_cursor_at_end_and_append_block(irb, range_block_yes);
65307234 if (!ir_gen_switch_prong_expr(irb, subexpr_scope, node, prong_node, end_block,
65317235 is_comptime, var_is_comptime, target_value_ptr, nullptr, 0,
6532 &incoming_blocks, &incoming_values, nullptr))
7236 &incoming_blocks, &incoming_values, nullptr, LValNone, &this_peer_result_loc->base))
65337237 {
65347238 return irb->codegen->invalid_instruction;
65357239 }
......@@ -6547,6 +7251,8 @@ static IrInstruction *ir_gen_switch_expr(IrBuilder *irb, Scope *scope, AstNode *
65477251 if (prong_node->data.switch_prong.any_items_are_range)
65487252 continue;
65497253
7254 ResultLocPeer *this_peer_result_loc = create_peer_result(peer_parent);
7255
65507256 IrBasicBlock *prong_block = ir_create_basic_block(irb, scope, "SwitchProng");
65517257 IrInstruction **items = allocate<IrInstruction *>(prong_item_count);
65527258
......@@ -6570,10 +7276,14 @@ static IrInstruction *ir_gen_switch_expr(IrBuilder *irb, Scope *scope, AstNode *
65707276 }
65717277
65727278 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);
65737283 ir_set_cursor_at_end_and_append_block(irb, prong_block);
65747284 if (!ir_gen_switch_prong_expr(irb, subexpr_scope, node, prong_node, end_block,
65757285 is_comptime, var_is_comptime, target_value_ptr, items, prong_item_count,
6576 &incoming_blocks, &incoming_values, nullptr))
7286 &incoming_blocks, &incoming_values, nullptr, LValNone, &this_peer_result_loc->base))
65777287 {
65787288 return irb->codegen->invalid_instruction;
65797289 }
......@@ -6582,38 +7292,57 @@ static IrInstruction *ir_gen_switch_expr(IrBuilder *irb, Scope *scope, AstNode *
65827292
65837293 }
65847294
6585 IrInstruction *switch_prongs_void = ir_build_check_switch_prongs(irb, scope, node, target_value, check_ranges.items, check_ranges.length,
6586 else_prong != nullptr);
7295 IrInstruction *switch_prongs_void = ir_build_check_switch_prongs(irb, scope, node, target_value,
7296 check_ranges.items, check_ranges.length, else_prong != nullptr);
65877297
7298 IrInstruction *br_instruction;
65887299 if (cases.length == 0) {
6589 ir_build_br(irb, scope, node, else_block, is_comptime);
7300 br_instruction = ir_build_br(irb, scope, node, else_block, is_comptime);
65907301 } else {
65917302 IrInstructionSwitchBr *switch_br = ir_build_switch_br(irb, scope, node, target_value, else_block,
65927303 cases.length, cases.items, is_comptime, switch_prongs_void);
65937304 if (switch_else_var != nullptr) {
65947305 switch_else_var->switch_br = switch_br;
65957306 }
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;
65967314 }
65977315
65987316 if (!else_prong) {
7317 if (peer_parent->peers.length != 0) {
7318 peer_parent->peers.last()->next_bb = else_block;
7319 }
65997320 ir_set_cursor_at_end_and_append_block(irb, else_block);
66007321 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 }
66017326 }
66027327
66037328 ir_set_cursor_at_end_and_append_block(irb, end_block);
66047329 assert(incoming_blocks.length == incoming_values.length);
7330 IrInstruction *result_instruction;
66057331 if (incoming_blocks.length == 0) {
6606 return ir_build_const_void(irb, scope, node);
7332 result_instruction = ir_build_const_void(irb, scope, node);
66077333 } else {
6608 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);
66097336 }
7337 return ir_lval_wrap(irb, scope, result_instruction, lval, result_loc);
66107338}
66117339
66127340static IrInstruction *ir_gen_comptime(IrBuilder *irb, Scope *parent_scope, AstNode *node, LVal lval) {
66137341 assert(node->type == NodeTypeCompTime);
66147342
66157343 Scope *child_scope = create_comptime_scope(irb->codegen, node, parent_scope);
6616 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);
66177346}
66187347
66197348static IrInstruction *ir_gen_return_from_block(IrBuilder *irb, Scope *break_scope, AstNode *node, ScopeBlock *block_scope) {
......@@ -6626,7 +7355,11 @@ static IrInstruction *ir_gen_return_from_block(IrBuilder *irb, Scope *break_scop
66267355
66277356 IrInstruction *result_value;
66287357 if (node->data.break_expr.expr) {
6629 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);
66307363 if (result_value == irb->codegen->invalid_instruction)
66317364 return irb->codegen->invalid_instruction;
66327365 } else {
......@@ -6696,7 +7429,11 @@ static IrInstruction *ir_gen_break(IrBuilder *irb, Scope *break_scope, AstNode *
66967429
66977430 IrInstruction *result_value;
66987431 if (node->data.break_expr.expr) {
6699 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);
67007437 if (result_value == irb->codegen->invalid_instruction)
67017438 return irb->codegen->invalid_instruction;
67027439 } else {
......@@ -6784,7 +7521,7 @@ static IrInstruction *ir_gen_defer(IrBuilder *irb, Scope *parent_scope, AstNode
67847521 return ir_build_const_void(irb, parent_scope, node);
67857522}
67867523
6787static 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) {
67887525 assert(node->type == NodeTypeSliceExpr);
67897526
67907527 AstNodeSliceExpr *slice_expr = &node->data.slice_expr;
......@@ -6792,7 +7529,7 @@ static IrInstruction *ir_gen_slice(IrBuilder *irb, Scope *scope, AstNode *node)
67927529 AstNode *start_node = slice_expr->start;
67937530 AstNode *end_node = slice_expr->end;
67947531
6795 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);
67967533 if (ptr_value == irb->codegen->invalid_instruction)
67977534 return irb->codegen->invalid_instruction;
67987535
......@@ -6809,11 +7546,14 @@ static IrInstruction *ir_gen_slice(IrBuilder *irb, Scope *scope, AstNode *node)
68097546 end_value = nullptr;
68107547 }
68117548
6812 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);
68137551}
68147552
6815static IrInstruction *ir_gen_catch(IrBuilder *irb, Scope *parent_scope, AstNode *node) {
6816 assert(node->type == NodeTypeUnwrapErrorExpr);
7553static IrInstruction *ir_gen_catch(IrBuilder *irb, Scope *parent_scope, AstNode *node, LVal lval,
7554 ResultLoc *result_loc)
7555{
7556 assert(node->type == NodeTypeCatchExpr);
68177557
68187558 AstNode *op1_node = node->data.unwrap_err_expr.op1;
68197559 AstNode *op2_node = node->data.unwrap_err_expr.op2;
......@@ -6826,16 +7566,15 @@ static IrInstruction *ir_gen_catch(IrBuilder *irb, Scope *parent_scope, AstNode
68267566 add_node_error(irb->codegen, var_node, buf_sprintf("unused variable: '%s'", buf_ptr(var_name)));
68277567 return irb->codegen->invalid_instruction;
68287568 }
6829 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);
68307570 }
68317571
68327572
6833 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);
68347574 if (err_union_ptr == irb->codegen->invalid_instruction)
68357575 return irb->codegen->invalid_instruction;
68367576
6837 IrInstruction *err_union_val = ir_build_load_ptr(irb, parent_scope, node, err_union_ptr);
6838 IrInstruction *is_err = ir_build_test_err(irb, parent_scope, node, err_union_val);
7577 IrInstruction *is_err = ir_build_test_err_src(irb, parent_scope, node, err_union_ptr, true);
68397578
68407579 IrInstruction *is_comptime;
68417580 if (ir_should_inline(irb->exec, parent_scope)) {
......@@ -6847,7 +7586,10 @@ static IrInstruction *ir_gen_catch(IrBuilder *irb, Scope *parent_scope, AstNode
68477586 IrBasicBlock *ok_block = ir_create_basic_block(irb, parent_scope, "UnwrapErrOk");
68487587 IrBasicBlock *err_block = ir_create_basic_block(irb, parent_scope, "UnwrapErrError");
68497588 IrBasicBlock *end_block = ir_create_basic_block(irb, parent_scope, "UnwrapErrEnd");
6850 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);
68517593
68527594 ir_set_cursor_at_end_and_append_block(irb, err_block);
68537595 Scope *err_scope;
......@@ -6859,12 +7601,12 @@ static IrInstruction *ir_gen_catch(IrBuilder *irb, Scope *parent_scope, AstNode
68597601 ZigVar *var = ir_create_var(irb, node, parent_scope, var_name,
68607602 is_const, is_const, is_shadowable, is_comptime);
68617603 err_scope = var->child_scope;
6862 IrInstruction *err_val = ir_build_unwrap_err_code(irb, err_scope, node, err_union_ptr);
6863 ir_build_var_decl_src(irb, err_scope, var_node, var, nullptr, nullptr, err_val);
7604 IrInstruction *err_ptr = ir_build_unwrap_err_code(irb, err_scope, node, err_union_ptr);
7605 ir_build_var_decl_src(irb, err_scope, var_node, var, nullptr, err_ptr);
68647606 } else {
68657607 err_scope = parent_scope;
68667608 }
6867 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);
68687610 if (err_result == irb->codegen->invalid_instruction)
68697611 return irb->codegen->invalid_instruction;
68707612 IrBasicBlock *after_err_block = irb->current_basic_block;
......@@ -6872,8 +7614,9 @@ static IrInstruction *ir_gen_catch(IrBuilder *irb, Scope *parent_scope, AstNode
68727614 ir_mark_gen(ir_build_br(irb, err_scope, node, end_block, is_comptime));
68737615
68747616 ir_set_cursor_at_end_and_append_block(irb, ok_block);
6875 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);
68767618 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);
68777620 IrBasicBlock *after_ok_block = irb->current_basic_block;
68787621 ir_build_br(irb, parent_scope, node, end_block, is_comptime);
68797622
......@@ -6884,7 +7627,8 @@ static IrInstruction *ir_gen_catch(IrBuilder *irb, Scope *parent_scope, AstNode
68847627 IrBasicBlock **incoming_blocks = allocate<IrBasicBlock *>(2);
68857628 incoming_blocks[0] = after_err_block;
68867629 incoming_blocks[1] = after_ok_block;
6887 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);
68887632}
68897633
68907634static bool render_instance_name_recursive(CodeGen *codegen, Buf *name, Scope *outer_scope, Scope *inner_scope) {
......@@ -7160,7 +7904,7 @@ static IrInstruction *ir_gen_cancel_target(IrBuilder *irb, Scope *scope, AstNode
71607904 IrInstruction *coro_promise_ptr = ir_build_coro_promise(irb, scope, node, casted_target_inst);
71617905 Buf *atomic_state_field_name = buf_create_from_str(ATOMIC_STATE_FIELD_NAME);
71627906 IrInstruction *atomic_state_ptr = ir_build_field_ptr(irb, scope, node, coro_promise_ptr,
7163 atomic_state_field_name);
7907 atomic_state_field_name, false);
71647908
71657909 // set the is_canceled bit
71667910 IrInstruction *prev_atomic_value = ir_build_atomic_rmw(irb, scope, node,
......@@ -7239,7 +7983,7 @@ static IrInstruction *ir_gen_resume_target(IrBuilder *irb, Scope *scope, AstNode
72397983 IrInstruction *coro_promise_ptr = ir_build_coro_promise(irb, scope, node, casted_target_inst);
72407984 Buf *atomic_state_field_name = buf_create_from_str(ATOMIC_STATE_FIELD_NAME);
72417985 IrInstruction *atomic_state_ptr = ir_build_field_ptr(irb, scope, node, coro_promise_ptr,
7242 atomic_state_field_name);
7986 atomic_state_field_name, false);
72437987
72447988 // clear the is_suspended bit
72457989 IrInstruction *prev_atomic_value = ir_build_atomic_rmw(irb, scope, node,
......@@ -7306,12 +8050,12 @@ static IrInstruction *ir_gen_await_expr(IrBuilder *irb, Scope *scope, AstNode *n
73068050
73078051 IrInstruction *coro_promise_ptr = ir_build_coro_promise(irb, scope, node, target_inst);
73088052 Buf *result_ptr_field_name = buf_create_from_str(RESULT_PTR_FIELD_NAME);
7309 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);
73108054
73118055 if (irb->codegen->have_err_ret_tracing) {
73128056 IrInstruction *err_ret_trace_ptr = ir_build_error_return_trace(irb, scope, node, IrInstructionErrorReturnTrace::NonNull);
73138057 Buf *err_ret_trace_ptr_field_name = buf_create_from_str(ERR_RET_TRACE_PTR_FIELD_NAME);
7314 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);
73158059 ir_build_store_ptr(irb, scope, node, err_ret_trace_ptr_field_ptr, err_ret_trace_ptr);
73168060 }
73178061
......@@ -7333,11 +8077,11 @@ static IrInstruction *ir_gen_await_expr(IrBuilder *irb, Scope *scope, AstNode *n
73338077
73348078 Buf *atomic_state_field_name = buf_create_from_str(ATOMIC_STATE_FIELD_NAME);
73358079 IrInstruction *atomic_state_ptr = ir_build_field_ptr(irb, scope, node, coro_promise_ptr,
7336 atomic_state_field_name);
8080 atomic_state_field_name, false);
73378081
73388082 IrInstruction *promise_type_val = ir_build_const_type(irb, scope, node, irb->codegen->builtin_types.entry_promise);
73398083 IrInstruction *const_bool_false = ir_build_const_bool(irb, scope, node, false);
7340 IrInstruction *undefined_value = ir_build_const_undefined(irb, scope, node);
8084 IrInstruction *undef = ir_build_const_undefined(irb, scope, node);
73418085 IrInstruction *usize_type_val = ir_build_const_type(irb, scope, node, irb->codegen->builtin_types.entry_usize);
73428086 IrInstruction *zero = ir_build_const_usize(irb, scope, node, 0);
73438087 IrInstruction *inverted_ptr_mask = ir_build_const_usize(irb, scope, node, 0x7); // 0b111
......@@ -7351,7 +8095,8 @@ static IrInstruction *ir_gen_await_expr(IrBuilder *irb, Scope *scope, AstNode *n
73518095 IrInstruction *target_promise_type = ir_build_typeof(irb, scope, node, target_inst);
73528096 IrInstruction *promise_result_type = ir_build_promise_result_type(irb, scope, node, target_promise_type);
73538097 ir_build_await_bookkeeping(irb, scope, node, promise_result_type);
7354 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);
73558100 IrInstruction *my_result_var_ptr = ir_build_var_ptr(irb, scope, node, result_var);
73568101 ir_build_store_ptr(irb, scope, node, result_ptr_field_ptr, my_result_var_ptr);
73578102 IrInstruction *save_token = ir_build_coro_save(irb, scope, node, irb->exec->coro_handle);
......@@ -7386,12 +8131,12 @@ static IrInstruction *ir_gen_await_expr(IrBuilder *irb, Scope *scope, AstNode *n
73868131 ir_set_cursor_at_end_and_append_block(irb, no_suspend_block);
73878132 if (irb->codegen->have_err_ret_tracing) {
73888133 Buf *err_ret_trace_field_name = buf_create_from_str(ERR_RET_TRACE_FIELD_NAME);
7389 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);
73908135 IrInstruction *dest_err_ret_trace_ptr = ir_build_error_return_trace(irb, scope, node, IrInstructionErrorReturnTrace::NonNull);
73918136 ir_build_merge_err_ret_traces(irb, scope, node, coro_promise_ptr, src_err_ret_trace_ptr, dest_err_ret_trace_ptr);
73928137 }
73938138 Buf *result_field_name = buf_create_from_str(RESULT_FIELD_NAME);
7394 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);
73958140 // If the type of the result handle_is_ptr then this does not actually perform a load. But we need it to,
73968141 // because we're about to destroy the memory. So we store it into our result variable.
73978142 IrInstruction *no_suspend_result = ir_build_load_ptr(irb, scope, node, promise_result_ptr);
......@@ -7567,7 +8312,8 @@ static IrInstruction *ir_gen_suspend(IrBuilder *irb, Scope *parent_scope, AstNod
75678312 incoming_values[0] = const_bool_true;
75688313 incoming_blocks[1] = post_cancel_awaiter_block;
75698314 incoming_values[1] = const_bool_false;
7570 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);
75718317 ir_gen_defers_for_block(irb, parent_scope, outer_scope, true);
75728318 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));
75738319
......@@ -7576,7 +8322,7 @@ static IrInstruction *ir_gen_suspend(IrBuilder *irb, Scope *parent_scope, AstNod
75768322}
75778323
75788324static IrInstruction *ir_gen_node_raw(IrBuilder *irb, AstNode *node, Scope *scope,
7579 LVal lval)
8325 LVal lval, ResultLoc *result_loc)
75808326{
75818327 assert(scope);
75828328 switch (node->type) {
......@@ -7590,37 +8336,37 @@ static IrInstruction *ir_gen_node_raw(IrBuilder *irb, AstNode *node, Scope *scop
75908336 case NodeTypeTestDecl:
75918337 zig_unreachable();
75928338 case NodeTypeBlock:
7593 return ir_lval_wrap(irb, scope, ir_gen_block(irb, scope, node), lval);
8339 return ir_gen_block(irb, scope, node, lval, result_loc);
75948340 case NodeTypeGroupedExpr:
7595 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);
75968342 case NodeTypeBinOpExpr:
7597 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);
75988344 case NodeTypeIntLiteral:
7599 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);
76008346 case NodeTypeFloatLiteral:
7601 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);
76028348 case NodeTypeCharLiteral:
7603 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);
76048350 case NodeTypeSymbol:
7605 return ir_gen_symbol(irb, scope, node, lval);
8351 return ir_gen_symbol(irb, scope, node, lval, result_loc);
76068352 case NodeTypeFnCallExpr:
7607 return ir_gen_fn_call(irb, scope, node, lval);
8353 return ir_gen_fn_call(irb, scope, node, lval, result_loc);
76088354 case NodeTypeIfBoolExpr:
7609 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);
76108356 case NodeTypePrefixOpExpr:
7611 return ir_gen_prefix_op_expr(irb, scope, node, lval);
8357 return ir_gen_prefix_op_expr(irb, scope, node, lval, result_loc);
76128358 case NodeTypeContainerInitExpr:
7613 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);
76148360 case NodeTypeVariableDeclaration:
7615 return ir_lval_wrap(irb, scope, ir_gen_var_decl(irb, scope, node), lval);
8361 return ir_gen_var_decl(irb, scope, node);
76168362 case NodeTypeWhileExpr:
7617 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);
76188364 case NodeTypeForExpr:
7619 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);
76208366 case NodeTypeArrayAccessExpr:
7621 return ir_gen_array_access(irb, scope, node, lval);
8367 return ir_gen_array_access(irb, scope, node, lval, result_loc);
76228368 case NodeTypeReturnExpr:
7623 return ir_gen_return(irb, scope, node, lval);
8369 return ir_gen_return(irb, scope, node, lval, result_loc);
76248370 case NodeTypeFieldAccessExpr:
76258371 {
76268372 IrInstruction *ptr_instruction = ir_gen_field_access(irb, scope, node);
......@@ -7629,86 +8375,89 @@ static IrInstruction *ir_gen_node_raw(IrBuilder *irb, AstNode *node, Scope *scop
76298375 if (lval == LValPtr)
76308376 return ptr_instruction;
76318377
7632 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);
76338380 }
76348381 case NodeTypePtrDeref: {
76358382 AstNode *expr_node = node->data.ptr_deref_expr.target;
7636 IrInstruction *value = ir_gen_node_extra(irb, expr_node, scope, lval);
8383 IrInstruction *value = ir_gen_node_extra(irb, expr_node, scope, lval, nullptr);
76378384 if (value == irb->codegen->invalid_instruction)
76388385 return value;
76398386
76408387 // We essentially just converted any lvalue from &(x.*) to (&x).*;
76418388 // this inhibits checking that x is a pointer later, so we directly
76428389 // record whether the pointer check is needed
7643 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);
76448392 }
76458393 case NodeTypeUnwrapOptional: {
76468394 AstNode *expr_node = node->data.unwrap_optional.expr;
76478395
7648 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);
76498397 if (maybe_ptr == irb->codegen->invalid_instruction)
76508398 return irb->codegen->invalid_instruction;
76518399
7652 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);
76538401 if (lval == LValPtr)
76548402 return unwrapped_ptr;
76558403
7656 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);
76578406 }
76588407 case NodeTypeBoolLiteral:
7659 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);
76608409 case NodeTypeArrayType:
7661 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);
76628411 case NodeTypePointerType:
7663 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);
76648413 case NodeTypePromiseType:
7665 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);
76668415 case NodeTypeStringLiteral:
7667 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);
76688417 case NodeTypeUndefinedLiteral:
7669 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);
76708419 case NodeTypeAsmExpr:
7671 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);
76728421 case NodeTypeNullLiteral:
7673 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);
76748423 case NodeTypeIfErrorExpr:
7675 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);
76768425 case NodeTypeIfOptional:
7677 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);
76788427 case NodeTypeSwitchExpr:
7679 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);
76808429 case NodeTypeCompTime:
7681 return ir_gen_comptime(irb, scope, node, lval);
8430 return ir_expr_wrap(irb, scope, ir_gen_comptime(irb, scope, node, lval), result_loc);
76828431 case NodeTypeErrorType:
7683 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);
76848433 case NodeTypeBreak:
7685 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);
76868435 case NodeTypeContinue:
7687 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);
76888437 case NodeTypeUnreachable:
7689 return ir_lval_wrap(irb, scope, ir_build_unreachable(irb, scope, node), lval);
8438 return ir_build_unreachable(irb, scope, node);
76908439 case NodeTypeDefer:
7691 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);
76928441 case NodeTypeSliceExpr:
7693 return ir_lval_wrap(irb, scope, ir_gen_slice(irb, scope, node), lval);
7694 case NodeTypeUnwrapErrorExpr:
7695 return ir_lval_wrap(irb, scope, ir_gen_catch(irb, scope, node), lval);
8442 return ir_gen_slice(irb, scope, node, lval, result_loc);
8443 case NodeTypeCatchExpr:
8444 return ir_gen_catch(irb, scope, node, lval, result_loc);
76968445 case NodeTypeContainerDecl:
7697 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);
76988447 case NodeTypeFnProto:
7699 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);
77008449 case NodeTypeErrorSetDecl:
7701 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);
77028451 case NodeTypeCancel:
7703 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);
77048453 case NodeTypeResume:
7705 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);
77068455 case NodeTypeAwaitExpr:
7707 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);
77088457 case NodeTypeSuspend:
7709 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);
77108459 case NodeTypeEnumLiteral:
7711 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);
77128461 case NodeTypeInferredArrayType:
77138462 add_node_error(irb->codegen, node,
77148463 buf_sprintf("inferred array size invalid here"));
......@@ -7717,14 +8466,28 @@ static IrInstruction *ir_gen_node_raw(IrBuilder *irb, AstNode *node, Scope *scop
77178466 zig_unreachable();
77188467}
77198468
7720static IrInstruction *ir_gen_node_extra(IrBuilder *irb, AstNode *node, Scope *scope, LVal lval) {
7721 IrInstruction *result = ir_gen_node_raw(irb, node, scope, lval);
8469static ResultLoc *no_result_loc(void) {
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);
77228485 irb->exec->invalid = irb->exec->invalid || (result == irb->codegen->invalid_instruction);
77238486 return result;
77248487}
77258488
77268489static IrInstruction *ir_gen_node(IrBuilder *irb, AstNode *node, Scope *scope) {
7727 return ir_gen_node_extra(irb, node, scope, LValNone);
8490 return ir_gen_node_extra(irb, node, scope, LValNone, nullptr);
77288491}
77298492
77308493static void invalidate_exec(IrExecutable *exec) {
......@@ -7775,17 +8538,19 @@ bool ir_gen(CodeGen *codegen, AstNode *node, Scope *scope, IrExecutable *ir_exec
77758538
77768539 return_type = fn_entry->type_entry->data.fn.fn_type_id.return_type;
77778540 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
77788542 ZigType *coro_frame_type = get_promise_frame_type(irb->codegen, return_type);
77798543 IrInstruction *coro_frame_type_value = ir_build_const_type(irb, coro_scope, node, coro_frame_type);
7780 // TODO mark this var decl as "no safety" e.g. disable initializing the undef value to 0xaa
7781 ir_build_var_decl_src(irb, coro_scope, node, promise_var, coro_frame_type_value, nullptr, undef);
8544 IrInstruction *undef_coro_frame = ir_build_implicit_cast(irb, coro_scope, node, coro_frame_type_value, undef, nullptr);
8545 build_decl_var_and_init(irb, coro_scope, node, promise_var, undef_coro_frame, "promise", const_bool_false);
77828546 coro_promise_ptr = ir_build_var_ptr(irb, coro_scope, node, promise_var);
77838547
77848548 ZigVar *await_handle_var = ir_create_var(irb, node, coro_scope, nullptr, false, false, true, const_bool_false);
77858549 IrInstruction *null_value = ir_build_const_null(irb, coro_scope, node);
77868550 IrInstruction *await_handle_type_val = ir_build_const_type(irb, coro_scope, node,
77878551 get_optional_type(irb->codegen, irb->codegen->builtin_types.entry_promise));
7788 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);
77898554 irb->exec->await_handle_var_ptr = ir_build_var_ptr(irb, coro_scope, node, await_handle_var);
77908555
77918556 u8_ptr_type = ir_build_const_type(irb, coro_scope, node,
......@@ -7795,13 +8560,14 @@ bool ir_gen(CodeGen *codegen, AstNode *node, Scope *scope, IrExecutable *ir_exec
77958560 coro_id = ir_build_coro_id(irb, coro_scope, node, promise_as_u8_ptr);
77968561 coro_size_var = ir_create_var(irb, node, coro_scope, nullptr, false, false, true, const_bool_false);
77978562 IrInstruction *coro_size = ir_build_coro_size(irb, coro_scope, node);
7798 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);
77998564 IrInstruction *implicit_allocator_ptr = ir_build_get_implicit_allocator(irb, coro_scope, node,
78008565 ImplicitAllocatorIdArg);
78018566 irb->exec->coro_allocator_var = ir_create_var(irb, node, coro_scope, nullptr, true, true, true, const_bool_false);
7802 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);
78038569 Buf *realloc_field_name = buf_create_from_str(ASYNC_REALLOC_FIELD_NAME);
7804 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);
78058571 IrInstruction *realloc_fn = ir_build_load_ptr(irb, coro_scope, node, realloc_fn_ptr);
78068572 IrInstruction *maybe_coro_mem_ptr = ir_build_coro_alloc_helper(irb, coro_scope, node, realloc_fn, coro_size);
78078573 IrInstruction *alloc_result_is_ok = ir_build_test_nonnull(irb, coro_scope, node, maybe_coro_mem_ptr);
......@@ -7821,32 +8587,32 @@ bool ir_gen(CodeGen *codegen, AstNode *node, Scope *scope, IrExecutable *ir_exec
78218587
78228588 Buf *atomic_state_field_name = buf_create_from_str(ATOMIC_STATE_FIELD_NAME);
78238589 irb->exec->atomic_state_field_ptr = ir_build_field_ptr(irb, scope, node, coro_promise_ptr,
7824 atomic_state_field_name);
8590 atomic_state_field_name, false);
78258591 IrInstruction *zero = ir_build_const_usize(irb, scope, node, 0);
78268592 ir_build_store_ptr(irb, scope, node, irb->exec->atomic_state_field_ptr, zero);
78278593 Buf *result_field_name = buf_create_from_str(RESULT_FIELD_NAME);
7828 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);
78298595 result_ptr_field_name = buf_create_from_str(RESULT_PTR_FIELD_NAME);
7830 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);
78318597 ir_build_store_ptr(irb, scope, node, irb->exec->coro_result_ptr_field_ptr, irb->exec->coro_result_field_ptr);
78328598 if (irb->codegen->have_err_ret_tracing) {
78338599 // initialize the error return trace
78348600 Buf *return_addresses_field_name = buf_create_from_str(RETURN_ADDRESSES_FIELD_NAME);
7835 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);
78368602
78378603 Buf *err_ret_trace_field_name = buf_create_from_str(ERR_RET_TRACE_FIELD_NAME);
7838 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);
78398605 ir_build_mark_err_ret_trace_ptr(irb, scope, node, err_ret_trace_ptr);
78408606
78418607 // coordinate with builtin.zig
78428608 Buf *index_name = buf_create_from_str("index");
7843 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);
78448610 ir_build_store_ptr(irb, scope, node, index_ptr, zero);
78458611
78468612 Buf *instruction_addresses_name = buf_create_from_str("instruction_addresses");
7847 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);
78488614
7849 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());
78508616 ir_build_store_ptr(irb, scope, node, addrs_slice_ptr, slice_value);
78518617 }
78528618
......@@ -7857,7 +8623,7 @@ bool ir_gen(CodeGen *codegen, AstNode *node, Scope *scope, IrExecutable *ir_exec
78578623 irb->exec->coro_final_cleanup_block = ir_create_basic_block(irb, scope, "FinalCleanup");
78588624 }
78598625
7860 IrInstruction *result = ir_gen_node_extra(irb, node, scope, LValNone);
8626 IrInstruction *result = ir_gen_node_extra(irb, node, scope, LValNone, nullptr);
78618627 assert(result);
78628628 if (irb->exec->invalid)
78638629 return false;
......@@ -7905,7 +8671,7 @@ bool ir_gen(CodeGen *codegen, AstNode *node, Scope *scope, IrExecutable *ir_exec
79058671 }
79068672 if (irb->codegen->have_err_ret_tracing) {
79078673 Buf *err_ret_trace_ptr_field_name = buf_create_from_str(ERR_RET_TRACE_PTR_FIELD_NAME);
7908 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);
79098675 IrInstruction *dest_err_ret_trace_ptr = ir_build_load_ptr(irb, scope, node, err_ret_trace_ptr_field_ptr);
79108676 ir_build_merge_err_ret_traces(irb, scope, node, coro_promise_ptr, err_ret_trace_ptr, dest_err_ret_trace_ptr);
79118677 }
......@@ -7913,7 +8679,7 @@ bool ir_gen(CodeGen *codegen, AstNode *node, Scope *scope, IrExecutable *ir_exec
79138679 // a register or local variable which does not get spilled into the frame,
79148680 // otherwise llvm tries to access memory inside the destroyed frame.
79158681 IrInstruction *unwrapped_await_handle_ptr = ir_build_optional_unwrap_ptr(irb, scope, node,
7916 irb->exec->await_handle_var_ptr, false);
8682 irb->exec->await_handle_var_ptr, false, false);
79178683 IrInstruction *await_handle_in_block = ir_build_load_ptr(irb, scope, node, unwrapped_await_handle_ptr);
79188684 ir_build_br(irb, scope, node, check_free_block, const_bool_false);
79198685
......@@ -7927,7 +8693,7 @@ bool ir_gen(CodeGen *codegen, AstNode *node, Scope *scope, IrExecutable *ir_exec
79278693 incoming_values[0] = const_bool_false;
79288694 incoming_blocks[1] = irb->exec->coro_normal_final;
79298695 incoming_values[1] = const_bool_true;
7930 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);
79318697
79328698 IrBasicBlock **merge_incoming_blocks = allocate<IrBasicBlock *>(2);
79338699 IrInstruction **merge_incoming_values = allocate<IrInstruction *>(2);
......@@ -7935,12 +8701,12 @@ bool ir_gen(CodeGen *codegen, AstNode *node, Scope *scope, IrExecutable *ir_exec
79358701 merge_incoming_values[0] = ir_build_const_undefined(irb, scope, node);
79368702 merge_incoming_blocks[1] = irb->exec->coro_normal_final;
79378703 merge_incoming_values[1] = await_handle_in_block;
7938 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);
79398705
79408706 Buf *shrink_field_name = buf_create_from_str(ASYNC_SHRINK_FIELD_NAME);
79418707 IrInstruction *implicit_allocator_ptr = ir_build_get_implicit_allocator(irb, scope, node,
79428708 ImplicitAllocatorIdLocalVar);
7943 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);
79448710 IrInstruction *shrink_fn = ir_build_load_ptr(irb, scope, node, shrink_fn_ptr);
79458711 IrInstruction *zero = ir_build_const_usize(irb, scope, node, 0);
79468712 IrInstruction *coro_mem_ptr_maybe = ir_build_coro_free(irb, scope, node, coro_id, irb->exec->coro_handle);
......@@ -7952,7 +8718,8 @@ bool ir_gen(CodeGen *codegen, AstNode *node, Scope *scope, IrExecutable *ir_exec
79528718 IrInstruction *coro_mem_ptr_ref = ir_build_ref(irb, scope, node, coro_mem_ptr, true, false);
79538719 IrInstruction *coro_size_ptr = ir_build_var_ptr(irb, scope, node, coro_size_var);
79548720 IrInstruction *coro_size = ir_build_load_ptr(irb, scope, node, coro_size_ptr);
7955 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());
79568723 size_t arg_count = 5;
79578724 IrInstruction **args = allocate<IrInstruction *>(arg_count);
79588725 args[0] = implicit_allocator_ptr; // self
......@@ -7966,7 +8733,8 @@ bool ir_gen(CodeGen *codegen, AstNode *node, Scope *scope, IrExecutable *ir_exec
79668733 // non-allocating. Basically coroutines are not supported right now until they are reworked.
79678734 args[3] = ir_build_const_usize(irb, scope, node, 1); // new_size
79688735 args[4] = ir_build_const_usize(irb, scope, node, 1); // new_align
7969 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());
79708738
79718739 IrBasicBlock *resume_block = ir_create_basic_block(irb, scope, "Resume");
79728740 ir_build_cond_br(irb, scope, node, resume_awaiter, resume_block, irb->exec->coro_suspend_block, const_bool_false);
......@@ -8073,6 +8841,15 @@ static ConstExprValue *ir_exec_const_result(CodeGen *codegen, IrExecutable *exec
80738841 }
80748842 return &value->value;
80758843 } 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 }
80768853 exec_add_error_node(codegen, exec, instruction->source_node,
80778854 buf_sprintf("unable to evaluate constant expression"));
80788855 return &codegen->invalid_instruction->value;
......@@ -9050,15 +9827,6 @@ static bool ir_num_lit_fits_in_other_type(IrAnalyze *ira, IrInstruction *instruc
90509827 return false;
90519828}
90529829
9053static bool is_slice(ZigType *type) {
9054 return type->id == ZigTypeIdStruct && type->data.structure.is_slice;
9055}
9056
9057static bool slice_is_const(ZigType *type) {
9058 assert(is_slice(type));
9059 return type->data.structure.fields[slice_ptr_index].type_entry->data.pointer.is_const;
9060}
9061
90629830static bool is_tagged_union(ZigType *type) {
90639831 if (type->id != ZigTypeIdUnion)
90649832 return false;
......@@ -9429,9 +10197,21 @@ static ZigType *ir_resolve_peer_types(IrAnalyze *ira, AstNode *source_node, ZigT
942910197{
943010198 Error err;
943110199 assert(instruction_count >= 1);
9432 IrInstruction *prev_inst = instructions[0];
9433 if (type_is_invalid(prev_inst->value.type)) {
9434 return ira->codegen->builtin_types.entry_invalid;
10200 IrInstruction *prev_inst;
10201 size_t i = 0;
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;
943510215 }
943610216 ErrorTableEntry **errors = nullptr;
943710217 size_t errors_count = 0;
......@@ -9456,7 +10236,7 @@ static ZigType *ir_resolve_peer_types(IrAnalyze *ira, AstNode *source_node, ZigT
945610236
945710237 bool any_are_null = (prev_inst->value.type->id == ZigTypeIdNull);
945810238 bool convert_to_const_slice = false;
9459 for (size_t i = 1; i < instruction_count; i += 1) {
10239 for (; i < instruction_count; i += 1) {
946010240 IrInstruction *cur_inst = instructions[i];
946110241 ZigType *cur_type = cur_inst->value.type;
946210242 ZigType *prev_type = prev_inst->value.type;
......@@ -9475,7 +10255,7 @@ static ZigType *ir_resolve_peer_types(IrAnalyze *ira, AstNode *source_node, ZigT
947510255 }
947610256
947710257 if (prev_type->id == ZigTypeIdErrorSet) {
9478 assert(err_set_type != nullptr);
10258 ir_assert(err_set_type != nullptr, prev_inst);
947910259 if (cur_type->id == ZigTypeIdErrorSet) {
948010260 if (type_is_global_error_set(err_set_type)) {
948110261 continue;
......@@ -9735,6 +10515,7 @@ static ZigType *ir_resolve_peer_types(IrAnalyze *ira, AstNode *source_node, ZigT
973510515
973610516 if (prev_type->id == ZigTypeIdNull) {
973710517 prev_inst = cur_inst;
10518 any_are_null = true;
973810519 continue;
973910520 }
974010521
......@@ -10049,6 +10830,8 @@ static ZigType *ir_resolve_peer_types(IrAnalyze *ira, AstNode *source_node, ZigT
1004910830 } else if (prev_inst->value.type->id == ZigTypeIdOptional) {
1005010831 return prev_inst->value.type;
1005110832 } else {
10833 if ((err = type_resolve(ira->codegen, prev_inst->value.type, ResolveStatusSizeKnown)))
10834 return ira->codegen->builtin_types.entry_invalid;
1005210835 return get_optional_type(ira->codegen, prev_inst->value.type);
1005310836 }
1005410837 } else {
......@@ -10056,24 +10839,18 @@ static ZigType *ir_resolve_peer_types(IrAnalyze *ira, AstNode *source_node, ZigT
1005610839 }
1005710840}
1005810841
10059static void ir_add_alloca(IrAnalyze *ira, IrInstruction *instruction, ZigType *type_entry) {
10060 if (type_has_bits(type_entry) && handle_is_ptr(type_entry)) {
10061 ZigFn *fn_entry = exec_fn_entry(ira->new_irb.exec);
10062 if (fn_entry != nullptr) {
10063 fn_entry->alloca_list.append(instruction);
10064 }
10065 }
10066}
10067
1006810842static void copy_const_val(ConstExprValue *dest, ConstExprValue *src, bool same_global_refs) {
1006910843 ConstGlobalRefs *global_refs = dest->global_refs;
10070 assert(!same_global_refs || src->global_refs != nullptr);
10071 *dest = *src;
10844 memcpy(dest, src, sizeof(ConstExprValue));
1007210845 if (!same_global_refs) {
1007310846 dest->global_refs = global_refs;
10847 if (src->special == ConstValSpecialUndef)
10848 return;
1007410849 if (dest->type->id == ZigTypeIdStruct) {
10075 dest->data.x_struct.fields = allocate_nonzero<ConstExprValue>(dest->type->data.structure.src_field_count);
10076 memcpy(dest->data.x_struct.fields, src->data.x_struct.fields, sizeof(ConstExprValue) * dest->type->data.structure.src_field_count);
10850 dest->data.x_struct.fields = create_const_vals(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 }
1007710854 }
1007810855 }
1007910856}
......@@ -10091,7 +10868,6 @@ static bool eval_const_expr_implicit_cast(IrAnalyze *ira, IrInstruction *source_
1009110868 zig_unreachable();
1009210869 case CastOpErrSet:
1009310870 case CastOpBitCast:
10094 case CastOpPtrOfArrayToSlice:
1009510871 zig_panic("TODO");
1009610872 case CastOpNoop:
1009710873 {
......@@ -10191,7 +10967,7 @@ static IrInstruction *ir_const(IrAnalyze *ira, IrInstruction *old_instruction, Z
1019110967}
1019210968
1019310969static IrInstruction *ir_resolve_cast(IrAnalyze *ira, IrInstruction *source_instr, IrInstruction *value,
10194 ZigType *wanted_type, CastOp cast_op, bool need_alloca)
10970 ZigType *wanted_type, CastOp cast_op)
1019510971{
1019610972 if (instr_is_comptime(value) || !type_has_bits(wanted_type)) {
1019710973 IrInstruction *result = ir_const(ira, source_instr, wanted_type);
......@@ -10204,9 +10980,6 @@ static IrInstruction *ir_resolve_cast(IrAnalyze *ira, IrInstruction *source_inst
1020410980 } else {
1020510981 IrInstruction *result = ir_build_cast(&ira->new_irb, source_instr->scope, source_instr->source_node, wanted_type, value, cast_op);
1020610982 result->value.type = wanted_type;
10207 if (need_alloca) {
10208 ir_add_alloca(ira, result, wanted_type);
10209 }
1021010983 return result;
1021110984 }
1021210985}
......@@ -10248,7 +11021,7 @@ static IrInstruction *ir_resolve_ptr_of_array_to_unknown_len_ptr(IrAnalyze *ira,
1024811021}
1024911022
1025011023static IrInstruction *ir_resolve_ptr_of_array_to_slice(IrAnalyze *ira, IrInstruction *source_instr,
10251 IrInstruction *value, ZigType *wanted_type)
11024 IrInstruction *value, ZigType *wanted_type, ResultLoc *result_loc)
1025211025{
1025311026 Error err;
1025411027
......@@ -10279,11 +11052,12 @@ static IrInstruction *ir_resolve_ptr_of_array_to_slice(IrAnalyze *ira, IrInstruc
1027911052 }
1028011053 }
1028111054
10282 IrInstruction *result = ir_build_cast(&ira->new_irb, source_instr->scope, source_instr->source_node,
10283 wanted_type, value, CastOpPtrOfArrayToSlice);
10284 result->value.type = wanted_type;
10285 ir_add_alloca(ira, result, wanted_type);
10286 return result;
11055 if (result_loc == nullptr) result_loc = no_result_loc();
11056 IrInstruction *result_loc_inst = ir_resolve_result(ira, source_instr, result_loc, wanted_type, nullptr, true, false);
11057 if (type_is_invalid(result_loc_inst->value.type) || instr_is_unreachable(result_loc_inst)) {
11058 return result_loc_inst;
11059 }
11060 return ir_build_ptr_of_array_to_slice(ira, source_instr, wanted_type, value, result_loc_inst);
1028711061}
1028811062
1028911063static IrBasicBlock *ir_get_new_bb(IrAnalyze *ira, IrBasicBlock *old_bb, IrInstruction *ref_old_instruction) {
......@@ -10315,51 +11089,136 @@ static IrBasicBlock *ir_get_new_bb_runtime(IrAnalyze *ira, IrBasicBlock *old_bb,
1031511089}
1031611090
1031711091static void ir_start_bb(IrAnalyze *ira, IrBasicBlock *old_bb, IrBasicBlock *const_predecessor_bb) {
11092 assert(!old_bb->suspended);
1031811093 ira->instruction_index = 0;
1031911094 ira->old_irb.current_basic_block = old_bb;
1032011095 ira->const_predecessor_bb = const_predecessor_bb;
11096 ira->old_bb_index = old_bb->index;
1032111097}
1032211098
10323static void ir_finish_bb(IrAnalyze *ira) {
10324 ira->new_irb.exec->basic_block_list.append(ira->new_irb.current_basic_block);
10325 ira->instruction_index += 1;
10326 while (ira->instruction_index < ira->old_irb.current_basic_block->instruction_list.length) {
10327 IrInstruction *next_instruction = ira->old_irb.current_basic_block->instruction_list.at(ira->instruction_index);
10328 if (!next_instruction->is_gen) {
10329 ir_add_error(ira, next_instruction, buf_sprintf("unreachable code"));
10330 break;
10331 }
10332 ira->instruction_index += 1;
11099static IrInstruction *ira_suspend(IrAnalyze *ira, IrInstruction *old_instruction, IrBasicBlock *next_bb,
11100 IrSuspendPosition *suspend_pos)
11101{
11102 if (ira->codegen->verbose_ir) {
11103 fprintf(stderr, "suspend %s_%zu %s_%zu #%zu (%zu,%zu)\n", ira->old_irb.current_basic_block->name_hint,
11104 ira->old_irb.current_basic_block->debug_id,
11105 ira->old_irb.exec->basic_block_list.at(ira->old_bb_index)->name_hint,
11106 ira->old_irb.exec->basic_block_list.at(ira->old_bb_index)->debug_id,
11107 ira->old_irb.current_basic_block->instruction_list.at(ira->instruction_index)->debug_id,
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;
1033311124 }
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}
1033411150
10335 size_t my_old_bb_index = ira->old_bb_index;
11151static void ir_start_next_bb(IrAnalyze *ira) {
1033611152 ira->old_bb_index += 1;
1033711153
1033811154 bool need_repeat = true;
1033911155 for (;;) {
1034011156 while (ira->old_bb_index < ira->old_irb.exec->basic_block_list.length) {
1034111157 IrBasicBlock *old_bb = ira->old_irb.exec->basic_block_list.at(ira->old_bb_index);
10342 if (old_bb->other == nullptr) {
11158 if (old_bb->other == nullptr && old_bb->suspend_instruction_ref == nullptr) {
1034311159 ira->old_bb_index += 1;
1034411160 continue;
1034511161 }
10346 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 {
1034711169 ira->old_bb_index += 1;
1034811170 continue;
1034911171 }
10350 ira->new_irb.current_basic_block = old_bb->other;
1035111172
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;
1035211185 ir_start_bb(ira, old_bb, nullptr);
1035311186 return;
1035411187 }
10355 if (!need_repeat)
11188 if (!need_repeat) {
11189 if (ira->resume_stack.length != 0) {
11190 ira_resume(ira);
11191 }
1035611192 return;
11193 }
1035711194 need_repeat = false;
1035811195 ira->old_bb_index = 0;
1035911196 continue;
1036011197 }
1036111198}
1036211199
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
1036311222static IrInstruction *ir_unreach_error(IrAnalyze *ira) {
1036411223 ira->old_bb_index = SIZE_MAX;
1036511224 ira->new_irb.exec->invalid = true;
......@@ -10420,6 +11279,12 @@ static IrInstruction *ir_const_undef(IrAnalyze *ira, IrInstruction *source_instr
1042011279 return result;
1042111280}
1042211281
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
1042311288static IrInstruction *ir_const_void(IrAnalyze *ira, IrInstruction *source_instruction) {
1042411289 return ir_const(ira, source_instruction, ira->codegen->builtin_types.entry_void);
1042511290}
......@@ -10617,7 +11482,7 @@ static ZigFn *ir_resolve_fn(IrAnalyze *ira, IrInstruction *fn_value) {
1061711482}
1061811483
1061911484static IrInstruction *ir_analyze_optional_wrap(IrAnalyze *ira, IrInstruction *source_instr, IrInstruction *value,
10620 ZigType *wanted_type)
11485 ZigType *wanted_type, ResultLoc *result_loc)
1062111486{
1062211487 assert(wanted_type->id == ZigTypeIdOptional);
1062311488
......@@ -10643,20 +11508,29 @@ static IrInstruction *ir_analyze_optional_wrap(IrAnalyze *ira, IrInstruction *so
1064311508 return &const_instruction->base;
1064411509 }
1064511510
10646 IrInstruction *result = ir_build_maybe_wrap(&ira->new_irb, source_instr->scope, source_instr->source_node, value);
10647 result->value.type = wanted_type;
11511 if (result_loc == nullptr && handle_is_ptr(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);
1064811522 result->value.data.rh_maybe = RuntimeHintOptionalNonNull;
10649 ir_add_alloca(ira, result, wanted_type);
1065011523 return result;
1065111524}
1065211525
1065311526static IrInstruction *ir_analyze_err_wrap_payload(IrAnalyze *ira, IrInstruction *source_instr,
10654 IrInstruction *value, ZigType *wanted_type)
11527 IrInstruction *value, ZigType *wanted_type, ResultLoc *result_loc)
1065511528{
1065611529 assert(wanted_type->id == ZigTypeIdErrorUnion);
1065711530
11531 ZigType *payload_type = wanted_type->data.error_union.payload_type;
11532 ZigType *err_set_type = wanted_type->data.error_union.err_set_type;
1065811533 if (instr_is_comptime(value)) {
10659 ZigType *payload_type = wanted_type->data.error_union.payload_type;
1066011534 IrInstruction *casted_payload = ir_implicit_cast(ira, value, payload_type);
1066111535 if (type_is_invalid(casted_payload->value.type))
1066211536 return ira->codegen->invalid_instruction;
......@@ -10666,7 +11540,7 @@ static IrInstruction *ir_analyze_err_wrap_payload(IrAnalyze *ira, IrInstruction
1066611540 return ira->codegen->invalid_instruction;
1066711541
1066811542 ConstExprValue *err_set_val = create_const_vals(1);
10669 err_set_val->type = wanted_type->data.error_union.err_set_type;
11543 err_set_val->type = err_set_type;
1067011544 err_set_val->special = ConstValSpecialStatic;
1067111545 err_set_val->data.x_err_set = nullptr;
1067211546
......@@ -10679,10 +11553,19 @@ static IrInstruction *ir_analyze_err_wrap_payload(IrAnalyze *ira, IrInstruction
1067911553 return &const_instruction->base;
1068011554 }
1068111555
10682 IrInstruction *result = ir_build_err_wrap_payload(&ira->new_irb, source_instr->scope, source_instr->source_node, value);
10683 result->value.type = wanted_type;
11556 IrInstruction *result_loc_inst;
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);
1068411568 result->value.data.rh_error_union = RuntimeHintErrorUnionNonError;
10685 ir_add_alloca(ira, result, wanted_type);
1068611569 return result;
1068711570}
1068811571
......@@ -10729,7 +11612,9 @@ static IrInstruction *ir_analyze_err_set_cast(IrAnalyze *ira, IrInstruction *sou
1072911612 return result;
1073011613}
1073111614
10732static 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{
1073311618 assert(wanted_type->id == ZigTypeIdErrorUnion);
1073411619
1073511620 IrInstruction *casted_value = ir_implicit_cast(ira, value, wanted_type->data.error_union.err_set_type);
......@@ -10753,10 +11638,20 @@ static IrInstruction *ir_analyze_err_wrap_code(IrAnalyze *ira, IrInstruction *so
1075311638 return &const_instruction->base;
1075411639 }
1075511640
10756 IrInstruction *result = ir_build_err_wrap_code(&ira->new_irb, source_instr->scope, source_instr->source_node, value);
10757 result->value.type = wanted_type;
11641 IrInstruction *result_loc_inst;
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);
1075811654 result->value.data.rh_error_union = RuntimeHintErrorUnionError;
10759 ir_add_alloca(ira, result, wanted_type);
1076011655 return result;
1076111656}
1076211657
......@@ -10816,20 +11711,21 @@ static IrInstruction *ir_get_ref(IrAnalyze *ira, IrInstruction *source_instructi
1081611711
1081711712 ZigType *ptr_type = get_pointer_to_type_extra(ira->codegen, value->value.type,
1081811713 is_const, is_volatile, PtrLenSingle, 0, 0, 0, false);
10819 IrInstruction *new_instruction = ir_build_ref(&ira->new_irb, source_instruction->scope,
10820 source_instruction->source_node, value, is_const, is_volatile);
10821 new_instruction->value.type = ptr_type;
10822 new_instruction->value.data.rh_ptr = RuntimeHintPtrStack;
11714
11715 IrInstruction *result_loc;
1082311716 if (type_has_bits(ptr_type) && !handle_is_ptr(value->value.type)) {
10824 ZigFn *fn_entry = exec_fn_entry(ira->new_irb.exec);
10825 assert(fn_entry);
10826 fn_entry->alloca_list.append(new_instruction);
11717 result_loc = ir_resolve_result(ira, source_instruction, no_result_loc(), value->value.type, nullptr, true, false);
11718 } else {
11719 result_loc = nullptr;
1082711720 }
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;
1082811724 return new_instruction;
1082911725}
1083011726
1083111727static IrInstruction *ir_analyze_array_to_slice(IrAnalyze *ira, IrInstruction *source_instr,
10832 IrInstruction *array_arg, ZigType *wanted_type)
11728 IrInstruction *array_arg, ZigType *wanted_type, ResultLoc *result_loc)
1083311729{
1083411730 assert(is_slice(wanted_type));
1083511731 // In this function we honor the const-ness of wanted_type, because
......@@ -10838,7 +11734,7 @@ static IrInstruction *ir_analyze_array_to_slice(IrAnalyze *ira, IrInstruction *s
1083811734 IrInstruction *array_ptr = nullptr;
1083911735 IrInstruction *array;
1084011736 if (array_arg->value.type->id == ZigTypeIdPointer) {
10841 array = ir_get_deref(ira, source_instr, array_arg);
11737 array = ir_get_deref(ira, source_instr, array_arg, nullptr);
1084211738 array_ptr = array_arg;
1084311739 } else {
1084411740 array = array_arg;
......@@ -10861,12 +11757,14 @@ static IrInstruction *ir_analyze_array_to_slice(IrAnalyze *ira, IrInstruction *s
1086111757
1086211758 if (!array_ptr) array_ptr = ir_get_ref(ira, source_instr, array, true, false);
1086311759
10864 IrInstruction *result = ir_build_slice(&ira->new_irb, source_instr->scope,
10865 source_instr->source_node, array_ptr, start, end, false);
10866 result->value.type = wanted_type;
11760 if (result_loc == nullptr) result_loc = no_result_loc();
11761 IrInstruction *result_loc_inst = ir_resolve_result(ira, source_instr, result_loc, wanted_type, nullptr, true, false);
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);
1086711766 result->value.data.rh_slice.id = RuntimeHintSliceIdLen;
1086811767 result->value.data.rh_slice.len = array_type->data.array.len;
10869 ir_add_alloca(ira, result, result->value.type);
1087011768
1087111769 return result;
1087211770}
......@@ -11504,7 +12402,7 @@ static IrInstruction *ir_analyze_array_to_vector(IrAnalyze *ira, IrInstruction *
1150412402}
1150512403
1150612404static IrInstruction *ir_analyze_vector_to_array(IrAnalyze *ira, IrInstruction *source_instr,
11507 IrInstruction *vector, ZigType *array_type)
12405 IrInstruction *vector, ZigType *array_type, ResultLoc *result_loc)
1150812406{
1150912407 if (instr_is_comptime(vector)) {
1151012408 // arrays and vectors have the same ConstExprValue representation
......@@ -11513,7 +12411,14 @@ static IrInstruction *ir_analyze_vector_to_array(IrAnalyze *ira, IrInstruction *
1151312411 result->value.type = array_type;
1151412412 return result;
1151512413 }
11516 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);
1151712422}
1151812423
1151912424static IrInstruction *ir_analyze_int_to_c_ptr(IrAnalyze *ira, IrInstruction *source_instr,
......@@ -11563,7 +12468,7 @@ static bool is_pointery_and_elem_is_not_pointery(ZigType *ty) {
1156312468}
1156412469
1156512470static IrInstruction *ir_analyze_cast(IrAnalyze *ira, IrInstruction *source_instr,
11566 ZigType *wanted_type, IrInstruction *value)
12471 ZigType *wanted_type, IrInstruction *value, ResultLoc *result_loc)
1156712472{
1156812473 Error err;
1156912474 ZigType *actual_type = value->value.type;
......@@ -11579,7 +12484,7 @@ static IrInstruction *ir_analyze_cast(IrAnalyze *ira, IrInstruction *source_inst
1157912484 if (const_cast_result.id == ConstCastResultIdInvalid)
1158012485 return ira->codegen->invalid_instruction;
1158112486 if (const_cast_result.id == ConstCastResultIdOk) {
11582 return ir_resolve_cast(ira, source_instr, value, wanted_type, CastOpNoop, false);
12487 return ir_resolve_cast(ira, source_instr, value, wanted_type, CastOpNoop);
1158312488 }
1158412489
1158512490 // cast from T to ?T
......@@ -11589,12 +12494,12 @@ static IrInstruction *ir_analyze_cast(IrAnalyze *ira, IrInstruction *source_inst
1158912494 if (types_match_const_cast_only(ira, wanted_child_type, actual_type, source_node,
1159012495 false).id == ConstCastResultIdOk)
1159112496 {
11592 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);
1159312498 } else if (actual_type->id == ZigTypeIdComptimeInt ||
1159412499 actual_type->id == ZigTypeIdComptimeFloat)
1159512500 {
1159612501 if (ir_num_lit_fits_in_other_type(ira, value, wanted_child_type, true)) {
11597 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);
1159812503 } else {
1159912504 return ira->codegen->invalid_instruction;
1160012505 }
......@@ -11618,7 +12523,7 @@ static IrInstruction *ir_analyze_cast(IrAnalyze *ira, IrInstruction *source_inst
1161812523 wanted_child_type);
1161912524 if (type_is_invalid(cast1->value.type))
1162012525 return ira->codegen->invalid_instruction;
11621 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);
1162212527 }
1162312528 }
1162412529 }
......@@ -11628,12 +12533,12 @@ static IrInstruction *ir_analyze_cast(IrAnalyze *ira, IrInstruction *source_inst
1162812533 if (types_match_const_cast_only(ira, wanted_type->data.error_union.payload_type, actual_type,
1162912534 source_node, false).id == ConstCastResultIdOk)
1163012535 {
11631 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);
1163212537 } else if (actual_type->id == ZigTypeIdComptimeInt ||
1163312538 actual_type->id == ZigTypeIdComptimeFloat)
1163412539 {
1163512540 if (ir_num_lit_fits_in_other_type(ira, value, wanted_type->data.error_union.payload_type, true)) {
11636 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);
1163712542 } else {
1163812543 return ira->codegen->invalid_instruction;
1163912544 }
......@@ -11651,11 +12556,11 @@ static IrInstruction *ir_analyze_cast(IrAnalyze *ira, IrInstruction *source_inst
1165112556 actual_type->id == ZigTypeIdComptimeInt ||
1165212557 actual_type->id == ZigTypeIdComptimeFloat)
1165312558 {
11654 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);
1165512560 if (type_is_invalid(cast1->value.type))
1165612561 return ira->codegen->invalid_instruction;
1165712562
11658 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);
1165912564 if (type_is_invalid(cast2->value.type))
1166012565 return ira->codegen->invalid_instruction;
1166112566
......@@ -11737,7 +12642,7 @@ static IrInstruction *ir_analyze_cast(IrAnalyze *ira, IrInstruction *source_inst
1173712642 types_match_const_cast_only(ira, ptr_type->data.pointer.child_type, actual_type->data.array.child_type,
1173812643 source_node, false).id == ConstCastResultIdOk)
1173912644 {
11740 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);
1174112646 }
1174212647 }
1174312648
......@@ -11754,11 +12659,11 @@ static IrInstruction *ir_analyze_cast(IrAnalyze *ira, IrInstruction *source_inst
1175412659 types_match_const_cast_only(ira, ptr_type->data.pointer.child_type, actual_type->data.array.child_type,
1175512660 source_node, false).id == ConstCastResultIdOk)
1175612661 {
11757 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);
1175812663 if (type_is_invalid(cast1->value.type))
1175912664 return ira->codegen->invalid_instruction;
1176012665
11761 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);
1176212667 if (type_is_invalid(cast2->value.type))
1176312668 return ira->codegen->invalid_instruction;
1176412669
......@@ -11801,7 +12706,7 @@ static IrInstruction *ir_analyze_cast(IrAnalyze *ira, IrInstruction *source_inst
1180112706 array_type->data.array.child_type, source_node,
1180212707 !slice_ptr_type->data.pointer.is_const).id == ConstCastResultIdOk)
1180312708 {
11804 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);
1180512710 }
1180612711 }
1180712712
......@@ -11832,11 +12737,11 @@ static IrInstruction *ir_analyze_cast(IrAnalyze *ira, IrInstruction *source_inst
1183212737 types_match_const_cast_only(ira, ptr_type->data.pointer.child_type, actual_type->data.array.child_type,
1183312738 source_node, false).id == ConstCastResultIdOk)
1183412739 {
11835 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);
1183612741 if (type_is_invalid(cast1->value.type))
1183712742 return ira->codegen->invalid_instruction;
1183812743
11839 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);
1184012745 if (type_is_invalid(cast2->value.type))
1184112746 return ira->codegen->invalid_instruction;
1184212747
......@@ -11848,7 +12753,7 @@ static IrInstruction *ir_analyze_cast(IrAnalyze *ira, IrInstruction *source_inst
1184812753 if (wanted_type->id == ZigTypeIdErrorUnion &&
1184912754 actual_type->id == ZigTypeIdErrorSet)
1185012755 {
11851 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);
1185212757 }
1185312758
1185412759 // cast from typed number to integer or float literal.
......@@ -11972,7 +12877,7 @@ static IrInstruction *ir_analyze_cast(IrAnalyze *ira, IrInstruction *source_inst
1197212877 types_match_const_cast_only(ira, wanted_type->data.array.child_type,
1197312878 actual_type->data.vector.elem_type, source_node, false).id == ConstCastResultIdOk)
1197412879 {
11975 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);
1197612881 }
1197712882
1197812883 // cast from [N]T to @Vector(N, T)
......@@ -12014,7 +12919,9 @@ static IrInstruction *ir_analyze_cast(IrAnalyze *ira, IrInstruction *source_inst
1201412919 return ira->codegen->invalid_instruction;
1201512920}
1201612921
12017static 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{
1201812925 assert(value);
1201912926 assert(value != ira->codegen->invalid_instruction);
1202012927 assert(!expected_type || !type_is_invalid(expected_type));
......@@ -12027,63 +12934,76 @@ static IrInstruction *ir_implicit_cast(IrAnalyze *ira, IrInstruction *value, Zig
1202712934 if (value->value.type->id == ZigTypeIdUnreachable)
1202812935 return value;
1202912936
12030 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);
1203112942}
1203212943
12033static 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{
1203412947 Error err;
1203512948 ZigType *type_entry = ptr->value.type;
12036 if (type_is_invalid(type_entry)) {
12949 if (type_is_invalid(type_entry))
1203712950 return ira->codegen->invalid_instruction;
12038 } else if (type_entry->id == ZigTypeIdPointer) {
12039 ZigType *child_type = type_entry->data.pointer.child_type;
12040 // if the child type has one possible value, the deref is comptime
12041 switch (type_has_one_possible_value(ira->codegen, child_type)) {
12042 case OnePossibleValueInvalid:
12043 return ira->codegen->invalid_instruction;
12044 case OnePossibleValueYes:
12045 return ir_const(ira, source_instruction, child_type);
12046 case OnePossibleValueNo:
12047 break;
12951
12952 if (type_entry->id != ZigTypeIdPointer) {
12953 ir_add_error_node(ira, source_instruction->source_node,
12954 buf_sprintf("attempt to dereference non-pointer type '%s'",
12955 buf_ptr(&type_entry->name)));
12956 return ira->codegen->invalid_instruction;
12957 }
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;
1204812973 }
12049 if (instr_is_comptime(ptr)) {
12050 if (ptr->value.special == ConstValSpecialUndef) {
12051 ir_add_error(ira, ptr, buf_sprintf("attempt to dereference undefined value"));
12052 return ira->codegen->invalid_instruction;
12053 }
12054 if (ptr->value.data.x_ptr.mut == ConstPtrMutComptimeConst ||
12055 ptr->value.data.x_ptr.mut == ConstPtrMutComptimeVar)
12056 {
12057 ConstExprValue *pointee = const_ptr_pointee_unchecked(ira->codegen, &ptr->value);
12058 if (pointee->special != ConstValSpecialRuntime) {
12059 IrInstruction *result = ir_const(ira, source_instruction, child_type);
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);
1206012978
12061 if ((err = ir_read_const_ptr(ira, ira->codegen, source_instruction->source_node, &result->value,
12062 &ptr->value)))
12063 {
12064 return ira->codegen->invalid_instruction;
12065 }
12066 result->value.type = child_type;
12067 return result;
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;
1206812983 }
12984 result->value.type = child_type;
12985 return result;
1206912986 }
1207012987 }
12071 // if the instruction is a const ref instruction we can skip it
12072 if (ptr->id == IrInstructionIdRef) {
12073 IrInstructionRef *ref_inst = reinterpret_cast<IrInstructionRef *>(ptr);
12074 return ref_inst->value;
12075 }
12076 IrInstruction *result = ir_build_load_ptr_gen(ira, source_instruction, ptr, child_type);
12077 if (type_entry->data.pointer.host_int_bytes != 0 && handle_is_ptr(child_type)) {
12078 ir_add_alloca(ira, result, child_type);
12988 }
12989 // if the instruction is a const ref instruction we can skip it
12990 if (ptr->id == IrInstructionIdRef) {
12991 IrInstructionRef *ref_inst = reinterpret_cast<IrInstructionRef *>(ptr);
12992 return ref_inst->value;
12993 }
12994
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;
1207913001 }
12080 return result;
1208113002 } else {
12082 ir_add_error_node(ira, source_instruction->source_node,
12083 buf_sprintf("attempt to dereference non-pointer type '%s'",
12084 buf_ptr(&type_entry->name)));
12085 return ira->codegen->invalid_instruction;
13003 result_loc_inst = nullptr;
1208613004 }
13005
13006 return ir_build_load_ptr_gen(ira, source_instruction, ptr, child_type, result_loc_inst);
1208713007}
1208813008
1208913009static bool ir_resolve_align(IrAnalyze *ira, IrInstruction *value, uint32_t *out) {
......@@ -12297,6 +13217,14 @@ static IrInstruction *ir_analyze_instruction_return(IrAnalyze *ira, IrInstructio
1229713217 if (type_is_invalid(value->value.type))
1229813218 return ir_unreach_error(ira);
1229913219
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
1230013228 IrInstruction *casted_value = ir_implicit_cast(ira, value, ira->explicit_return_type);
1230113229 if (type_is_invalid(casted_value->value.type)) {
1230213230 AstNode *source_node = ira->explicit_return_type_source_node;
......@@ -12459,7 +13387,7 @@ static IrInstruction *ir_analyze_bin_op_cmp(IrAnalyze *ira, IrInstructionBinOp *
1245913387 } else {
1246013388 return is_non_null;
1246113389 }
12462 } else if (is_equality_cmp &&
13390 } else if (is_equality_cmp &&
1246313391 ((op1->value.type->id == ZigTypeIdNull && op2->value.type->id == ZigTypeIdPointer &&
1246413392 op2->value.type->data.pointer.ptr_len == PtrLenC) ||
1246513393 (op2->value.type->id == ZigTypeIdNull && op1->value.type->id == ZigTypeIdPointer &&
......@@ -12901,7 +13829,7 @@ static ErrorMsg *ir_eval_math_op_scalar(IrAnalyze *ira, IrInstruction *source_in
1290113829 }
1290213830 } else {
1290313831 float_div_trunc(out_val, op1_val, op2_val);
12904 ConstExprValue remainder;
13832 ConstExprValue remainder = {};
1290513833 float_rem(&remainder, op1_val, op2_val);
1290613834 if (float_cmp_zero(&remainder) != CmpEQ) {
1290713835 return ir_add_error(ira, source_instr, buf_sprintf("exact division had a remainder"));
......@@ -13276,8 +14204,8 @@ static IrInstruction *ir_analyze_bin_op_math(IrAnalyze *ira, IrInstructionBinOp
1327614204 // have a remainder function ambiguity problem
1327714205 ok = true;
1327814206 } else {
13279 ConstExprValue rem_result;
13280 ConstExprValue mod_result;
14207 ConstExprValue rem_result = {};
14208 ConstExprValue mod_result = {};
1328114209 float_rem(&rem_result, op1_val, op2_val);
1328214210 float_mod(&mod_result, op1_val, op2_val);
1328314211 ok = float_cmp(&rem_result, &mod_result) == CmpEQ;
......@@ -13500,10 +14428,12 @@ static IrInstruction *ir_analyze_array_cat(IrAnalyze *ira, IrInstructionBinOp *i
1350014428
1350114429 size_t next_index = 0;
1350214430 for (size_t i = op1_array_index; i < op1_array_end; i += 1, next_index += 1) {
13503 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);
1350414433 }
1350514434 for (size_t i = op2_array_index; i < op2_array_end; i += 1, next_index += 1) {
13506 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);
1350714437 }
1350814438 if (next_index < new_len) {
1350914439 ConstExprValue *null_byte = &out_array_val->data.x_array.data.s_none.elements[next_index];
......@@ -13564,7 +14494,8 @@ static IrInstruction *ir_analyze_array_mult(IrAnalyze *ira, IrInstructionBinOp *
1356414494 uint64_t i = 0;
1356514495 for (uint64_t x = 0; x < mult_amt; x += 1) {
1356614496 for (uint64_t y = 0; y < old_array_len; y += 1) {
13567 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);
1356814499 i += 1;
1356914500 }
1357014501 }
......@@ -13661,12 +14592,6 @@ static IrInstruction *ir_analyze_instruction_decl_var(IrAnalyze *ira,
1366114592 Error err;
1366214593 ZigVar *var = decl_var_instruction->var;
1366314594
13664 IrInstruction *init_value = decl_var_instruction->init_value->child;
13665 if (type_is_invalid(init_value->value.type)) {
13666 var->var_type = ira->codegen->builtin_types.entry_invalid;
13667 return ira->codegen->invalid_instruction;
13668 }
13669
1367014595 ZigType *explicit_type = nullptr;
1367114596 IrInstruction *var_type = nullptr;
1367214597 if (decl_var_instruction->var_type != nullptr) {
......@@ -13681,18 +14606,40 @@ static IrInstruction *ir_analyze_instruction_decl_var(IrAnalyze *ira,
1368114606
1368214607 AstNode *source_node = decl_var_instruction->base.source_node;
1368314608
13684 IrInstruction *casted_init_value = ir_implicit_cast(ira, init_value, explicit_type);
1368514609 bool is_comptime_var = ir_get_var_is_comptime(var);
1368614610
1368714611 bool var_class_requires_const = false;
1368814612
13689 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;
1369014626 if (type_is_invalid(result_type)) {
1369114627 result_type = ira->codegen->builtin_types.entry_invalid;
1369214628 } else if (result_type->id == ZigTypeIdUnreachable || result_type->id == ZigTypeIdOpaque) {
13693 ir_add_error_node(ira, source_node,
13694 buf_sprintf("variable of type '%s' not allowed", buf_ptr(&result_type->name)));
13695 result_type = ira->codegen->builtin_types.entry_invalid;
14629 zig_unreachable();
14630 }
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 }
1369614643 }
1369714644
1369814645 switch (type_requires_comptime(ira->codegen, result_type)) {
......@@ -13709,18 +14656,20 @@ static IrInstruction *ir_analyze_instruction_decl_var(IrAnalyze *ira,
1370914656 }
1371014657 break;
1371114658 case ReqCompTimeNo:
13712 if (casted_init_value->value.special == ConstValSpecialStatic &&
13713 casted_init_value->value.type->id == ZigTypeIdFn &&
13714 casted_init_value->value.data.x_ptr.special != ConstPtrSpecialHardCodedAddr &&
13715 casted_init_value->value.data.x_ptr.data.fn.fn_entry->fn_inline == FnInlineAlways)
13716 {
13717 var_class_requires_const = true;
13718 if (!var->src_is_const && !is_comptime_var) {
13719 ErrorMsg *msg = ir_add_error_node(ira, source_node,
13720 buf_sprintf("functions marked inline must be stored in const or comptime var"));
13721 AstNode *proto_node = casted_init_value->value.data.x_ptr.data.fn.fn_entry->proto_node;
13722 add_error_note(ira->codegen, msg, proto_node, buf_sprintf("declared here"));
13723 result_type = ira->codegen->builtin_types.entry_invalid;
14659 if (init_val != nullptr) {
14660 if (init_val->special == ConstValSpecialStatic &&
14661 init_val->type->id == ZigTypeIdFn &&
14662 init_val->data.x_ptr.special != ConstPtrSpecialHardCodedAddr &&
14663 init_val->data.x_ptr.data.fn.fn_entry->fn_inline == FnInlineAlways)
14664 {
14665 var_class_requires_const = true;
14666 if (!var->src_is_const && !is_comptime_var) {
14667 ErrorMsg *msg = ir_add_error_node(ira, source_node,
14668 buf_sprintf("functions marked inline must be stored in const or comptime var"));
14669 AstNode *proto_node = init_val->data.x_ptr.data.fn.fn_entry->proto_node;
14670 add_error_note(ira->codegen, msg, proto_node, buf_sprintf("declared here"));
14671 result_type = ira->codegen->builtin_types.entry_invalid;
14672 }
1372414673 }
1372514674 }
1372614675 break;
......@@ -13767,11 +14716,29 @@ static IrInstruction *ir_analyze_instruction_decl_var(IrAnalyze *ira,
1376714716 }
1376814717 }
1376914718
13770 if (casted_init_value->value.special != ConstValSpecialRuntime) {
13771 if (var->mem_slot_index != SIZE_MAX) {
14719 if (init_val != nullptr && init_val->special != ConstValSpecialRuntime) {
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) {
1377214739 assert(var->mem_slot_index < ira->exec_context.mem_slot_list.length);
1377314740 ConstExprValue *mem_slot = ira->exec_context.mem_slot_list.at(var->mem_slot_index);
13774 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);
1377514742
1377614743 if (is_comptime_var || (var_class_requires_const && var->gen_is_const)) {
1377714744 return ir_const_void(ira, &decl_var_instruction->base);
......@@ -13788,7 +14755,7 @@ static IrInstruction *ir_analyze_instruction_decl_var(IrAnalyze *ira,
1378814755 if (fn_entry)
1378914756 fn_entry->variable_list.append(var);
1379014757
13791 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);
1379214759}
1379314760
1379414761static IrInstruction *ir_analyze_instruction_export(IrAnalyze *ira, IrInstructionExport *instruction) {
......@@ -14082,7 +15049,7 @@ IrInstruction *ir_get_implicit_allocator(IrAnalyze *ira, IrInstruction *source_i
1408215049 ZigVar *coro_allocator_var = ira->old_irb.exec->coro_allocator_var;
1408315050 assert(coro_allocator_var != nullptr);
1408415051 IrInstruction *var_ptr_inst = ir_get_var_ptr(ira, source_instr, coro_allocator_var);
14085 IrInstruction *result = ir_get_deref(ira, source_instr, var_ptr_inst);
15052 IrInstruction *result = ir_get_deref(ira, source_instr, var_ptr_inst, nullptr);
1408615053 assert(result->value.type != nullptr);
1408715054 return result;
1408815055 }
......@@ -14090,109 +15057,543 @@ IrInstruction *ir_get_implicit_allocator(IrAnalyze *ira, IrInstruction *source_i
1409015057 zig_unreachable();
1409115058}
1409215059
14093static IrInstruction *ir_analyze_async_call(IrAnalyze *ira, IrInstructionCall *call_instruction, ZigFn *fn_entry,
14094 ZigType *fn_type, IrInstruction *fn_ref, IrInstruction **casted_args, size_t arg_count,
14095 IrInstruction *async_allocator_inst)
15060static IrInstruction *ir_analyze_alloca(IrAnalyze *ira, IrInstruction *source_inst, ZigType *var_type,
15061 uint32_t align, const char *name_hint, bool force_comptime)
1409615062{
14097 Buf *realloc_field_name = buf_create_from_str(ASYNC_REALLOC_FIELD_NAME);
14098 ir_assert(async_allocator_inst->value.type->id == ZigTypeIdPointer, &call_instruction->base);
14099 ZigType *container_type = async_allocator_inst->value.type->data.pointer.child_type;
14100 IrInstruction *field_ptr_inst = ir_analyze_container_field_ptr(ira, realloc_field_name, &call_instruction->base,
14101 async_allocator_inst, container_type);
14102 if (type_is_invalid(field_ptr_inst->value.type)) {
14103 return ira->codegen->invalid_instruction;
14104 }
14105 ZigType *ptr_to_realloc_fn_type = field_ptr_inst->value.type;
14106 ir_assert(ptr_to_realloc_fn_type->id == ZigTypeIdPointer, &call_instruction->base);
15063 Error err;
1410715064
14108 ZigType *realloc_fn_type = ptr_to_realloc_fn_type->data.pointer.child_type;
14109 if (realloc_fn_type->id != ZigTypeIdFn) {
14110 ir_add_error(ira, &call_instruction->base,
14111 buf_sprintf("expected reallocation function, found '%s'", buf_ptr(&realloc_fn_type->name)));
14112 return ira->codegen->invalid_instruction;
14113 }
15065 ConstExprValue *pointee = create_const_vals(1);
15066 pointee->special = ConstValSpecialUndef;
1411415067
14115 ZigType *realloc_fn_return_type = realloc_fn_type->data.fn.fn_type_id.return_type;
14116 if (realloc_fn_return_type->id != ZigTypeIdErrorUnion) {
14117 ir_add_error(ira, fn_ref,
14118 buf_sprintf("expected allocation function to return error union, but it returns '%s'", buf_ptr(&realloc_fn_return_type->name)));
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)))
1411915075 return ira->codegen->invalid_instruction;
14120 }
14121 ZigType *alloc_fn_error_set_type = realloc_fn_return_type->data.error_union.err_set_type;
14122 ZigType *return_type = fn_type->data.fn.fn_type_id.return_type;
14123 ZigType *promise_type = get_promise_type(ira->codegen, return_type);
14124 ZigType *async_return_type = get_error_union_type(ira->codegen, alloc_fn_error_set_type, promise_type);
15076 assert(result->base.value.data.x_ptr.special != ConstPtrSpecialInvalid);
1412515077
14126 IrInstruction *result = ir_build_call(&ira->new_irb, call_instruction->base.scope, call_instruction->base.source_node,
14127 fn_entry, fn_ref, arg_count, casted_args, false, FnInlineAuto, true, async_allocator_inst, nullptr);
14128 result->value.type = async_return_type;
14129 return result;
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;
1413015088}
1413115089
14132static bool ir_analyze_fn_call_inline_arg(IrAnalyze *ira, AstNode *fn_proto_node,
14133 IrInstruction *arg, Scope **exec_scope, size_t *next_proto_i)
15090static ZigType *ir_result_loc_expected_type(IrAnalyze *ira, IrInstruction *suspend_source_instr,
15091 ResultLoc *result_loc)
1413415092{
14135 AstNode *param_decl_node = fn_proto_node->data.fn_proto.params.at(*next_proto_i);
14136 assert(param_decl_node->type == NodeTypeParamDecl);
14137
14138 IrInstruction *casted_arg;
14139 if (param_decl_node->data.param_decl.var_token == nullptr) {
14140 AstNode *param_type_node = param_decl_node->data.param_decl.type;
14141 ZigType *param_type = ir_analyze_type_expr(ira, *exec_scope, param_type_node);
14142 if (type_is_invalid(param_type))
14143 return false;
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}
1414415110
14145 casted_arg = ir_implicit_cast(ira, arg, param_type);
14146 if (type_is_invalid(casted_arg->value.type))
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:
1414715126 return false;
14148 } else {
14149 casted_arg = arg;
15127 default:
15128 // TODO list these types out explicitly, there are probably some other invalid ones here
15129 return true;
1415015130 }
15131}
1415115132
14152 ConstExprValue *arg_val = ir_resolve_const(ira, casted_arg, UndefBad);
14153 if (!arg_val)
14154 return false;
14155
14156 Buf *param_name = param_decl_node->data.param_decl.name;
14157 ZigVar *var = add_variable(ira->codegen, param_decl_node,
14158 *exec_scope, param_name, true, arg_val, nullptr, arg_val->type);
14159 *exec_scope = var->child_scope;
14160 *next_proto_i += 1;
14161
14162 return true;
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;
1416315141}
1416415142
14165static bool ir_analyze_fn_call_generic_arg(IrAnalyze *ira, AstNode *fn_proto_node,
14166 IrInstruction *arg, Scope **child_scope, size_t *next_proto_i,
14167 GenericFnTypeId *generic_id, FnTypeId *fn_type_id, IrInstruction **casted_args,
14168 ZigFn *impl_fn)
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)
1416915146{
14170 AstNode *param_decl_node = fn_proto_node->data.fn_proto.params.at(*next_proto_i);
14171 assert(param_decl_node->type == NodeTypeParamDecl);
14172 bool is_var_args = param_decl_node->data.param_decl.is_var_args;
14173 bool arg_part_of_generic_id = false;
14174 IrInstruction *casted_arg;
14175 if (is_var_args) {
14176 arg_part_of_generic_id = true;
14177 casted_arg = arg;
14178 } else {
14179 if (param_decl_node->data.param_decl.var_token == nullptr) {
14180 AstNode *param_type_node = param_decl_node->data.param_decl.type;
14181 ZigType *param_type = ir_analyze_type_expr(ira, *child_scope, param_type_node);
14182 if (type_is_invalid(param_type))
14183 return false;
14184
14185 casted_arg = ir_implicit_cast(ira, arg, param_type);
14186 if (type_is_invalid(casted_arg->value.type))
14187 return false;
14188 } else {
14189 arg_part_of_generic_id = true;
14190 casted_arg = arg;
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;
1419115152 }
1419215153 }
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 }
1419315188
14194 bool comptime_arg = param_decl_node->data.param_decl.is_inline ||
14195 casted_arg->value.type->id == ZigTypeIdComptimeInt || casted_arg->value.type->id == ZigTypeIdComptimeFloat;
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,
15490 ZigType *fn_type, IrInstruction *fn_ref, IrInstruction **casted_args, size_t arg_count,
15491 IrInstruction *async_allocator_inst)
15492{
15493 Buf *realloc_field_name = buf_create_from_str(ASYNC_REALLOC_FIELD_NAME);
15494 ir_assert(async_allocator_inst->value.type->id == ZigTypeIdPointer, &call_instruction->base);
15495 ZigType *container_type = async_allocator_inst->value.type->data.pointer.child_type;
15496 IrInstruction *field_ptr_inst = ir_analyze_container_field_ptr(ira, realloc_field_name, &call_instruction->base,
15497 async_allocator_inst, container_type, false);
15498 if (type_is_invalid(field_ptr_inst->value.type)) {
15499 return ira->codegen->invalid_instruction;
15500 }
15501 ZigType *ptr_to_realloc_fn_type = field_ptr_inst->value.type;
15502 ir_assert(ptr_to_realloc_fn_type->id == ZigTypeIdPointer, &call_instruction->base);
15503
15504 ZigType *realloc_fn_type = ptr_to_realloc_fn_type->data.pointer.child_type;
15505 if (realloc_fn_type->id != ZigTypeIdFn) {
15506 ir_add_error(ira, &call_instruction->base,
15507 buf_sprintf("expected reallocation function, found '%s'", buf_ptr(&realloc_fn_type->name)));
15508 return ira->codegen->invalid_instruction;
15509 }
15510
15511 ZigType *realloc_fn_return_type = realloc_fn_type->data.fn.fn_type_id.return_type;
15512 if (realloc_fn_return_type->id != ZigTypeIdErrorUnion) {
15513 ir_add_error(ira, fn_ref,
15514 buf_sprintf("expected allocation function to return error union, but it returns '%s'", buf_ptr(&realloc_fn_return_type->name)));
15515 return ira->codegen->invalid_instruction;
15516 }
15517 ZigType *alloc_fn_error_set_type = realloc_fn_return_type->data.error_union.err_set_type;
15518 ZigType *return_type = fn_type->data.fn.fn_type_id.return_type;
15519 ZigType *promise_type = get_promise_type(ira->codegen, return_type);
15520 ZigType *async_return_type = get_error_union_type(ira->codegen, alloc_fn_error_set_type, promise_type);
15521
15522 IrInstruction *result_loc = ir_resolve_result(ira, &call_instruction->base, no_result_loc(),
15523 async_return_type, nullptr, true, true);
15524 if (type_is_invalid(result_loc->value.type) || instr_is_unreachable(result_loc)) {
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);
15531}
15532
15533static bool ir_analyze_fn_call_inline_arg(IrAnalyze *ira, AstNode *fn_proto_node,
15534 IrInstruction *arg, Scope **exec_scope, size_t *next_proto_i)
15535{
15536 AstNode *param_decl_node = fn_proto_node->data.fn_proto.params.at(*next_proto_i);
15537 assert(param_decl_node->type == NodeTypeParamDecl);
15538
15539 IrInstruction *casted_arg;
15540 if (param_decl_node->data.param_decl.var_token == nullptr) {
15541 AstNode *param_type_node = param_decl_node->data.param_decl.type;
15542 ZigType *param_type = ir_analyze_type_expr(ira, *exec_scope, param_type_node);
15543 if (type_is_invalid(param_type))
15544 return false;
15545
15546 casted_arg = ir_implicit_cast(ira, arg, param_type);
15547 if (type_is_invalid(casted_arg->value.type))
15548 return false;
15549 } else {
15550 casted_arg = arg;
15551 }
15552
15553 ConstExprValue *arg_val = ir_resolve_const(ira, casted_arg, UndefOk);
15554 if (!arg_val)
15555 return false;
15556
15557 Buf *param_name = param_decl_node->data.param_decl.name;
15558 ZigVar *var = add_variable(ira->codegen, param_decl_node,
15559 *exec_scope, param_name, true, arg_val, nullptr, arg_val->type);
15560 *exec_scope = var->child_scope;
15561 *next_proto_i += 1;
15562
15563 return true;
15564}
15565
15566static bool ir_analyze_fn_call_generic_arg(IrAnalyze *ira, AstNode *fn_proto_node,
15567 IrInstruction *arg, Scope **child_scope, size_t *next_proto_i,
15568 GenericFnTypeId *generic_id, FnTypeId *fn_type_id, IrInstruction **casted_args,
15569 ZigFn *impl_fn)
15570{
15571 AstNode *param_decl_node = fn_proto_node->data.fn_proto.params.at(*next_proto_i);
15572 assert(param_decl_node->type == NodeTypeParamDecl);
15573 bool is_var_args = param_decl_node->data.param_decl.is_var_args;
15574 bool arg_part_of_generic_id = false;
15575 IrInstruction *casted_arg;
15576 if (is_var_args) {
15577 arg_part_of_generic_id = true;
15578 casted_arg = arg;
15579 } else {
15580 if (param_decl_node->data.param_decl.var_token == nullptr) {
15581 AstNode *param_type_node = param_decl_node->data.param_decl.type;
15582 ZigType *param_type = ir_analyze_type_expr(ira, *child_scope, param_type_node);
15583 if (type_is_invalid(param_type))
15584 return false;
15585
15586 casted_arg = ir_implicit_cast(ira, arg, param_type);
15587 if (type_is_invalid(casted_arg->value.type))
15588 return false;
15589 } else {
15590 arg_part_of_generic_id = true;
15591 casted_arg = arg;
15592 }
15593 }
15594
15595 bool comptime_arg = param_decl_node->data.param_decl.is_inline ||
15596 casted_arg->value.type->id == ZigTypeIdComptimeInt || casted_arg->value.type->id == ZigTypeIdComptimeFloat;
1419615597
1419715598 ConstExprValue *arg_val;
1419815599
......@@ -14205,7 +15606,7 @@ static bool ir_analyze_fn_call_generic_arg(IrAnalyze *ira, AstNode *fn_proto_nod
1420515606 arg_val = create_const_runtime(casted_arg->value.type);
1420615607 }
1420715608 if (arg_part_of_generic_id) {
14208 generic_id->params[generic_id->param_count] = *arg_val;
15609 copy_const_val(&generic_id->params[generic_id->param_count], arg_val, true);
1420915610 generic_id->param_count += 1;
1421015611 }
1421115612
......@@ -14376,7 +15777,9 @@ static IrInstruction *ir_analyze_store_ptr(IrAnalyze *ira, IrInstruction *source
1437615777 ir_add_error(ira, source_instr, buf_sprintf("cannot assign to constant"));
1437715778 return ira->codegen->invalid_instruction;
1437815779 }
14379 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 {
1438015783 if (instr_is_comptime(value)) {
1438115784 ConstExprValue *dest_val = const_ptr_pointee(ira, ira->codegen, &ptr->value, source_instr->source_node);
1438215785 if (dest_val == nullptr)
......@@ -14390,18 +15793,24 @@ static IrInstruction *ir_analyze_store_ptr(IrAnalyze *ira, IrInstruction *source
1439015793 // ConstPtrMutComptimeVar, thus defeating the logic below.
1439115794 bool same_global_refs = ptr->value.data.x_ptr.mut != ConstPtrMutComptimeVar;
1439215795 copy_const_val(dest_val, &value->value, same_global_refs);
14393 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 {
1439415799 ira->new_irb.current_basic_block->must_be_comptime_source_instr = source_instr;
1439515800 }
1439615801 return ir_const_void(ira, source_instr);
1439715802 }
1439815803 }
14399 ir_add_error(ira, source_instr,
14400 buf_sprintf("cannot store runtime value in compile time variable"));
14401 ConstExprValue *dest_val = const_ptr_pointee_unchecked(ira->codegen, &ptr->value);
14402 dest_val->type = ira->codegen->builtin_types.entry_invalid;
15804 if (ptr->value.data.x_ptr.mut == ConstPtrMutInfer) {
15805 ptr->value.special = ConstValSpecialRuntime;
15806 } else {
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;
1440315811
14404 return ira->codegen->invalid_instruction;
15812 return ira->codegen->invalid_instruction;
15813 }
1440515814 }
1440615815 }
1440715816
......@@ -14430,7 +15839,7 @@ static IrInstruction *ir_analyze_store_ptr(IrAnalyze *ira, IrInstruction *source
1443015839 return result;
1443115840}
1443215841
14433static IrInstruction *ir_analyze_fn_call(IrAnalyze *ira, IrInstructionCall *call_instruction,
15842static IrInstruction *ir_analyze_fn_call(IrAnalyze *ira, IrInstructionCallSrc *call_instruction,
1443415843 ZigFn *fn_entry, ZigType *fn_type, IrInstruction *fn_ref,
1443515844 IrInstruction *first_arg_ptr, bool comptime_fn_call, FnInline fn_inline)
1443615845{
......@@ -14533,7 +15942,7 @@ static IrInstruction *ir_analyze_fn_call(IrAnalyze *ira, IrInstructionCall *call
1453315942 if (!first_arg_known_bare && handle_is_ptr(first_arg_ptr->value.type->data.pointer.child_type)) {
1453415943 first_arg = first_arg_ptr;
1453515944 } else {
14536 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);
1453715946 if (type_is_invalid(first_arg->value.type))
1453815947 return ira->codegen->invalid_instruction;
1453915948 }
......@@ -14692,7 +16101,7 @@ static IrInstruction *ir_analyze_fn_call(IrAnalyze *ira, IrInstructionCall *call
1469216101 if (!first_arg_known_bare && handle_is_ptr(first_arg_ptr->value.type->data.pointer.child_type)) {
1469316102 first_arg = first_arg_ptr;
1469416103 } else {
14695 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);
1469616105 if (type_is_invalid(first_arg->value.type))
1469716106 return ira->codegen->invalid_instruction;
1469816107 }
......@@ -14736,7 +16145,7 @@ static IrInstruction *ir_analyze_fn_call(IrAnalyze *ira, IrInstructionCall *call
1473616145 if (type_is_invalid(arg_var_ptr_inst->value.type))
1473716146 return ira->codegen->invalid_instruction;
1473816147
14739 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);
1474016149 if (type_is_invalid(arg_tuple_arg->value.type))
1474116150 return ira->codegen->invalid_instruction;
1474216151
......@@ -14785,7 +16194,7 @@ static IrInstruction *ir_analyze_fn_call(IrAnalyze *ira, IrInstructionCall *call
1478516194 nullptr, nullptr, fn_proto_node->data.fn_proto.align_expr, nullptr, ira->new_irb.exec, nullptr);
1478616195 IrInstructionConst *const_instruction = ir_create_instruction<IrInstructionConst>(&ira->new_irb,
1478716196 impl_fn->child_scope, fn_proto_node->data.fn_proto.align_expr);
14788 const_instruction->base.value = *align_result;
16197 copy_const_val(&const_instruction->base.value, align_result, true);
1478916198
1479016199 uint32_t align_bytes = 0;
1479116200 ir_resolve_align(ira, &const_instruction->base, &align_bytes);
......@@ -14867,6 +16276,19 @@ static IrInstruction *ir_analyze_fn_call(IrAnalyze *ira, IrInstructionCall *call
1486716276 }
1486816277
1486916278 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
1487016292 if (fn_type_can_fail(impl_fn_type_id)) {
1487116293 parent_fn_entry->calls_or_awaits_errorable_fn = true;
1487216294 }
......@@ -14875,18 +16297,14 @@ static IrInstruction *ir_analyze_fn_call(IrAnalyze *ira, IrInstructionCall *call
1487516297 if (call_instruction->is_async) {
1487616298 IrInstruction *result = ir_analyze_async_call(ira, call_instruction, impl_fn, impl_fn->type_entry,
1487716299 fn_ref, casted_args, impl_param_count, async_allocator_inst);
14878 ir_add_alloca(ira, result, result->value.type);
1487916300 return ir_finish_anal(ira, result);
1488016301 }
1488116302
1488216303 assert(async_allocator_inst == nullptr);
14883 IrInstruction *new_call_instruction = ir_build_call(&ira->new_irb,
14884 call_instruction->base.scope, call_instruction->base.source_node,
14885 impl_fn, nullptr, impl_param_count, casted_args, false, fn_inline,
14886 call_instruction->is_async, nullptr, casted_new_stack);
14887 new_call_instruction->value.type = impl_fn_type_id->return_type;
14888
14889 ir_add_alloca(ira, new_call_instruction, impl_fn_type_id->return_type);
16304 IrInstruction *new_call_instruction = ir_build_call_gen(ira, &call_instruction->base,
16305 impl_fn, nullptr, impl_param_count, casted_args, fn_inline,
16306 call_instruction->is_async, nullptr, casted_new_stack, result_loc,
16307 impl_fn_type_id->return_type);
1489016308
1489116309 return ir_finish_anal(ira, new_call_instruction);
1489216310 }
......@@ -14914,7 +16332,7 @@ static IrInstruction *ir_analyze_fn_call(IrAnalyze *ira, IrInstructionCall *call
1491416332 {
1491516333 first_arg = first_arg_ptr;
1491616334 } else {
14917 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);
1491816336 if (type_is_invalid(first_arg->value.type))
1491916337 return ira->codegen->invalid_instruction;
1492016338 }
......@@ -14971,7 +16389,6 @@ static IrInstruction *ir_analyze_fn_call(IrAnalyze *ira, IrInstructionCall *call
1497116389
1497216390 IrInstruction *result = ir_analyze_async_call(ira, call_instruction, fn_entry, fn_type, fn_ref,
1497316391 casted_args, call_param_count, async_allocator_inst);
14974 ir_add_alloca(ira, result, result->value.type);
1497516392 return ir_finish_anal(ira, result);
1497616393 }
1497716394
......@@ -14981,15 +16398,24 @@ static IrInstruction *ir_analyze_fn_call(IrAnalyze *ira, IrInstructionCall *call
1498116398 return ira->codegen->invalid_instruction;
1498216399 }
1498316400
14984 IrInstruction *new_call_instruction = ir_build_call(&ira->new_irb,
14985 call_instruction->base.scope, call_instruction->base.source_node,
14986 fn_entry, fn_ref, call_param_count, casted_args, false, fn_inline, false, nullptr, casted_new_stack);
14987 new_call_instruction->value.type = return_type;
14988 ir_add_alloca(ira, new_call_instruction, return_type);
16401 IrInstruction *result_loc;
16402 if (handle_is_ptr(return_type)) {
16403 result_loc = ir_resolve_result(ira, &call_instruction->base, call_instruction->result_loc,
16404 return_type, nullptr, true, true);
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);
1498916415 return ir_finish_anal(ira, new_call_instruction);
1499016416}
1499116417
14992static IrInstruction *ir_analyze_instruction_call(IrAnalyze *ira, IrInstructionCall *call_instruction) {
16418static IrInstruction *ir_analyze_instruction_call(IrAnalyze *ira, IrInstructionCallSrc *call_instruction) {
1499316419 IrInstruction *fn_ref = call_instruction->fn_ref->child;
1499416420 if (type_is_invalid(fn_ref->value.type))
1499516421 return ira->codegen->invalid_instruction;
......@@ -15013,7 +16439,8 @@ static IrInstruction *ir_analyze_instruction_call(IrAnalyze *ira, IrInstructionC
1501316439
1501416440 IrInstruction *arg = call_instruction->args[0]->child;
1501516441
15016 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);
1501716444 if (type_is_invalid(cast_instruction->value.type))
1501816445 return ira->codegen->invalid_instruction;
1501916446 return ir_finish_anal(ira, cast_instruction);
......@@ -15066,7 +16493,7 @@ static Error ir_read_const_ptr(IrAnalyze *ira, CodeGen *codegen, AstNode *source
1506616493
1506716494 if (dst_size <= src_size) {
1506816495 if (src_size == dst_size && types_have_same_zig_comptime_repr(pointee->type, out_val->type)) {
15069 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);
1507016497 return ErrorNone;
1507116498 }
1507216499 Buf buf = BUF_INIT;
......@@ -15315,7 +16742,7 @@ static IrInstruction *ir_analyze_instruction_un_op(IrAnalyze *ira, IrInstruction
1531516742 return ira->codegen->invalid_instruction;
1531616743 }
1531716744
15318 IrInstruction *result = ir_get_deref(ira, &instruction->base, ptr);
16745 IrInstruction *result = ir_get_deref(ira, &instruction->base, ptr, instruction->result_loc);
1531916746 if (result == ira->codegen->invalid_instruction)
1532016747 return ira->codegen->invalid_instruction;
1532116748
......@@ -15334,6 +16761,19 @@ static IrInstruction *ir_analyze_instruction_un_op(IrAnalyze *ira, IrInstruction
1533416761 zig_unreachable();
1533516762}
1533616763
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
1533716777static IrInstruction *ir_analyze_instruction_br(IrAnalyze *ira, IrInstructionBr *br_instruction) {
1533816778 IrBasicBlock *old_dest_block = br_instruction->dest_block;
1533916779
......@@ -15341,13 +16781,15 @@ static IrInstruction *ir_analyze_instruction_br(IrAnalyze *ira, IrInstructionBr
1534116781 if (!ir_resolve_comptime(ira, br_instruction->is_comptime->child, &is_comptime))
1534216782 return ir_unreach_error(ira);
1534316783
15344 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))
1534516785 return ir_inline_bb(ira, &br_instruction->base, old_dest_block);
1534616786
1534716787 IrBasicBlock *new_bb = ir_get_new_bb_runtime(ira, old_dest_block, &br_instruction->base);
1534816788 if (new_bb == nullptr)
1534916789 return ir_unreach_error(ira);
1535016790
16791 ir_push_resume_block(ira, old_dest_block);
16792
1535116793 IrInstruction *result = ir_build_br(&ira->new_irb,
1535216794 br_instruction->base.scope, br_instruction->base.source_node, new_bb, nullptr);
1535316795 result->value.type = ira->codegen->builtin_types.entry_unreachable;
......@@ -15376,13 +16818,15 @@ static IrInstruction *ir_analyze_instruction_cond_br(IrAnalyze *ira, IrInstructi
1537616818 IrBasicBlock *old_dest_block = cond_is_true ?
1537716819 cond_br_instruction->then_block : cond_br_instruction->else_block;
1537816820
15379 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))
1538016822 return ir_inline_bb(ira, &cond_br_instruction->base, old_dest_block);
1538116823
1538216824 IrBasicBlock *new_dest_block = ir_get_new_bb_runtime(ira, old_dest_block, &cond_br_instruction->base);
1538316825 if (new_dest_block == nullptr)
1538416826 return ir_unreach_error(ira);
1538516827
16828 ir_push_resume_block(ira, old_dest_block);
16829
1538616830 IrInstruction *result = ir_build_br(&ira->new_irb,
1538716831 cond_br_instruction->base.scope, cond_br_instruction->base.source_node, new_dest_block, nullptr);
1538816832 result->value.type = ira->codegen->builtin_types.entry_unreachable;
......@@ -15398,6 +16842,9 @@ static IrInstruction *ir_analyze_instruction_cond_br(IrAnalyze *ira, IrInstructi
1539816842 if (new_else_block == nullptr)
1539916843 return ir_unreach_error(ira);
1540016844
16845 ir_push_resume_block(ira, cond_br_instruction->else_block);
16846 ir_push_resume_block(ira, cond_br_instruction->then_block);
16847
1540116848 IrInstruction *result = ir_build_cond_br(&ira->new_irb,
1540216849 cond_br_instruction->base.scope, cond_br_instruction->base.source_node,
1540316850 casted_condition, new_then_block, new_else_block, nullptr);
......@@ -15436,6 +16883,80 @@ static IrInstruction *ir_analyze_instruction_phi(IrAnalyze *ira, IrInstructionPh
1543616883 zig_unreachable();
1543716884 }
1543816885
16886 ResultLocPeerParent *peer_parent = phi_instruction->peer_parent;
16887 if (peer_parent != nullptr && !peer_parent->skipped && !peer_parent->done_resuming &&
16888 peer_parent->peers.length >= 2)
16889 {
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
1543916960 ZigList<IrBasicBlock*> new_incoming_blocks = {0};
1544016961 ZigList<IrInstruction*> new_incoming_values = {0};
1544116962
......@@ -15508,7 +17029,7 @@ static IrInstruction *ir_analyze_instruction_phi(IrAnalyze *ira, IrInstructionPh
1550817029 IrInstruction *branch_instruction = predecessor->instruction_list.pop();
1550917030 ir_set_cursor_at_end(&ira->new_irb, predecessor);
1551017031 IrInstruction *casted_value = ir_implicit_cast(ira, new_value, resolved_type);
15511 if (casted_value == ira->codegen->invalid_instruction) {
17032 if (type_is_invalid(casted_value->value.type)) {
1551217033 return ira->codegen->invalid_instruction;
1551317034 }
1551417035 new_incoming_values.items[i] = casted_value;
......@@ -15524,7 +17045,7 @@ static IrInstruction *ir_analyze_instruction_phi(IrAnalyze *ira, IrInstructionPh
1552417045
1552517046 IrInstruction *result = ir_build_phi(&ira->new_irb,
1552617047 phi_instruction->base.scope, phi_instruction->base.source_node,
15527 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);
1552817049 result->value.type = resolved_type;
1552917050
1553017051 if (all_stack_ptrs) {
......@@ -15742,6 +17263,52 @@ static IrInstruction *ir_analyze_instruction_elem_ptr(IrAnalyze *ira, IrInstruct
1574217263 if (array_ptr_val == nullptr)
1574317264 return ira->codegen->invalid_instruction;
1574417265
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 if (actual_array_type->id != ZigTypeIdArray) {
17284 ir_add_error(ira, elem_ptr_instruction->init_array_type,
17285 buf_sprintf("expected array type or [_], found slice"));
17286 return ira->codegen->invalid_instruction;
17287 }
17288
17289 ConstExprValue *array_init_val = create_const_vals(1);
17290 array_init_val->special = ConstValSpecialStatic;
17291 array_init_val->type = actual_array_type;
17292 array_init_val->data.x_array.special = ConstArraySpecialNone;
17293 array_init_val->data.x_array.data.s_none.elements = create_const_vals(actual_array_type->data.array.len);
17294 array_init_val->special = ConstValSpecialStatic;
17295 for (size_t i = 0; i < actual_array_type->data.array.len; i += 1) {
17296 ConstExprValue *elem_val = &array_init_val->data.x_array.data.s_none.elements[i];
17297 elem_val->special = ConstValSpecialUndef;
17298 elem_val->type = actual_array_type->data.array.child_type;
17299 elem_val->parent.id = ConstParentIdArray;
17300 elem_val->parent.data.p_array.array_val = array_init_val;
17301 elem_val->parent.data.p_array.elem_index = i;
17302 }
17303
17304 init_const_slice(ira->codegen, array_ptr_val, array_init_val, 0, actual_array_type->data.array.len,
17305 false);
17306 array_ptr_val->data.x_struct.fields[slice_ptr_index].data.x_ptr.mut = ConstPtrMutInfer;
17307 } else {
17308 zig_unreachable();
17309 }
17310 }
17311
1574517312 if (array_ptr_val->special != ConstValSpecialRuntime &&
1574617313 (array_type->id != ZigTypeIdPointer ||
1574717314 array_ptr_val->data.x_ptr.special != ConstPtrSpecialHardCodedAddr))
......@@ -15807,8 +17374,9 @@ static IrInstruction *ir_analyze_instruction_elem_ptr(IrAnalyze *ira, IrInstruct
1580717374 } else if (is_slice(array_type)) {
1580817375 ConstExprValue *ptr_field = &array_ptr_val->data.x_struct.fields[slice_ptr_index];
1580917376 if (ptr_field->data.x_ptr.special == ConstPtrSpecialHardCodedAddr) {
15810 IrInstruction *result = ir_build_elem_ptr(&ira->new_irb, elem_ptr_instruction->base.scope, elem_ptr_instruction->base.source_node,
15811 array_ptr, casted_elem_index, false, elem_ptr_instruction->ptr_len);
17377 IrInstruction *result = ir_build_elem_ptr(&ira->new_irb, elem_ptr_instruction->base.scope,
17378 elem_ptr_instruction->base.source_node, array_ptr, casted_elem_index, false,
17379 elem_ptr_instruction->ptr_len, nullptr);
1581217380 result->value.type = return_type;
1581317381 return result;
1581417382 }
......@@ -15861,7 +17429,16 @@ static IrInstruction *ir_analyze_instruction_elem_ptr(IrAnalyze *ira, IrInstruct
1586117429 }
1586217430 return result;
1586317431 } else if (array_type->id == ZigTypeIdArray) {
15864 IrInstruction *result = ir_const(ira, &elem_ptr_instruction->base, return_type);
17432 IrInstruction *result;
17433 if (orig_array_ptr_val->data.x_ptr.mut == ConstPtrMutInfer) {
17434 result = ir_build_elem_ptr(&ira->new_irb, elem_ptr_instruction->base.scope,
17435 elem_ptr_instruction->base.source_node, array_ptr, casted_elem_index,
17436 false, elem_ptr_instruction->ptr_len, elem_ptr_instruction->init_array_type);
17437 result->value.type = return_type;
17438 result->value.special = ConstValSpecialStatic;
17439 } else {
17440 result = ir_const(ira, &elem_ptr_instruction->base, return_type);
17441 }
1586517442 ConstExprValue *out_val = &result->value;
1586617443 out_val->data.x_ptr.special = ConstPtrSpecialBaseArray;
1586717444 out_val->data.x_ptr.mut = orig_array_ptr_val->data.x_ptr.mut;
......@@ -15873,7 +17450,6 @@ static IrInstruction *ir_analyze_instruction_elem_ptr(IrAnalyze *ira, IrInstruct
1587317450 }
1587417451 }
1587517452 }
15876
1587717453 } else {
1587817454 // runtime known element index
1587917455 switch (type_requires_comptime(ira->codegen, return_type)) {
......@@ -15899,8 +17475,9 @@ static IrInstruction *ir_analyze_instruction_elem_ptr(IrAnalyze *ira, IrInstruct
1589917475 }
1590017476 }
1590117477
15902 IrInstruction *result = ir_build_elem_ptr(&ira->new_irb, elem_ptr_instruction->base.scope, elem_ptr_instruction->base.source_node,
15903 array_ptr, casted_elem_index, safety_check_on, elem_ptr_instruction->ptr_len);
17478 IrInstruction *result = ir_build_elem_ptr(&ira->new_irb, elem_ptr_instruction->base.scope,
17479 elem_ptr_instruction->base.source_node, array_ptr, casted_elem_index, safety_check_on,
17480 elem_ptr_instruction->ptr_len, elem_ptr_instruction->init_array_type);
1590417481 result->value.type = return_type;
1590517482 return result;
1590617483}
......@@ -15945,8 +17522,80 @@ static IrInstruction *ir_analyze_container_member_access_inner(IrAnalyze *ira,
1594517522 return ira->codegen->invalid_instruction;
1594617523}
1594717524
17525static IrInstruction *ir_analyze_struct_field_ptr(IrAnalyze *ira, IrInstruction *source_instr,
17526 TypeStructField *field, IrInstruction *struct_ptr, ZigType *struct_type, bool initializing)
17527{
17528 switch (type_has_one_possible_value(ira->codegen, field->type_entry)) {
17529 case OnePossibleValueInvalid:
17530 return ira->codegen->invalid_instruction;
17531 case OnePossibleValueYes: {
17532 IrInstruction *elem = ir_const(ira, source_instr, field->type_entry);
17533 return ir_get_ref(ira, source_instr, elem, false, false);
17534 }
17535 case OnePossibleValueNo:
17536 break;
17537 }
17538 assert(struct_ptr->value.type->id == ZigTypeIdPointer);
17539 bool is_packed = (struct_type->data.structure.layout == ContainerLayoutPacked);
17540 uint32_t align_bytes = is_packed ? 1 : get_abi_alignment(ira->codegen, field->type_entry);
17541 uint32_t ptr_bit_offset = struct_ptr->value.type->data.pointer.bit_offset_in_host;
17542 uint32_t ptr_host_int_bytes = struct_ptr->value.type->data.pointer.host_int_bytes;
17543 uint32_t host_int_bytes_for_result_type = (ptr_host_int_bytes == 0) ?
17544 get_host_int_bytes(ira->codegen, struct_type, field) : ptr_host_int_bytes;
17545 bool is_const = struct_ptr->value.type->data.pointer.is_const;
17546 bool is_volatile = struct_ptr->value.type->data.pointer.is_volatile;
17547 ZigType *ptr_type = get_pointer_to_type_extra(ira->codegen, field->type_entry,
17548 is_const, is_volatile, PtrLenSingle, align_bytes,
17549 (uint32_t)(ptr_bit_offset + field->bit_offset_in_host),
17550 (uint32_t)host_int_bytes_for_result_type, false);
17551 if (instr_is_comptime(struct_ptr)) {
17552 ConstExprValue *ptr_val = ir_resolve_const(ira, struct_ptr, UndefBad);
17553 if (!ptr_val)
17554 return ira->codegen->invalid_instruction;
17555
17556 if (ptr_val->data.x_ptr.special != ConstPtrSpecialHardCodedAddr) {
17557 ConstExprValue *struct_val = const_ptr_pointee(ira, ira->codegen, ptr_val, source_instr->source_node);
17558 if (struct_val == nullptr)
17559 return ira->codegen->invalid_instruction;
17560 if (type_is_invalid(struct_val->type))
17561 return ira->codegen->invalid_instruction;
17562 if (struct_val->special == ConstValSpecialUndef && initializing) {
17563 struct_val->data.x_struct.fields = create_const_vals(struct_type->data.structure.src_field_count);
17564 struct_val->special = ConstValSpecialStatic;
17565 for (size_t i = 0; i < struct_type->data.structure.src_field_count; i += 1) {
17566 ConstExprValue *field_val = &struct_val->data.x_struct.fields[i];
17567 field_val->special = ConstValSpecialUndef;
17568 field_val->type = struct_type->data.structure.fields[i].type_entry;
17569 field_val->parent.id = ConstParentIdStruct;
17570 field_val->parent.data.p_struct.struct_val = struct_val;
17571 field_val->parent.data.p_struct.field_index = i;
17572 }
17573 }
17574 IrInstruction *result;
17575 if (ptr_val->data.x_ptr.mut == ConstPtrMutInfer) {
17576 result = ir_build_struct_field_ptr(&ira->new_irb, source_instr->scope,
17577 source_instr->source_node, struct_ptr, field);
17578 result->value.type = ptr_type;
17579 result->value.special = ConstValSpecialStatic;
17580 } else {
17581 result = ir_const(ira, source_instr, ptr_type);
17582 }
17583 ConstExprValue *const_val = &result->value;
17584 const_val->data.x_ptr.special = ConstPtrSpecialBaseStruct;
17585 const_val->data.x_ptr.mut = ptr_val->data.x_ptr.mut;
17586 const_val->data.x_ptr.data.base_struct.struct_val = struct_val;
17587 const_val->data.x_ptr.data.base_struct.field_index = field->src_index;
17588 return result;
17589 }
17590 }
17591 IrInstruction *result = ir_build_struct_field_ptr(&ira->new_irb, source_instr->scope, source_instr->source_node,
17592 struct_ptr, field);
17593 result->value.type = ptr_type;
17594 return result;
17595}
17596
1594817597static IrInstruction *ir_analyze_container_field_ptr(IrAnalyze *ira, Buf *field_name,
15949 IrInstruction *source_instr, IrInstruction *container_ptr, ZigType *container_type)
17598 IrInstruction *source_instr, IrInstruction *container_ptr, ZigType *container_type, bool initializing)
1595017599{
1595117600 Error err;
1595217601
......@@ -15955,81 +17604,55 @@ static IrInstruction *ir_analyze_container_field_ptr(IrAnalyze *ira, Buf *field_
1595517604 return ira->codegen->invalid_instruction;
1595617605
1595717606 assert(container_ptr->value.type->id == ZigTypeIdPointer);
15958 bool is_const = container_ptr->value.type->data.pointer.is_const;
15959 bool is_volatile = container_ptr->value.type->data.pointer.is_volatile;
1596017607 if (bare_type->id == ZigTypeIdStruct) {
1596117608 TypeStructField *field = find_struct_type_field(bare_type, field_name);
15962 if (field) {
15963 switch (type_has_one_possible_value(ira->codegen, field->type_entry)) {
15964 case OnePossibleValueInvalid:
15965 return ira->codegen->invalid_instruction;
15966 case OnePossibleValueYes: {
15967 IrInstruction *elem = ir_const(ira, source_instr, field->type_entry);
15968 return ir_get_ref(ira, source_instr, elem, false, false);
15969 }
15970 case OnePossibleValueNo:
15971 break;
15972 }
15973 bool is_packed = (bare_type->data.structure.layout == ContainerLayoutPacked);
15974 uint32_t align_bytes = is_packed ? 1 : get_abi_alignment(ira->codegen, field->type_entry);
15975 uint32_t ptr_bit_offset = container_ptr->value.type->data.pointer.bit_offset_in_host;
15976 uint32_t ptr_host_int_bytes = container_ptr->value.type->data.pointer.host_int_bytes;
15977 uint32_t host_int_bytes_for_result_type = (ptr_host_int_bytes == 0) ?
15978 get_host_int_bytes(ira->codegen, bare_type, field) : ptr_host_int_bytes;
15979 if (instr_is_comptime(container_ptr)) {
15980 ConstExprValue *ptr_val = ir_resolve_const(ira, container_ptr, UndefBad);
15981 if (!ptr_val)
15982 return ira->codegen->invalid_instruction;
15983
15984 if (ptr_val->data.x_ptr.special != ConstPtrSpecialHardCodedAddr) {
15985 ConstExprValue *struct_val = const_ptr_pointee(ira, ira->codegen, ptr_val, source_instr->source_node);
15986 if (struct_val == nullptr)
15987 return ira->codegen->invalid_instruction;
15988 if (type_is_invalid(struct_val->type))
15989 return ira->codegen->invalid_instruction;
15990 ZigType *ptr_type = get_pointer_to_type_extra(ira->codegen, field->type_entry,
15991 is_const, is_volatile, PtrLenSingle, align_bytes,
15992 (uint32_t)(ptr_bit_offset + field->bit_offset_in_host),
15993 (uint32_t)host_int_bytes_for_result_type, false);
15994 IrInstruction *result = ir_const(ira, source_instr, ptr_type);
15995 ConstExprValue *const_val = &result->value;
15996 const_val->data.x_ptr.special = ConstPtrSpecialBaseStruct;
15997 const_val->data.x_ptr.mut = container_ptr->value.data.x_ptr.mut;
15998 const_val->data.x_ptr.data.base_struct.struct_val = struct_val;
15999 const_val->data.x_ptr.data.base_struct.field_index = field->src_index;
16000 return result;
16001 }
16002 }
16003 IrInstruction *result = ir_build_struct_field_ptr(&ira->new_irb, source_instr->scope, source_instr->source_node,
16004 container_ptr, field);
16005 result->value.type = get_pointer_to_type_extra(ira->codegen, field->type_entry, is_const, is_volatile,
16006 PtrLenSingle,
16007 align_bytes,
16008 (uint32_t)(ptr_bit_offset + field->bit_offset_in_host),
16009 host_int_bytes_for_result_type, false);
16010 return result;
17609 if (field != nullptr) {
17610 return ir_analyze_struct_field_ptr(ira, source_instr, field, container_ptr, bare_type, initializing);
1601117611 } else {
1601217612 return ir_analyze_container_member_access_inner(ira, bare_type, field_name,
1601317613 source_instr, container_ptr, container_type);
1601417614 }
16015 } else if (bare_type->id == ZigTypeIdEnum) {
17615 }
17616
17617 if (bare_type->id == ZigTypeIdEnum) {
1601617618 return ir_analyze_container_member_access_inner(ira, bare_type, field_name,
1601717619 source_instr, container_ptr, container_type);
16018 } else if (bare_type->id == ZigTypeIdUnion) {
17620 }
17621
17622 if (bare_type->id == ZigTypeIdUnion) {
17623 bool is_const = container_ptr->value.type->data.pointer.is_const;
17624 bool is_volatile = container_ptr->value.type->data.pointer.is_volatile;
17625
1601917626 TypeUnionField *field = find_union_type_field(bare_type, field_name);
16020 if (field) {
16021 if (instr_is_comptime(container_ptr)) {
16022 ConstExprValue *ptr_val = ir_resolve_const(ira, container_ptr, UndefBad);
16023 if (!ptr_val)
17627 if (field == nullptr) {
17628 return ir_analyze_container_member_access_inner(ira, bare_type, field_name,
17629 source_instr, container_ptr, container_type);
17630 }
17631 ZigType *ptr_type = get_pointer_to_type_extra(ira->codegen, field->type_entry,
17632 is_const, is_volatile, PtrLenSingle, 0, 0, 0, false);
17633 if (instr_is_comptime(container_ptr)) {
17634 ConstExprValue *ptr_val = ir_resolve_const(ira, container_ptr, UndefBad);
17635 if (!ptr_val)
17636 return ira->codegen->invalid_instruction;
17637
17638 if (ptr_val->data.x_ptr.special != ConstPtrSpecialHardCodedAddr) {
17639 ConstExprValue *union_val = const_ptr_pointee(ira, ira->codegen, ptr_val, source_instr->source_node);
17640 if (union_val == nullptr)
17641 return ira->codegen->invalid_instruction;
17642 if (type_is_invalid(union_val->type))
1602417643 return ira->codegen->invalid_instruction;
1602517644
16026 if (ptr_val->data.x_ptr.special != ConstPtrSpecialHardCodedAddr) {
16027 ConstExprValue *union_val = const_ptr_pointee(ira, ira->codegen, ptr_val, source_instr->source_node);
16028 if (union_val == nullptr)
16029 return ira->codegen->invalid_instruction;
16030 if (type_is_invalid(union_val->type))
16031 return ira->codegen->invalid_instruction;
17645 if (initializing) {
17646 ConstExprValue *payload_val = create_const_vals(1);
17647 payload_val->special = ConstValSpecialUndef;
17648 payload_val->type = field->type_entry;
17649 payload_val->parent.id = ConstParentIdUnion;
17650 payload_val->parent.data.p_union.union_val = union_val;
1603217651
17652 union_val->special = ConstValSpecialStatic;
17653 bigint_init_bigint(&union_val->data.x_union.tag, &field->enum_field->value);
17654 union_val->data.x_union.payload = payload_val;
17655 } else {
1603317656 TypeUnionField *actual_field = find_union_field_by_tag(bare_type, &union_val->data.x_union.tag);
1603417657 if (actual_field == nullptr)
1603517658 zig_unreachable();
......@@ -16040,33 +17663,35 @@ static IrInstruction *ir_analyze_container_field_ptr(IrAnalyze *ira, Buf *field_
1604017663 buf_ptr(actual_field->name)));
1604117664 return ira->codegen->invalid_instruction;
1604217665 }
17666 }
1604317667
16044 ConstExprValue *payload_val = union_val->data.x_union.payload;
17668 ConstExprValue *payload_val = union_val->data.x_union.payload;
1604517669
16046 ZigType *field_type = field->type_entry;
16047 ZigType *ptr_type = get_pointer_to_type_extra(ira->codegen, field_type,
16048 is_const, is_volatile, PtrLenSingle, 0, 0, 0, false);
1604917670
16050 IrInstruction *result = ir_const(ira, source_instr, ptr_type);
16051 ConstExprValue *const_val = &result->value;
16052 const_val->data.x_ptr.special = ConstPtrSpecialRef;
16053 const_val->data.x_ptr.mut = container_ptr->value.data.x_ptr.mut;
16054 const_val->data.x_ptr.data.ref.pointee = payload_val;
16055 return result;
17671 IrInstruction *result;
17672 if (ptr_val->data.x_ptr.mut == ConstPtrMutInfer) {
17673 result = ir_build_union_field_ptr(&ira->new_irb, source_instr->scope,
17674 source_instr->source_node, container_ptr, field, true, initializing);
17675 result->value.type = ptr_type;
17676 result->value.special = ConstValSpecialStatic;
17677 } else {
17678 result = ir_const(ira, source_instr, ptr_type);
1605617679 }
17680 ConstExprValue *const_val = &result->value;
17681 const_val->data.x_ptr.special = ConstPtrSpecialRef;
17682 const_val->data.x_ptr.mut = container_ptr->value.data.x_ptr.mut;
17683 const_val->data.x_ptr.data.ref.pointee = payload_val;
17684 return result;
1605717685 }
16058
16059 IrInstruction *result = ir_build_union_field_ptr(&ira->new_irb, source_instr->scope, source_instr->source_node, container_ptr, field);
16060 result->value.type = get_pointer_to_type_extra(ira->codegen, field->type_entry, is_const, is_volatile,
16061 PtrLenSingle, 0, 0, 0, false);
16062 return result;
16063 } else {
16064 return ir_analyze_container_member_access_inner(ira, bare_type, field_name,
16065 source_instr, container_ptr, container_type);
1606617686 }
16067 } else {
16068 zig_unreachable();
17687
17688 IrInstruction *result = ir_build_union_field_ptr(&ira->new_irb, source_instr->scope,
17689 source_instr->source_node, container_ptr, field, true, initializing);
17690 result->value.type = ptr_type;
17691 return result;
1606917692 }
17693
17694 zig_unreachable();
1607017695}
1607117696
1607217697static void add_link_lib_symbol(IrAnalyze *ira, Buf *lib_name, Buf *symbol_name, AstNode *source_node) {
......@@ -16104,6 +17729,11 @@ static void add_link_lib_symbol(IrAnalyze *ira, Buf *lib_name, Buf *symbol_name,
1610417729 link_lib->symbols.append(symbol_name);
1610517730}
1610617731
17732static IrInstruction *ir_error_dependency_loop(IrAnalyze *ira, IrInstruction *source_instr) {
17733 ErrorMsg *msg = ir_add_error(ira, source_instr, buf_sprintf("dependency loop detected"));
17734 emit_error_notes_for_ref_stack(ira->codegen, msg);
17735 return ira->codegen->invalid_instruction;
17736}
1610717737
1610817738static IrInstruction *ir_analyze_decl_ref(IrAnalyze *ira, IrInstruction *source_instruction, Tld *tld) {
1610917739 resolve_top_level_decl(ira->codegen, tld, source_instruction->source_node);
......@@ -16118,6 +17748,9 @@ static IrInstruction *ir_analyze_decl_ref(IrAnalyze *ira, IrInstruction *source_
1611817748 {
1611917749 TldVar *tld_var = (TldVar *)tld;
1612017750 ZigVar *var = tld_var->var;
17751 if (var == nullptr) {
17752 return ir_error_dependency_loop(ira, source_instruction);
17753 }
1612117754 if (tld_var->extern_lib_name != nullptr) {
1612217755 add_link_lib_symbol(ira, tld_var->extern_lib_name, &var->name, source_instruction->source_node);
1612317756 }
......@@ -16133,23 +17766,13 @@ static IrInstruction *ir_analyze_decl_ref(IrAnalyze *ira, IrInstruction *source_
1613317766 if (type_is_invalid(fn_entry->type_entry))
1613417767 return ira->codegen->invalid_instruction;
1613517768
16136 // TODO instead of allocating this every time, put it in the tld value and we can reference
16137 // the same one every time
16138 ConstExprValue *const_val = create_const_vals(1);
16139 const_val->special = ConstValSpecialStatic;
16140 const_val->type = fn_entry->type_entry;
16141 const_val->data.x_ptr.data.fn.fn_entry = fn_entry;
16142 const_val->data.x_ptr.special = ConstPtrSpecialFunction;
16143 const_val->data.x_ptr.mut = ConstPtrMutComptimeConst;
16144
1614517769 if (tld_fn->extern_lib_name != nullptr) {
1614617770 add_link_lib_symbol(ira, tld_fn->extern_lib_name, &fn_entry->symbol_name, source_instruction->source_node);
1614717771 }
1614817772
16149 bool ptr_is_const = true;
16150 bool ptr_is_volatile = false;
16151 return ir_get_const_ptr(ira, source_instruction, const_val, fn_entry->type_entry,
16152 ConstPtrMutComptimeConst, ptr_is_const, ptr_is_volatile, 0);
17773 IrInstruction *fn_inst = ir_create_const_fn(&ira->new_irb, source_instruction->scope,
17774 source_instruction->source_node, fn_entry);
17775 return ir_get_ref(ira, source_instruction, fn_inst, true, false);
1615317776 }
1615417777 }
1615517778 zig_unreachable();
......@@ -16191,14 +17814,14 @@ static IrInstruction *ir_analyze_instruction_field_ptr(IrAnalyze *ira, IrInstruc
1619117814 assert(container_ptr->value.type->id == ZigTypeIdPointer);
1619217815 if (container_type->id == ZigTypeIdPointer) {
1619317816 ZigType *bare_type = container_ref_type(container_type);
16194 IrInstruction *container_child = ir_get_deref(ira, &field_ptr_instruction->base, container_ptr);
16195 IrInstruction *result = ir_analyze_container_field_ptr(ira, field_name, &field_ptr_instruction->base, container_child, bare_type);
17817 IrInstruction *container_child = ir_get_deref(ira, &field_ptr_instruction->base, container_ptr, nullptr);
17818 IrInstruction *result = ir_analyze_container_field_ptr(ira, field_name, &field_ptr_instruction->base, container_child, bare_type, field_ptr_instruction->initializing);
1619617819 return result;
1619717820 } else {
16198 IrInstruction *result = ir_analyze_container_field_ptr(ira, field_name, &field_ptr_instruction->base, container_ptr, container_type);
17821 IrInstruction *result = ir_analyze_container_field_ptr(ira, field_name, &field_ptr_instruction->base, container_ptr, container_type, field_ptr_instruction->initializing);
1619917822 return result;
1620017823 }
16201 } else if (is_array_ref(container_type)) {
17824 } else if (is_array_ref(container_type) && !field_ptr_instruction->initializing) {
1620217825 if (buf_eql_str(field_name, "len")) {
1620317826 ConstExprValue *len_val = create_const_vals(1);
1620417827 if (container_type->id == ZigTypeIdPointer) {
......@@ -16513,6 +18136,10 @@ static IrInstruction *ir_analyze_instruction_field_ptr(IrAnalyze *ira, IrInstruc
1651318136 buf_sprintf("type '%s' does not support field access", buf_ptr(&child_type->name)));
1651418137 return ira->codegen->invalid_instruction;
1651518138 }
18139 } else if (field_ptr_instruction->initializing) {
18140 ir_add_error(ira, &field_ptr_instruction->base,
18141 buf_sprintf("type '%s' does not support struct initialization syntax", buf_ptr(&container_type->name)));
18142 return ira->codegen->invalid_instruction;
1651618143 } else {
1651718144 ir_add_error_node(ira, field_ptr_instruction->base.source_node,
1651818145 buf_sprintf("type '%s' does not support field access", buf_ptr(&container_type->name)));
......@@ -16536,7 +18163,7 @@ static IrInstruction *ir_analyze_instruction_load_ptr(IrAnalyze *ira, IrInstruct
1653618163 IrInstruction *ptr = instruction->ptr->child;
1653718164 if (type_is_invalid(ptr->value.type))
1653818165 return ira->codegen->invalid_instruction;
16539 return ir_get_deref(ira, &instruction->base, ptr);
18166 return ir_get_deref(ira, &instruction->base, ptr, nullptr);
1654018167}
1654118168
1654218169static IrInstruction *ir_analyze_instruction_typeof(IrAnalyze *ira, IrInstructionTypeOf *typeof_instruction) {
......@@ -16547,64 +18174,6 @@ static IrInstruction *ir_analyze_instruction_typeof(IrAnalyze *ira, IrInstructio
1654718174 return ir_const_type(ira, &typeof_instruction->base, type_entry);
1654818175}
1654918176
16550static IrInstruction *ir_analyze_instruction_to_ptr_type(IrAnalyze *ira,
16551 IrInstructionToPtrType *to_ptr_type_instruction)
16552{
16553 Error err;
16554 IrInstruction *ptr_ptr = to_ptr_type_instruction->ptr->child;
16555 if (type_is_invalid(ptr_ptr->value.type))
16556 return ira->codegen->invalid_instruction;
16557
16558 ZigType *ptr_ptr_type = ptr_ptr->value.type;
16559 assert(ptr_ptr_type->id == ZigTypeIdPointer);
16560 ZigType *type_entry = ptr_ptr_type->data.pointer.child_type;
16561
16562 ZigType *ptr_type;
16563 if (type_entry->id == ZigTypeIdArray) {
16564 ptr_type = get_pointer_to_type(ira->codegen, type_entry->data.array.child_type, ptr_ptr_type->data.pointer.is_const);
16565 } else if (is_array_ref(type_entry)) {
16566 ptr_type = get_pointer_to_type(ira->codegen,
16567 type_entry->data.pointer.child_type->data.array.child_type, type_entry->data.pointer.is_const);
16568 } else if (is_slice(type_entry)) {
16569 ZigType *slice_ptr_type = type_entry->data.structure.fields[0].type_entry;
16570 ptr_type = adjust_ptr_len(ira->codegen, slice_ptr_type, PtrLenSingle);
16571 // If the pointer is over-aligned, we may have to reduce it based on the alignment of the element type.
16572 if (slice_ptr_type->data.pointer.explicit_alignment != 0) {
16573 ZigType *elem_type = slice_ptr_type->data.pointer.child_type;
16574 if ((err = type_resolve(ira->codegen, elem_type, ResolveStatusAlignmentKnown)))
16575 return ira->codegen->invalid_instruction;
16576 uint32_t elem_align = get_abi_alignment(ira->codegen, elem_type);
16577 uint32_t reduced_align = min(elem_align, slice_ptr_type->data.pointer.explicit_alignment);
16578 ptr_type = adjust_ptr_align(ira->codegen, ptr_type, reduced_align);
16579 }
16580 } else if (type_entry->id == ZigTypeIdArgTuple) {
16581 zig_panic("TODO for loop on var args");
16582 } else {
16583 ir_add_error_node(ira, to_ptr_type_instruction->base.source_node,
16584 buf_sprintf("expected array type, found '%s'", buf_ptr(&type_entry->name)));
16585 return ira->codegen->invalid_instruction;
16586 }
16587
16588 return ir_const_type(ira, &to_ptr_type_instruction->base, ptr_type);
16589}
16590
16591static IrInstruction *ir_analyze_instruction_ptr_type_child(IrAnalyze *ira,
16592 IrInstructionPtrTypeChild *ptr_type_child_instruction)
16593{
16594 IrInstruction *type_value = ptr_type_child_instruction->value->child;
16595 ZigType *type_entry = ir_resolve_type(ira, type_value);
16596 if (type_is_invalid(type_entry))
16597 return ira->codegen->invalid_instruction;
16598
16599 if (type_entry->id != ZigTypeIdPointer) {
16600 ir_add_error_node(ira, ptr_type_child_instruction->base.source_node,
16601 buf_sprintf("expected pointer type, found '%s'", buf_ptr(&type_entry->name)));
16602 return ira->codegen->invalid_instruction;
16603 }
16604
16605 return ir_const_type(ira, &ptr_type_child_instruction->base, type_entry->data.pointer.child_type);
16606}
16607
1660818177static IrInstruction *ir_analyze_instruction_set_cold(IrAnalyze *ira, IrInstructionSetCold *instruction) {
1660918178 if (ira->new_irb.exec->is_inline) {
1661018179 // ignore setCold when running functions at compile time
......@@ -17034,7 +18603,7 @@ static IrInstruction *ir_analyze_instruction_test_non_null(IrAnalyze *ira, IrIns
1703418603}
1703518604
1703618605static IrInstruction *ir_analyze_unwrap_optional_payload(IrAnalyze *ira, IrInstruction *source_instr,
17037 IrInstruction *base_ptr, bool safety_check_on)
18606 IrInstruction *base_ptr, bool safety_check_on, bool initializing)
1703818607{
1703918608 ZigType *ptr_type = base_ptr->value.type;
1704018609 assert(ptr_type->id == ZigTypeIdPointer);
......@@ -17064,7 +18633,7 @@ static IrInstruction *ir_analyze_unwrap_optional_payload(IrAnalyze *ira, IrInstr
1706418633 }
1706518634 if (!safety_check_on)
1706618635 return base_ptr;
17067 IrInstruction *c_ptr_val = ir_get_deref(ira, source_instr, base_ptr);
18636 IrInstruction *c_ptr_val = ir_get_deref(ira, source_instr, base_ptr, nullptr);
1706818637 ir_build_assert_non_null(ira, source_instr, c_ptr_val);
1706918638 return base_ptr;
1707018639 }
......@@ -17079,34 +18648,84 @@ static IrInstruction *ir_analyze_unwrap_optional_payload(IrAnalyze *ira, IrInstr
1707918648 ZigType *result_type = get_pointer_to_type_extra(ira->codegen, child_type,
1708018649 ptr_type->data.pointer.is_const, ptr_type->data.pointer.is_volatile, PtrLenSingle, 0, 0, 0, false);
1708118650
18651 bool same_comptime_repr = types_have_same_zig_comptime_repr(type_entry, child_type);
18652
1708218653 if (instr_is_comptime(base_ptr)) {
17083 ConstExprValue *val = ir_resolve_const(ira, base_ptr, UndefBad);
17084 if (!val)
18654 ConstExprValue *ptr_val = ir_resolve_const(ira, base_ptr, UndefBad);
18655 if (!ptr_val)
1708518656 return ira->codegen->invalid_instruction;
17086 if (val->data.x_ptr.mut != ConstPtrMutRuntimeVar) {
17087 ConstExprValue *maybe_val = const_ptr_pointee(ira, ira->codegen, val, source_instr->source_node);
17088 if (maybe_val == nullptr)
18657 if (ptr_val->data.x_ptr.mut != ConstPtrMutRuntimeVar) {
18658 ConstExprValue *optional_val = const_ptr_pointee(ira, ira->codegen, ptr_val, source_instr->source_node);
18659 if (optional_val == nullptr)
1708918660 return ira->codegen->invalid_instruction;
1709018661
17091 if (optional_value_is_null(maybe_val)) {
18662 if (initializing && optional_val->special == ConstValSpecialUndef) {
18663 switch (type_has_one_possible_value(ira->codegen, child_type)) {
18664 case OnePossibleValueInvalid:
18665 return ira->codegen->invalid_instruction;
18666 case OnePossibleValueNo:
18667 if (!same_comptime_repr) {
18668 ConstExprValue *payload_val = create_const_vals(1);
18669 payload_val->type = child_type;
18670 payload_val->special = ConstValSpecialUndef;
18671 payload_val->parent.id = ConstParentIdOptionalPayload;
18672 payload_val->parent.data.p_optional_payload.optional_val = optional_val;
18673
18674 optional_val->data.x_optional = payload_val;
18675 optional_val->special = ConstValSpecialStatic;
18676 }
18677 break;
18678 case OnePossibleValueYes: {
18679 ConstExprValue *pointee = create_const_vals(1);
18680 pointee->special = ConstValSpecialStatic;
18681 pointee->type = child_type;
18682 pointee->parent.id = ConstParentIdOptionalPayload;
18683 pointee->parent.data.p_optional_payload.optional_val = optional_val;
18684
18685 optional_val->special = ConstValSpecialStatic;
18686 optional_val->data.x_optional = pointee;
18687 break;
18688 }
18689 }
18690 } else if (optional_value_is_null(optional_val)) {
1709218691 ir_add_error(ira, source_instr, buf_sprintf("unable to unwrap null"));
1709318692 return ira->codegen->invalid_instruction;
1709418693 }
17095 IrInstruction *result = ir_const(ira, source_instr, result_type);
17096 ConstExprValue *out_val = &result->value;
17097 out_val->data.x_ptr.special = ConstPtrSpecialRef;
17098 out_val->data.x_ptr.mut = val->data.x_ptr.mut;
17099 if (types_have_same_zig_comptime_repr(type_entry, child_type)) {
17100 out_val->data.x_ptr.data.ref.pointee = maybe_val;
18694
18695 IrInstruction *result;
18696 if (ptr_val->data.x_ptr.mut == ConstPtrMutInfer) {
18697 result = ir_build_optional_unwrap_ptr(&ira->new_irb, source_instr->scope,
18698 source_instr->source_node, base_ptr, false, initializing);
18699 result->value.type = result_type;
18700 result->value.special = ConstValSpecialStatic;
1710118701 } else {
17102 out_val->data.x_ptr.data.ref.pointee = maybe_val->data.x_optional;
18702 result = ir_const(ira, source_instr, result_type);
18703 }
18704 ConstExprValue *result_val = &result->value;
18705 result_val->data.x_ptr.special = ConstPtrSpecialRef;
18706 result_val->data.x_ptr.mut = ptr_val->data.x_ptr.mut;
18707 switch (type_has_one_possible_value(ira->codegen, child_type)) {
18708 case OnePossibleValueInvalid:
18709 return ira->codegen->invalid_instruction;
18710 case OnePossibleValueNo:
18711 if (same_comptime_repr) {
18712 result_val->data.x_ptr.data.ref.pointee = optional_val;
18713 } else {
18714 assert(optional_val->data.x_optional != nullptr);
18715 result_val->data.x_ptr.data.ref.pointee = optional_val->data.x_optional;
18716 }
18717 break;
18718 case OnePossibleValueYes:
18719 assert(optional_val->data.x_optional != nullptr);
18720 result_val->data.x_ptr.data.ref.pointee = optional_val->data.x_optional;
18721 break;
1710318722 }
1710418723 return result;
1710518724 }
1710618725 }
1710718726
1710818727 IrInstruction *result = ir_build_optional_unwrap_ptr(&ira->new_irb, source_instr->scope,
17109 source_instr->source_node, base_ptr, safety_check_on);
18728 source_instr->source_node, base_ptr, safety_check_on, initializing);
1711018729 result->value.type = result_type;
1711118730 return result;
1711218731}
......@@ -17118,7 +18737,8 @@ static IrInstruction *ir_analyze_instruction_optional_unwrap_ptr(IrAnalyze *ira,
1711818737 if (type_is_invalid(base_ptr->value.type))
1711918738 return ira->codegen->invalid_instruction;
1712018739
17121 return ir_analyze_unwrap_optional_payload(ira, &instruction->base, base_ptr, instruction->safety_check_on);
18740 return ir_analyze_unwrap_optional_payload(ira, &instruction->base, base_ptr,
18741 instruction->safety_check_on, false);
1712218742}
1712318743
1712418744static IrInstruction *ir_analyze_instruction_ctz(IrAnalyze *ira, IrInstructionCtz *instruction) {
......@@ -17419,7 +19039,7 @@ static IrInstruction *ir_analyze_instruction_switch_target(IrAnalyze *ira,
1741919039 return result;
1742019040 }
1742119041
17422 IrInstruction *result = ir_get_deref(ira, &switch_target_instruction->base, target_value_ptr);
19042 IrInstruction *result = ir_get_deref(ira, &switch_target_instruction->base, target_value_ptr, nullptr);
1742319043 result->value.type = target_type;
1742419044 return result;
1742519045 }
......@@ -17449,7 +19069,7 @@ static IrInstruction *ir_analyze_instruction_switch_target(IrAnalyze *ira,
1744919069 return result;
1745019070 }
1745119071
17452 IrInstruction *union_value = ir_get_deref(ira, &switch_target_instruction->base, target_value_ptr);
19072 IrInstruction *union_value = ir_get_deref(ira, &switch_target_instruction->base, target_value_ptr, nullptr);
1745319073 union_value->value.type = target_type;
1745419074
1745519075 IrInstruction *union_tag_inst = ir_build_union_tag(&ira->new_irb, switch_target_instruction->base.scope,
......@@ -17473,7 +19093,7 @@ static IrInstruction *ir_analyze_instruction_switch_target(IrAnalyze *ira,
1747319093 return result;
1747419094 }
1747519095
17476 IrInstruction *enum_value = ir_get_deref(ira, &switch_target_instruction->base, target_value_ptr);
19096 IrInstruction *enum_value = ir_get_deref(ira, &switch_target_instruction->base, target_value_ptr, nullptr);
1747719097 enum_value->value.type = target_type;
1747819098 return enum_value;
1747919099 }
......@@ -17546,7 +19166,7 @@ static IrInstruction *ir_analyze_instruction_switch_var(IrAnalyze *ira, IrInstru
1754619166 }
1754719167
1754819168 IrInstruction *result = ir_build_union_field_ptr(&ira->new_irb,
17549 instruction->base.scope, instruction->base.source_node, target_value_ptr, field);
19169 instruction->base.scope, instruction->base.source_node, target_value_ptr, field, false, false);
1755019170 result->value.type = get_pointer_to_type(ira->codegen, field->type_entry,
1755119171 target_value_ptr->value.type->data.pointer.is_const);
1755219172 return result;
......@@ -17756,7 +19376,8 @@ static IrInstruction *ir_analyze_instruction_ref(IrAnalyze *ira, IrInstructionRe
1775619376}
1775719377
1775819378static IrInstruction *ir_analyze_container_init_fields_union(IrAnalyze *ira, IrInstruction *instruction,
17759 ZigType *container_type, size_t instr_field_count, IrInstructionContainerInitFieldsField *fields)
19379 ZigType *container_type, size_t instr_field_count, IrInstructionContainerInitFieldsField *fields,
19380 IrInstruction *result_loc)
1776019381{
1776119382 Error err;
1776219383 assert(container_type->id == ZigTypeIdUnion);
......@@ -17771,12 +19392,12 @@ static IrInstruction *ir_analyze_container_init_fields_union(IrAnalyze *ira, IrI
1777119392 }
1777219393
1777319394 IrInstructionContainerInitFieldsField *field = &fields[0];
17774 IrInstruction *field_value = field->value->child;
17775 if (type_is_invalid(field_value->value.type))
19395 IrInstruction *field_result_loc = field->result_loc->child;
19396 if (type_is_invalid(field_result_loc->value.type))
1777619397 return ira->codegen->invalid_instruction;
1777719398
1777819399 TypeUnionField *type_field = find_union_type_field(container_type, field->name);
17779 if (!type_field) {
19400 if (type_field == nullptr) {
1778019401 ir_add_error_node(ira, field->source_node,
1778119402 buf_sprintf("no member named '%s' in union '%s'",
1778219403 buf_ptr(field->name), buf_ptr(&container_type->name)));
......@@ -17786,46 +19407,36 @@ static IrInstruction *ir_analyze_container_init_fields_union(IrAnalyze *ira, IrI
1778619407 if (type_is_invalid(type_field->type_entry))
1778719408 return ira->codegen->invalid_instruction;
1778819409
17789 IrInstruction *casted_field_value = ir_implicit_cast(ira, field_value, type_field->type_entry);
17790 if (casted_field_value == ira->codegen->invalid_instruction)
17791 return ira->codegen->invalid_instruction;
17792
17793 if ((err = type_resolve(ira->codegen, casted_field_value->value.type, ResolveStatusZeroBitsKnown)))
17794 return ira->codegen->invalid_instruction;
19410 if (result_loc->value.data.x_ptr.mut == ConstPtrMutInfer) {
19411 if (instr_is_comptime(field_result_loc) &&
19412 field_result_loc->value.data.x_ptr.mut != ConstPtrMutRuntimeVar)
19413 {
19414 // nothing
19415 } else {
19416 result_loc->value.special = ConstValSpecialRuntime;
19417 }
19418 }
1779519419
1779619420 bool is_comptime = ir_should_inline(ira->new_irb.exec, instruction->scope)
1779719421 || type_requires_comptime(ira->codegen, container_type) == ReqCompTimeYes;
17798 if (is_comptime || casted_field_value->value.special != ConstValSpecialRuntime ||
17799 !type_has_bits(casted_field_value->value.type))
17800 {
17801 ConstExprValue *field_val = ir_resolve_const(ira, casted_field_value, UndefOk);
17802 if (!field_val)
17803 return ira->codegen->invalid_instruction;
17804
17805 IrInstruction *result = ir_const(ira, instruction, container_type);
17806 ConstExprValue *out_val = &result->value;
17807 out_val->data.x_union.payload = field_val;
17808 out_val->data.x_union.tag = type_field->enum_field->value;
17809 out_val->parent.id = ConstParentIdUnion;
17810 out_val->parent.data.p_union.union_val = out_val;
1781119422
17812 return result;
19423 IrInstruction *result = ir_get_deref(ira, instruction, result_loc, nullptr);
19424 if (is_comptime && !instr_is_comptime(result)) {
19425 ir_add_error(ira, field->result_loc,
19426 buf_sprintf("unable to evaluate constant expression"));
19427 return ira->codegen->invalid_instruction;
1781319428 }
17814
17815 IrInstruction *new_instruction = ir_build_union_init(&ira->new_irb,
17816 instruction->scope, instruction->source_node,
17817 container_type, type_field, casted_field_value);
17818 new_instruction->value.type = container_type;
17819 ir_add_alloca(ira, new_instruction, container_type);
17820 return new_instruction;
19429 return result;
1782119430}
1782219431
1782319432static IrInstruction *ir_analyze_container_init_fields(IrAnalyze *ira, IrInstruction *instruction,
17824 ZigType *container_type, size_t instr_field_count, IrInstructionContainerInitFieldsField *fields)
19433 ZigType *container_type, size_t instr_field_count, IrInstructionContainerInitFieldsField *fields,
19434 IrInstruction *result_loc)
1782519435{
1782619436 Error err;
1782719437 if (container_type->id == ZigTypeIdUnion) {
17828 return ir_analyze_container_init_fields_union(ira, instruction, container_type, instr_field_count, fields);
19438 return ir_analyze_container_init_fields_union(ira, instruction, container_type, instr_field_count,
19439 fields, result_loc);
1782919440 }
1783019441 if (container_type->id != ZigTypeIdStruct || is_slice(container_type)) {
1783119442 ir_add_error(ira, instruction,
......@@ -17842,22 +19453,28 @@ static IrInstruction *ir_analyze_container_init_fields(IrAnalyze *ira, IrInstruc
1784219453 IrInstruction *first_non_const_instruction = nullptr;
1784319454
1784419455 AstNode **field_assign_nodes = allocate<AstNode *>(actual_field_count);
17845
17846 IrInstructionStructInitField *new_fields = allocate<IrInstructionStructInitField>(actual_field_count);
19456 ZigList<IrInstruction *> const_ptrs = {};
1784719457
1784819458 bool is_comptime = ir_should_inline(ira->new_irb.exec, instruction->scope)
1784919459 || type_requires_comptime(ira->codegen, container_type) == ReqCompTimeYes;
1785019460
17851 ConstExprValue const_val = {};
17852 const_val.special = ConstValSpecialStatic;
17853 const_val.type = container_type;
17854 // const_val.global_refs = allocate<ConstGlobalRefs>(1);
17855 const_val.data.x_struct.fields = create_const_vals(actual_field_count);
19461
19462 // Here we iterate over the fields that have been initialized, and emit
19463 // compile errors for missing fields and duplicate fields.
19464 // It is only now that we find out whether the struct initialization can be a comptime
19465 // value, but we have already emitted runtime instructions for the fields that
19466 // were initialized with runtime values, and have omitted instructions that would have
19467 // initialized fields with comptime values.
19468 // So now we must clean up this situation. If it turns out the struct initialization can
19469 // be a comptime value, overwrite ConstPtrMutInfer with ConstPtrMutComptimeConst.
19470 // Otherwise, we must emit instructions to runtime-initialize the fields that have
19471 // comptime-known values.
19472
1785619473 for (size_t i = 0; i < instr_field_count; i += 1) {
1785719474 IrInstructionContainerInitFieldsField *field = &fields[i];
1785819475
17859 IrInstruction *field_value = field->value->child;
17860 if (type_is_invalid(field_value->value.type))
19476 IrInstruction *field_result_loc = field->result_loc->child;
19477 if (type_is_invalid(field_result_loc->value.type))
1786119478 return ira->codegen->invalid_instruction;
1786219479
1786319480 TypeStructField *type_field = find_struct_type_field(container_type, field->name);
......@@ -17871,10 +19488,6 @@ static IrInstruction *ir_analyze_container_init_fields(IrAnalyze *ira, IrInstruc
1787119488 if (type_is_invalid(type_field->type_entry))
1787219489 return ira->codegen->invalid_instruction;
1787319490
17874 IrInstruction *casted_field_value = ir_implicit_cast(ira, field_value, type_field->type_entry);
17875 if (casted_field_value == ira->codegen->invalid_instruction)
17876 return ira->codegen->invalid_instruction;
17877
1787819491 size_t field_index = type_field->src_index;
1787919492 AstNode *existing_assign_node = field_assign_nodes[field_index];
1788019493 if (existing_assign_node) {
......@@ -17884,26 +19497,18 @@ static IrInstruction *ir_analyze_container_init_fields(IrAnalyze *ira, IrInstruc
1788419497 }
1788519498 field_assign_nodes[field_index] = field->source_node;
1788619499
17887 new_fields[field_index].value = casted_field_value;
17888 new_fields[field_index].type_struct_field = type_field;
17889
17890 if (const_val.special == ConstValSpecialStatic) {
17891 if (is_comptime || casted_field_value->value.special != ConstValSpecialRuntime) {
17892 ConstExprValue *field_val = ir_resolve_const(ira, casted_field_value, UndefOk);
17893 if (!field_val)
17894 return ira->codegen->invalid_instruction;
17895
17896 copy_const_val(&const_val.data.x_struct.fields[field_index], field_val, true);
17897 } else {
17898 first_non_const_instruction = casted_field_value;
17899 const_val.special = ConstValSpecialRuntime;
17900 }
19500 if (instr_is_comptime(field_result_loc) &&
19501 field_result_loc->value.data.x_ptr.mut != ConstPtrMutRuntimeVar)
19502 {
19503 const_ptrs.append(field_result_loc);
19504 } else {
19505 first_non_const_instruction = field_result_loc;
1790119506 }
1790219507 }
1790319508
1790419509 bool any_missing = false;
1790519510 for (size_t i = 0; i < actual_field_count; i += 1) {
17906 if (field_assign_nodes[i]) continue;
19511 if (field_assign_nodes[i] != nullptr) continue;
1790719512
1790819513 // look for a default field value
1790919514 TypeStructField *field = &container_type->data.structure.fields[i];
......@@ -17929,182 +19534,177 @@ static IrInstruction *ir_analyze_container_init_fields(IrAnalyze *ira, IrInstruc
1792919534 IrInstruction *runtime_inst = ir_const(ira, instruction, field->init_val->type);
1793019535 copy_const_val(&runtime_inst->value, field->init_val, true);
1793119536
17932 new_fields[i].value = runtime_inst;
17933 new_fields[i].type_struct_field = field;
17934
17935 if (const_val.special == ConstValSpecialStatic) {
17936 copy_const_val(&const_val.data.x_struct.fields[i], field->init_val, true);
19537 IrInstruction *field_ptr = ir_analyze_struct_field_ptr(ira, instruction, field, result_loc,
19538 container_type, true);
19539 ir_analyze_store_ptr(ira, instruction, field_ptr, runtime_inst);
19540 if (instr_is_comptime(field_ptr) && field_ptr->value.data.x_ptr.mut != ConstPtrMutRuntimeVar) {
19541 const_ptrs.append(field_ptr);
19542 } else {
19543 first_non_const_instruction = result_loc;
1793719544 }
1793819545 }
1793919546 if (any_missing)
1794019547 return ira->codegen->invalid_instruction;
1794119548
17942 if (const_val.special == ConstValSpecialStatic) {
17943 IrInstruction *result = ir_const(ira, instruction, nullptr);
17944 ConstExprValue *out_val = &result->value;
17945 copy_const_val(out_val, &const_val, false);
17946 out_val->type = container_type;
17947
17948 for (size_t i = 0; i < instr_field_count; i += 1) {
17949 ConstExprValue *field_val = &out_val->data.x_struct.fields[i];
17950 ConstParent *parent = get_const_val_parent(ira->codegen, field_val);
17951 if (parent != nullptr) {
17952 parent->id = ConstParentIdStruct;
17953 parent->data.p_struct.field_index = i;
17954 parent->data.p_struct.struct_val = out_val;
19549 if (result_loc->value.data.x_ptr.mut == ConstPtrMutInfer) {
19550 if (const_ptrs.length != actual_field_count) {
19551 result_loc->value.special = ConstValSpecialRuntime;
19552 for (size_t i = 0; i < const_ptrs.length; i += 1) {
19553 IrInstruction *field_result_loc = const_ptrs.at(i);
19554 IrInstruction *deref = ir_get_deref(ira, field_result_loc, field_result_loc, nullptr);
19555 field_result_loc->value.special = ConstValSpecialRuntime;
19556 ir_analyze_store_ptr(ira, field_result_loc, field_result_loc, deref);
1795519557 }
1795619558 }
17957
17958 return result;
1795919559 }
1796019560
17961 if (is_comptime) {
19561 IrInstruction *result = ir_get_deref(ira, instruction, result_loc, nullptr);
19562
19563 if (is_comptime && !instr_is_comptime(result)) {
1796219564 ir_add_error_node(ira, first_non_const_instruction->source_node,
1796319565 buf_sprintf("unable to evaluate constant expression"));
1796419566 return ira->codegen->invalid_instruction;
1796519567 }
1796619568
17967 IrInstruction *new_instruction = ir_build_struct_init(&ira->new_irb,
17968 instruction->scope, instruction->source_node,
17969 container_type, actual_field_count, new_fields);
17970 new_instruction->value.type = container_type;
17971 ir_add_alloca(ira, new_instruction, container_type);
17972 return new_instruction;
19569 return result;
1797319570}
1797419571
1797519572static IrInstruction *ir_analyze_instruction_container_init_list(IrAnalyze *ira,
1797619573 IrInstructionContainerInitList *instruction)
1797719574{
17978 Error err;
19575 ZigType *container_type = ir_resolve_type(ira, instruction->container_type->child);
19576 if (type_is_invalid(container_type))
19577 return ira->codegen->invalid_instruction;
1797919578
1798019579 size_t elem_count = instruction->item_count;
1798119580
17982 ZigType *container_type;
17983 if (instruction->container_type != nullptr) {
17984 container_type = ir_resolve_type(ira, instruction->container_type->child);
17985 if (type_is_invalid(container_type))
17986 return ira->codegen->invalid_instruction;
17987 } else {
17988 ZigType *elem_type = ir_resolve_type(ira, instruction->elem_type->child);
17989 if (type_is_invalid(elem_type))
17990 return ira->codegen->invalid_instruction;
17991 if ((err = type_resolve(ira->codegen, elem_type, ResolveStatusSizeKnown))) {
17992 return ira->codegen->invalid_instruction;
17993 }
17994 container_type = get_array_type(ira->codegen, elem_type, elem_count);
17995 }
17996
1799719581 if (is_slice(container_type)) {
17998 ir_add_error(ira, &instruction->base,
19582 ir_add_error(ira, instruction->container_type,
1799919583 buf_sprintf("expected array type or [_], found slice"));
1800019584 return ira->codegen->invalid_instruction;
18001 } else if (container_type->id == ZigTypeIdStruct && !is_slice(container_type) && elem_count == 0) {
18002 return ir_analyze_container_init_fields(ira, &instruction->base, container_type,
18003 0, nullptr);
18004 } else if (container_type->id == ZigTypeIdArray) {
18005 // array is same as slice init but we make a compile error if the length is wrong
18006 ZigType *child_type;
18007 if (container_type->id == ZigTypeIdArray) {
18008 child_type = container_type->data.array.child_type;
18009 if (container_type->data.array.len != elem_count) {
18010 ZigType *literal_type = get_array_type(ira->codegen, child_type, elem_count);
18011
18012 ir_add_error(ira, &instruction->base,
18013 buf_sprintf("expected %s literal, found %s literal",
18014 buf_ptr(&container_type->name), buf_ptr(&literal_type->name)));
18015 return ira->codegen->invalid_instruction;
18016 }
18017 } else {
18018 ZigType *pointer_type = container_type->data.structure.fields[slice_ptr_index].type_entry;
18019 assert(pointer_type->id == ZigTypeIdPointer);
18020 child_type = pointer_type->data.pointer.child_type;
18021 }
19585 }
1802219586
18023 if ((err = type_resolve(ira->codegen, child_type, ResolveStatusSizeKnown))) {
19587 if (container_type->id == ZigTypeIdVoid) {
19588 if (elem_count != 0) {
19589 ir_add_error_node(ira, instruction->base.source_node,
19590 buf_sprintf("void expression expects no arguments"));
1802419591 return ira->codegen->invalid_instruction;
1802519592 }
19593 return ir_const_void(ira, &instruction->base);
19594 }
1802619595
18027 ZigType *fixed_size_array_type = get_array_type(ira->codegen, child_type, elem_count);
19596 if (container_type->id == ZigTypeIdStruct && elem_count == 0) {
19597 ir_assert(instruction->result_loc != nullptr, &instruction->base);
19598 IrInstruction *result_loc = instruction->result_loc->child;
19599 if (type_is_invalid(result_loc->value.type))
19600 return result_loc;
19601 return ir_analyze_container_init_fields(ira, &instruction->base, container_type, 0, nullptr, result_loc);
19602 }
1802819603
18029 ConstExprValue const_val = {};
18030 const_val.special = ConstValSpecialStatic;
18031 const_val.type = fixed_size_array_type;
18032 // const_val.global_refs = allocate<ConstGlobalRefs>(1);
18033 const_val.data.x_array.data.s_none.elements = create_const_vals(elem_count);
19604 if (container_type->id != ZigTypeIdArray) {
19605 ir_add_error_node(ira, instruction->base.source_node,
19606 buf_sprintf("type '%s' does not support array initialization",
19607 buf_ptr(&container_type->name)));
19608 return ira->codegen->invalid_instruction;
19609 }
1803419610
18035 bool is_comptime = ir_should_inline(ira->new_irb.exec, instruction->base.scope);
19611 ir_assert(instruction->result_loc != nullptr, &instruction->base);
19612 IrInstruction *result_loc = instruction->result_loc->child;
19613 if (type_is_invalid(result_loc->value.type))
19614 return result_loc;
19615 ir_assert(result_loc->value.type->id == ZigTypeIdPointer, &instruction->base);
1803619616
18037 IrInstruction **new_items = allocate<IrInstruction *>(elem_count);
19617 ZigType *child_type = container_type->data.array.child_type;
19618 if (container_type->data.array.len != elem_count) {
19619 ZigType *literal_type = get_array_type(ira->codegen, child_type, elem_count);
1803819620
18039 IrInstruction *first_non_const_instruction = nullptr;
19621 ir_add_error(ira, &instruction->base,
19622 buf_sprintf("expected %s literal, found %s literal",
19623 buf_ptr(&container_type->name), buf_ptr(&literal_type->name)));
19624 return ira->codegen->invalid_instruction;
19625 }
1804019626
18041 for (size_t i = 0; i < elem_count; i += 1) {
18042 IrInstruction *arg_value = instruction->items[i]->child;
18043 if (type_is_invalid(arg_value->value.type))
18044 return ira->codegen->invalid_instruction;
19627 switch (type_has_one_possible_value(ira->codegen, container_type)) {
19628 case OnePossibleValueInvalid:
19629 return ira->codegen->invalid_instruction;
19630 case OnePossibleValueYes:
19631 return ir_const(ira, &instruction->base, container_type);
19632 case OnePossibleValueNo:
19633 break;
19634 }
1804519635
18046 IrInstruction *casted_arg = ir_implicit_cast(ira, arg_value, child_type);
18047 if (casted_arg == ira->codegen->invalid_instruction)
18048 return ira->codegen->invalid_instruction;
19636 bool is_comptime;
19637 switch (type_requires_comptime(ira->codegen, container_type)) {
19638 case ReqCompTimeInvalid:
19639 return ira->codegen->invalid_instruction;
19640 case ReqCompTimeNo:
19641 is_comptime = ir_should_inline(ira->new_irb.exec, instruction->base.scope);
19642 break;
19643 case ReqCompTimeYes:
19644 is_comptime = true;
19645 break;
19646 }
1804919647
18050 new_items[i] = casted_arg;
19648 IrInstruction *first_non_const_instruction = nullptr;
1805119649
18052 if (const_val.special == ConstValSpecialStatic) {
18053 if (is_comptime || casted_arg->value.special != ConstValSpecialRuntime) {
18054 ConstExprValue *elem_val = ir_resolve_const(ira, casted_arg, UndefBad);
18055 if (!elem_val)
18056 return ira->codegen->invalid_instruction;
19650 // The Result Location Mechanism has already emitted runtime instructions to
19651 // initialize runtime elements and has omitted instructions for the comptime
19652 // elements. However it is only now that we find out whether the array initialization
19653 // can be a comptime value. So we must clean up the situation. If it turns out
19654 // array initialization can be a comptime value, overwrite ConstPtrMutInfer with
19655 // ConstPtrMutComptimeConst. Otherwise, emit instructions to runtime-initialize the
19656 // elements that have comptime-known values.
19657 ZigList<IrInstruction *> const_ptrs = {};
19658
19659 for (size_t i = 0; i < elem_count; i += 1) {
19660 IrInstruction *elem_result_loc = instruction->elem_result_loc_list[i]->child;
19661 if (type_is_invalid(elem_result_loc->value.type))
19662 return ira->codegen->invalid_instruction;
1805719663
18058 copy_const_val(&const_val.data.x_array.data.s_none.elements[i], elem_val, true);
18059 } else {
18060 first_non_const_instruction = casted_arg;
18061 const_val.special = ConstValSpecialRuntime;
18062 }
18063 }
19664 assert(elem_result_loc->value.type->id == ZigTypeIdPointer);
19665
19666 if (instr_is_comptime(elem_result_loc) &&
19667 elem_result_loc->value.data.x_ptr.mut != ConstPtrMutRuntimeVar)
19668 {
19669 const_ptrs.append(elem_result_loc);
19670 } else {
19671 first_non_const_instruction = elem_result_loc;
1806419672 }
19673 }
1806519674
18066 if (const_val.special == ConstValSpecialStatic) {
18067 IrInstruction *result = ir_const(ira, &instruction->base, nullptr);
18068 ConstExprValue *out_val = &result->value;
18069 copy_const_val(out_val, &const_val, false);
18070 result->value.type = fixed_size_array_type;
18071 for (size_t i = 0; i < elem_count; i += 1) {
18072 ConstExprValue *elem_val = &out_val->data.x_array.data.s_none.elements[i];
18073 ConstParent *parent = get_const_val_parent(ira->codegen, elem_val);
18074 if (parent != nullptr) {
18075 parent->id = ConstParentIdArray;
18076 parent->data.p_array.array_val = out_val;
18077 parent->data.p_array.elem_index = i;
18078 }
19675 if (result_loc->value.data.x_ptr.mut == ConstPtrMutInfer) {
19676 if (const_ptrs.length != elem_count) {
19677 result_loc->value.special = ConstValSpecialRuntime;
19678 for (size_t i = 0; i < const_ptrs.length; i += 1) {
19679 IrInstruction *elem_result_loc = const_ptrs.at(i);
19680 assert(elem_result_loc->value.special == ConstValSpecialStatic);
19681 IrInstruction *deref = ir_get_deref(ira, elem_result_loc, elem_result_loc, nullptr);
19682 elem_result_loc->value.special = ConstValSpecialRuntime;
19683 ir_analyze_store_ptr(ira, elem_result_loc, elem_result_loc, deref);
1807919684 }
18080 return result;
1808119685 }
19686 }
1808219687
18083 if (is_comptime) {
18084 ir_add_error_node(ira, first_non_const_instruction->source_node,
18085 buf_sprintf("unable to evaluate constant expression"));
18086 return ira->codegen->invalid_instruction;
18087 }
19688 IrInstruction *result = ir_get_deref(ira, &instruction->base, result_loc, nullptr);
19689 if (instr_is_comptime(result))
19690 return result;
1808819691
18089 IrInstruction *new_instruction = ir_build_container_init_list(&ira->new_irb,
18090 instruction->base.scope, instruction->base.source_node,
18091 nullptr, nullptr, elem_count, new_items);
18092 new_instruction->value.type = fixed_size_array_type;
18093 ir_add_alloca(ira, new_instruction, fixed_size_array_type);
18094 return new_instruction;
18095 } else if (container_type->id == ZigTypeIdVoid) {
18096 if (elem_count != 0) {
18097 ir_add_error_node(ira, instruction->base.source_node,
18098 buf_sprintf("void expression expects no arguments"));
18099 return ira->codegen->invalid_instruction;
18100 }
18101 return ir_const_void(ira, &instruction->base);
18102 } else {
18103 ir_add_error_node(ira, instruction->base.source_node,
18104 buf_sprintf("type '%s' does not support array initialization",
18105 buf_ptr(&container_type->name)));
19692 if (is_comptime) {
19693 ir_add_error_node(ira, first_non_const_instruction->source_node,
19694 buf_sprintf("unable to evaluate constant expression"));
19695 return ira->codegen->invalid_instruction;
19696 }
19697
19698 ZigType *result_elem_type = result_loc->value.type->data.pointer.child_type;
19699 if (is_slice(result_elem_type)) {
19700 ErrorMsg *msg = ir_add_error(ira, &instruction->base,
19701 buf_sprintf("runtime-initialized array cannot be casted to slice type '%s'",
19702 buf_ptr(&result_elem_type->name)));
19703 add_error_note(ira->codegen, msg, first_non_const_instruction->source_node,
19704 buf_sprintf("this value is not comptime-known"));
1810619705 return ira->codegen->invalid_instruction;
1810719706 }
19707 return result;
1810819708}
1810919709
1811019710static IrInstruction *ir_analyze_instruction_container_init_fields(IrAnalyze *ira,
......@@ -18115,8 +19715,13 @@ static IrInstruction *ir_analyze_instruction_container_init_fields(IrAnalyze *ir
1811519715 if (type_is_invalid(container_type))
1811619716 return ira->codegen->invalid_instruction;
1811719717
19718 ir_assert(instruction->result_loc != nullptr, &instruction->base);
19719 IrInstruction *result_loc = instruction->result_loc->child;
19720 if (type_is_invalid(result_loc->value.type))
19721 return result_loc;
19722
1811819723 return ir_analyze_container_init_fields(ira, &instruction->base, container_type,
18119 instruction->field_count, instruction->fields);
19724 instruction->field_count, instruction->fields, result_loc);
1812019725}
1812119726
1812219727static IrInstruction *ir_analyze_instruction_compile_err(IrAnalyze *ira,
......@@ -18385,12 +19990,6 @@ static IrInstruction *ir_analyze_instruction_bit_offset_of(IrAnalyze *ira,
1838519990 return ir_const_unsigned(ira, &instruction->base, bit_offset);
1838619991}
1838719992
18388static IrInstruction *ir_error_dependency_loop(IrAnalyze *ira, IrInstruction *source_instr) {
18389 ErrorMsg *msg = ir_add_error(ira, source_instr, buf_sprintf("dependency loop detected"));
18390 emit_error_notes_for_ref_stack(ira->codegen, msg);
18391 return ira->codegen->invalid_instruction;
18392}
18393
1839419993static void ensure_field_index(ZigType *type, const char *field_name, size_t index) {
1839519994 Buf *field_name_buf;
1839619995
......@@ -19509,7 +21108,7 @@ static IrInstruction *ir_analyze_instruction_c_import(IrAnalyze *ira, IrInstruct
1950921108 ir_add_error_node(ira, node, buf_sprintf("C import failed: unable to make dir: %s", err_str(err)));
1951021109 return ira->codegen->invalid_instruction;
1951121110 }
19512
21111
1951321112 if ((err = os_write_file(&tmp_c_file_path, &cimport_scope->buf))) {
1951421113 ir_add_error_node(ira, node, buf_sprintf("C import failed: unable to write .h file: %s", err_str(err)));
1951521114 return ira->codegen->invalid_instruction;
......@@ -19796,12 +21395,21 @@ static IrInstruction *ir_analyze_instruction_cmpxchg(IrAnalyze *ira, IrInstructi
1979621395 zig_panic("TODO compile-time execution of cmpxchg");
1979721396 }
1979821397
19799 IrInstruction *result = ir_build_cmpxchg_gen(ira, &instruction->base,
21398 ZigType *result_type = get_optional_type(ira->codegen, operand_type);
21399 IrInstruction *result_loc;
21400 if (handle_is_ptr(result_type)) {
21401 result_loc = ir_resolve_result(ira, &instruction->base, instruction->result_loc,
21402 result_type, nullptr, true, false);
21403 if (type_is_invalid(result_loc->value.type) || instr_is_unreachable(result_loc)) {
21404 return result_loc;
21405 }
21406 } else {
21407 result_loc = nullptr;
21408 }
21409
21410 return ir_build_cmpxchg_gen(ira, &instruction->base, result_type,
1980021411 casted_ptr, casted_cmp_value, casted_new_value,
19801 success_order, failure_order, instruction->is_weak);
19802 result->value.type = get_optional_type(ira->codegen, operand_type);
19803 ir_add_alloca(ira, result, result->value.type);
19804 return result;
21412 success_order, failure_order, instruction->is_weak, result_loc);
1980521413}
1980621414
1980721415static IrInstruction *ir_analyze_instruction_fence(IrAnalyze *ira, IrInstructionFence *instruction) {
......@@ -19939,7 +21547,7 @@ static IrInstruction *ir_analyze_instruction_float_cast(IrAnalyze *ira, IrInstru
1993921547 } else {
1994021548 op = CastOpNumLitToConcrete;
1994121549 }
19942 return ir_resolve_cast(ira, &instruction->base, target, dest_type, op, false);
21550 return ir_resolve_cast(ira, &instruction->base, target, dest_type, op);
1994321551 } else {
1994421552 return ira->codegen->invalid_instruction;
1994521553 }
......@@ -20047,6 +21655,12 @@ static IrInstruction *ir_analyze_instruction_from_bytes(IrAnalyze *ira, IrInstru
2004721655 }
2004821656 }
2004921657
21658 IrInstruction *result_loc = ir_resolve_result(ira, &instruction->base, instruction->result_loc,
21659 dest_slice_type, nullptr, true, false);
21660 if (result_loc != nullptr && (type_is_invalid(result_loc->value.type) || instr_is_unreachable(result_loc))) {
21661 return result_loc;
21662 }
21663
2005021664 if (casted_value->value.data.rh_slice.id == RuntimeHintSliceIdLen) {
2005121665 known_len = casted_value->value.data.rh_slice.len;
2005221666 have_known_len = true;
......@@ -20066,9 +21680,7 @@ static IrInstruction *ir_analyze_instruction_from_bytes(IrAnalyze *ira, IrInstru
2006621680 }
2006721681 }
2006821682
20069 IrInstruction *result = ir_build_resize_slice(ira, &instruction->base, casted_value, dest_slice_type);
20070 ir_add_alloca(ira, result, dest_slice_type);
20071 return result;
21683 return ir_build_resize_slice(ira, &instruction->base, casted_value, dest_slice_type, result_loc);
2007221684}
2007321685
2007421686static IrInstruction *ir_analyze_instruction_to_bytes(IrAnalyze *ira, IrInstructionToBytes *instruction) {
......@@ -20120,9 +21732,13 @@ static IrInstruction *ir_analyze_instruction_to_bytes(IrAnalyze *ira, IrInstruct
2012021732 return result;
2012121733 }
2012221734
20123 IrInstruction *result = ir_build_resize_slice(ira, &instruction->base, target, dest_slice_type);
20124 ir_add_alloca(ira, result, dest_slice_type);
20125 return result;
21735 IrInstruction *result_loc = ir_resolve_result(ira, &instruction->base, instruction->result_loc,
21736 dest_slice_type, nullptr, true, false);
21737 if (type_is_invalid(result_loc->value.type) || instr_is_unreachable(result_loc)) {
21738 return result_loc;
21739 }
21740
21741 return ir_build_resize_slice(ira, &instruction->base, target, dest_slice_type, result_loc);
2012621742}
2012721743
2012821744static Error resolve_ptr_align(IrAnalyze *ira, ZigType *ty, uint32_t *result_align) {
......@@ -20154,7 +21770,7 @@ static IrInstruction *ir_analyze_instruction_int_to_float(IrAnalyze *ira, IrInst
2015421770 return ira->codegen->invalid_instruction;
2015521771 }
2015621772
20157 return ir_resolve_cast(ira, &instruction->base, target, dest_type, CastOpIntToFloat, false);
21773 return ir_resolve_cast(ira, &instruction->base, target, dest_type, CastOpIntToFloat);
2015821774}
2015921775
2016021776static IrInstruction *ir_analyze_instruction_float_to_int(IrAnalyze *ira, IrInstructionFloatToInt *instruction) {
......@@ -20176,7 +21792,7 @@ static IrInstruction *ir_analyze_instruction_float_to_int(IrAnalyze *ira, IrInst
2017621792 return ira->codegen->invalid_instruction;
2017721793 }
2017821794
20179 return ir_resolve_cast(ira, &instruction->base, target, dest_type, CastOpFloatToInt, false);
21795 return ir_resolve_cast(ira, &instruction->base, target, dest_type, CastOpFloatToInt);
2018021796}
2018121797
2018221798static IrInstruction *ir_analyze_instruction_err_to_int(IrAnalyze *ira, IrInstructionErrToInt *instruction) {
......@@ -20228,7 +21844,7 @@ static IrInstruction *ir_analyze_instruction_bool_to_int(IrAnalyze *ira, IrInstr
2022821844 }
2022921845
2023021846 ZigType *u1_type = get_int_type(ira->codegen, false, 1);
20231 return ir_resolve_cast(ira, &instruction->base, target, u1_type, CastOpBoolToInt, false);
21847 return ir_resolve_cast(ira, &instruction->base, target, u1_type, CastOpBoolToInt);
2023221848}
2023321849
2023421850static IrInstruction *ir_analyze_instruction_int_type(IrAnalyze *ira, IrInstructionIntType *instruction) {
......@@ -20389,7 +22005,7 @@ static IrInstruction *ir_analyze_instruction_memset(IrAnalyze *ira, IrInstructio
2038922005
2039022006 ConstExprValue *byte_val = &casted_byte->value;
2039122007 for (size_t i = start; i < end; i += 1) {
20392 dest_elements[i] = *byte_val;
22008 copy_const_val(&dest_elements[i], byte_val, true);
2039322009 }
2039422010
2039522011 return ir_const_void(ira, &instruction->base);
......@@ -20459,7 +22075,7 @@ static IrInstruction *ir_analyze_instruction_memcpy(IrAnalyze *ira, IrInstructio
2045922075 return ira->codegen->invalid_instruction;
2046022076
2046122077 // TODO test this at comptime with u8 and non-u8 types
20462 // TODO test with dest ptr being a global runtime variable
22078 // TODO test with dest ptr being a global runtime variable
2046322079 if (casted_dest_ptr->value.special == ConstValSpecialStatic &&
2046422080 casted_src_ptr->value.special == ConstValSpecialStatic &&
2046522081 casted_count->value.special == ConstValSpecialStatic &&
......@@ -20557,7 +22173,7 @@ static IrInstruction *ir_analyze_instruction_memcpy(IrAnalyze *ira, IrInstructio
2055722173 // TODO check for noalias violations - this should be generalized to work for any function
2055822174
2055922175 for (size_t i = 0; i < count; i += 1) {
20560 dest_elements[dest_start + i] = src_elements[src_start + i];
22176 copy_const_val(&dest_elements[dest_start + i], &src_elements[src_start + i], true);
2056122177 }
2056222178
2056322179 return ir_const_void(ira, &instruction->base);
......@@ -20569,7 +22185,7 @@ static IrInstruction *ir_analyze_instruction_memcpy(IrAnalyze *ira, IrInstructio
2056922185 return result;
2057022186}
2057122187
20572static IrInstruction *ir_analyze_instruction_slice(IrAnalyze *ira, IrInstructionSlice *instruction) {
22188static IrInstruction *ir_analyze_instruction_slice(IrAnalyze *ira, IrInstructionSliceSrc *instruction) {
2057322189 IrInstruction *ptr_ptr = instruction->ptr->child;
2057422190 if (type_is_invalid(ptr_ptr->value.type))
2057522191 return ira->codegen->invalid_instruction;
......@@ -20858,12 +22474,13 @@ static IrInstruction *ir_analyze_instruction_slice(IrAnalyze *ira, IrInstruction
2085822474 return result;
2085922475 }
2086022476
20861 IrInstruction *new_instruction = ir_build_slice(&ira->new_irb,
20862 instruction->base.scope, instruction->base.source_node,
20863 ptr_ptr, casted_start, end, instruction->safety_check_on);
20864 new_instruction->value.type = return_type;
20865 ir_add_alloca(ira, new_instruction, return_type);
20866 return new_instruction;
22477 IrInstruction *result_loc = ir_resolve_result(ira, &instruction->base, instruction->result_loc,
22478 return_type, nullptr, true, false);
22479 if (type_is_invalid(result_loc->value.type) || instr_is_unreachable(result_loc)) {
22480 return result_loc;
22481 }
22482 return ir_build_slice_gen(ira, &instruction->base, return_type,
22483 ptr_ptr, casted_start, end, instruction->safety_check_on, result_loc);
2086722484}
2086822485
2086922486static IrInstruction *ir_analyze_instruction_member_count(IrAnalyze *ira, IrInstructionMemberCount *instruction) {
......@@ -21187,15 +22804,149 @@ static IrInstruction *ir_analyze_instruction_overflow_op(IrAnalyze *ira, IrInstr
2118722804 return result;
2118822805}
2118922806
21190static IrInstruction *ir_analyze_instruction_test_err(IrAnalyze *ira, IrInstructionTestErr *instruction) {
21191 IrInstruction *value = instruction->value->child;
21192 if (type_is_invalid(value->value.type))
22807static IrInstruction *ir_analyze_instruction_result_ptr(IrAnalyze *ira, IrInstructionResultPtr *instruction) {
22808 IrInstruction *result = instruction->result->child;
22809 if (type_is_invalid(result->value.type))
22810 return result;
22811
22812 if (instruction->result_loc->written && instruction->result_loc->resolved_loc != nullptr &&
22813 !instr_is_comptime(result))
22814 {
22815 return instruction->result_loc->resolved_loc;
22816 }
22817 return ir_get_ref(ira, &instruction->base, result, true, false);
22818}
22819
22820static void ir_eval_mul_add(IrAnalyze *ira, IrInstructionMulAdd *source_instr, ZigType *float_type,
22821 ConstExprValue *op1, ConstExprValue *op2, ConstExprValue *op3, ConstExprValue *out_val) {
22822 if (float_type->id == ZigTypeIdComptimeFloat) {
22823 f128M_mulAdd(&out_val->data.x_bigfloat.value, &op1->data.x_bigfloat.value, &op2->data.x_bigfloat.value,
22824 &op3->data.x_bigfloat.value);
22825 } else if (float_type->id == ZigTypeIdFloat) {
22826 switch (float_type->data.floating.bit_count) {
22827 case 16:
22828 out_val->data.x_f16 = f16_mulAdd(op1->data.x_f16, op2->data.x_f16, op3->data.x_f16);
22829 break;
22830 case 32:
22831 out_val->data.x_f32 = fmaf(op1->data.x_f32, op2->data.x_f32, op3->data.x_f32);
22832 break;
22833 case 64:
22834 out_val->data.x_f64 = fma(op1->data.x_f64, op2->data.x_f64, op3->data.x_f64);
22835 break;
22836 case 128:
22837 f128M_mulAdd(&op1->data.x_f128, &op2->data.x_f128, &op3->data.x_f128, &out_val->data.x_f128);
22838 break;
22839 default:
22840 zig_unreachable();
22841 }
22842 } else {
22843 zig_unreachable();
22844 }
22845}
22846
22847static IrInstruction *ir_analyze_instruction_mul_add(IrAnalyze *ira, IrInstructionMulAdd *instruction) {
22848 IrInstruction *type_value = instruction->type_value->child;
22849 if (type_is_invalid(type_value->value.type))
22850 return ira->codegen->invalid_instruction;
22851
22852 ZigType *expr_type = ir_resolve_type(ira, type_value);
22853 if (type_is_invalid(expr_type))
22854 return ira->codegen->invalid_instruction;
22855
22856 // Only allow float types, and vectors of floats.
22857 ZigType *float_type = (expr_type->id == ZigTypeIdVector) ? expr_type->data.vector.elem_type : expr_type;
22858 if (float_type->id != ZigTypeIdFloat) {
22859 ir_add_error(ira, type_value,
22860 buf_sprintf("expected float or vector of float type, found '%s'", buf_ptr(&float_type->name)));
22861 return ira->codegen->invalid_instruction;
22862 }
22863
22864 IrInstruction *op1 = instruction->op1->child;
22865 if (type_is_invalid(op1->value.type))
22866 return ira->codegen->invalid_instruction;
22867
22868 IrInstruction *casted_op1 = ir_implicit_cast(ira, op1, expr_type);
22869 if (type_is_invalid(casted_op1->value.type))
22870 return ira->codegen->invalid_instruction;
22871
22872 IrInstruction *op2 = instruction->op2->child;
22873 if (type_is_invalid(op2->value.type))
22874 return ira->codegen->invalid_instruction;
22875
22876 IrInstruction *casted_op2 = ir_implicit_cast(ira, op2, expr_type);
22877 if (type_is_invalid(casted_op2->value.type))
22878 return ira->codegen->invalid_instruction;
22879
22880 IrInstruction *op3 = instruction->op3->child;
22881 if (type_is_invalid(op3->value.type))
22882 return ira->codegen->invalid_instruction;
22883
22884 IrInstruction *casted_op3 = ir_implicit_cast(ira, op3, expr_type);
22885 if (type_is_invalid(casted_op3->value.type))
22886 return ira->codegen->invalid_instruction;
22887
22888 if (instr_is_comptime(casted_op1) &&
22889 instr_is_comptime(casted_op2) &&
22890 instr_is_comptime(casted_op3)) {
22891 ConstExprValue *op1_const = ir_resolve_const(ira, casted_op1, UndefBad);
22892 if (!op1_const)
22893 return ira->codegen->invalid_instruction;
22894 ConstExprValue *op2_const = ir_resolve_const(ira, casted_op2, UndefBad);
22895 if (!op2_const)
22896 return ira->codegen->invalid_instruction;
22897 ConstExprValue *op3_const = ir_resolve_const(ira, casted_op3, UndefBad);
22898 if (!op3_const)
22899 return ira->codegen->invalid_instruction;
22900
22901 IrInstruction *result = ir_const(ira, &instruction->base, expr_type);
22902 ConstExprValue *out_val = &result->value;
22903
22904 if (expr_type->id == ZigTypeIdVector) {
22905 expand_undef_array(ira->codegen, op1_const);
22906 expand_undef_array(ira->codegen, op2_const);
22907 expand_undef_array(ira->codegen, op3_const);
22908 out_val->special = ConstValSpecialUndef;
22909 expand_undef_array(ira->codegen, out_val);
22910 size_t len = expr_type->data.vector.len;
22911 for (size_t i = 0; i < len; i += 1) {
22912 ConstExprValue *float_operand_op1 = &op1_const->data.x_array.data.s_none.elements[i];
22913 ConstExprValue *float_operand_op2 = &op2_const->data.x_array.data.s_none.elements[i];
22914 ConstExprValue *float_operand_op3 = &op3_const->data.x_array.data.s_none.elements[i];
22915 ConstExprValue *float_out_val = &out_val->data.x_array.data.s_none.elements[i];
22916 assert(float_operand_op1->type == float_type);
22917 assert(float_operand_op2->type == float_type);
22918 assert(float_operand_op3->type == float_type);
22919 assert(float_out_val->type == float_type);
22920 ir_eval_mul_add(ira, instruction, float_type,
22921 op1_const, op2_const, op3_const, float_out_val);
22922 float_out_val->type = float_type;
22923 }
22924 out_val->type = expr_type;
22925 out_val->special = ConstValSpecialStatic;
22926 } else {
22927 ir_eval_mul_add(ira, instruction, float_type, op1_const, op2_const, op3_const, out_val);
22928 }
22929 return result;
22930 }
22931
22932 IrInstruction *result = ir_build_mul_add(&ira->new_irb,
22933 instruction->base.scope, instruction->base.source_node,
22934 type_value, casted_op1, casted_op2, casted_op3);
22935 result->value.type = expr_type;
22936 return result;
22937}
22938
22939static IrInstruction *ir_analyze_instruction_test_err(IrAnalyze *ira, IrInstructionTestErrSrc *instruction) {
22940 IrInstruction *base_ptr = instruction->base_ptr->child;
22941 if (type_is_invalid(base_ptr->value.type))
2119322942 return ira->codegen->invalid_instruction;
2119422943
22944 IrInstruction *value = ir_get_deref(ira, &instruction->base, base_ptr, nullptr);
2119522945 ZigType *type_entry = value->value.type;
21196 if (type_is_invalid(type_entry)) {
22946 if (type_is_invalid(type_entry))
2119722947 return ira->codegen->invalid_instruction;
21198 } else if (type_entry->id == ZigTypeIdErrorUnion) {
22948
22949 if (type_entry->id == ZigTypeIdErrorUnion) {
2119922950 if (instr_is_comptime(value)) {
2120022951 ConstExprValue *err_union_val = ir_resolve_const(ira, value, UndefBad);
2120122952 if (!err_union_val)
......@@ -21207,21 +22958,20 @@ static IrInstruction *ir_analyze_instruction_test_err(IrAnalyze *ira, IrInstruct
2120722958 }
2120822959 }
2120922960
21210 ZigType *err_set_type = type_entry->data.error_union.err_set_type;
21211 if (!resolve_inferred_error_set(ira->codegen, err_set_type, instruction->base.source_node)) {
21212 return ira->codegen->invalid_instruction;
21213 }
21214 if (!type_is_global_error_set(err_set_type) &&
21215 err_set_type->data.error_set.err_count == 0)
21216 {
21217 assert(err_set_type->data.error_set.infer_fn == nullptr);
21218 return ir_const_bool(ira, &instruction->base, false);
22961 if (instruction->resolve_err_set) {
22962 ZigType *err_set_type = type_entry->data.error_union.err_set_type;
22963 if (!resolve_inferred_error_set(ira->codegen, err_set_type, instruction->base.source_node)) {
22964 return ira->codegen->invalid_instruction;
22965 }
22966 if (!type_is_global_error_set(err_set_type) &&
22967 err_set_type->data.error_set.err_count == 0)
22968 {
22969 assert(err_set_type->data.error_set.infer_fn == nullptr);
22970 return ir_const_bool(ira, &instruction->base, false);
22971 }
2121922972 }
2122022973
21221 IrInstruction *result = ir_build_test_err(&ira->new_irb,
21222 instruction->base.scope, instruction->base.source_node, value);
21223 result->value.type = ira->codegen->builtin_types.entry_bool;
21224 return result;
22974 return ir_build_test_err_gen(ira, &instruction->base, value);
2122522975 } else if (type_entry->id == ZigTypeIdErrorSet) {
2122622976 return ir_const_bool(ira, &instruction->base, true);
2122722977 } else {
......@@ -21229,10 +22979,9 @@ static IrInstruction *ir_analyze_instruction_test_err(IrAnalyze *ira, IrInstruct
2122922979 }
2123022980}
2123122981
21232static IrInstruction *ir_analyze_instruction_unwrap_err_code(IrAnalyze *ira, IrInstructionUnwrapErrCode *instruction) {
21233 IrInstruction *base_ptr = instruction->err_union->child;
21234 if (type_is_invalid(base_ptr->value.type))
21235 return ira->codegen->invalid_instruction;
22982static IrInstruction *ir_analyze_unwrap_err_code(IrAnalyze *ira, IrInstruction *source_instr,
22983 IrInstruction *base_ptr, bool initializing)
22984{
2123622985 ZigType *ptr_type = base_ptr->value.type;
2123722986
2123822987 // This will be a pointer type because unwrap err payload IR instruction operates on a pointer to a thing.
......@@ -21248,40 +22997,79 @@ static IrInstruction *ir_analyze_instruction_unwrap_err_code(IrAnalyze *ira, IrI
2124822997 return ira->codegen->invalid_instruction;
2124922998 }
2125022999
23000 ZigType *err_set_type = type_entry->data.error_union.err_set_type;
23001 ZigType *result_type = get_pointer_to_type_extra(ira->codegen, err_set_type,
23002 ptr_type->data.pointer.is_const, ptr_type->data.pointer.is_volatile, PtrLenSingle,
23003 ptr_type->data.pointer.explicit_alignment, 0, 0, false);
23004
2125123005 if (instr_is_comptime(base_ptr)) {
2125223006 ConstExprValue *ptr_val = ir_resolve_const(ira, base_ptr, UndefBad);
2125323007 if (!ptr_val)
2125423008 return ira->codegen->invalid_instruction;
21255 if (ptr_val->data.x_ptr.mut != ConstPtrMutRuntimeVar) {
21256 ConstExprValue *err_union_val = const_ptr_pointee(ira, ira->codegen, ptr_val, instruction->base.source_node);
23009 if (ptr_val->data.x_ptr.mut != ConstPtrMutRuntimeVar &&
23010 ptr_val->data.x_ptr.special != ConstPtrSpecialHardCodedAddr)
23011 {
23012 ConstExprValue *err_union_val = const_ptr_pointee(ira, ira->codegen, ptr_val, source_instr->source_node);
2125723013 if (err_union_val == nullptr)
2125823014 return ira->codegen->invalid_instruction;
21259 if (err_union_val->special != ConstValSpecialRuntime) {
21260 ErrorTableEntry *err = err_union_val->data.x_err_union.error_set->data.x_err_set;
21261 assert(err);
2126223015
21263 IrInstruction *result = ir_const(ira, &instruction->base,
21264 type_entry->data.error_union.err_set_type);
21265 result->value.data.x_err_set = err;
21266 return result;
23016 if (initializing && err_union_val->special == ConstValSpecialUndef) {
23017 ConstExprValue *vals = create_const_vals(2);
23018 ConstExprValue *err_set_val = &vals[0];
23019 ConstExprValue *payload_val = &vals[1];
23020
23021 err_set_val->special = ConstValSpecialUndef;
23022 err_set_val->type = err_set_type;
23023 err_set_val->parent.id = ConstParentIdErrUnionCode;
23024 err_set_val->parent.data.p_err_union_code.err_union_val = err_union_val;
23025
23026 payload_val->special = ConstValSpecialUndef;
23027 payload_val->type = type_entry->data.error_union.payload_type;
23028 payload_val->parent.id = ConstParentIdErrUnionPayload;
23029 payload_val->parent.data.p_err_union_payload.err_union_val = err_union_val;
23030
23031 err_union_val->special = ConstValSpecialStatic;
23032 err_union_val->data.x_err_union.error_set = err_set_val;
23033 err_union_val->data.x_err_union.payload = payload_val;
23034 }
23035 ir_assert(err_union_val->special != ConstValSpecialRuntime, source_instr);
23036
23037 IrInstruction *result;
23038 if (ptr_val->data.x_ptr.mut == ConstPtrMutInfer) {
23039 result = ir_build_unwrap_err_code(&ira->new_irb, source_instr->scope,
23040 source_instr->source_node, base_ptr);
23041 result->value.type = result_type;
23042 result->value.special = ConstValSpecialStatic;
23043 } else {
23044 result = ir_const(ira, source_instr, result_type);
2126723045 }
23046 ConstExprValue *const_val = &result->value;
23047 const_val->data.x_ptr.special = ConstPtrSpecialBaseErrorUnionCode;
23048 const_val->data.x_ptr.data.base_err_union_code.err_union_val = err_union_val;
23049 const_val->data.x_ptr.mut = ptr_val->data.x_ptr.mut;
23050 return result;
2126823051 }
2126923052 }
2127023053
2127123054 IrInstruction *result = ir_build_unwrap_err_code(&ira->new_irb,
21272 instruction->base.scope, instruction->base.source_node, base_ptr);
21273 result->value.type = type_entry->data.error_union.err_set_type;
23055 source_instr->scope, source_instr->source_node, base_ptr);
23056 result->value.type = result_type;
2127423057 return result;
2127523058}
2127623059
21277static IrInstruction *ir_analyze_instruction_unwrap_err_payload(IrAnalyze *ira,
21278 IrInstructionUnwrapErrPayload *instruction)
23060static IrInstruction *ir_analyze_instruction_unwrap_err_code(IrAnalyze *ira,
23061 IrInstructionUnwrapErrCode *instruction)
2127923062{
21280 assert(instruction->value->child);
21281 IrInstruction *value = instruction->value->child;
21282 if (type_is_invalid(value->value.type))
23063 IrInstruction *base_ptr = instruction->err_union_ptr->child;
23064 if (type_is_invalid(base_ptr->value.type))
2128323065 return ira->codegen->invalid_instruction;
21284 ZigType *ptr_type = value->value.type;
23066 return ir_analyze_unwrap_err_code(ira, &instruction->base, base_ptr, false);
23067}
23068
23069static IrInstruction *ir_analyze_unwrap_error_payload(IrAnalyze *ira, IrInstruction *source_instr,
23070 IrInstruction *base_ptr, bool safety_check_on, bool initializing)
23071{
23072 ZigType *ptr_type = base_ptr->value.type;
2128523073
2128623074 // This will be a pointer type because unwrap err payload IR instruction operates on a pointer to a thing.
2128723075 assert(ptr_type->id == ZigTypeIdPointer);
......@@ -21291,7 +23079,7 @@ static IrInstruction *ir_analyze_instruction_unwrap_err_payload(IrAnalyze *ira,
2129123079 return ira->codegen->invalid_instruction;
2129223080
2129323081 if (type_entry->id != ZigTypeIdErrorUnion) {
21294 ir_add_error(ira, value,
23082 ir_add_error(ira, base_ptr,
2129523083 buf_sprintf("expected error union type, found '%s'", buf_ptr(&type_entry->name)));
2129623084 return ira->codegen->invalid_instruction;
2129723085 }
......@@ -21303,36 +23091,73 @@ static IrInstruction *ir_analyze_instruction_unwrap_err_payload(IrAnalyze *ira,
2130323091 ZigType *result_type = get_pointer_to_type_extra(ira->codegen, payload_type,
2130423092 ptr_type->data.pointer.is_const, ptr_type->data.pointer.is_volatile,
2130523093 PtrLenSingle, 0, 0, 0, false);
21306 if (instr_is_comptime(value)) {
21307 ConstExprValue *ptr_val = ir_resolve_const(ira, value, UndefBad);
23094 if (instr_is_comptime(base_ptr)) {
23095 ConstExprValue *ptr_val = ir_resolve_const(ira, base_ptr, UndefBad);
2130823096 if (!ptr_val)
2130923097 return ira->codegen->invalid_instruction;
2131023098 if (ptr_val->data.x_ptr.mut != ConstPtrMutRuntimeVar) {
21311 ConstExprValue *err_union_val = const_ptr_pointee(ira, ira->codegen, ptr_val, instruction->base.source_node);
23099 ConstExprValue *err_union_val = const_ptr_pointee(ira, ira->codegen, ptr_val, source_instr->source_node);
2131223100 if (err_union_val == nullptr)
2131323101 return ira->codegen->invalid_instruction;
23102 if (err_union_val->special == ConstValSpecialUndef && initializing) {
23103 ConstExprValue *vals = create_const_vals(2);
23104 ConstExprValue *err_set_val = &vals[0];
23105 ConstExprValue *payload_val = &vals[1];
23106
23107 err_set_val->special = ConstValSpecialStatic;
23108 err_set_val->type = type_entry->data.error_union.err_set_type;
23109 err_set_val->data.x_err_set = nullptr;
23110
23111 payload_val->special = ConstValSpecialUndef;
23112 payload_val->type = payload_type;
23113
23114 err_union_val->special = ConstValSpecialStatic;
23115 err_union_val->data.x_err_union.error_set = err_set_val;
23116 err_union_val->data.x_err_union.payload = payload_val;
23117 }
23118
2131423119 if (err_union_val->special != ConstValSpecialRuntime) {
2131523120 ErrorTableEntry *err = err_union_val->data.x_err_union.error_set->data.x_err_set;
2131623121 if (err != nullptr) {
21317 ir_add_error(ira, &instruction->base,
23122 ir_add_error(ira, source_instr,
2131823123 buf_sprintf("caught unexpected error '%s'", buf_ptr(&err->name)));
2131923124 return ira->codegen->invalid_instruction;
2132023125 }
2132123126
21322 IrInstruction *result = ir_const(ira, &instruction->base, result_type);
23127 IrInstruction *result;
23128 if (ptr_val->data.x_ptr.mut == ConstPtrMutInfer) {
23129 result = ir_build_unwrap_err_payload(&ira->new_irb, source_instr->scope,
23130 source_instr->source_node, base_ptr, safety_check_on, initializing);
23131 result->value.type = result_type;
23132 result->value.special = ConstValSpecialStatic;
23133 } else {
23134 result = ir_const(ira, source_instr, result_type);
23135 }
2132323136 result->value.data.x_ptr.special = ConstPtrSpecialRef;
2132423137 result->value.data.x_ptr.data.ref.pointee = err_union_val->data.x_err_union.payload;
23138 result->value.data.x_ptr.mut = ptr_val->data.x_ptr.mut;
2132523139 return result;
2132623140 }
2132723141 }
2132823142 }
2132923143
21330 IrInstruction *result = ir_build_unwrap_err_payload(&ira->new_irb,
21331 instruction->base.scope, instruction->base.source_node, value, instruction->safety_check_on);
23144 IrInstruction *result = ir_build_unwrap_err_payload(&ira->new_irb, source_instr->scope,
23145 source_instr->source_node, base_ptr, safety_check_on, initializing);
2133223146 result->value.type = result_type;
2133323147 return result;
2133423148}
2133523149
23150static IrInstruction *ir_analyze_instruction_unwrap_err_payload(IrAnalyze *ira,
23151 IrInstructionUnwrapErrPayload *instruction)
23152{
23153 assert(instruction->value->child);
23154 IrInstruction *value = instruction->value->child;
23155 if (type_is_invalid(value->value.type))
23156 return ira->codegen->invalid_instruction;
23157
23158 return ir_analyze_unwrap_error_payload(ira, &instruction->base, value, instruction->safety_check_on, false);
23159}
23160
2133623161static IrInstruction *ir_analyze_instruction_fn_proto(IrAnalyze *ira, IrInstructionFnProto *instruction) {
2133723162 AstNode *proto_node = instruction->base.source_node;
2133823163 assert(proto_node->type == NodeTypeFnProto);
......@@ -21824,14 +23649,19 @@ static IrInstruction *ir_analyze_ptr_cast(IrAnalyze *ira, IrInstruction *source_
2182423649 }
2182523650 }
2182623651
21827 IrInstruction *result = ir_const(ira, source_instr, dest_type);
23652 IrInstruction *result;
23653 if (ptr->value.data.x_ptr.mut == ConstPtrMutInfer) {
23654 result = ir_build_ptr_cast_gen(ira, source_instr, dest_type, ptr, safety_check_on);
23655 } else {
23656 result = ir_const(ira, source_instr, dest_type);
23657 }
2182823658 copy_const_val(&result->value, val, true);
2182923659 result->value.type = dest_type;
2183023660
2183123661 // Keep the bigger alignment, it can only help-
2183223662 // unless the target is zero bits.
2183323663 if (src_align_bytes > dest_align_bytes && type_has_bits(dest_type)) {
21834 result = ir_align_cast(ira, result, src_align_bytes, false);
23664 result = ir_align_cast(ira, result, src_align_bytes, false);
2183523665 }
2183623666
2183723667 return result;
......@@ -21915,6 +23745,8 @@ static void buf_write_value_bytes(CodeGen *codegen, uint8_t *buf, ConstExprValue
2191523745 case ZigTypeIdUndefined:
2191623746 case ZigTypeIdNull:
2191723747 case ZigTypeIdPromise:
23748 case ZigTypeIdErrorUnion:
23749 case ZigTypeIdErrorSet:
2191823750 zig_unreachable();
2191923751 case ZigTypeIdVoid:
2192023752 return;
......@@ -22018,10 +23850,6 @@ static void buf_write_value_bytes(CodeGen *codegen, uint8_t *buf, ConstExprValue
2201823850 }
2201923851 case ZigTypeIdOptional:
2202023852 zig_panic("TODO buf_write_value_bytes maybe type");
22021 case ZigTypeIdErrorUnion:
22022 zig_panic("TODO buf_write_value_bytes error union");
22023 case ZigTypeIdErrorSet:
22024 zig_panic("TODO buf_write_value_bytes pure error type");
2202523853 case ZigTypeIdFn:
2202623854 zig_panic("TODO buf_write_value_bytes fn type");
2202723855 case ZigTypeIdUnion:
......@@ -22210,28 +24038,6 @@ static Error buf_read_value_bytes(IrAnalyze *ira, CodeGen *codegen, AstNode *sou
2221024038 zig_unreachable();
2221124039}
2221224040
22213static bool type_can_bit_cast(ZigType *t) {
22214 switch (t->id) {
22215 case ZigTypeIdInvalid:
22216 zig_unreachable();
22217 case ZigTypeIdMetaType:
22218 case ZigTypeIdOpaque:
22219 case ZigTypeIdBoundFn:
22220 case ZigTypeIdArgTuple:
22221 case ZigTypeIdUnreachable:
22222 case ZigTypeIdComptimeFloat:
22223 case ZigTypeIdComptimeInt:
22224 case ZigTypeIdEnumLiteral:
22225 case ZigTypeIdUndefined:
22226 case ZigTypeIdNull:
22227 case ZigTypeIdPointer:
22228 return false;
22229 default:
22230 // TODO list these types out explicitly, there are probably some other invalid ones here
22231 return true;
22232 }
22233}
22234
2223524041static IrInstruction *ir_analyze_bit_cast(IrAnalyze *ira, IrInstruction *source_instr, IrInstruction *value,
2223624042 ZigType *dest_type)
2223724043{
......@@ -22283,49 +24089,7 @@ static IrInstruction *ir_analyze_bit_cast(IrAnalyze *ira, IrInstruction *source_
2228324089 return result;
2228424090 }
2228524091
22286 IrInstruction *result = ir_build_bit_cast_gen(ira, source_instr, value, dest_type);
22287 if (handle_is_ptr(dest_type) && !handle_is_ptr(src_type)) {
22288 ir_add_alloca(ira, result, dest_type);
22289 }
22290 return result;
22291}
22292
22293static IrInstruction *ir_analyze_instruction_bit_cast(IrAnalyze *ira, IrInstructionBitCast *instruction) {
22294 IrInstruction *dest_type_value = instruction->dest_type->child;
22295 ZigType *dest_type = ir_resolve_type(ira, dest_type_value);
22296 if (type_is_invalid(dest_type))
22297 return ira->codegen->invalid_instruction;
22298
22299 IrInstruction *value = instruction->value->child;
22300 ZigType *src_type = value->value.type;
22301 if (type_is_invalid(src_type))
22302 return ira->codegen->invalid_instruction;
22303
22304 if (get_codegen_ptr_type(src_type) != nullptr) {
22305 ir_add_error(ira, value,
22306 buf_sprintf("unable to @bitCast from pointer type '%s'", buf_ptr(&src_type->name)));
22307 return ira->codegen->invalid_instruction;
22308 }
22309
22310 if (!type_can_bit_cast(src_type)) {
22311 ir_add_error(ira, dest_type_value,
22312 buf_sprintf("unable to @bitCast from type '%s'", buf_ptr(&src_type->name)));
22313 return ira->codegen->invalid_instruction;
22314 }
22315
22316 if (get_codegen_ptr_type(dest_type) != nullptr) {
22317 ir_add_error(ira, dest_type_value,
22318 buf_sprintf("unable to @bitCast to pointer type '%s'", buf_ptr(&dest_type->name)));
22319 return ira->codegen->invalid_instruction;
22320 }
22321
22322 if (!type_can_bit_cast(dest_type)) {
22323 ir_add_error(ira, dest_type_value,
22324 buf_sprintf("unable to @bitCast to type '%s'", buf_ptr(&dest_type->name)));
22325 return ira->codegen->invalid_instruction;
22326 }
22327
22328 return ir_analyze_bit_cast(ira, &instruction->base, value, dest_type);
24092 return ir_build_bit_cast_gen(ira, source_instr, value, dest_type);
2232924093}
2233024094
2233124095static IrInstruction *ir_analyze_int_to_ptr(IrAnalyze *ira, IrInstruction *source_instr, IrInstruction *target,
......@@ -22395,58 +24159,15 @@ static IrInstruction *ir_analyze_instruction_int_to_ptr(IrAnalyze *ira, IrInstru
2239524159static IrInstruction *ir_analyze_instruction_decl_ref(IrAnalyze *ira,
2239624160 IrInstructionDeclRef *instruction)
2239724161{
22398 Tld *tld = instruction->tld;
22399 LVal lval = instruction->lval;
22400
22401 resolve_top_level_decl(ira->codegen, tld, instruction->base.source_node);
22402 if (tld->resolution == TldResolutionInvalid)
24162 IrInstruction *ref_instruction = ir_analyze_decl_ref(ira, &instruction->base, instruction->tld);
24163 if (type_is_invalid(ref_instruction->value.type))
2240324164 return ira->codegen->invalid_instruction;
2240424165
22405 switch (tld->id) {
22406 case TldIdContainer:
22407 case TldIdCompTime:
22408 zig_unreachable();
22409 case TldIdVar: {
22410 TldVar *tld_var = (TldVar *)tld;
22411 ZigVar *var = tld_var->var;
22412
22413 if (var == nullptr) {
22414 return ir_error_dependency_loop(ira, &instruction->base);
22415 }
22416
22417 IrInstruction *var_ptr = ir_get_var_ptr(ira, &instruction->base, var);
22418 if (type_is_invalid(var_ptr->value.type))
22419 return ira->codegen->invalid_instruction;
22420
22421 if (tld_var->extern_lib_name != nullptr) {
22422 add_link_lib_symbol(ira, tld_var->extern_lib_name, &var->name, instruction->base.source_node);
22423 }
22424
22425 if (lval == LValPtr) {
22426 return var_ptr;
22427 } else {
22428 return ir_get_deref(ira, &instruction->base, var_ptr);
22429 }
22430 }
22431 case TldIdFn: {
22432 TldFn *tld_fn = (TldFn *)tld;
22433 ZigFn *fn_entry = tld_fn->fn_entry;
22434 ir_assert(fn_entry->type_entry, &instruction->base);
22435
22436 if (tld_fn->extern_lib_name != nullptr) {
22437 add_link_lib_symbol(ira, tld_fn->extern_lib_name, &fn_entry->symbol_name, instruction->base.source_node);
22438 }
22439
22440 IrInstruction *ref_instruction = ir_create_const_fn(&ira->new_irb, instruction->base.scope,
22441 instruction->base.source_node, fn_entry);
22442 if (lval == LValPtr) {
22443 return ir_get_ref(ira, &instruction->base, ref_instruction, true, false);
22444 } else {
22445 return ref_instruction;
22446 }
22447 }
24166 if (instruction->lval == LValPtr) {
24167 return ref_instruction;
24168 } else {
24169 return ir_get_deref(ira, &instruction->base, ref_instruction, nullptr);
2244824170 }
22449 zig_unreachable();
2245024171}
2245124172
2245224173static IrInstruction *ir_analyze_instruction_ptr_to_int(IrAnalyze *ira, IrInstructionPtrToInt *instruction) {
......@@ -22960,7 +24681,7 @@ static IrInstruction *ir_analyze_instruction_atomic_load(IrAnalyze *ira, IrInstr
2296024681 }
2296124682
2296224683 if (instr_is_comptime(casted_ptr)) {
22963 IrInstruction *result = ir_get_deref(ira, &instruction->base, casted_ptr);
24684 IrInstruction *result = ir_get_deref(ira, &instruction->base, casted_ptr, nullptr);
2296424685 ir_assert(result->value.type != nullptr, &instruction->base);
2296524686 return result;
2296624687 }
......@@ -23048,70 +24769,254 @@ static IrInstruction *ir_analyze_instruction_mark_err_ret_trace_ptr(IrAnalyze *i
2304824769 return result;
2304924770}
2305024771
23051static IrInstruction *ir_analyze_instruction_sqrt(IrAnalyze *ira, IrInstructionSqrt *instruction) {
23052 ZigType *float_type = ir_resolve_type(ira, instruction->type->child);
23053 if (type_is_invalid(float_type))
23054 return ira->codegen->invalid_instruction;
24772static void ir_eval_float_op(IrAnalyze *ira, IrInstructionFloatOp *source_instr, ZigType *float_type,
24773 ConstExprValue *op, ConstExprValue *out_val) {
24774 assert(ira && source_instr && float_type && out_val && op);
24775 assert(float_type->id == ZigTypeIdFloat ||
24776 float_type->id == ZigTypeIdComptimeFloat);
2305524777
23056 IrInstruction *op = instruction->op->child;
23057 if (type_is_invalid(op->value.type))
24778 BuiltinFnId fop = source_instr->op;
24779 unsigned bits;
24780
24781 switch (float_type->id) {
24782 case ZigTypeIdComptimeFloat:
24783 bits = 128;
24784 break;
24785 case ZigTypeIdFloat:
24786 bits = float_type->data.floating.bit_count;
24787 break;
24788 default:
24789 zig_unreachable();
24790 }
24791
24792 switch (bits) {
24793 case 16: {
24794 switch (fop) {
24795 case BuiltinFnIdSqrt:
24796 out_val->data.x_f16 = f16_sqrt(op->data.x_f16);
24797 break;
24798 case BuiltinFnIdSin:
24799 case BuiltinFnIdCos:
24800 case BuiltinFnIdExp:
24801 case BuiltinFnIdExp2:
24802 case BuiltinFnIdLn:
24803 case BuiltinFnIdLog10:
24804 case BuiltinFnIdLog2:
24805 case BuiltinFnIdFabs:
24806 case BuiltinFnIdFloor:
24807 case BuiltinFnIdCeil:
24808 case BuiltinFnIdTrunc:
24809 case BuiltinFnIdNearbyInt:
24810 case BuiltinFnIdRound:
24811 zig_panic("unimplemented f16 builtin");
24812 default:
24813 zig_unreachable();
24814 };
24815 break;
24816 };
24817 case 32: {
24818 switch (fop) {
24819 case BuiltinFnIdSqrt:
24820 out_val->data.x_f32 = sqrtf(op->data.x_f32);
24821 break;
24822 case BuiltinFnIdSin:
24823 out_val->data.x_f32 = sinf(op->data.x_f32);
24824 break;
24825 case BuiltinFnIdCos:
24826 out_val->data.x_f32 = cosf(op->data.x_f32);
24827 break;
24828 case BuiltinFnIdExp:
24829 out_val->data.x_f32 = expf(op->data.x_f32);
24830 break;
24831 case BuiltinFnIdExp2:
24832 out_val->data.x_f32 = exp2f(op->data.x_f32);
24833 break;
24834 case BuiltinFnIdLn:
24835 out_val->data.x_f32 = logf(op->data.x_f32);
24836 break;
24837 case BuiltinFnIdLog10:
24838 out_val->data.x_f32 = log10f(op->data.x_f32);
24839 break;
24840 case BuiltinFnIdLog2:
24841 out_val->data.x_f32 = log2f(op->data.x_f32);
24842 break;
24843 case BuiltinFnIdFabs:
24844 out_val->data.x_f32 = fabsf(op->data.x_f32);
24845 break;
24846 case BuiltinFnIdFloor:
24847 out_val->data.x_f32 = floorf(op->data.x_f32);
24848 break;
24849 case BuiltinFnIdCeil:
24850 out_val->data.x_f32 = ceilf(op->data.x_f32);
24851 break;
24852 case BuiltinFnIdTrunc:
24853 out_val->data.x_f32 = truncf(op->data.x_f32);
24854 break;
24855 case BuiltinFnIdNearbyInt:
24856 out_val->data.x_f32 = nearbyintf(op->data.x_f32);
24857 break;
24858 case BuiltinFnIdRound:
24859 out_val->data.x_f32 = roundf(op->data.x_f32);
24860 break;
24861 default:
24862 zig_unreachable();
24863 };
24864 break;
24865 };
24866 case 64: {
24867 switch (fop) {
24868 case BuiltinFnIdSqrt:
24869 out_val->data.x_f64 = sqrt(op->data.x_f64);
24870 break;
24871 case BuiltinFnIdSin:
24872 out_val->data.x_f64 = sin(op->data.x_f64);
24873 break;
24874 case BuiltinFnIdCos:
24875 out_val->data.x_f64 = cos(op->data.x_f64);
24876 break;
24877 case BuiltinFnIdExp:
24878 out_val->data.x_f64 = exp(op->data.x_f64);
24879 break;
24880 case BuiltinFnIdExp2:
24881 out_val->data.x_f64 = exp2(op->data.x_f64);
24882 break;
24883 case BuiltinFnIdLn:
24884 out_val->data.x_f64 = log(op->data.x_f64);
24885 break;
24886 case BuiltinFnIdLog10:
24887 out_val->data.x_f64 = log10(op->data.x_f64);
24888 break;
24889 case BuiltinFnIdLog2:
24890 out_val->data.x_f64 = log2(op->data.x_f64);
24891 break;
24892 case BuiltinFnIdFabs:
24893 out_val->data.x_f64 = fabs(op->data.x_f64);
24894 break;
24895 case BuiltinFnIdFloor:
24896 out_val->data.x_f64 = floor(op->data.x_f64);
24897 break;
24898 case BuiltinFnIdCeil:
24899 out_val->data.x_f64 = ceil(op->data.x_f64);
24900 break;
24901 case BuiltinFnIdTrunc:
24902 out_val->data.x_f64 = trunc(op->data.x_f64);
24903 break;
24904 case BuiltinFnIdNearbyInt:
24905 out_val->data.x_f64 = nearbyint(op->data.x_f64);
24906 break;
24907 case BuiltinFnIdRound:
24908 out_val->data.x_f64 = round(op->data.x_f64);
24909 break;
24910 default:
24911 zig_unreachable();
24912 }
24913 break;
24914 };
24915 case 128: {
24916 float128_t *out, *in;
24917 if (float_type->id == ZigTypeIdComptimeFloat) {
24918 out = &out_val->data.x_bigfloat.value;
24919 in = &op->data.x_bigfloat.value;
24920 } else {
24921 out = &out_val->data.x_f128;
24922 in = &op->data.x_f128;
24923 }
24924 switch (fop) {
24925 case BuiltinFnIdSqrt:
24926 f128M_sqrt(in, out);
24927 break;
24928 case BuiltinFnIdNearbyInt:
24929 case BuiltinFnIdSin:
24930 case BuiltinFnIdCos:
24931 case BuiltinFnIdExp:
24932 case BuiltinFnIdExp2:
24933 case BuiltinFnIdLn:
24934 case BuiltinFnIdLog10:
24935 case BuiltinFnIdLog2:
24936 case BuiltinFnIdFabs:
24937 case BuiltinFnIdFloor:
24938 case BuiltinFnIdCeil:
24939 case BuiltinFnIdTrunc:
24940 case BuiltinFnIdRound:
24941 zig_panic("unimplemented f128 builtin");
24942 default:
24943 zig_unreachable();
24944 }
24945 break;
24946 };
24947 default:
24948 zig_unreachable();
24949 }
24950}
24951
24952static IrInstruction *ir_analyze_instruction_float_op(IrAnalyze *ira, IrInstructionFloatOp *instruction) {
24953 IrInstruction *type = instruction->type->child;
24954 if (type_is_invalid(type->value.type))
24955 return ira->codegen->invalid_instruction;
24956
24957 ZigType *expr_type = ir_resolve_type(ira, type);
24958 if (type_is_invalid(expr_type))
2305824959 return ira->codegen->invalid_instruction;
2305924960
23060 bool ok_type = float_type->id == ZigTypeIdComptimeFloat || float_type->id == ZigTypeIdFloat;
23061 if (!ok_type) {
23062 ir_add_error(ira, instruction->type, buf_sprintf("@sqrt does not support type '%s'", buf_ptr(&float_type->name)));
24961 // Only allow float types, and vectors of floats.
24962 ZigType *float_type = (expr_type->id == ZigTypeIdVector) ? expr_type->data.vector.elem_type : expr_type;
24963 if (float_type->id != ZigTypeIdFloat && float_type->id != ZigTypeIdComptimeFloat) {
24964 ir_add_error(ira, instruction->type, buf_sprintf("@%s does not support type '%s'", float_op_to_name(instruction->op, false), buf_ptr(&float_type->name)));
2306324965 return ira->codegen->invalid_instruction;
2306424966 }
2306524967
23066 IrInstruction *casted_op = ir_implicit_cast(ira, op, float_type);
23067 if (type_is_invalid(casted_op->value.type))
24968 IrInstruction *op1 = instruction->op1->child;
24969 if (type_is_invalid(op1->value.type))
24970 return ira->codegen->invalid_instruction;
24971
24972 IrInstruction *casted_op1 = ir_implicit_cast(ira, op1, float_type);
24973 if (type_is_invalid(casted_op1->value.type))
2306824974 return ira->codegen->invalid_instruction;
2306924975
23070 if (instr_is_comptime(casted_op)) {
23071 ConstExprValue *val = ir_resolve_const(ira, casted_op, UndefBad);
23072 if (!val)
24976 if (instr_is_comptime(casted_op1)) {
24977 // Our comptime 16-bit and 128-bit support is quite limited.
24978 if ((float_type->id == ZigTypeIdComptimeFloat ||
24979 float_type->data.floating.bit_count == 16 ||
24980 float_type->data.floating.bit_count == 128) &&
24981 instruction->op != BuiltinFnIdSqrt) {
24982 ir_add_error(ira, instruction->type, buf_sprintf("@%s does not support type '%s'", float_op_to_name(instruction->op, false), buf_ptr(&float_type->name)));
24983 return ira->codegen->invalid_instruction;
24984 }
24985
24986 ConstExprValue *op1_const = ir_resolve_const(ira, casted_op1, UndefBad);
24987 if (!op1_const)
2307324988 return ira->codegen->invalid_instruction;
2307424989
23075 IrInstruction *result = ir_const(ira, &instruction->base, float_type);
24990 IrInstruction *result = ir_const(ira, &instruction->base, expr_type);
2307624991 ConstExprValue *out_val = &result->value;
2307724992
23078 if (float_type->id == ZigTypeIdComptimeFloat) {
23079 bigfloat_sqrt(&out_val->data.x_bigfloat, &val->data.x_bigfloat);
23080 } else if (float_type->id == ZigTypeIdFloat) {
23081 switch (float_type->data.floating.bit_count) {
23082 case 16:
23083 out_val->data.x_f16 = f16_sqrt(val->data.x_f16);
23084 break;
23085 case 32:
23086 out_val->data.x_f32 = sqrtf(val->data.x_f32);
23087 break;
23088 case 64:
23089 out_val->data.x_f64 = sqrt(val->data.x_f64);
23090 break;
23091 case 128:
23092 f128M_sqrt(&val->data.x_f128, &out_val->data.x_f128);
23093 break;
23094 default:
23095 zig_unreachable();
24993 if (expr_type->id == ZigTypeIdVector) {
24994 expand_undef_array(ira->codegen, op1_const);
24995 out_val->special = ConstValSpecialUndef;
24996 expand_undef_array(ira->codegen, out_val);
24997 size_t len = expr_type->data.vector.len;
24998 for (size_t i = 0; i < len; i += 1) {
24999 ConstExprValue *float_operand_op1 = &op1_const->data.x_array.data.s_none.elements[i];
25000 ConstExprValue *float_out_val = &out_val->data.x_array.data.s_none.elements[i];
25001 assert(float_operand_op1->type == float_type);
25002 assert(float_out_val->type == float_type);
25003 ir_eval_float_op(ira, instruction, float_type,
25004 op1_const, float_out_val);
25005 float_out_val->type = float_type;
2309625006 }
25007 out_val->type = expr_type;
25008 out_val->special = ConstValSpecialStatic;
2309725009 } else {
23098 zig_unreachable();
25010 ir_eval_float_op(ira, instruction, float_type, op1_const, out_val);
2309925011 }
23100
2310125012 return result;
2310225013 }
2310325014
2310425015 ir_assert(float_type->id == ZigTypeIdFloat, &instruction->base);
23105 if (float_type->data.floating.bit_count != 16 &&
23106 float_type->data.floating.bit_count != 32 &&
23107 float_type->data.floating.bit_count != 64) {
23108 ir_add_error(ira, instruction->type, buf_sprintf("compiler TODO: add implementation of sqrt for '%s'", buf_ptr(&float_type->name)));
23109 return ira->codegen->invalid_instruction;
23110 }
2311125016
23112 IrInstruction *result = ir_build_sqrt(&ira->new_irb, instruction->base.scope,
23113 instruction->base.source_node, nullptr, casted_op);
23114 result->value.type = float_type;
25017 IrInstruction *result = ir_build_float_op(&ira->new_irb, instruction->base.scope,
25018 instruction->base.source_node, nullptr, casted_op1, instruction->op);
25019 result->value.type = expr_type;
2311525020 return result;
2311625021}
2311725022
......@@ -23314,12 +25219,56 @@ static IrInstruction *ir_analyze_instruction_undeclared_ident(IrAnalyze *ira, Ir
2331425219 return ira->codegen->invalid_instruction;
2331525220}
2331625221
23317static IrInstruction *ir_analyze_instruction_nocast(IrAnalyze *ira, IrInstruction *instruction) {
25222static IrInstruction *ir_analyze_instruction_end_expr(IrAnalyze *ira, IrInstructionEndExpr *instruction) {
25223 IrInstruction *value = instruction->value->child;
25224 if (type_is_invalid(value->value.type))
25225 return ira->codegen->invalid_instruction;
25226
25227 bool was_written = instruction->result_loc->written;
25228 IrInstruction *result_loc = ir_resolve_result(ira, &instruction->base, instruction->result_loc,
25229 value->value.type, value, false, false);
25230 if (result_loc != nullptr) {
25231 if (type_is_invalid(result_loc->value.type))
25232 return ira->codegen->invalid_instruction;
25233 if (result_loc->value.type->id == ZigTypeIdUnreachable)
25234 return result_loc;
25235
25236 if (!was_written) {
25237 IrInstruction *store_ptr = ir_analyze_store_ptr(ira, &instruction->base, result_loc, value);
25238 if (type_is_invalid(store_ptr->value.type)) {
25239 return ira->codegen->invalid_instruction;
25240 }
25241 }
25242
25243 if (result_loc->value.data.x_ptr.mut == ConstPtrMutInfer) {
25244 if (instr_is_comptime(value)) {
25245 result_loc->value.data.x_ptr.mut = ConstPtrMutComptimeConst;
25246 } else {
25247 result_loc->value.special = ConstValSpecialRuntime;
25248 }
25249 }
25250 }
25251
25252 return ir_const_void(ira, &instruction->base);
25253}
25254
25255static IrInstruction *ir_analyze_instruction_bit_cast_src(IrAnalyze *ira, IrInstructionBitCastSrc *instruction) {
25256 IrInstruction *operand = instruction->operand->child;
25257 if (type_is_invalid(operand->value.type))
25258 return operand;
25259
25260 IrInstruction *result_loc = ir_resolve_result(ira, &instruction->base,
25261 &instruction->result_loc_bit_cast->base, operand->value.type, operand, false, false);
25262 if (result_loc != nullptr && (type_is_invalid(result_loc->value.type) || instr_is_unreachable(result_loc)))
25263 return result_loc;
25264
25265 return instruction->result_loc_bit_cast->parent->gen_instruction;
25266}
25267
25268static IrInstruction *ir_analyze_instruction_base(IrAnalyze *ira, IrInstruction *instruction) {
2331825269 switch (instruction->id) {
2331925270 case IrInstructionIdInvalid:
2332025271 case IrInstructionIdWidenOrShorten:
23321 case IrInstructionIdStructInit:
23322 case IrInstructionIdUnionInit:
2332325272 case IrInstructionIdStructFieldPtr:
2332425273 case IrInstructionIdUnionFieldPtr:
2332525274 case IrInstructionIdOptionalWrap:
......@@ -23331,11 +25280,18 @@ static IrInstruction *ir_analyze_instruction_nocast(IrAnalyze *ira, IrInstructio
2333125280 case IrInstructionIdCmpxchgGen:
2333225281 case IrInstructionIdArrayToVector:
2333325282 case IrInstructionIdVectorToArray:
25283 case IrInstructionIdPtrOfArrayToSlice:
2333425284 case IrInstructionIdAssertZero:
2333525285 case IrInstructionIdAssertNonNull:
2333625286 case IrInstructionIdResizeSlice:
2333725287 case IrInstructionIdLoadPtrGen:
2333825288 case IrInstructionIdBitCastGen:
25289 case IrInstructionIdCallGen:
25290 case IrInstructionIdReturnPtr:
25291 case IrInstructionIdAllocaGen:
25292 case IrInstructionIdSliceGen:
25293 case IrInstructionIdRefGen:
25294 case IrInstructionIdTestErrGen:
2333925295 zig_unreachable();
2334025296
2334125297 case IrInstructionIdReturn:
......@@ -23358,8 +25314,8 @@ static IrInstruction *ir_analyze_instruction_nocast(IrAnalyze *ira, IrInstructio
2335825314 return ir_analyze_instruction_var_ptr(ira, (IrInstructionVarPtr *)instruction);
2335925315 case IrInstructionIdFieldPtr:
2336025316 return ir_analyze_instruction_field_ptr(ira, (IrInstructionFieldPtr *)instruction);
23361 case IrInstructionIdCall:
23362 return ir_analyze_instruction_call(ira, (IrInstructionCall *)instruction);
25317 case IrInstructionIdCallSrc:
25318 return ir_analyze_instruction_call(ira, (IrInstructionCallSrc *)instruction);
2336325319 case IrInstructionIdBr:
2336425320 return ir_analyze_instruction_br(ira, (IrInstructionBr *)instruction);
2336525321 case IrInstructionIdCondBr:
......@@ -23370,10 +25326,6 @@ static IrInstruction *ir_analyze_instruction_nocast(IrAnalyze *ira, IrInstructio
2337025326 return ir_analyze_instruction_phi(ira, (IrInstructionPhi *)instruction);
2337125327 case IrInstructionIdTypeOf:
2337225328 return ir_analyze_instruction_typeof(ira, (IrInstructionTypeOf *)instruction);
23373 case IrInstructionIdToPtrType:
23374 return ir_analyze_instruction_to_ptr_type(ira, (IrInstructionToPtrType *)instruction);
23375 case IrInstructionIdPtrTypeChild:
23376 return ir_analyze_instruction_ptr_type_child(ira, (IrInstructionPtrTypeChild *)instruction);
2337725329 case IrInstructionIdSetCold:
2337825330 return ir_analyze_instruction_set_cold(ira, (IrInstructionSetCold *)instruction);
2337925331 case IrInstructionIdSetRuntimeSafety:
......@@ -23474,8 +25426,8 @@ static IrInstruction *ir_analyze_instruction_nocast(IrAnalyze *ira, IrInstructio
2347425426 return ir_analyze_instruction_memset(ira, (IrInstructionMemset *)instruction);
2347525427 case IrInstructionIdMemcpy:
2347625428 return ir_analyze_instruction_memcpy(ira, (IrInstructionMemcpy *)instruction);
23477 case IrInstructionIdSlice:
23478 return ir_analyze_instruction_slice(ira, (IrInstructionSlice *)instruction);
25429 case IrInstructionIdSliceSrc:
25430 return ir_analyze_instruction_slice(ira, (IrInstructionSliceSrc *)instruction);
2347925431 case IrInstructionIdMemberCount:
2348025432 return ir_analyze_instruction_member_count(ira, (IrInstructionMemberCount *)instruction);
2348125433 case IrInstructionIdMemberType:
......@@ -23494,8 +25446,8 @@ static IrInstruction *ir_analyze_instruction_nocast(IrAnalyze *ira, IrInstructio
2349425446 return ir_analyze_instruction_align_of(ira, (IrInstructionAlignOf *)instruction);
2349525447 case IrInstructionIdOverflowOp:
2349625448 return ir_analyze_instruction_overflow_op(ira, (IrInstructionOverflowOp *)instruction);
23497 case IrInstructionIdTestErr:
23498 return ir_analyze_instruction_test_err(ira, (IrInstructionTestErr *)instruction);
25449 case IrInstructionIdTestErrSrc:
25450 return ir_analyze_instruction_test_err(ira, (IrInstructionTestErrSrc *)instruction);
2349925451 case IrInstructionIdUnwrapErrCode:
2350025452 return ir_analyze_instruction_unwrap_err_code(ira, (IrInstructionUnwrapErrCode *)instruction);
2350125453 case IrInstructionIdUnwrapErrPayload:
......@@ -23514,8 +25466,6 @@ static IrInstruction *ir_analyze_instruction_nocast(IrAnalyze *ira, IrInstructio
2351425466 return ir_analyze_instruction_panic(ira, (IrInstructionPanic *)instruction);
2351525467 case IrInstructionIdPtrCastSrc:
2351625468 return ir_analyze_instruction_ptr_cast(ira, (IrInstructionPtrCastSrc *)instruction);
23517 case IrInstructionIdBitCast:
23518 return ir_analyze_instruction_bit_cast(ira, (IrInstructionBitCast *)instruction);
2351925469 case IrInstructionIdIntToPtr:
2352025470 return ir_analyze_instruction_int_to_ptr(ira, (IrInstructionIntToPtr *)instruction);
2352125471 case IrInstructionIdPtrToInt:
......@@ -23538,6 +25488,14 @@ static IrInstruction *ir_analyze_instruction_nocast(IrAnalyze *ira, IrInstructio
2353825488 return ir_analyze_instruction_ptr_type(ira, (IrInstructionPtrType *)instruction);
2353925489 case IrInstructionIdAlignCast:
2354025490 return ir_analyze_instruction_align_cast(ira, (IrInstructionAlignCast *)instruction);
25491 case IrInstructionIdImplicitCast:
25492 return ir_analyze_instruction_implicit_cast(ira, (IrInstructionImplicitCast *)instruction);
25493 case IrInstructionIdResolveResult:
25494 return ir_analyze_instruction_resolve_result(ira, (IrInstructionResolveResult *)instruction);
25495 case IrInstructionIdResetResult:
25496 return ir_analyze_instruction_reset_result(ira, (IrInstructionResetResult *)instruction);
25497 case IrInstructionIdResultPtr:
25498 return ir_analyze_instruction_result_ptr(ira, (IrInstructionResultPtr *)instruction);
2354125499 case IrInstructionIdOpaqueType:
2354225500 return ir_analyze_instruction_opaque_type(ira, (IrInstructionOpaqueType *)instruction);
2354325501 case IrInstructionIdSetAlignStack:
......@@ -23596,8 +25554,10 @@ static IrInstruction *ir_analyze_instruction_nocast(IrAnalyze *ira, IrInstructio
2359625554 return ir_analyze_instruction_merge_err_ret_traces(ira, (IrInstructionMergeErrRetTraces *)instruction);
2359725555 case IrInstructionIdMarkErrRetTracePtr:
2359825556 return ir_analyze_instruction_mark_err_ret_trace_ptr(ira, (IrInstructionMarkErrRetTracePtr *)instruction);
23599 case IrInstructionIdSqrt:
23600 return ir_analyze_instruction_sqrt(ira, (IrInstructionSqrt *)instruction);
25557 case IrInstructionIdFloatOp:
25558 return ir_analyze_instruction_float_op(ira, (IrInstructionFloatOp *)instruction);
25559 case IrInstructionIdMulAdd:
25560 return ir_analyze_instruction_mul_add(ira, (IrInstructionMulAdd *)instruction);
2360125561 case IrInstructionIdIntToErr:
2360225562 return ir_analyze_instruction_int_to_err(ira, (IrInstructionIntToErr *)instruction);
2360325563 case IrInstructionIdErrToInt:
......@@ -23612,17 +25572,16 @@ static IrInstruction *ir_analyze_instruction_nocast(IrAnalyze *ira, IrInstructio
2361225572 return ir_analyze_instruction_has_decl(ira, (IrInstructionHasDecl *)instruction);
2361325573 case IrInstructionIdUndeclaredIdent:
2361425574 return ir_analyze_instruction_undeclared_ident(ira, (IrInstructionUndeclaredIdent *)instruction);
25575 case IrInstructionIdAllocaSrc:
25576 return nullptr;
25577 case IrInstructionIdEndExpr:
25578 return ir_analyze_instruction_end_expr(ira, (IrInstructionEndExpr *)instruction);
25579 case IrInstructionIdBitCastSrc:
25580 return ir_analyze_instruction_bit_cast_src(ira, (IrInstructionBitCastSrc *)instruction);
2361525581 }
2361625582 zig_unreachable();
2361725583}
2361825584
23619static IrInstruction *ir_analyze_instruction(IrAnalyze *ira, IrInstruction *old_instruction) {
23620 IrInstruction *new_instruction = ir_analyze_instruction_nocast(ira, old_instruction);
23621 ir_assert(new_instruction->value.type != nullptr, old_instruction);
23622 old_instruction->child = new_instruction;
23623 return new_instruction;
23624}
23625
2362625585// This function attempts to evaluate IR code while doing type checking and other analysis.
2362725586// It emits a new IrExecutable which is partially evaluated IR code.
2362825587ZigType *ir_analyze(CodeGen *codegen, IrExecutable *old_exec, IrExecutable *new_exec,
......@@ -23668,14 +25627,22 @@ ZigType *ir_analyze(CodeGen *codegen, IrExecutable *old_exec, IrExecutable *new_
2366825627 continue;
2366925628 }
2367025629
23671 IrInstruction *new_instruction = ir_analyze_instruction(ira, old_instruction);
23672 if (type_is_invalid(new_instruction->value.type) && ir_should_inline(new_exec, old_instruction->scope)) {
23673 return ira->codegen->builtin_types.entry_invalid;
25630 if (ira->codegen->verbose_ir) {
25631 fprintf(stderr, "analyze #%zu\n", old_instruction->debug_id);
2367425632 }
25633 IrInstruction *new_instruction = ir_analyze_instruction_base(ira, old_instruction);
25634 if (new_instruction != nullptr) {
25635 ir_assert(new_instruction->value.type != nullptr || new_instruction->value.type != nullptr, old_instruction);
25636 old_instruction->child = new_instruction;
2367525637
23676 // unreachable instructions do their own control flow.
23677 if (new_instruction->value.type->id == ZigTypeIdUnreachable)
23678 continue;
25638 if (type_is_invalid(new_instruction->value.type)) {
25639 return ira->codegen->builtin_types.entry_invalid;
25640 }
25641
25642 // unreachable instructions do their own control flow.
25643 if (new_instruction->value.type->id == ZigTypeIdUnreachable)
25644 continue;
25645 }
2367925646
2368025647 ira->instruction_index += 1;
2368125648 }
......@@ -23700,7 +25667,8 @@ bool ir_has_side_effects(IrInstruction *instruction) {
2370025667 case IrInstructionIdDeclVarSrc:
2370125668 case IrInstructionIdDeclVarGen:
2370225669 case IrInstructionIdStorePtr:
23703 case IrInstructionIdCall:
25670 case IrInstructionIdCallSrc:
25671 case IrInstructionIdCallGen:
2370425672 case IrInstructionIdReturn:
2370525673 case IrInstructionIdUnreachable:
2370625674 case IrInstructionIdSetCold:
......@@ -23747,27 +25715,28 @@ bool ir_has_side_effects(IrInstruction *instruction) {
2374725715 case IrInstructionIdResizeSlice:
2374825716 case IrInstructionIdGlobalAsm:
2374925717 case IrInstructionIdUndeclaredIdent:
25718 case IrInstructionIdEndExpr:
25719 case IrInstructionIdPtrOfArrayToSlice:
25720 case IrInstructionIdSliceGen:
25721 case IrInstructionIdOptionalWrap:
25722 case IrInstructionIdVectorToArray:
25723 case IrInstructionIdResetResult:
2375025724 return true;
2375125725
2375225726 case IrInstructionIdPhi:
2375325727 case IrInstructionIdUnOp:
2375425728 case IrInstructionIdBinOp:
2375525729 case IrInstructionIdLoadPtr:
23756 case IrInstructionIdLoadPtrGen:
2375725730 case IrInstructionIdConst:
2375825731 case IrInstructionIdCast:
2375925732 case IrInstructionIdContainerInitList:
2376025733 case IrInstructionIdContainerInitFields:
23761 case IrInstructionIdStructInit:
23762 case IrInstructionIdUnionInit:
2376325734 case IrInstructionIdFieldPtr:
2376425735 case IrInstructionIdElemPtr:
2376525736 case IrInstructionIdVarPtr:
25737 case IrInstructionIdReturnPtr:
2376625738 case IrInstructionIdTypeOf:
23767 case IrInstructionIdToPtrType:
23768 case IrInstructionIdPtrTypeChild:
2376925739 case IrInstructionIdStructFieldPtr:
23770 case IrInstructionIdUnionFieldPtr:
2377125740 case IrInstructionIdArrayType:
2377225741 case IrInstructionIdPromiseType:
2377325742 case IrInstructionIdSliceType:
......@@ -23789,7 +25758,7 @@ bool ir_has_side_effects(IrInstruction *instruction) {
2378925758 case IrInstructionIdIntType:
2379025759 case IrInstructionIdVectorType:
2379125760 case IrInstructionIdBoolNot:
23792 case IrInstructionIdSlice:
25761 case IrInstructionIdSliceSrc:
2379325762 case IrInstructionIdMemberCount:
2379425763 case IrInstructionIdMemberType:
2379525764 case IrInstructionIdMemberName:
......@@ -23797,16 +25766,13 @@ bool ir_has_side_effects(IrInstruction *instruction) {
2379725766 case IrInstructionIdReturnAddress:
2379825767 case IrInstructionIdFrameAddress:
2379925768 case IrInstructionIdHandle:
23800 case IrInstructionIdTestErr:
23801 case IrInstructionIdUnwrapErrCode:
23802 case IrInstructionIdOptionalWrap:
23803 case IrInstructionIdErrWrapCode:
23804 case IrInstructionIdErrWrapPayload:
25769 case IrInstructionIdTestErrSrc:
25770 case IrInstructionIdTestErrGen:
2380525771 case IrInstructionIdFnProto:
2380625772 case IrInstructionIdTestComptime:
2380725773 case IrInstructionIdPtrCastSrc:
2380825774 case IrInstructionIdPtrCastGen:
23809 case IrInstructionIdBitCast:
25775 case IrInstructionIdBitCastSrc:
2381025776 case IrInstructionIdBitCastGen:
2381125777 case IrInstructionIdWidenOrShorten:
2381225778 case IrInstructionIdPtrToInt:
......@@ -23824,6 +25790,8 @@ bool ir_has_side_effects(IrInstruction *instruction) {
2382425790 case IrInstructionIdTypeInfo:
2382525791 case IrInstructionIdTypeId:
2382625792 case IrInstructionIdAlignCast:
25793 case IrInstructionIdImplicitCast:
25794 case IrInstructionIdResolveResult:
2382725795 case IrInstructionIdOpaqueType:
2382825796 case IrInstructionIdArgType:
2382925797 case IrInstructionIdTagType:
......@@ -23836,7 +25804,8 @@ bool ir_has_side_effects(IrInstruction *instruction) {
2383625804 case IrInstructionIdCoroFree:
2383725805 case IrInstructionIdCoroPromise:
2383825806 case IrInstructionIdPromiseResultType:
23839 case IrInstructionIdSqrt:
25807 case IrInstructionIdFloatOp:
25808 case IrInstructionIdMulAdd:
2384025809 case IrInstructionIdAtomicLoad:
2384125810 case IrInstructionIdIntCast:
2384225811 case IrInstructionIdFloatCast:
......@@ -23847,9 +25816,11 @@ bool ir_has_side_effects(IrInstruction *instruction) {
2384725816 case IrInstructionIdFromBytes:
2384825817 case IrInstructionIdToBytes:
2384925818 case IrInstructionIdEnumToInt:
23850 case IrInstructionIdVectorToArray:
2385125819 case IrInstructionIdArrayToVector:
2385225820 case IrInstructionIdHasDecl:
25821 case IrInstructionIdAllocaSrc:
25822 case IrInstructionIdAllocaGen:
25823 case IrInstructionIdResultPtr:
2385325824 return false;
2385425825
2385525826 case IrInstructionIdAsm:
......@@ -23861,8 +25832,21 @@ bool ir_has_side_effects(IrInstruction *instruction) {
2386125832 {
2386225833 IrInstructionUnwrapErrPayload *unwrap_err_payload_instruction =
2386325834 (IrInstructionUnwrapErrPayload *)instruction;
23864 return unwrap_err_payload_instruction->safety_check_on;
25835 return unwrap_err_payload_instruction->safety_check_on ||
25836 unwrap_err_payload_instruction->initializing;
2386525837 }
25838 case IrInstructionIdUnwrapErrCode:
25839 return reinterpret_cast<IrInstructionUnwrapErrCode *>(instruction)->initializing;
25840 case IrInstructionIdUnionFieldPtr:
25841 return reinterpret_cast<IrInstructionUnionFieldPtr *>(instruction)->initializing;
25842 case IrInstructionIdErrWrapPayload:
25843 return reinterpret_cast<IrInstructionErrWrapPayload *>(instruction)->result_loc != nullptr;
25844 case IrInstructionIdErrWrapCode:
25845 return reinterpret_cast<IrInstructionErrWrapCode *>(instruction)->result_loc != nullptr;
25846 case IrInstructionIdLoadPtrGen:
25847 return reinterpret_cast<IrInstructionLoadPtrGen *>(instruction)->result_loc != nullptr;
25848 case IrInstructionIdRefGen:
25849 return reinterpret_cast<IrInstructionRefGen *>(instruction)->result_loc != nullptr;
2386625850 }
2386725851 zig_unreachable();
2386825852}
src/ir.hpp+1
......@@ -26,5 +26,6 @@ bool ir_has_side_effects(IrInstruction *instruction);
2626struct IrAnalyze;
2727ConstExprValue *const_ptr_pointee(IrAnalyze *ira, CodeGen *codegen, ConstExprValue *const_val,
2828 AstNode *source_node);
29const char *float_op_to_name(BuiltinFnId op, bool llvm_name);
2930
3031#endif
src/ir_print.cpp+278-95
......@@ -57,13 +57,18 @@ static void ir_print_other_instruction(IrPrint *irp, IrInstruction *instruction)
5757}
5858
5959static 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 }
6165}
6266
6367static void ir_print_return(IrPrint *irp, IrInstructionReturn *return_instruction) {
64 assert(return_instruction->value);
6568 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 }
6772}
6873
6974static 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
188193 fprintf(irp->f, " ");
189194 }
190195 fprintf(irp->f, "= ");
191 ir_print_other_instruction(irp, decl_var_instruction->init_value);
196 ir_print_other_instruction(irp, decl_var_instruction->ptr);
192197 if (decl_var_instruction->var->is_comptime != nullptr) {
193198 fprintf(irp->f, " // comptime = ");
194199 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) {
201206 fprintf(irp->f, " to %s", buf_ptr(&cast_instruction->dest_type->name));
202207}
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) {
205259 if (call_instruction->is_async) {
206260 fprintf(irp->f, "async");
207261 if (call_instruction->async_allocator != nullptr) {
......@@ -224,7 +278,35 @@ static void ir_print_call(IrPrint *irp, IrInstructionCall *call_instruction) {
224278 fprintf(irp->f, ", ");
225279 ir_print_other_instruction(irp, arg);
226280 }
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);
228310}
229311
230312static 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
270352 fprintf(irp->f, "...(%" ZIG_PRI_usize " items)...", instruction->item_count);
271353 } else {
272354 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];
274356 if (i != 0)
275357 fprintf(irp->f, ", ");
276 ir_print_other_instruction(irp, item);
358 ir_print_other_instruction(irp, result_loc);
277359 }
278360 }
279361 fprintf(irp->f, "}");
......@@ -286,32 +368,11 @@ static void ir_print_container_init_fields(IrPrint *irp, IrInstructionContainerI
286368 IrInstructionContainerInitFieldsField *field = &instruction->fields[i];
287369 const char *comma = (i == 0) ? "" : ", ";
288370 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);
290372 }
291373 fprintf(irp->f, "} // container init");
292374}
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
315376static void ir_print_unreachable(IrPrint *irp, IrInstructionUnreachable *instruction) {
316377 fprintf(irp->f, "unreachable");
317378}
......@@ -331,14 +392,20 @@ static void ir_print_var_ptr(IrPrint *irp, IrInstructionVarPtr *instruction) {
331392 fprintf(irp->f, "&%s", buf_ptr(&instruction->var->name));
332393}
333394
395static void ir_print_return_ptr(IrPrint *irp, IrInstructionReturnPtr *instruction) {
396 fprintf(irp->f, "@ReturnPtr");
397}
398
334399static void ir_print_load_ptr(IrPrint *irp, IrInstructionLoadPtr *instruction) {
335400 ir_print_other_instruction(irp, instruction->ptr);
336401 fprintf(irp->f, ".*");
337402}
338403
339404static void ir_print_load_ptr_gen(IrPrint *irp, IrInstructionLoadPtrGen *instruction) {
405 fprintf(irp->f, "loadptr(");
340406 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);
342409}
343410
344411static void ir_print_store_ptr(IrPrint *irp, IrInstructionStorePtr *instruction) {
......@@ -354,18 +421,6 @@ static void ir_print_typeof(IrPrint *irp, IrInstructionTypeOf *instruction) {
354421 fprintf(irp->f, ")");
355422}
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
369424static void ir_print_field_ptr(IrPrint *irp, IrInstructionFieldPtr *instruction) {
370425 if (instruction->field_name_buffer) {
371426 fprintf(irp->f, "fieldptr ");
......@@ -618,6 +673,13 @@ static void ir_print_ref(IrPrint *irp, IrInstructionRef *instruction) {
618673 ir_print_other_instruction(irp, instruction->value);
619674}
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
621683static void ir_print_compile_err(IrPrint *irp, IrInstructionCompileErr *instruction) {
622684 fprintf(irp->f, "@compileError(");
623685 ir_print_other_instruction(irp, instruction->msg);
......@@ -682,7 +744,8 @@ static void ir_print_cmpxchg_src(IrPrint *irp, IrInstructionCmpxchgSrc *instruct
682744 ir_print_other_instruction(irp, instruction->success_order_value);
683745 fprintf(irp->f, ", ");
684746 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);
686749}
687750
688751static void ir_print_cmpxchg_gen(IrPrint *irp, IrInstructionCmpxchgGen *instruction) {
......@@ -692,7 +755,8 @@ static void ir_print_cmpxchg_gen(IrPrint *irp, IrInstructionCmpxchgGen *instruct
692755 ir_print_other_instruction(irp, instruction->cmp_value);
693756 fprintf(irp->f, ", ");
694757 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);
696760}
697761
698762static void ir_print_fence(IrPrint *irp, IrInstructionFence *instruction) {
......@@ -810,14 +874,26 @@ static void ir_print_memcpy(IrPrint *irp, IrInstructionMemcpy *instruction) {
810874 fprintf(irp->f, ")");
811875}
812876
813static void ir_print_slice(IrPrint *irp, IrInstructionSlice *instruction) {
877static void ir_print_slice_src(IrPrint *irp, IrInstructionSliceSrc *instruction) {
814878 ir_print_other_instruction(irp, instruction->ptr);
815879 fprintf(irp->f, "[");
816880 ir_print_other_instruction(irp, instruction->start);
817881 fprintf(irp->f, "..");
818882 if (instruction->end)
819883 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);
821897}
822898
823899static void ir_print_member_count(IrPrint *irp, IrInstructionMemberCount *instruction) {
......@@ -889,43 +965,49 @@ static void ir_print_overflow_op(IrPrint *irp, IrInstructionOverflowOp *instruct
889965 fprintf(irp->f, ")");
890966}
891967
892static void ir_print_test_err(IrPrint *irp, IrInstructionTestErr *instruction) {
968static void ir_print_test_err_src(IrPrint *irp, IrInstructionTestErrSrc *instruction) {
893969 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);
895977 fprintf(irp->f, ")");
896978}
897979
898980static void ir_print_unwrap_err_code(IrPrint *irp, IrInstructionUnwrapErrCode *instruction) {
899981 fprintf(irp->f, "UnwrapErrorCode(");
900 ir_print_other_instruction(irp, instruction->err_union);
982 ir_print_other_instruction(irp, instruction->err_union_ptr);
901983 fprintf(irp->f, ")");
902984}
903985
904986static void ir_print_unwrap_err_payload(IrPrint *irp, IrInstructionUnwrapErrPayload *instruction) {
905987 fprintf(irp->f, "ErrorUnionFieldPayload(");
906988 ir_print_other_instruction(irp, instruction->value);
907 fprintf(irp->f, ")");
908 if (!instruction->safety_check_on) {
909 fprintf(irp->f, " // no safety");
910 }
989 fprintf(irp->f, ")safety=%d,init=%d",instruction->safety_check_on, instruction->initializing);
911990}
912991
913static void ir_print_maybe_wrap(IrPrint *irp, IrInstructionOptionalWrap *instruction) {
914 fprintf(irp->f, "@maybeWrap(");
915 ir_print_other_instruction(irp, instruction->value);
916 fprintf(irp->f, ")");
992static void ir_print_optional_wrap(IrPrint *irp, IrInstructionOptionalWrap *instruction) {
993 fprintf(irp->f, "@optionalWrap(");
994 ir_print_other_instruction(irp, instruction->operand);
995 fprintf(irp->f, ")result=");
996 ir_print_other_instruction(irp, instruction->result_loc);
917997}
918998
919999static void ir_print_err_wrap_code(IrPrint *irp, IrInstructionErrWrapCode *instruction) {
9201000 fprintf(irp->f, "@errWrapCode(");
921 ir_print_other_instruction(irp, instruction->value);
922 fprintf(irp->f, ")");
1001 ir_print_other_instruction(irp, instruction->operand);
1002 fprintf(irp->f, ")result=");
1003 ir_print_other_instruction(irp, instruction->result_loc);
9231004}
9241005
9251006static void ir_print_err_wrap_payload(IrPrint *irp, IrInstructionErrWrapPayload *instruction) {
9261007 fprintf(irp->f, "@errWrapPayload(");
927 ir_print_other_instruction(irp, instruction->value);
928 fprintf(irp->f, ")");
1008 ir_print_other_instruction(irp, instruction->operand);
1009 fprintf(irp->f, ")result=");
1010 ir_print_other_instruction(irp, instruction->result_loc);
9291011}
9301012
9311013static void ir_print_fn_proto(IrPrint *irp, IrInstructionFnProto *instruction) {
......@@ -971,12 +1053,11 @@ static void ir_print_ptr_cast_gen(IrPrint *irp, IrInstructionPtrCastGen *instruc
9711053 fprintf(irp->f, ")");
9721054}
9731055
974static void ir_print_bit_cast(IrPrint *irp, IrInstructionBitCast *instruction) {
1056static void ir_print_bit_cast_src(IrPrint *irp, IrInstructionBitCastSrc *instruction) {
9751057 fprintf(irp->f, "@bitCast(");
976 ir_print_other_instruction(irp, instruction->dest_type);
977 fprintf(irp->f, ",");
978 ir_print_other_instruction(irp, instruction->value);
979 fprintf(irp->f, ")");
1058 ir_print_other_instruction(irp, instruction->operand);
1059 fprintf(irp->f, ")result=");
1060 ir_print_result_loc(irp, &instruction->result_loc_bit_cast->base);
9801061}
9811062
9821063static 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
10431124static void ir_print_vector_to_array(IrPrint *irp, IrInstructionVectorToArray *instruction) {
10441125 fprintf(irp->f, "VectorToArray(");
10451126 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);
10471136}
10481137
10491138static void ir_print_assert_zero(IrPrint *irp, IrInstructionAssertZero *instruction) {
......@@ -1061,6 +1150,25 @@ static void ir_print_assert_non_null(IrPrint *irp, IrInstructionAssertNonNull *i
10611150static void ir_print_resize_slice(IrPrint *irp, IrInstructionResizeSlice *instruction) {
10621151 fprintf(irp->f, "@resizeSlice(");
10631152 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);
10641172 fprintf(irp->f, ")");
10651173}
10661174
......@@ -1186,6 +1294,34 @@ static void ir_print_align_cast(IrPrint *irp, IrInstructionAlignCast *instructio
11861294 fprintf(irp->f, ")");
11871295}
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
11891325static void ir_print_opaque_type(IrPrint *irp, IrInstructionOpaqueType *instruction) {
11901326 fprintf(irp->f, "@OpaqueType()");
11911327}
......@@ -1427,15 +1563,32 @@ static void ir_print_mark_err_ret_trace_ptr(IrPrint *irp, IrInstructionMarkErrRe
14271563 fprintf(irp->f, ")");
14281564}
14291565
1430static void ir_print_sqrt(IrPrint *irp, IrInstructionSqrt *instruction) {
1431 fprintf(irp->f, "@sqrt(");
1566static void ir_print_float_op(IrPrint *irp, IrInstructionFloatOp *instruction) {
1567
1568 fprintf(irp->f, "@%s(", float_op_to_name(instruction->op, false));
14321569 if (instruction->type != nullptr) {
14331570 ir_print_other_instruction(irp, instruction->type);
14341571 } else {
14351572 fprintf(irp->f, "null");
14361573 }
14371574 fprintf(irp->f, ",");
1438 ir_print_other_instruction(irp, instruction->op);
1575 ir_print_other_instruction(irp, instruction->op1);
1576 fprintf(irp->f, ")");
1577}
1578
1579static void ir_print_mul_add(IrPrint *irp, IrInstructionMulAdd *instruction) {
1580 fprintf(irp->f, "@mulAdd(");
1581 if (instruction->type_value != nullptr) {
1582 ir_print_other_instruction(irp, instruction->type_value);
1583 } else {
1584 fprintf(irp->f, "null");
1585 }
1586 fprintf(irp->f, ",");
1587 ir_print_other_instruction(irp, instruction->op1);
1588 fprintf(irp->f, ",");
1589 ir_print_other_instruction(irp, instruction->op2);
1590 fprintf(irp->f, ",");
1591 ir_print_other_instruction(irp, instruction->op3);
14391592 fprintf(irp->f, ")");
14401593}
14411594
......@@ -1446,7 +1599,7 @@ static void ir_print_decl_var_gen(IrPrint *irp, IrInstructionDeclVarGen *decl_va
14461599 fprintf(irp->f, "%s %s: %s align(%u) = ", var_or_const, name, buf_ptr(&var->var_type->name),
14471600 var->align_bytes);
14481601
1449 ir_print_other_instruction(irp, decl_var_instruction->init_value);
1602 ir_print_other_instruction(irp, decl_var_instruction->var_ptr);
14501603 if (decl_var_instruction->var->is_comptime != nullptr) {
14511604 fprintf(irp->f, " // comptime = ");
14521605 ir_print_other_instruction(irp, decl_var_instruction->var->is_comptime);
......@@ -1485,8 +1638,11 @@ static void ir_print_instruction(IrPrint *irp, IrInstruction *instruction) {
14851638 case IrInstructionIdCast:
14861639 ir_print_cast(irp, (IrInstructionCast *)instruction);
14871640 break;
1488 case IrInstructionIdCall:
1489 ir_print_call(irp, (IrInstructionCall *)instruction);
1641 case IrInstructionIdCallSrc:
1642 ir_print_call_src(irp, (IrInstructionCallSrc *)instruction);
1643 break;
1644 case IrInstructionIdCallGen:
1645 ir_print_call_gen(irp, (IrInstructionCallGen *)instruction);
14901646 break;
14911647 case IrInstructionIdUnOp:
14921648 ir_print_un_op(irp, (IrInstructionUnOp *)instruction);
......@@ -1506,12 +1662,6 @@ static void ir_print_instruction(IrPrint *irp, IrInstruction *instruction) {
15061662 case IrInstructionIdContainerInitFields:
15071663 ir_print_container_init_fields(irp, (IrInstructionContainerInitFields *)instruction);
15081664 break;
1509 case IrInstructionIdStructInit:
1510 ir_print_struct_init(irp, (IrInstructionStructInit *)instruction);
1511 break;
1512 case IrInstructionIdUnionInit:
1513 ir_print_union_init(irp, (IrInstructionUnionInit *)instruction);
1514 break;
15151665 case IrInstructionIdUnreachable:
15161666 ir_print_unreachable(irp, (IrInstructionUnreachable *)instruction);
15171667 break;
......@@ -1521,6 +1671,9 @@ static void ir_print_instruction(IrPrint *irp, IrInstruction *instruction) {
15211671 case IrInstructionIdVarPtr:
15221672 ir_print_var_ptr(irp, (IrInstructionVarPtr *)instruction);
15231673 break;
1674 case IrInstructionIdReturnPtr:
1675 ir_print_return_ptr(irp, (IrInstructionReturnPtr *)instruction);
1676 break;
15241677 case IrInstructionIdLoadPtr:
15251678 ir_print_load_ptr(irp, (IrInstructionLoadPtr *)instruction);
15261679 break;
......@@ -1533,12 +1686,6 @@ static void ir_print_instruction(IrPrint *irp, IrInstruction *instruction) {
15331686 case IrInstructionIdTypeOf:
15341687 ir_print_typeof(irp, (IrInstructionTypeOf *)instruction);
15351688 break;
1536 case IrInstructionIdToPtrType:
1537 ir_print_to_ptr_type(irp, (IrInstructionToPtrType *)instruction);
1538 break;
1539 case IrInstructionIdPtrTypeChild:
1540 ir_print_ptr_type_child(irp, (IrInstructionPtrTypeChild *)instruction);
1541 break;
15421689 case IrInstructionIdFieldPtr:
15431690 ir_print_field_ptr(irp, (IrInstructionFieldPtr *)instruction);
15441691 break;
......@@ -1617,6 +1764,9 @@ static void ir_print_instruction(IrPrint *irp, IrInstruction *instruction) {
16171764 case IrInstructionIdRef:
16181765 ir_print_ref(irp, (IrInstructionRef *)instruction);
16191766 break;
1767 case IrInstructionIdRefGen:
1768 ir_print_ref_gen(irp, (IrInstructionRefGen *)instruction);
1769 break;
16201770 case IrInstructionIdCompileErr:
16211771 ir_print_compile_err(irp, (IrInstructionCompileErr *)instruction);
16221772 break;
......@@ -1692,8 +1842,11 @@ static void ir_print_instruction(IrPrint *irp, IrInstruction *instruction) {
16921842 case IrInstructionIdMemcpy:
16931843 ir_print_memcpy(irp, (IrInstructionMemcpy *)instruction);
16941844 break;
1695 case IrInstructionIdSlice:
1696 ir_print_slice(irp, (IrInstructionSlice *)instruction);
1845 case IrInstructionIdSliceSrc:
1846 ir_print_slice_src(irp, (IrInstructionSliceSrc *)instruction);
1847 break;
1848 case IrInstructionIdSliceGen:
1849 ir_print_slice_gen(irp, (IrInstructionSliceGen *)instruction);
16971850 break;
16981851 case IrInstructionIdMemberCount:
16991852 ir_print_member_count(irp, (IrInstructionMemberCount *)instruction);
......@@ -1722,8 +1875,11 @@ static void ir_print_instruction(IrPrint *irp, IrInstruction *instruction) {
17221875 case IrInstructionIdOverflowOp:
17231876 ir_print_overflow_op(irp, (IrInstructionOverflowOp *)instruction);
17241877 break;
1725 case IrInstructionIdTestErr:
1726 ir_print_test_err(irp, (IrInstructionTestErr *)instruction);
1878 case IrInstructionIdTestErrSrc:
1879 ir_print_test_err_src(irp, (IrInstructionTestErrSrc *)instruction);
1880 break;
1881 case IrInstructionIdTestErrGen:
1882 ir_print_test_err_gen(irp, (IrInstructionTestErrGen *)instruction);
17271883 break;
17281884 case IrInstructionIdUnwrapErrCode:
17291885 ir_print_unwrap_err_code(irp, (IrInstructionUnwrapErrCode *)instruction);
......@@ -1732,7 +1888,7 @@ static void ir_print_instruction(IrPrint *irp, IrInstruction *instruction) {
17321888 ir_print_unwrap_err_payload(irp, (IrInstructionUnwrapErrPayload *)instruction);
17331889 break;
17341890 case IrInstructionIdOptionalWrap:
1735 ir_print_maybe_wrap(irp, (IrInstructionOptionalWrap *)instruction);
1891 ir_print_optional_wrap(irp, (IrInstructionOptionalWrap *)instruction);
17361892 break;
17371893 case IrInstructionIdErrWrapCode:
17381894 ir_print_err_wrap_code(irp, (IrInstructionErrWrapCode *)instruction);
......@@ -1752,8 +1908,8 @@ static void ir_print_instruction(IrPrint *irp, IrInstruction *instruction) {
17521908 case IrInstructionIdPtrCastGen:
17531909 ir_print_ptr_cast_gen(irp, (IrInstructionPtrCastGen *)instruction);
17541910 break;
1755 case IrInstructionIdBitCast:
1756 ir_print_bit_cast(irp, (IrInstructionBitCast *)instruction);
1911 case IrInstructionIdBitCastSrc:
1912 ir_print_bit_cast_src(irp, (IrInstructionBitCastSrc *)instruction);
17571913 break;
17581914 case IrInstructionIdBitCastGen:
17591915 ir_print_bit_cast_gen(irp, (IrInstructionBitCastGen *)instruction);
......@@ -1818,6 +1974,18 @@ static void ir_print_instruction(IrPrint *irp, IrInstruction *instruction) {
18181974 case IrInstructionIdAlignCast:
18191975 ir_print_align_cast(irp, (IrInstructionAlignCast *)instruction);
18201976 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;
18211989 case IrInstructionIdOpaqueType:
18221990 ir_print_opaque_type(irp, (IrInstructionOpaqueType *)instruction);
18231991 break;
......@@ -1902,8 +2070,11 @@ static void ir_print_instruction(IrPrint *irp, IrInstruction *instruction) {
19022070 case IrInstructionIdMarkErrRetTracePtr:
19032071 ir_print_mark_err_ret_trace_ptr(irp, (IrInstructionMarkErrRetTracePtr *)instruction);
19042072 break;
1905 case IrInstructionIdSqrt:
1906 ir_print_sqrt(irp, (IrInstructionSqrt *)instruction);
2073 case IrInstructionIdFloatOp:
2074 ir_print_float_op(irp, (IrInstructionFloatOp *)instruction);
2075 break;
2076 case IrInstructionIdMulAdd:
2077 ir_print_mul_add(irp, (IrInstructionMulAdd *)instruction);
19072078 break;
19082079 case IrInstructionIdAtomicLoad:
19092080 ir_print_atomic_load(irp, (IrInstructionAtomicLoad *)instruction);
......@@ -1923,6 +2094,9 @@ static void ir_print_instruction(IrPrint *irp, IrInstruction *instruction) {
19232094 case IrInstructionIdVectorToArray:
19242095 ir_print_vector_to_array(irp, (IrInstructionVectorToArray *)instruction);
19252096 break;
2097 case IrInstructionIdPtrOfArrayToSlice:
2098 ir_print_ptr_of_array_to_slice(irp, (IrInstructionPtrOfArrayToSlice *)instruction);
2099 break;
19262100 case IrInstructionIdAssertZero:
19272101 ir_print_assert_zero(irp, (IrInstructionAssertZero *)instruction);
19282102 break;
......@@ -1938,6 +2112,15 @@ static void ir_print_instruction(IrPrint *irp, IrInstruction *instruction) {
19382112 case IrInstructionIdUndeclaredIdent:
19392113 ir_print_undeclared_ident(irp, (IrInstructionUndeclaredIdent *)instruction);
19402114 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;
19412124 }
19422125 fprintf(irp->f, "\n");
19432126}
src/main.cpp+14-2
......@@ -913,8 +913,20 @@ int main(int argc, char **argv) {
913913 get_native_target(&target);
914914 } else {
915915 if ((err = target_parse_triple(&target, target_string))) {
916 fprintf(stderr, "invalid target: %s\n", err_str(err));
917 return print_error_usage(arg0);
916 if (err == ErrorUnknownArchitecture && target.arch != ZigLLVM_UnknownArch) {
917 fprintf(stderr, "'%s' requires a sub-architecture. Try one of these:\n",
918 target_arch_name(target.arch));
919 SubArchList sub_arch_list = target_subarch_list(target.arch);
920 size_t subarch_count = target_subarch_count(sub_arch_list);
921 for (size_t sub_i = 0; sub_i < subarch_count; sub_i += 1) {
922 ZigLLVM_SubArchType sub = target_subarch_enum(sub_arch_list, sub_i);
923 fprintf(stderr, " %s%s\n", target_arch_name(target.arch), target_subarch_name(sub));
924 }
925 return print_error_usage(arg0);
926 } else {
927 fprintf(stderr, "invalid target: %s\n", err_str(err));
928 return print_error_usage(arg0);
929 }
918930 }
919931 }
920932
src/parser.cpp+3-3
......@@ -344,7 +344,7 @@ static AstNode *ast_parse_bin_op_expr(
344344 op->data.bin_op_expr.op1 = left;
345345 op->data.bin_op_expr.op2 = right;
346346 break;
347 case NodeTypeUnwrapErrorExpr:
347 case NodeTypeCatchExpr:
348348 op->data.unwrap_err_expr.op1 = left;
349349 op->data.unwrap_err_expr.op2 = right;
350350 break;
......@@ -2404,7 +2404,7 @@ static AstNode *ast_parse_bitwise_op(ParseContext *pc) {
24042404 Token *catch_token = eat_token_if(pc, TokenIdKeywordCatch);
24052405 if (catch_token != nullptr) {
24062406 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);
24082408 if (payload != nullptr)
24092409 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
28972897 visit_field(&node->data.bin_op_expr.op1, visit, context);
28982898 visit_field(&node->data.bin_op_expr.op2, visit, context);
28992899 break;
2900 case NodeTypeUnwrapErrorExpr:
2900 case NodeTypeCatchExpr:
29012901 visit_field(&node->data.unwrap_err_expr.op1, visit, context);
29022902 visit_field(&node->data.unwrap_err_expr.symbol, visit, context);
29032903 visit_field(&node->data.unwrap_err_expr.op2, visit, context);
src/target.cpp+5-5
......@@ -486,17 +486,17 @@ void get_native_target(ZigTarget *target) {
486486Error target_parse_archsub(ZigLLVM_ArchType *out_arch, ZigLLVM_SubArchType *out_sub,
487487 const char *archsub_ptr, size_t archsub_len)
488488{
489 *out_arch = ZigLLVM_UnknownArch;
490 *out_sub = ZigLLVM_NoSubArch;
489491 for (size_t arch_i = 0; arch_i < array_length(arch_list); arch_i += 1) {
490492 ZigLLVM_ArchType arch = arch_list[arch_i];
491493 SubArchList sub_arch_list = target_subarch_list(arch);
492494 size_t subarch_count = target_subarch_count(sub_arch_list);
493 if (subarch_count == 0) {
494 if (mem_eql_str(archsub_ptr, archsub_len, target_arch_name(arch))) {
495 *out_arch = arch;
496 *out_sub = ZigLLVM_NoSubArch;
495 if (mem_eql_str(archsub_ptr, archsub_len, target_arch_name(arch))) {
496 *out_arch = arch;
497 if (subarch_count == 0) {
497498 return ErrorNone;
498499 }
499 continue;
500500 }
501501 for (size_t sub_i = 0; sub_i < subarch_count; sub_i += 1) {
502502 ZigLLVM_SubArchType sub = target_subarch_enum(sub_arch_list, sub_i);
std/event/fs.zig+1-2
......@@ -1290,10 +1290,9 @@ pub fn Watch(comptime V: type) type {
12901290 error.FileDescriptorAlreadyPresentInSet => unreachable,
12911291 error.OperationCausesCircularLoop => unreachable,
12921292 error.FileDescriptorNotRegistered => unreachable,
1293 error.SystemResources => error.SystemResources,
1294 error.UserResourceLimitReached => error.UserResourceLimitReached,
12951293 error.FileDescriptorIncompatibleWithEpoll => unreachable,
12961294 error.Unexpected => unreachable,
1295 else => |e| e,
12971296 };
12981297 await (async channel.put(transformed_err) catch unreachable);
12991298 };
std/event/lock.zig+2-1
......@@ -123,7 +123,8 @@ pub const Lock = struct {
123123};
124124
125125test "std.event.Lock" {
126 // https://github.com/ziglang/zig/issues/1908
126 // TODO https://github.com/ziglang/zig/issues/2377
127 if (true) return error.SkipZigTest;
127128 if (builtin.single_threaded) return error.SkipZigTest;
128129
129130 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 {
263263}
264264
265265test "listen on a port, send bytes, receive bytes" {
266 // https://github.com/ziglang/zig/issues/1908
267 if (builtin.single_threaded) return error.SkipZigTest;
266 // https://github.com/ziglang/zig/issues/2377
267 if (true) return error.SkipZigTest;
268268
269269 if (builtin.os != builtin.Os.linux) {
270270 // TODO build abstractions for other operating systems
std/event/rwlock.zig+2-2
......@@ -212,8 +212,8 @@ pub const RwLock = struct {
212212};
213213
214214test "std.event.RwLock" {
215 // https://github.com/ziglang/zig/issues/1908
216 if (builtin.single_threaded or builtin.os != builtin.Os.linux) return error.SkipZigTest;
215 // https://github.com/ziglang/zig/issues/2377
216 if (true) return error.SkipZigTest;
217217
218218 const allocator = std.heap.direct_allocator;
219219
std/fmt.zig+387-363
......@@ -10,6 +10,42 @@ const lossyCast = std.math.lossyCast;
1010
1111pub const default_max_depth = 3;
1212
13pub const Alignment = enum {
14 Left,
15 Center,
16 Right,
17};
18
19pub const FormatOptions = struct {
20 precision: ?usize = null,
21 width: ?usize = null,
22 alignment: ?Alignment = null,
23 fill: u8 = ' ',
24};
25
26fn nextArg(comptime used_pos_args: *u32, comptime maybe_pos_arg: ?comptime_int, comptime next_arg: *comptime_int) comptime_int {
27 if (maybe_pos_arg) |pos_arg| {
28 used_pos_args.* |= 1 << pos_arg;
29 return pos_arg;
30 } else {
31 const arg = next_arg.*;
32 next_arg.* += 1;
33 return arg;
34 }
35}
36
37fn peekIsAlign(comptime fmt: []const u8) bool {
38 // Should only be called during a state transition to the format segment.
39 std.debug.assert(fmt[0] == ':');
40
41 inline for (([_]u8{ 1, 2 })[0..]) |i| {
42 if (fmt.len > i and (fmt[i] == '<' or fmt[i] == '^' or fmt[i] == '>')) {
43 return true;
44 }
45 }
46 return false;
47}
48
1349/// Renders fmt string with args, calling output with slices of bytes.
1450/// If `output` returns an error, the error is returned from `format` and
1551/// `output` is not called again.
......@@ -20,17 +56,30 @@ pub fn format(
2056 comptime fmt: []const u8,
2157 args: ...,
2258) Errors!void {
59 const ArgSetType = @IntType(false, 32);
60 if (args.len > ArgSetType.bit_count) {
61 @compileError("32 arguments max are supported per format call");
62 }
63
2364 const State = enum {
2465 Start,
25 OpenBrace,
66 Positional,
2667 CloseBrace,
27 FormatString,
68 Specifier,
69 FormatFillAndAlign,
70 FormatWidth,
71 FormatPrecision,
2872 Pointer,
2973 };
3074
3175 comptime var start_index = 0;
3276 comptime var state = State.Start;
3377 comptime var next_arg = 0;
78 comptime var maybe_pos_arg: ?comptime_int = null;
79 comptime var used_pos_args: ArgSetType = 0;
80 comptime var specifier_start = 0;
81 comptime var specifier_end = 0;
82 comptime var options = FormatOptions{};
3483
3584 inline for (fmt) |c, i| {
3685 switch (state) {
......@@ -39,58 +88,183 @@ pub fn format(
3988 if (start_index < i) {
4089 try output(context, fmt[start_index..i]);
4190 }
91
4292 start_index = i;
43 state = State.OpenBrace;
93 specifier_start = i + 1;
94 specifier_end = i + 1;
95 maybe_pos_arg = null;
96 state = .Positional;
97 options = FormatOptions{};
4498 },
45
4699 '}' => {
47100 if (start_index < i) {
48101 try output(context, fmt[start_index..i]);
49102 }
50 state = State.CloseBrace;
103 state = .CloseBrace;
51104 },
52105 else => {},
53106 },
54 .OpenBrace => switch (c) {
107 .Positional => switch (c) {
55108 '{' => {
56 state = State.Start;
109 state = .Start;
57110 start_index = i;
58111 },
112 '*' => {
113 state = .Pointer;
114 },
115 ':' => {
116 state = if (comptime peekIsAlign(fmt[i..])) State.FormatFillAndAlign else State.FormatWidth;
117 specifier_end = i;
118 },
119 '0'...'9' => {
120 if (maybe_pos_arg == null) {
121 maybe_pos_arg = 0;
122 }
123
124 maybe_pos_arg.? *= 10;
125 maybe_pos_arg.? += c - '0';
126 specifier_start = i + 1;
127
128 if (maybe_pos_arg.? >= args.len) {
129 @compileError("Positional value refers to non-existent argument");
130 }
131 },
59132 '}' => {
60 try formatType(args[next_arg], fmt[0..0], context, Errors, output, default_max_depth);
61 next_arg += 1;
62 state = State.Start;
133 const arg_to_print = comptime nextArg(&used_pos_args, maybe_pos_arg, &next_arg);
134
135 try formatType(
136 args[arg_to_print],
137 fmt[0..0],
138 options,
139 context,
140 Errors,
141 output,
142 default_max_depth,
143 );
144
145 state = .Start;
63146 start_index = i + 1;
64147 },
65 '*' => state = State.Pointer,
66148 else => {
67 state = State.FormatString;
149 state = .Specifier;
150 specifier_start = i;
68151 },
69152 },
70153 .CloseBrace => switch (c) {
71154 '}' => {
72 state = State.Start;
155 state = .Start;
73156 start_index = i;
74157 },
75158 else => @compileError("Single '}' encountered in format string"),
76159 },
77 .FormatString => switch (c) {
160 .Specifier => switch (c) {
161 ':' => {
162 specifier_end = i;
163 state = if (comptime peekIsAlign(fmt[i..])) State.FormatFillAndAlign else State.FormatWidth;
164 },
78165 '}' => {
79 const s = start_index + 1;
80 try formatType(args[next_arg], fmt[s..i], context, Errors, output, default_max_depth);
81 next_arg += 1;
82 state = State.Start;
166 const arg_to_print = comptime nextArg(&used_pos_args, maybe_pos_arg, &next_arg);
167
168 try formatType(
169 args[arg_to_print],
170 fmt[specifier_start..i],
171 options,
172 context,
173 Errors,
174 output,
175 default_max_depth,
176 );
177 state = .Start;
83178 start_index = i + 1;
84179 },
85180 else => {},
86181 },
182 // Only entered if the format string contains a fill/align segment.
183 .FormatFillAndAlign => switch (c) {
184 '<' => {
185 options.alignment = Alignment.Left;
186 state = .FormatWidth;
187 },
188 '^' => {
189 options.alignment = Alignment.Center;
190 state = .FormatWidth;
191 },
192 '>' => {
193 options.alignment = Alignment.Right;
194 state = .FormatWidth;
195 },
196 else => {
197 options.fill = c;
198 },
199 },
200 .FormatWidth => switch (c) {
201 '0'...'9' => {
202 if (options.width == null) {
203 options.width = 0;
204 }
205
206 options.width.? *= 10;
207 options.width.? += c - '0';
208 },
209 '.' => {
210 state = .FormatPrecision;
211 },
212 '}' => {
213 const arg_to_print = comptime nextArg(&used_pos_args, maybe_pos_arg, &next_arg);
214
215 try formatType(
216 args[arg_to_print],
217 fmt[specifier_start..specifier_end],
218 options,
219 context,
220 Errors,
221 output,
222 default_max_depth,
223 );
224 state = .Start;
225 start_index = i + 1;
226 },
227 else => {
228 @compileError("Unexpected character in width value: " ++ [_]u8{c});
229 },
230 },
231 .FormatPrecision => switch (c) {
232 '0'...'9' => {
233 if (options.precision == null) {
234 options.precision = 0;
235 }
236
237 options.precision.? *= 10;
238 options.precision.? += c - '0';
239 },
240 '}' => {
241 const arg_to_print = comptime nextArg(&used_pos_args, maybe_pos_arg, &next_arg);
242
243 try formatType(
244 args[arg_to_print],
245 fmt[specifier_start..specifier_end],
246 options,
247 context,
248 Errors,
249 output,
250 default_max_depth,
251 );
252 state = .Start;
253 start_index = i + 1;
254 },
255 else => {
256 @compileError("Unexpected character in precision value: " ++ [_]u8{c});
257 },
258 },
87259 .Pointer => switch (c) {
88260 '}' => {
89 try output(context, @typeName(@typeOf(args[next_arg]).Child));
261 const arg_to_print = comptime nextArg(&used_pos_args, maybe_pos_arg, &next_arg);
262
263 try output(context, @typeName(@typeOf(args[arg_to_print]).Child));
90264 try output(context, "@");
91 try formatInt(@ptrToInt(args[next_arg]), 16, false, 0, context, Errors, output);
92 next_arg += 1;
93 state = State.Start;
265 try formatInt(@ptrToInt(args[arg_to_print]), 16, false, 0, context, Errors, output);
266
267 state = .Start;
94268 start_index = i + 1;
95269 },
96270 else => @compileError("Unexpected format character after '*'"),
......@@ -98,7 +272,13 @@ pub fn format(
98272 }
99273 }
100274 comptime {
101 if (args.len != next_arg) {
275 // All arguments must have been printed but we allow mixing positional and fixed to achieve this.
276 var i: usize = 0;
277 inline while (i < next_arg) : (i += 1) {
278 used_pos_args |= 1 << i;
279 }
280
281 if (@popCount(ArgSetType, used_pos_args) != args.len) {
102282 @compileError("Unused arguments");
103283 }
104284 if (state != State.Start) {
......@@ -113,6 +293,7 @@ pub fn format(
113293pub fn formatType(
114294 value: var,
115295 comptime fmt: []const u8,
296 comptime options: FormatOptions,
116297 context: var,
117298 comptime Errors: type,
118299 output: fn (@typeOf(context), []const u8) Errors!void,
......@@ -121,7 +302,7 @@ pub fn formatType(
121302 const T = @typeOf(value);
122303 switch (@typeInfo(T)) {
123304 .ComptimeInt, .Int, .Float => {
124 return formatValue(value, fmt, context, Errors, output);
305 return formatValue(value, fmt, options, context, Errors, output);
125306 },
126307 .Void => {
127308 return output(context, "void");
......@@ -131,16 +312,16 @@ pub fn formatType(
131312 },
132313 .Optional => {
133314 if (value) |payload| {
134 return formatType(payload, fmt, context, Errors, output, max_depth);
315 return formatType(payload, fmt, options, context, Errors, output, max_depth);
135316 } else {
136317 return output(context, "null");
137318 }
138319 },
139320 .ErrorUnion => {
140321 if (value) |payload| {
141 return formatType(payload, fmt, context, Errors, output, max_depth);
322 return formatType(payload, fmt, options, context, Errors, output, max_depth);
142323 } else |err| {
143 return formatType(err, fmt, context, Errors, output, max_depth);
324 return formatType(err, fmt, options, context, Errors, output, max_depth);
144325 }
145326 },
146327 .ErrorSet => {
......@@ -152,16 +333,16 @@ pub fn formatType(
152333 },
153334 .Enum => {
154335 if (comptime std.meta.trait.hasFn("format")(T)) {
155 return value.format(fmt, context, Errors, output);
336 return value.format(fmt, options, context, Errors, output);
156337 }
157338
158339 try output(context, @typeName(T));
159340 try output(context, ".");
160 return formatType(@tagName(value), "", context, Errors, output, max_depth);
341 return formatType(@tagName(value), "", options, context, Errors, output, max_depth);
161342 },
162343 .Union => {
163344 if (comptime std.meta.trait.hasFn("format")(T)) {
164 return value.format(fmt, context, Errors, output);
345 return value.format(fmt, options, context, Errors, output);
165346 }
166347
167348 try output(context, @typeName(T));
......@@ -175,7 +356,7 @@ pub fn formatType(
175356 try output(context, " = ");
176357 inline for (info.fields) |u_field| {
177358 if (@enumToInt(UnionTagType(value)) == u_field.enum_field.?.value) {
178 try formatType(@field(value, u_field.name), "", context, Errors, output, max_depth - 1);
359 try formatType(@field(value, u_field.name), "", options, context, Errors, output, max_depth - 1);
179360 }
180361 }
181362 try output(context, " }");
......@@ -185,7 +366,7 @@ pub fn formatType(
185366 },
186367 .Struct => {
187368 if (comptime std.meta.trait.hasFn("format")(T)) {
188 return value.format(fmt, context, Errors, output);
369 return value.format(fmt, options, context, Errors, output);
189370 }
190371
191372 try output(context, @typeName(T));
......@@ -201,7 +382,7 @@ pub fn formatType(
201382 }
202383 try output(context, @memberName(T, field_i));
203384 try output(context, " = ");
204 try formatType(@field(value, @memberName(T, field_i)), "", context, Errors, output, max_depth - 1);
385 try formatType(@field(value, @memberName(T, field_i)), "", options, context, Errors, output, max_depth - 1);
205386 }
206387 try output(context, " }");
207388 },
......@@ -209,12 +390,12 @@ pub fn formatType(
209390 .One => switch (@typeInfo(ptr_info.child)) {
210391 builtin.TypeId.Array => |info| {
211392 if (info.child == u8) {
212 return formatText(value, fmt, context, Errors, output);
393 return formatText(value, fmt, options, context, Errors, output);
213394 }
214395 return format(context, Errors, output, "{}@{x}", @typeName(T.Child), @ptrToInt(value));
215396 },
216397 builtin.TypeId.Enum, builtin.TypeId.Union, builtin.TypeId.Struct => {
217 return formatType(value.*, fmt, context, Errors, output, max_depth);
398 return formatType(value.*, fmt, options, context, Errors, output, max_depth);
218399 },
219400 else => return format(context, Errors, output, "{}@{x}", @typeName(T.Child), @ptrToInt(value)),
220401 },
......@@ -222,17 +403,17 @@ pub fn formatType(
222403 if (ptr_info.child == u8) {
223404 if (fmt.len > 0 and fmt[0] == 's') {
224405 const len = mem.len(u8, value);
225 return formatText(value[0..len], fmt, context, Errors, output);
406 return formatText(value[0..len], fmt, options, context, Errors, output);
226407 }
227408 }
228409 return format(context, Errors, output, "{}@{x}", @typeName(T.Child), @ptrToInt(value));
229410 },
230411 .Slice => {
231412 if (fmt.len > 0 and ((fmt[0] == 'x') or (fmt[0] == 'X'))) {
232 return formatText(value, fmt, context, Errors, output);
413 return formatText(value, fmt, options, context, Errors, output);
233414 }
234415 if (ptr_info.child == u8) {
235 return formatText(value, fmt, context, Errors, output);
416 return formatText(value, fmt, options, context, Errors, output);
236417 }
237418 return format(context, Errors, output, "{}@{x}", @typeName(ptr_info.child), @ptrToInt(value.ptr));
238419 },
......@@ -242,7 +423,7 @@ pub fn formatType(
242423 },
243424 .Array => |info| {
244425 if (info.child == u8) {
245 return formatText(value, fmt, context, Errors, output);
426 return formatText(value, fmt, options, context, Errors, output);
246427 }
247428 return format(context, Errors, output, "{}@{x}", @typeName(T.Child), @ptrToInt(&value));
248429 },
......@@ -256,28 +437,21 @@ pub fn formatType(
256437fn formatValue(
257438 value: var,
258439 comptime fmt: []const u8,
440 comptime options: FormatOptions,
259441 context: var,
260442 comptime Errors: type,
261443 output: fn (@typeOf(context), []const u8) Errors!void,
262444) Errors!void {
263 if (fmt.len > 0 and fmt[0] == 'B') {
264 comptime var width: ?usize = null;
265 if (fmt.len > 1) {
266 if (fmt[1] == 'i') {
267 if (fmt.len > 2) {
268 width = comptime (parseUnsigned(usize, fmt[2..], 10) catch unreachable);
269 }
270 return formatBytes(value, width, 1024, context, Errors, output);
271 }
272 width = comptime (parseUnsigned(usize, fmt[1..], 10) catch unreachable);
273 }
274 return formatBytes(value, width, 1000, context, Errors, output);
445 if (comptime std.mem.eql(u8, fmt, "B")) {
446 return formatBytes(value, options.width, 1000, context, Errors, output);
447 } else if (comptime std.mem.eql(u8, fmt, "Bi")) {
448 return formatBytes(value, options.width, 1024, context, Errors, output);
275449 }
276450
277451 const T = @typeOf(value);
278452 switch (@typeId(T)) {
279 .Float => return formatFloatValue(value, fmt, context, Errors, output),
280 .Int, .ComptimeInt => return formatIntValue(value, fmt, context, Errors, output),
453 .Float => return formatFloatValue(value, fmt, options, context, Errors, output),
454 .Int, .ComptimeInt => return formatIntValue(value, fmt, options, context, Errors, output),
281455 else => comptime unreachable,
282456 }
283457}
......@@ -285,13 +459,13 @@ fn formatValue(
285459pub fn formatIntValue(
286460 value: var,
287461 comptime fmt: []const u8,
462 comptime options: FormatOptions,
288463 context: var,
289464 comptime Errors: type,
290465 output: fn (@typeOf(context), []const u8) Errors!void,
291466) Errors!void {
292467 comptime var radix = 10;
293468 comptime var uppercase = false;
294 comptime var width = 0;
295469
296470 const int_value = if (@typeOf(value) == comptime_int) blk: {
297471 const Int = math.IntFittingRange(value, value);
......@@ -299,83 +473,69 @@ pub fn formatIntValue(
299473 } else
300474 value;
301475
302 if (fmt.len > 0) {
303 switch (fmt[0]) {
304 'c' => {
305 if (@typeOf(int_value).bit_count <= 8) {
306 if (fmt.len > 1)
307 @compileError("Unknown format character: " ++ [_]u8{fmt[1]});
308 return formatAsciiChar(u8(int_value), context, Errors, output);
309 }
310 },
311 'b' => {
312 radix = 2;
313 uppercase = false;
314 width = 0;
315 },
316 'd' => {
317 radix = 10;
318 uppercase = false;
319 width = 0;
320 },
321 'x' => {
322 radix = 16;
323 uppercase = false;
324 width = 0;
325 },
326 'X' => {
327 radix = 16;
328 uppercase = true;
329 width = 0;
330 },
331 else => @compileError("Unknown format character: " ++ [_]u8{fmt[0]}),
476 if (fmt.len == 0 or comptime std.mem.eql(u8, fmt, "d")) {
477 radix = 10;
478 uppercase = false;
479 } else if (comptime std.mem.eql(u8, fmt, "c")) {
480 if (@typeOf(int_value).bit_count <= 8) {
481 return formatAsciiChar(u8(int_value), context, Errors, output);
482 } else {
483 @compileError("Cannot print integer that is larger than 8 bits as a ascii");
332484 }
333 if (fmt.len > 1) width = comptime (parseUnsigned(usize, fmt[1..], 10) catch unreachable);
485 } else if (comptime std.mem.eql(u8, fmt, "b")) {
486 radix = 2;
487 uppercase = false;
488 } else if (comptime std.mem.eql(u8, fmt, "x")) {
489 radix = 16;
490 uppercase = false;
491 } else if (comptime std.mem.eql(u8, fmt, "X")) {
492 radix = 16;
493 uppercase = true;
494 } else {
495 @compileError("Unknown format string: '" ++ fmt ++ "'");
334496 }
335 return formatInt(int_value, radix, uppercase, width, context, Errors, output);
497
498 return formatInt(int_value, radix, uppercase, options.width orelse 0, context, Errors, output);
336499}
337500
338501fn formatFloatValue(
339502 value: var,
340503 comptime fmt: []const u8,
504 comptime options: FormatOptions,
341505 context: var,
342506 comptime Errors: type,
343507 output: fn (@typeOf(context), []const u8) Errors!void,
344508) Errors!void {
345 comptime var width: ?usize = null;
346 comptime var float_fmt = 'e';
347 if (fmt.len > 0) {
348 float_fmt = fmt[0];
349 if (fmt.len > 1) width = comptime (parseUnsigned(usize, fmt[1..], 10) catch unreachable);
350 }
351
352 switch (float_fmt) {
353 'e' => try formatFloatScientific(value, width, context, Errors, output),
354 '.' => try formatFloatDecimal(value, width, context, Errors, output),
355 else => @compileError("Unknown format character: " ++ [_]u8{float_fmt}),
509 if (fmt.len == 0 or comptime std.mem.eql(u8, fmt, "e")) {
510 return formatFloatScientific(value, options.precision, context, Errors, output);
511 } else if (comptime std.mem.eql(u8, fmt, "d")) {
512 return formatFloatDecimal(value, options.precision, context, Errors, output);
513 } else {
514 @compileError("Unknown format string: '" ++ fmt ++ "'");
356515 }
357516}
358517
359518pub fn formatText(
360519 bytes: []const u8,
361520 comptime fmt: []const u8,
521 comptime options: FormatOptions,
362522 context: var,
363523 comptime Errors: type,
364524 output: fn (@typeOf(context), []const u8) Errors!void,
365525) Errors!void {
366 if (fmt.len > 0) {
367 if (fmt[0] == 's') {
368 comptime var width = 0;
369 if (fmt.len > 1) width = comptime (parseUnsigned(usize, fmt[1..], 10) catch unreachable);
370 return formatBuf(bytes, width, context, Errors, output);
371 } else if ((fmt[0] == 'x') or (fmt[0] == 'X')) {
372 for (bytes) |c| {
373 try formatInt(c, 16, fmt[0] == 'X', 2, context, Errors, output);
374 }
375 return;
376 } else @compileError("Unknown format character: " ++ [_]u8{fmt[0]});
526 if (fmt.len == 0) {
527 return output(context, bytes);
528 } else if (comptime std.mem.eql(u8, fmt, "s")) {
529 if (options.width) |w| return formatBuf(bytes, w, context, Errors, output);
530 return formatBuf(bytes, 0, context, Errors, output);
531 } else if (comptime (std.mem.eql(u8, fmt, "x") or std.mem.eql(u8, fmt, "X"))) {
532 for (bytes) |c| {
533 try formatInt(c, 16, fmt[0] == 'X', 2, context, Errors, output);
534 }
535 return;
536 } else {
537 @compileError("Unknown format string: '" ++ fmt ++ "'");
377538 }
378 return output(context, bytes);
379539}
380540
381541pub fn formatAsciiChar(
......@@ -868,7 +1028,7 @@ test "parseUnsigned" {
8681028
8691029pub const parseFloat = @import("fmt/parse_float.zig").parseFloat;
8701030
871test "fmt.parseFloat" {
1031test "parseFloat" {
8721032 _ = @import("fmt/parse_float.zig");
8731033}
8741034
......@@ -960,7 +1120,7 @@ test "parse unsigned comptime" {
9601120 }
9611121}
9621122
963test "fmt.optional" {
1123test "optional" {
9641124 {
9651125 const value: ?i32 = 1234;
9661126 try testFmt("optional: 1234\n", "optional: {}\n", value);
......@@ -971,7 +1131,7 @@ test "fmt.optional" {
9711131 }
9721132}
9731133
974test "fmt.error" {
1134test "error" {
9751135 {
9761136 const value: anyerror!i32 = 1234;
9771137 try testFmt("error union: 1234\n", "error union: {}\n", value);
......@@ -982,14 +1142,14 @@ test "fmt.error" {
9821142 }
9831143}
9841144
985test "fmt.int.small" {
1145test "int.small" {
9861146 {
9871147 const value: u3 = 0b101;
9881148 try testFmt("u3: 5\n", "u3: {}\n", value);
9891149 }
9901150}
9911151
992test "fmt.int.specifier" {
1152test "int.specifier" {
9931153 {
9941154 const value: u8 = 'a';
9951155 try testFmt("u8: a\n", "u8: {c}\n", value);
......@@ -1000,27 +1160,31 @@ test "fmt.int.specifier" {
10001160 }
10011161}
10021162
1003test "fmt.buffer" {
1163test "int.padded" {
1164 try testFmt("u8: '0001'", "u8: '{:4}'", u8(1));
1165}
1166
1167test "buffer" {
10041168 {
10051169 var buf1: [32]u8 = undefined;
10061170 var context = BufPrintContext{ .remaining = buf1[0..] };
1007 try formatType(1234, "", &context, error{BufferTooSmall}, bufPrintWrite, default_max_depth);
1171 try formatType(1234, "", FormatOptions{}, &context, error{BufferTooSmall}, bufPrintWrite, default_max_depth);
10081172 var res = buf1[0 .. buf1.len - context.remaining.len];
10091173 testing.expect(mem.eql(u8, res, "1234"));
10101174
10111175 context = BufPrintContext{ .remaining = buf1[0..] };
1012 try formatType('a', "c", &context, error{BufferTooSmall}, bufPrintWrite, default_max_depth);
1176 try formatType('a', "c", FormatOptions{}, &context, error{BufferTooSmall}, bufPrintWrite, default_max_depth);
10131177 res = buf1[0 .. buf1.len - context.remaining.len];
10141178 testing.expect(mem.eql(u8, res, "a"));
10151179
10161180 context = BufPrintContext{ .remaining = buf1[0..] };
1017 try formatType(0b1100, "b", &context, error{BufferTooSmall}, bufPrintWrite, default_max_depth);
1181 try formatType(0b1100, "b", FormatOptions{}, &context, error{BufferTooSmall}, bufPrintWrite, default_max_depth);
10181182 res = buf1[0 .. buf1.len - context.remaining.len];
10191183 testing.expect(mem.eql(u8, res, "1100"));
10201184 }
10211185}
10221186
1023test "fmt.array" {
1187test "array" {
10241188 {
10251189 const value: [3]u8 = "abc";
10261190 try testFmt("array: abc\n", "array: {}\n", value);
......@@ -1035,7 +1199,7 @@ test "fmt.array" {
10351199 }
10361200}
10371201
1038test "fmt.slice" {
1202test "slice" {
10391203 {
10401204 const value: []const u8 = "abc";
10411205 try testFmt("slice: abc\n", "slice: {}\n", value);
......@@ -1045,11 +1209,11 @@ test "fmt.slice" {
10451209 try testFmt("slice: []const u8@deadbeef\n", "slice: {}\n", value);
10461210 }
10471211
1048 try testFmt("buf: Test \n", "buf: {s5}\n", "Test");
1212 try testFmt("buf: Test \n", "buf: {s:5}\n", "Test");
10491213 try testFmt("buf: Test\n Other text", "buf: {s}\n Other text", "Test");
10501214}
10511215
1052test "fmt.pointer" {
1216test "pointer" {
10531217 {
10541218 const value = @intToPtr(*i32, 0xdeadbeef);
10551219 try testFmt("pointer: i32@deadbeef\n", "pointer: {}\n", value);
......@@ -1065,17 +1229,17 @@ test "fmt.pointer" {
10651229 }
10661230}
10671231
1068test "fmt.cstr" {
1232test "cstr" {
10691233 try testFmt("cstr: Test C\n", "cstr: {s}\n", c"Test C");
1070 try testFmt("cstr: Test C \n", "cstr: {s10}\n", c"Test C");
1234 try testFmt("cstr: Test C \n", "cstr: {s:10}\n", c"Test C");
10711235}
10721236
1073test "fmt.filesize" {
1237test "filesize" {
10741238 try testFmt("file size: 63MiB\n", "file size: {Bi}\n", usize(63 * 1024 * 1024));
1075 try testFmt("file size: 66.06MB\n", "file size: {B2}\n", usize(63 * 1024 * 1024));
1239 try testFmt("file size: 66.06MB\n", "file size: {B:2}\n", usize(63 * 1024 * 1024));
10761240}
10771241
1078test "fmt.struct" {
1242test "struct" {
10791243 {
10801244 const Struct = struct {
10811245 field: u8,
......@@ -1094,7 +1258,7 @@ test "fmt.struct" {
10941258 }
10951259}
10961260
1097test "fmt.enum" {
1261test "enum" {
10981262 const Enum = enum {
10991263 One,
11001264 Two,
......@@ -1104,229 +1268,71 @@ test "fmt.enum" {
11041268 try testFmt("enum: Enum.Two\n", "enum: {}\n", &value);
11051269}
11061270
1107test "fmt.float.scientific" {
1108 {
1109 var buf1: [32]u8 = undefined;
1110 const value: f32 = 1.34;
1111 const result = try bufPrint(buf1[0..], "f32: {e}\n", value);
1112 testing.expect(mem.eql(u8, result, "f32: 1.34000003e+00\n"));
1113 }
1114 {
1115 var buf1: [32]u8 = undefined;
1116 const value: f32 = 12.34;
1117 const result = try bufPrint(buf1[0..], "f32: {e}\n", value);
1118 testing.expect(mem.eql(u8, result, "f32: 1.23400001e+01\n"));
1119 }
1120 {
1121 var buf1: [32]u8 = undefined;
1122 const value: f64 = -12.34e10;
1123 const result = try bufPrint(buf1[0..], "f64: {e}\n", value);
1124 testing.expect(mem.eql(u8, result, "f64: -1.234e+11\n"));
1125 }
1126 {
1127 // This fails on release due to a minor rounding difference.
1128 // --release-fast outputs 9.999960000000001e-40 vs. the expected.
1129 // TODO fix this, it should be the same in Debug and ReleaseFast
1130 if (builtin.mode == builtin.Mode.Debug) {
1131 var buf1: [32]u8 = undefined;
1132 const value: f64 = 9.999960e-40;
1133 const result = try bufPrint(buf1[0..], "f64: {e}\n", value);
1134 testing.expect(mem.eql(u8, result, "f64: 9.99996e-40\n"));
1135 }
1136 }
1271test "float.scientific" {
1272 try testFmt("f32: 1.34000003e+00", "f32: {e}", f32(1.34));
1273 try testFmt("f32: 1.23400001e+01", "f32: {e}", f32(12.34));
1274 try testFmt("f64: -1.234e+11", "f64: {e}", f64(-12.34e10));
1275 try testFmt("f64: 9.99996e-40", "f64: {e}", f64(9.999960e-40));
11371276}
11381277
1139test "fmt.float.scientific.precision" {
1140 {
1141 var buf1: [32]u8 = undefined;
1142 const value: f64 = 1.409706e-42;
1143 const result = try bufPrint(buf1[0..], "f64: {e5}\n", value);
1144 testing.expect(mem.eql(u8, result, "f64: 1.40971e-42\n"));
1145 }
1146 {
1147 var buf1: [32]u8 = undefined;
1148 const value: f64 = @bitCast(f32, u32(814313563));
1149 const result = try bufPrint(buf1[0..], "f64: {e5}\n", value);
1150 testing.expect(mem.eql(u8, result, "f64: 1.00000e-09\n"));
1151 }
1152 {
1153 var buf1: [32]u8 = undefined;
1154 const value: f64 = @bitCast(f32, u32(1006632960));
1155 const result = try bufPrint(buf1[0..], "f64: {e5}\n", value);
1156 testing.expect(mem.eql(u8, result, "f64: 7.81250e-03\n"));
1157 }
1158 {
1159 // libc rounds 1.000005e+05 to 1.00000e+05 but zig does 1.00001e+05.
1160 // In fact, libc doesn't round a lot of 5 cases up when one past the precision point.
1161 var buf1: [32]u8 = undefined;
1162 const value: f64 = @bitCast(f32, u32(1203982400));
1163 const result = try bufPrint(buf1[0..], "f64: {e5}\n", value);
1164 testing.expect(mem.eql(u8, result, "f64: 1.00001e+05\n"));
1165 }
1278test "float.scientific.precision" {
1279 try testFmt("f64: 1.40971e-42", "f64: {e:.5}", f64(1.409706e-42));
1280 try testFmt("f64: 1.00000e-09", "f64: {e:.5}", f64(@bitCast(f32, u32(814313563))));
1281 try testFmt("f64: 7.81250e-03", "f64: {e:.5}", f64(@bitCast(f32, u32(1006632960))));
1282 // libc rounds 1.000005e+05 to 1.00000e+05 but zig does 1.00001e+05.
1283 // In fact, libc doesn't round a lot of 5 cases up when one past the precision point.
1284 try testFmt("f64: 1.00001e+05", "f64: {e:.5}", f64(@bitCast(f32, u32(1203982400))));
11661285}
11671286
1168test "fmt.float.special" {
1169 {
1170 var buf1: [32]u8 = undefined;
1171 const result = try bufPrint(buf1[0..], "f64: {}\n", math.nan_f64);
1172 testing.expect(mem.eql(u8, result, "f64: nan\n"));
1173 }
1287test "float.special" {
1288 try testFmt("f64: nan", "f64: {}", math.nan_f64);
1289 // negative nan is not defined by IEE 754,
1290 // and ARM thus normalizes it to positive nan
11741291 if (builtin.arch != builtin.Arch.arm) {
1175 // negative nan is not defined by IEE 754,
1176 // and ARM thus normalizes it to positive nan
1177 var buf1: [32]u8 = undefined;
1178 const result = try bufPrint(buf1[0..], "f64: {}\n", -math.nan_f64);
1179 testing.expect(mem.eql(u8, result, "f64: -nan\n"));
1180 }
1181 {
1182 var buf1: [32]u8 = undefined;
1183 const result = try bufPrint(buf1[0..], "f64: {}\n", math.inf_f64);
1184 testing.expect(mem.eql(u8, result, "f64: inf\n"));
1185 }
1186 {
1187 var buf1: [32]u8 = undefined;
1188 const result = try bufPrint(buf1[0..], "f64: {}\n", -math.inf_f64);
1189 testing.expect(mem.eql(u8, result, "f64: -inf\n"));
1292 try testFmt("f64: -nan", "f64: {}", -math.nan_f64);
11901293 }
1294 try testFmt("f64: inf", "f64: {}", math.inf_f64);
1295 try testFmt("f64: -inf", "f64: {}", -math.inf_f64);
11911296}
11921297
1193test "fmt.float.decimal" {
1194 {
1195 var buf1: [64]u8 = undefined;
1196 const value: f64 = 1.52314e+29;
1197 const result = try bufPrint(buf1[0..], "f64: {.}\n", value);
1198 testing.expect(mem.eql(u8, result, "f64: 152314000000000000000000000000\n"));
1199 }
1200 {
1201 var buf1: [32]u8 = undefined;
1202 const value: f32 = 1.1234;
1203 const result = try bufPrint(buf1[0..], "f32: {.1}\n", value);
1204 testing.expect(mem.eql(u8, result, "f32: 1.1\n"));
1205 }
1206 {
1207 var buf1: [32]u8 = undefined;
1208 const value: f32 = 1234.567;
1209 const result = try bufPrint(buf1[0..], "f32: {.2}\n", value);
1210 testing.expect(mem.eql(u8, result, "f32: 1234.57\n"));
1211 }
1212 {
1213 var buf1: [32]u8 = undefined;
1214 const value: f32 = -11.1234;
1215 const result = try bufPrint(buf1[0..], "f32: {.4}\n", value);
1216 // -11.1234 is converted to f64 -11.12339... internally (errol3() function takes f64).
1217 // -11.12339... is rounded back up to -11.1234
1218 testing.expect(mem.eql(u8, result, "f32: -11.1234\n"));
1219 }
1220 {
1221 var buf1: [32]u8 = undefined;
1222 const value: f32 = 91.12345;
1223 const result = try bufPrint(buf1[0..], "f32: {.5}\n", value);
1224 testing.expect(mem.eql(u8, result, "f32: 91.12345\n"));
1225 }
1226 {
1227 var buf1: [32]u8 = undefined;
1228 const value: f64 = 91.12345678901235;
1229 const result = try bufPrint(buf1[0..], "f64: {.10}\n", value);
1230 testing.expect(mem.eql(u8, result, "f64: 91.1234567890\n"));
1231 }
1232 {
1233 var buf1: [32]u8 = undefined;
1234 const value: f64 = 0.0;
1235 const result = try bufPrint(buf1[0..], "f64: {.5}\n", value);
1236 testing.expect(mem.eql(u8, result, "f64: 0.00000\n"));
1237 }
1238 {
1239 var buf1: [32]u8 = undefined;
1240 const value: f64 = 5.700;
1241 const result = try bufPrint(buf1[0..], "f64: {.0}\n", value);
1242 testing.expect(mem.eql(u8, result, "f64: 6\n"));
1243 }
1244 {
1245 var buf1: [32]u8 = undefined;
1246 const value: f64 = 9.999;
1247 const result = try bufPrint(buf1[0..], "f64: {.1}\n", value);
1248 testing.expect(mem.eql(u8, result, "f64: 10.0\n"));
1249 }
1250 {
1251 var buf1: [32]u8 = undefined;
1252 const value: f64 = 1.0;
1253 const result = try bufPrint(buf1[0..], "f64: {.3}\n", value);
1254 testing.expect(mem.eql(u8, result, "f64: 1.000\n"));
1255 }
1256 {
1257 var buf1: [32]u8 = undefined;
1258 const value: f64 = 0.0003;
1259 const result = try bufPrint(buf1[0..], "f64: {.8}\n", value);
1260 testing.expect(mem.eql(u8, result, "f64: 0.00030000\n"));
1261 }
1262 {
1263 var buf1: [32]u8 = undefined;
1264 const value: f64 = 1.40130e-45;
1265 const result = try bufPrint(buf1[0..], "f64: {.5}\n", value);
1266 testing.expect(mem.eql(u8, result, "f64: 0.00000\n"));
1267 }
1268 {
1269 var buf1: [32]u8 = undefined;
1270 const value: f64 = 9.999960e-40;
1271 const result = try bufPrint(buf1[0..], "f64: {.5}\n", value);
1272 testing.expect(mem.eql(u8, result, "f64: 0.00000\n"));
1273 }
1298test "float.decimal" {
1299 try testFmt("f64: 152314000000000000000000000000", "f64: {d}", f64(1.52314e+29));
1300 try testFmt("f32: 1.1", "f32: {d:.1}", f32(1.1234));
1301 try testFmt("f32: 1234.57", "f32: {d:.2}", f32(1234.567));
1302 // -11.1234 is converted to f64 -11.12339... internally (errol3() function takes f64).
1303 // -11.12339... is rounded back up to -11.1234
1304 try testFmt("f32: -11.1234", "f32: {d:.4}", f32(-11.1234));
1305 try testFmt("f32: 91.12345", "f32: {d:.5}", f32(91.12345));
1306 try testFmt("f64: 91.1234567890", "f64: {d:.10}", f64(91.12345678901235));
1307 try testFmt("f64: 0.00000", "f64: {d:.5}", f64(0.0));
1308 try testFmt("f64: 6", "f64: {d:.0}", f64(5.700));
1309 try testFmt("f64: 10.0", "f64: {d:.1}", f64(9.999));
1310 try testFmt("f64: 1.000", "f64: {d:.3}", f64(1.0));
1311 try testFmt("f64: 0.00030000", "f64: {d:.8}", f64(0.0003));
1312 try testFmt("f64: 0.00000", "f64: {d:.5}", f64(1.40130e-45));
1313 try testFmt("f64: 0.00000", "f64: {d:.5}", f64(9.999960e-40));
12741314}
12751315
1276test "fmt.float.libc.sanity" {
1277 {
1278 var buf1: [32]u8 = undefined;
1279 const value: f64 = f64(@bitCast(f32, u32(916964781)));
1280 const result = try bufPrint(buf1[0..], "f64: {.5}\n", value);
1281 testing.expect(mem.eql(u8, result, "f64: 0.00001\n"));
1282 }
1283 {
1284 var buf1: [32]u8 = undefined;
1285 const value: f64 = f64(@bitCast(f32, u32(925353389)));
1286 const result = try bufPrint(buf1[0..], "f64: {.5}\n", value);
1287 testing.expect(mem.eql(u8, result, "f64: 0.00001\n"));
1288 }
1289 {
1290 var buf1: [32]u8 = undefined;
1291 const value: f64 = f64(@bitCast(f32, u32(1036831278)));
1292 const result = try bufPrint(buf1[0..], "f64: {.5}\n", value);
1293 testing.expect(mem.eql(u8, result, "f64: 0.10000\n"));
1294 }
1295 {
1296 var buf1: [32]u8 = undefined;
1297 const value: f64 = f64(@bitCast(f32, u32(1065353133)));
1298 const result = try bufPrint(buf1[0..], "f64: {.5}\n", value);
1299 testing.expect(mem.eql(u8, result, "f64: 1.00000\n"));
1300 }
1301 {
1302 var buf1: [32]u8 = undefined;
1303 const value: f64 = f64(@bitCast(f32, u32(1092616192)));
1304 const result = try bufPrint(buf1[0..], "f64: {.5}\n", value);
1305 testing.expect(mem.eql(u8, result, "f64: 10.00000\n"));
1306 }
1316test "float.libc.sanity" {
1317 try testFmt("f64: 0.00001", "f64: {d:.5}", f64(@bitCast(f32, u32(916964781))));
1318 try testFmt("f64: 0.00001", "f64: {d:.5}", f64(@bitCast(f32, u32(925353389))));
1319 try testFmt("f64: 0.10000", "f64: {d:.5}", f64(@bitCast(f32, u32(1036831278))));
1320 try testFmt("f64: 1.00000", "f64: {d:.5}", f64(@bitCast(f32, u32(1065353133))));
1321 try testFmt("f64: 10.00000", "f64: {d:.5}", f64(@bitCast(f32, u32(1092616192))));
1322
13071323 // libc differences
1308 {
1309 var buf1: [32]u8 = undefined;
1310 // This is 0.015625 exactly according to gdb. We thus round down,
1311 // however glibc rounds up for some reason. This occurs for all
1312 // floats of the form x.yyyy25 on a precision point.
1313 const value: f64 = f64(@bitCast(f32, u32(1015021568)));
1314 const result = try bufPrint(buf1[0..], "f64: {.5}\n", value);
1315 testing.expect(mem.eql(u8, result, "f64: 0.01563\n"));
1316 }
1317 // std-windows-x86_64-Debug-bare test case fails
1318 {
1319 // errol3 rounds to ... 630 but libc rounds to ...632. Grisu3
1320 // also rounds to 630 so I'm inclined to believe libc is not
1321 // optimal here.
1322 var buf1: [32]u8 = undefined;
1323 const value: f64 = f64(@bitCast(f32, u32(1518338049)));
1324 const result = try bufPrint(buf1[0..], "f64: {.5}\n", value);
1325 testing.expect(mem.eql(u8, result, "f64: 18014400656965630.00000\n"));
1326 }
1324 //
1325 // This is 0.015625 exactly according to gdb. We thus round down,
1326 // however glibc rounds up for some reason. This occurs for all
1327 // floats of the form x.yyyy25 on a precision point.
1328 try testFmt("f64: 0.01563", "f64: {d:.5}", f64(@bitCast(f32, u32(1015021568))));
1329 // errol3 rounds to ... 630 but libc rounds to ...632. Grisu3
1330 // also rounds to 630 so I'm inclined to believe libc is not
1331 // optimal here.
1332 try testFmt("f64: 18014400656965630.00000", "f64: {d:.5}", f64(@bitCast(f32, u32(1518338049))));
13271333}
13281334
1329test "fmt.custom" {
1335test "custom" {
13301336 const Vec2 = struct {
13311337 const SelfType = @This();
13321338 x: f32,
......@@ -1335,20 +1341,17 @@ test "fmt.custom" {
13351341 pub fn format(
13361342 self: SelfType,
13371343 comptime fmt: []const u8,
1344 comptime options: FormatOptions,
13381345 context: var,
13391346 comptime Errors: type,
13401347 output: fn (@typeOf(context), []const u8) Errors!void,
13411348 ) Errors!void {
1342 switch (fmt.len) {
1343 0 => return std.fmt.format(context, Errors, output, "({.3},{.3})", self.x, self.y),
1344 1 => switch (fmt[0]) {
1345 //point format
1346 'p' => return std.fmt.format(context, Errors, output, "({.3},{.3})", self.x, self.y),
1347 //dimension format
1348 'd' => return std.fmt.format(context, Errors, output, "{.3}x{.3}", self.x, self.y),
1349 else => unreachable,
1350 },
1351 else => unreachable,
1349 if (fmt.len == 0 or comptime std.mem.eql(u8, fmt, "p")) {
1350 return std.fmt.format(context, Errors, output, "({d:.3},{d:.3})", self.x, self.y);
1351 } else if (comptime std.mem.eql(u8, fmt, "d")) {
1352 return std.fmt.format(context, Errors, output, "{d:.3}x{d:.3}", self.x, self.y);
1353 } else {
1354 @compileError("Unknown format character: '" ++ fmt ++ "'");
13521355 }
13531356 }
13541357 };
......@@ -1366,7 +1369,7 @@ test "fmt.custom" {
13661369 try testFmt("dim: 10.200x2.220\n", "dim: {d}\n", value);
13671370}
13681371
1369test "fmt.struct" {
1372test "struct" {
13701373 const S = struct {
13711374 a: u32,
13721375 b: anyerror,
......@@ -1380,7 +1383,7 @@ test "fmt.struct" {
13801383 try testFmt("S{ .a = 456, .b = error.Unused }", "{}", inst);
13811384}
13821385
1383test "fmt.union" {
1386test "union" {
13841387 const TU = union(enum) {
13851388 float: f32,
13861389 int: u32,
......@@ -1410,7 +1413,7 @@ test "fmt.union" {
14101413 testing.expect(mem.eql(u8, uu_result[0..3], "EU@"));
14111414}
14121415
1413test "fmt.enum" {
1416test "enum" {
14141417 const E = enum {
14151418 One,
14161419 Two,
......@@ -1422,7 +1425,7 @@ test "fmt.enum" {
14221425 try testFmt("E.Two", "{}", inst);
14231426}
14241427
1425test "fmt.struct.self-referential" {
1428test "struct.self-referential" {
14261429 const S = struct {
14271430 const SelfType = @This();
14281431 a: ?*SelfType,
......@@ -1436,7 +1439,7 @@ test "fmt.struct.self-referential" {
14361439 try testFmt("S{ .a = S{ .a = S{ .a = S{ ... } } } }", "{}", inst);
14371440}
14381441
1439test "fmt.bytes.hex" {
1442test "bytes.hex" {
14401443 const some_bytes = "\xCA\xFE\xBA\xBE";
14411444 try testFmt("lowercase: cafebabe\n", "lowercase: {x}\n", some_bytes);
14421445 try testFmt("uppercase: CAFEBABE\n", "uppercase: {X}\n", some_bytes);
......@@ -1478,7 +1481,7 @@ pub fn trim(buf: []const u8) []const u8 {
14781481 return buf[start..end];
14791482}
14801483
1481test "fmt.trim" {
1484test "trim" {
14821485 testing.expect(mem.eql(u8, "abc", trim("\n abc \t")));
14831486 testing.expect(mem.eql(u8, "", trim(" ")));
14841487 testing.expect(mem.eql(u8, "", trim("")));
......@@ -1505,22 +1508,22 @@ pub fn hexToBytes(out: []u8, input: []const u8) !void {
15051508 }
15061509}
15071510
1508test "fmt.hexToBytes" {
1511test "hexToBytes" {
15091512 const test_hex_str = "909A312BB12ED1F819B3521AC4C1E896F2160507FFC1C8381E3B07BB16BD1706";
15101513 var pb: [32]u8 = undefined;
15111514 try hexToBytes(pb[0..], test_hex_str);
15121515 try testFmt(test_hex_str, "{X}", pb);
15131516}
15141517
1515test "fmt.formatIntValue with comptime_int" {
1518test "formatIntValue with comptime_int" {
15161519 const value: comptime_int = 123456789123456789;
15171520
15181521 var buf = try std.Buffer.init(std.debug.global_allocator, "");
1519 try formatIntValue(value, "", &buf, @typeOf(std.Buffer.append).ReturnType.ErrorSet, std.Buffer.append);
1522 try formatIntValue(value, "", FormatOptions{}, &buf, @typeOf(std.Buffer.append).ReturnType.ErrorSet, std.Buffer.append);
15201523 assert(mem.eql(u8, buf.toSlice(), "123456789123456789"));
15211524}
15221525
1523test "fmt.formatType max_depth" {
1526test "formatType max_depth" {
15241527 const Vec2 = struct {
15251528 const SelfType = @This();
15261529 x: f32,
......@@ -1529,11 +1532,16 @@ test "fmt.formatType max_depth" {
15291532 pub fn format(
15301533 self: SelfType,
15311534 comptime fmt: []const u8,
1535 comptime options: FormatOptions,
15321536 context: var,
15331537 comptime Errors: type,
15341538 output: fn (@typeOf(context), []const u8) Errors!void,
15351539 ) Errors!void {
1536 return std.fmt.format(context, Errors, output, "({.3},{.3})", self.x, self.y);
1540 if (fmt.len == 0) {
1541 return std.fmt.format(context, Errors, output, "({d:.3},{d:.3})", self.x, self.y);
1542 } else {
1543 @compileError("Unknown format string: '" ++ fmt ++ "'");
1544 }
15371545 }
15381546 };
15391547 const E = enum {
......@@ -1565,18 +1573,34 @@ test "fmt.formatType max_depth" {
15651573 inst.tu.ptr = &inst.tu;
15661574
15671575 var buf0 = try std.Buffer.init(std.debug.global_allocator, "");
1568 try formatType(inst, "", &buf0, @typeOf(std.Buffer.append).ReturnType.ErrorSet, std.Buffer.append, 0);
1576 try formatType(inst, "", FormatOptions{}, &buf0, @typeOf(std.Buffer.append).ReturnType.ErrorSet, std.Buffer.append, 0);
15691577 assert(mem.eql(u8, buf0.toSlice(), "S{ ... }"));
15701578
15711579 var buf1 = try std.Buffer.init(std.debug.global_allocator, "");
1572 try formatType(inst, "", &buf1, @typeOf(std.Buffer.append).ReturnType.ErrorSet, std.Buffer.append, 1);
1580 try formatType(inst, "", FormatOptions{}, &buf1, @typeOf(std.Buffer.append).ReturnType.ErrorSet, std.Buffer.append, 1);
15731581 assert(mem.eql(u8, buf1.toSlice(), "S{ .a = S{ ... }, .tu = TU{ ... }, .e = E.Two, .vec = (10.200,2.220) }"));
15741582
15751583 var buf2 = try std.Buffer.init(std.debug.global_allocator, "");
1576 try formatType(inst, "", &buf2, @typeOf(std.Buffer.append).ReturnType.ErrorSet, std.Buffer.append, 2);
1584 try formatType(inst, "", FormatOptions{}, &buf2, @typeOf(std.Buffer.append).ReturnType.ErrorSet, std.Buffer.append, 2);
15771585 assert(mem.eql(u8, buf2.toSlice(), "S{ .a = S{ .a = S{ ... }, .tu = TU{ ... }, .e = E.Two, .vec = (10.200,2.220) }, .tu = TU{ .ptr = TU{ ... } }, .e = E.Two, .vec = (10.200,2.220) }"));
15781586
15791587 var buf3 = try std.Buffer.init(std.debug.global_allocator, "");
1580 try formatType(inst, "", &buf3, @typeOf(std.Buffer.append).ReturnType.ErrorSet, std.Buffer.append, 3);
1588 try formatType(inst, "", FormatOptions{}, &buf3, @typeOf(std.Buffer.append).ReturnType.ErrorSet, std.Buffer.append, 3);
15811589 assert(mem.eql(u8, buf3.toSlice(), "S{ .a = S{ .a = S{ .a = S{ ... }, .tu = TU{ ... }, .e = E.Two, .vec = (10.200,2.220) }, .tu = TU{ .ptr = TU{ ... } }, .e = E.Two, .vec = (10.200,2.220) }, .tu = TU{ .ptr = TU{ .ptr = TU{ ... } } }, .e = E.Two, .vec = (10.200,2.220) }"));
15821590}
1591
1592test "positional" {
1593 try testFmt("2 1 0", "{2} {1} {0}", usize(0), usize(1), usize(2));
1594 try testFmt("2 1 0", "{2} {1} {}", usize(0), usize(1), usize(2));
1595 try testFmt("0 0", "{0} {0}", usize(0));
1596 try testFmt("0 1", "{} {1}", usize(0), usize(1));
1597 try testFmt("1 0 0 1", "{1} {} {0} {}", usize(0), usize(1));
1598}
1599
1600test "positional with specifier" {
1601 try testFmt("10.0", "{0d:.1}", f64(9.999));
1602}
1603
1604test "positional/alignment/width/precision" {
1605 try testFmt("10.0", "{0d: >3.1}", f64(9.999));
1606}
std/heap.zig+4-2
......@@ -8,6 +8,8 @@ const builtin = @import("builtin");
88const c = std.c;
99const maxInt = std.math.maxInt;
1010
11pub const LoggingAllocator = @import("heap/logging_allocator.zig").LoggingAllocator;
12
1113const Allocator = mem.Allocator;
1214
1315pub const c_allocator = &c_allocator_state;
......@@ -360,9 +362,9 @@ pub const ArenaAllocator = struct {
360362 var it = self.buffer_list.first;
361363 while (it) |node| {
362364 // this has to occur before the free because the free frees node
363 it = node.next;
364
365 const next_it = node.next;
365366 self.child_allocator.free(node.data);
367 it = next_it;
366368 }
367369 }
368370
std/heap/logging_allocator.zig created+53
......@@ -0,0 +1,53 @@
1const std = @import("../std.zig");
2const Allocator = std.mem.Allocator;
3
4const AnyErrorOutStream = std.io.OutStream(anyerror);
5
6/// This allocator is used in front of another allocator and logs to the provided stream
7/// on every call to the allocator. Stream errors are ignored.
8/// If https://github.com/ziglang/zig/issues/2586 is implemented, this API can be improved.
9pub const LoggingAllocator = struct {
10 allocator: Allocator,
11 parent_allocator: *Allocator,
12 out_stream: *AnyErrorOutStream,
13
14 const Self = @This();
15
16 pub fn init(parent_allocator: *Allocator, out_stream: *AnyErrorOutStream) Self {
17 return Self{
18 .allocator = Allocator{
19 .reallocFn = realloc,
20 .shrinkFn = shrink,
21 },
22 .parent_allocator = parent_allocator,
23 .out_stream = out_stream,
24 };
25 }
26
27 fn realloc(allocator: *Allocator, old_mem: []u8, old_align: u29, new_size: usize, new_align: u29) ![]u8 {
28 const self = @fieldParentPtr(Self, "allocator", allocator);
29 if (old_mem.len == 0) {
30 self.out_stream.print("allocation of {} ", new_size) catch {};
31 } else {
32 self.out_stream.print("resize from {} to {} ", old_mem.len, new_size) catch {};
33 }
34 const result = self.parent_allocator.reallocFn(self.parent_allocator, old_mem, old_align, new_size, new_align);
35 if (result) |buff| {
36 self.out_stream.print("success!\n") catch {};
37 } else |err| {
38 self.out_stream.print("failure!\n") catch {};
39 }
40 return result;
41 }
42
43 fn shrink(allocator: *Allocator, old_mem: []u8, old_align: u29, new_size: usize, new_align: u29) []u8 {
44 const self = @fieldParentPtr(Self, "allocator", allocator);
45 const result = self.parent_allocator.shrinkFn(self.parent_allocator, old_mem, old_align, new_size, new_align);
46 if (new_size == 0) {
47 self.out_stream.print("free of {} bytes success!\n", old_mem.len) catch {};
48 } else {
49 self.out_stream.print("shrink from {} bytes to {} bytes success!\n", old_mem.len, new_size) catch {};
50 }
51 return result;
52 }
53};
std/http.zig created+5
......@@ -0,0 +1,5 @@
1test "std.http" {
2 _ = @import("http/headers.zig");
3}
4
5pub const Headers = @import("http/headers.zig").Headers;
std/http/headers.zig created+614
......@@ -0,0 +1,614 @@
1// HTTP Header data structure/type
2// Based on lua-http's http.header module
3//
4// Design criteria:
5// - the same header field is allowed more than once
6// - must be able to fetch separate occurrences (important for some headers e.g. Set-Cookie)
7// - optionally available as comma separated list
8// - http2 adds flag to headers that they should never be indexed
9// - header order should be recoverable
10//
11// Headers are implemented as an array of entries.
12// An index of field name => array indices is kept.
13
14const std = @import("../std.zig");
15const debug = std.debug;
16const assert = debug.assert;
17const testing = std.testing;
18const mem = std.mem;
19const Allocator = mem.Allocator;
20
21fn never_index_default(name: []const u8) bool {
22 if (mem.eql(u8, "authorization", name)) return true;
23 if (mem.eql(u8, "proxy-authorization", name)) return true;
24 if (mem.eql(u8, "cookie", name)) return true;
25 if (mem.eql(u8, "set-cookie", name)) return true;
26 return false;
27}
28
29const HeaderEntry = struct {
30 allocator: *Allocator,
31 pub name: []const u8,
32 pub value: []u8,
33 pub never_index: bool,
34
35 const Self = @This();
36
37 fn init(allocator: *Allocator, name: []const u8, value: []const u8, never_index: ?bool) !Self {
38 return Self{
39 .allocator = allocator,
40 .name = name, // takes reference
41 .value = try mem.dupe(allocator, u8, value),
42 .never_index = never_index orelse never_index_default(name),
43 };
44 }
45
46 fn deinit(self: Self) void {
47 self.allocator.free(self.value);
48 }
49
50 pub fn modify(self: *Self, value: []const u8, never_index: ?bool) !void {
51 const old_len = self.value.len;
52 if (value.len > old_len) {
53 self.value = try self.allocator.realloc(self.value, value.len);
54 } else if (value.len < old_len) {
55 self.value = self.allocator.shrink(self.value, value.len);
56 }
57 mem.copy(u8, self.value, value);
58 self.never_index = never_index orelse never_index_default(self.name);
59 }
60
61 fn compare(a: HeaderEntry, b: HeaderEntry) bool {
62 if (a.name.ptr != b.name.ptr and a.name.len != b.name.len) {
63 // Things beginning with a colon *must* be before others
64 const a_is_colon = a.name[0] == ':';
65 const b_is_colon = b.name[0] == ':';
66 if (a_is_colon and !b_is_colon) {
67 return true;
68 } else if (!a_is_colon and b_is_colon) {
69 return false;
70 }
71
72 // Sort lexicographically on header name
73 return mem.compare(u8, a.name, b.name) == mem.Compare.LessThan;
74 }
75
76 // Sort lexicographically on header value
77 if (!mem.eql(u8, a.value, b.value)) {
78 return mem.compare(u8, a.value, b.value) == mem.Compare.LessThan;
79 }
80
81 // Doesn't matter here; need to pick something for sort consistency
82 return a.never_index;
83 }
84};
85
86var test_memory: [32 * 1024]u8 = undefined;
87var test_fba_state = std.heap.FixedBufferAllocator.init(&test_memory);
88const test_allocator = &test_fba_state.allocator;
89
90test "HeaderEntry" {
91 var e = try HeaderEntry.init(test_allocator, "foo", "bar", null);
92 defer e.deinit();
93 testing.expectEqualSlices(u8, "foo", e.name);
94 testing.expectEqualSlices(u8, "bar", e.value);
95 testing.expectEqual(false, e.never_index);
96
97 try e.modify("longer value", null);
98 testing.expectEqualSlices(u8, "longer value", e.value);
99
100 // shorter value
101 try e.modify("x", null);
102 testing.expectEqualSlices(u8, "x", e.value);
103}
104
105const HeaderList = std.ArrayList(HeaderEntry);
106const HeaderIndexList = std.ArrayList(usize);
107const HeaderIndex = std.AutoHashMap([]const u8, HeaderIndexList);
108
109pub const Headers = struct {
110 // the owned header field name is stored in the index as part of the key
111 allocator: *Allocator,
112 data: HeaderList,
113 index: HeaderIndex,
114
115 const Self = @This();
116
117 pub fn init(allocator: *Allocator) Self {
118 return Self{
119 .allocator = allocator,
120 .data = HeaderList.init(allocator),
121 .index = HeaderIndex.init(allocator),
122 };
123 }
124
125 pub fn deinit(self: Self) void {
126 {
127 var it = self.index.iterator();
128 while (it.next()) |kv| {
129 var dex = &kv.value;
130 dex.deinit();
131 self.allocator.free(kv.key);
132 }
133 self.index.deinit();
134 }
135 {
136 var it = self.data.iterator();
137 while (it.next()) |entry| {
138 entry.deinit();
139 }
140 self.data.deinit();
141 }
142 }
143
144 pub fn clone(self: Self, allocator: *Allocator) !Self {
145 var other = Headers.init(allocator);
146 errdefer other.deinit();
147 try other.data.ensureCapacity(self.data.count());
148 try other.index.initCapacity(self.index.entries.len);
149 var it = self.data.iterator();
150 while (it.next()) |entry| {
151 try other.append(entry.name, entry.value, entry.never_index);
152 }
153 return other;
154 }
155
156 pub fn count(self: Self) usize {
157 return self.data.count();
158 }
159
160 pub const Iterator = HeaderList.Iterator;
161
162 pub fn iterator(self: Self) Iterator {
163 return self.data.iterator();
164 }
165
166 pub fn append(self: *Self, name: []const u8, value: []const u8, never_index: ?bool) !void {
167 const n = self.data.count() + 1;
168 try self.data.ensureCapacity(n);
169 var entry: HeaderEntry = undefined;
170 if (self.index.get(name)) |kv| {
171 entry = try HeaderEntry.init(self.allocator, kv.key, value, never_index);
172 errdefer entry.deinit();
173 var dex = &kv.value;
174 try dex.append(n - 1);
175 } else {
176 const name_dup = try mem.dupe(self.allocator, u8, name);
177 errdefer self.allocator.free(name_dup);
178 entry = try HeaderEntry.init(self.allocator, name_dup, value, never_index);
179 errdefer entry.deinit();
180 var dex = HeaderIndexList.init(self.allocator);
181 try dex.append(n - 1);
182 errdefer dex.deinit();
183 _ = try self.index.put(name, dex);
184 }
185 self.data.appendAssumeCapacity(entry);
186 }
187
188 /// If the header already exists, replace the current value, otherwise append it to the list of headers.
189 /// If the header has multiple entries then returns an error.
190 pub fn upsert(self: *Self, name: []const u8, value: []const u8, never_index: ?bool) !void {
191 if (self.index.get(name)) |kv| {
192 const dex = kv.value;
193 if (dex.count() != 1)
194 return error.CannotUpsertMultiValuedField;
195 var e = &self.data.at(dex.at(0));
196 try e.modify(value, never_index);
197 } else {
198 try self.append(name, value, never_index);
199 }
200 }
201
202 /// Returns boolean indicating if the field is present.
203 pub fn contains(self: Self, name: []const u8) bool {
204 return self.index.contains(name);
205 }
206
207 /// Returns boolean indicating if something was deleted.
208 pub fn delete(self: *Self, name: []const u8) bool {
209 if (self.index.remove(name)) |kv| {
210 var dex = &kv.value;
211 // iterate backwards
212 var i = dex.count();
213 while (i > 0) {
214 i -= 1;
215 const data_index = dex.at(i);
216 const removed = self.data.orderedRemove(data_index);
217 assert(mem.eql(u8, removed.name, name));
218 removed.deinit();
219 }
220 dex.deinit();
221 self.allocator.free(kv.key);
222 self.rebuild_index();
223 return true;
224 } else {
225 return false;
226 }
227 }
228
229 /// Removes the element at the specified index.
230 /// Moves items down to fill the empty space.
231 pub fn orderedRemove(self: *Self, i: usize) void {
232 const removed = self.data.orderedRemove(i);
233 const kv = self.index.get(removed.name).?;
234 var dex = &kv.value;
235 if (dex.count() == 1) {
236 // was last item; delete the index
237 _ = self.index.remove(kv.key);
238 dex.deinit();
239 removed.deinit();
240 self.allocator.free(kv.key);
241 } else {
242 dex.shrink(dex.count() - 1);
243 removed.deinit();
244 }
245 // if it was the last item; no need to rebuild index
246 if (i != self.data.count()) {
247 self.rebuild_index();
248 }
249 }
250
251 /// Removes the element at the specified index.
252 /// The empty slot is filled from the end of the list.
253 pub fn swapRemove(self: *Self, i: usize) void {
254 const removed = self.data.swapRemove(i);
255 const kv = self.index.get(removed.name).?;
256 var dex = &kv.value;
257 if (dex.count() == 1) {
258 // was last item; delete the index
259 _ = self.index.remove(kv.key);
260 dex.deinit();
261 removed.deinit();
262 self.allocator.free(kv.key);
263 } else {
264 dex.shrink(dex.count() - 1);
265 removed.deinit();
266 }
267 // if it was the last item; no need to rebuild index
268 if (i != self.data.count()) {
269 self.rebuild_index();
270 }
271 }
272
273 /// Access the header at the specified index.
274 pub fn at(self: Self, i: usize) HeaderEntry {
275 return self.data.at(i);
276 }
277
278 /// Returns a list of indices containing headers with the given name.
279 /// The returned list should not be modified by the caller.
280 pub fn getIndices(self: Self, name: []const u8) ?HeaderIndexList {
281 if (self.index.get(name)) |kv| {
282 return kv.value;
283 } else {
284 return null;
285 }
286 }
287
288 /// Returns a slice containing each header with the given name.
289 pub fn get(self: Self, allocator: *Allocator, name: []const u8) !?[]const HeaderEntry {
290 const dex = self.getIndices(name) orelse return null;
291
292 const buf = try allocator.alloc(HeaderEntry, dex.count());
293 var it = dex.iterator();
294 var n: usize = 0;
295 while (it.next()) |idx| {
296 buf[n] = self.data.at(idx);
297 n += 1;
298 }
299 return buf;
300 }
301
302 /// Returns all headers with the given name as a comma seperated string.
303 ///
304 /// Useful for HTTP headers that follow RFC-7230 section 3.2.2:
305 /// A recipient MAY combine multiple header fields with the same field
306 /// name into one "field-name: field-value" pair, without changing the
307 /// semantics of the message, by appending each subsequent field value to
308 /// the combined field value in order, separated by a comma. The order
309 /// in which header fields with the same field name are received is
310 /// therefore significant to the interpretation of the combined field
311 /// value
312 pub fn getCommaSeparated(self: Self, allocator: *Allocator, name: []const u8) !?[]u8 {
313 const dex = self.getIndices(name) orelse return null;
314
315 // adapted from mem.join
316 const total_len = blk: {
317 var sum: usize = dex.count() - 1; // space for separator(s)
318 var it = dex.iterator();
319 while (it.next()) |idx|
320 sum += self.data.at(idx).value.len;
321 break :blk sum;
322 };
323
324 const buf = try allocator.alloc(u8, total_len);
325 errdefer allocator.free(buf);
326
327 const first_value = self.data.at(dex.at(0)).value;
328 mem.copy(u8, buf, first_value);
329 var buf_index: usize = first_value.len;
330 for (dex.toSlice()[1..]) |idx| {
331 const value = self.data.at(idx).value;
332 buf[buf_index] = ',';
333 buf_index += 1;
334 mem.copy(u8, buf[buf_index..], value);
335 buf_index += value.len;
336 }
337
338 // No need for shrink since buf is exactly the correct size.
339 return buf;
340 }
341
342 fn rebuild_index(self: *Self) void {
343 { // clear out the indexes
344 var it = self.index.iterator();
345 while (it.next()) |kv| {
346 var dex = &kv.value;
347 dex.len = 0; // keeps capacity available
348 }
349 }
350 { // fill up indexes again; we know capacity is fine from before
351 var it = self.data.iterator();
352 while (it.next()) |entry| {
353 var dex = &self.index.get(entry.name).?.value;
354 dex.appendAssumeCapacity(it.count);
355 }
356 }
357 }
358
359 pub fn sort(self: *Self) void {
360 std.sort.sort(HeaderEntry, self.data.toSlice(), HeaderEntry.compare);
361 self.rebuild_index();
362 }
363
364 pub fn format(
365 self: Self,
366 comptime fmt: []const u8,
367 options: std.fmt.FormatOptions,
368 context: var,
369 comptime Errors: type,
370 output: fn (@typeOf(context), []const u8) Errors!void,
371 ) Errors!void {
372 var it = self.iterator();
373 while (it.next()) |entry| {
374 try output(context, entry.name);
375 try output(context, ": ");
376 try output(context, entry.value);
377 try output(context, "\n");
378 }
379 }
380};
381
382test "Headers.iterator" {
383 var h = Headers.init(test_allocator);
384 defer h.deinit();
385 try h.append("foo", "bar", null);
386 try h.append("cookie", "somevalue", null);
387
388 var count: i32 = 0;
389 var it = h.iterator();
390 while (it.next()) |e| {
391 if (count == 0) {
392 testing.expectEqualSlices(u8, "foo", e.name);
393 testing.expectEqualSlices(u8, "bar", e.value);
394 testing.expectEqual(false, e.never_index);
395 } else if (count == 1) {
396 testing.expectEqualSlices(u8, "cookie", e.name);
397 testing.expectEqualSlices(u8, "somevalue", e.value);
398 testing.expectEqual(true, e.never_index);
399 }
400 count += 1;
401 }
402 testing.expectEqual(i32(2), count);
403}
404
405test "Headers.contains" {
406 var h = Headers.init(test_allocator);
407 defer h.deinit();
408 try h.append("foo", "bar", null);
409 try h.append("cookie", "somevalue", null);
410
411 testing.expectEqual(true, h.contains("foo"));
412 testing.expectEqual(false, h.contains("flooble"));
413}
414
415test "Headers.delete" {
416 var h = Headers.init(test_allocator);
417 defer h.deinit();
418 try h.append("foo", "bar", null);
419 try h.append("baz", "qux", null);
420 try h.append("cookie", "somevalue", null);
421
422 testing.expectEqual(false, h.delete("not-present"));
423 testing.expectEqual(usize(3), h.count());
424
425 testing.expectEqual(true, h.delete("foo"));
426 testing.expectEqual(usize(2), h.count());
427 {
428 const e = h.at(0);
429 testing.expectEqualSlices(u8, "baz", e.name);
430 testing.expectEqualSlices(u8, "qux", e.value);
431 testing.expectEqual(false, e.never_index);
432 }
433 {
434 const e = h.at(1);
435 testing.expectEqualSlices(u8, "cookie", e.name);
436 testing.expectEqualSlices(u8, "somevalue", e.value);
437 testing.expectEqual(true, e.never_index);
438 }
439
440 testing.expectEqual(false, h.delete("foo"));
441}
442
443test "Headers.orderedRemove" {
444 var h = Headers.init(test_allocator);
445 defer h.deinit();
446 try h.append("foo", "bar", null);
447 try h.append("baz", "qux", null);
448 try h.append("cookie", "somevalue", null);
449
450 h.orderedRemove(0);
451 testing.expectEqual(usize(2), h.count());
452 {
453 const e = h.at(0);
454 testing.expectEqualSlices(u8, "baz", e.name);
455 testing.expectEqualSlices(u8, "qux", e.value);
456 testing.expectEqual(false, e.never_index);
457 }
458 {
459 const e = h.at(1);
460 testing.expectEqualSlices(u8, "cookie", e.name);
461 testing.expectEqualSlices(u8, "somevalue", e.value);
462 testing.expectEqual(true, e.never_index);
463 }
464}
465
466test "Headers.swapRemove" {
467 var h = Headers.init(test_allocator);
468 defer h.deinit();
469 try h.append("foo", "bar", null);
470 try h.append("baz", "qux", null);
471 try h.append("cookie", "somevalue", null);
472
473 h.swapRemove(0);
474 testing.expectEqual(usize(2), h.count());
475 {
476 const e = h.at(0);
477 testing.expectEqualSlices(u8, "cookie", e.name);
478 testing.expectEqualSlices(u8, "somevalue", e.value);
479 testing.expectEqual(true, e.never_index);
480 }
481 {
482 const e = h.at(1);
483 testing.expectEqualSlices(u8, "baz", e.name);
484 testing.expectEqualSlices(u8, "qux", e.value);
485 testing.expectEqual(false, e.never_index);
486 }
487}
488
489test "Headers.at" {
490 var h = Headers.init(test_allocator);
491 defer h.deinit();
492 try h.append("foo", "bar", null);
493 try h.append("cookie", "somevalue", null);
494
495 {
496 const e = h.at(0);
497 testing.expectEqualSlices(u8, "foo", e.name);
498 testing.expectEqualSlices(u8, "bar", e.value);
499 testing.expectEqual(false, e.never_index);
500 }
501 {
502 const e = h.at(1);
503 testing.expectEqualSlices(u8, "cookie", e.name);
504 testing.expectEqualSlices(u8, "somevalue", e.value);
505 testing.expectEqual(true, e.never_index);
506 }
507}
508
509test "Headers.getIndices" {
510 var h = Headers.init(test_allocator);
511 defer h.deinit();
512 try h.append("foo", "bar", null);
513 try h.append("set-cookie", "x=1", null);
514 try h.append("set-cookie", "y=2", null);
515
516 testing.expect(null == h.getIndices("not-present"));
517 testing.expectEqualSlices(usize, [_]usize{0}, h.getIndices("foo").?.toSliceConst());
518 testing.expectEqualSlices(usize, [_]usize{ 1, 2 }, h.getIndices("set-cookie").?.toSliceConst());
519}
520
521test "Headers.get" {
522 var h = Headers.init(test_allocator);
523 defer h.deinit();
524 try h.append("foo", "bar", null);
525 try h.append("set-cookie", "x=1", null);
526 try h.append("set-cookie", "y=2", null);
527
528 {
529 const v = try h.get(test_allocator, "not-present");
530 testing.expect(null == v);
531 }
532 {
533 const v = (try h.get(test_allocator, "foo")).?;
534 defer test_allocator.free(v);
535 const e = v[0];
536 testing.expectEqualSlices(u8, "foo", e.name);
537 testing.expectEqualSlices(u8, "bar", e.value);
538 testing.expectEqual(false, e.never_index);
539 }
540 {
541 const v = (try h.get(test_allocator, "set-cookie")).?;
542 defer test_allocator.free(v);
543 {
544 const e = v[0];
545 testing.expectEqualSlices(u8, "set-cookie", e.name);
546 testing.expectEqualSlices(u8, "x=1", e.value);
547 testing.expectEqual(true, e.never_index);
548 }
549 {
550 const e = v[1];
551 testing.expectEqualSlices(u8, "set-cookie", e.name);
552 testing.expectEqualSlices(u8, "y=2", e.value);
553 testing.expectEqual(true, e.never_index);
554 }
555 }
556}
557
558test "Headers.getCommaSeparated" {
559 var h = Headers.init(test_allocator);
560 defer h.deinit();
561 try h.append("foo", "bar", null);
562 try h.append("set-cookie", "x=1", null);
563 try h.append("set-cookie", "y=2", null);
564
565 {
566 const v = try h.getCommaSeparated(test_allocator, "not-present");
567 testing.expect(null == v);
568 }
569 {
570 const v = (try h.getCommaSeparated(test_allocator, "foo")).?;
571 defer test_allocator.free(v);
572 testing.expectEqualSlices(u8, "bar", v);
573 }
574 {
575 const v = (try h.getCommaSeparated(test_allocator, "set-cookie")).?;
576 defer test_allocator.free(v);
577 testing.expectEqualSlices(u8, "x=1,y=2", v);
578 }
579}
580
581test "Headers.sort" {
582 var h = Headers.init(test_allocator);
583 defer h.deinit();
584 try h.append("foo", "bar", null);
585 try h.append("cookie", "somevalue", null);
586
587 h.sort();
588 {
589 const e = h.at(0);
590 testing.expectEqualSlices(u8, "cookie", e.name);
591 testing.expectEqualSlices(u8, "somevalue", e.value);
592 testing.expectEqual(true, e.never_index);
593 }
594 {
595 const e = h.at(1);
596 testing.expectEqualSlices(u8, "foo", e.name);
597 testing.expectEqualSlices(u8, "bar", e.value);
598 testing.expectEqual(false, e.never_index);
599 }
600}
601
602test "Headers.format" {
603 var h = Headers.init(test_allocator);
604 defer h.deinit();
605 try h.append("foo", "bar", null);
606 try h.append("cookie", "somevalue", null);
607
608 var buf: [100]u8 = undefined;
609 testing.expectEqualSlices(u8,
610 \\foo: bar
611 \\cookie: somevalue
612 \\
613 , try std.fmt.bufPrint(buf[0..], "{}", h));
614}
std/io.zig+10-10
......@@ -164,32 +164,32 @@ pub fn InStream(comptime ReadError: type) type {
164164
165165 /// Reads a native-endian integer
166166 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;
168168 try self.readNoEof(bytes[0..]);
169169 return mem.readIntNative(T, &bytes);
170170 }
171171
172172 /// Reads a foreign-endian integer
173173 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;
175175 try self.readNoEof(bytes[0..]);
176176 return mem.readIntForeign(T, &bytes);
177177 }
178178
179179 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;
181181 try self.readNoEof(bytes[0..]);
182182 return mem.readIntLittle(T, &bytes);
183183 }
184184
185185 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;
187187 try self.readNoEof(bytes[0..]);
188188 return mem.readIntBig(T, &bytes);
189189 }
190190
191191 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;
193193 try self.readNoEof(bytes[0..]);
194194 return mem.readInt(T, &bytes, endian);
195195 }
......@@ -249,32 +249,32 @@ pub fn OutStream(comptime WriteError: type) type {
249249
250250 /// Write a native-endian integer.
251251 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;
253253 mem.writeIntNative(T, &bytes, value);
254254 return self.writeFn(self, bytes);
255255 }
256256
257257 /// Write a foreign-endian integer.
258258 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;
260260 mem.writeIntForeign(T, &bytes, value);
261261 return self.writeFn(self, bytes);
262262 }
263263
264264 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;
266266 mem.writeIntLittle(T, &bytes, value);
267267 return self.writeFn(self, bytes);
268268 }
269269
270270 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;
272272 mem.writeIntBig(T, &bytes, value);
273273 return self.writeFn(self, bytes);
274274 }
275275
276276 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;
278278 mem.writeInt(T, &bytes, value, endian);
279279 return self.writeFn(self, bytes);
280280 }
std/io/test.zig+4-1
......@@ -597,7 +597,10 @@ test "c out stream" {
597597
598598 const filename = c"tmp_io_test_file.txt";
599599 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
602605 const out_stream = &io.COutStream.init(out_file).stream;
603606 try out_stream.print("hi: {}\n", i32(123));
std/json.zig+2-1
......@@ -876,8 +876,9 @@ pub const TokenStream = struct {
876876
877877 pub fn next(self: *TokenStream) !?Token {
878878 if (self.token) |token| {
879 const copy = token;
879880 self.token = null;
880 return token;
881 return copy;
881882 }
882883
883884 var t1: ?Token = undefined;
std/math/big/int.zig+1
......@@ -519,6 +519,7 @@ pub const Int = struct {
519519 pub fn format(
520520 self: Int,
521521 comptime fmt: []const u8,
522 comptime options: std.fmt.FormatOptions,
522523 context: var,
523524 comptime FmtError: type,
524525 output: fn (@typeOf(context), []const u8) FmtError!void,
std/mem.zig+6
......@@ -1481,6 +1481,7 @@ test "subArrayPtr" {
14811481}
14821482
14831483/// Round an address up to the nearest aligned address
1484/// The alignment must be a power of 2 and greater than 0.
14841485pub fn alignForward(addr: usize, alignment: usize) usize {
14851486 return alignBackward(addr + (alignment - 1), alignment);
14861487}
......@@ -1500,13 +1501,18 @@ test "alignForward" {
15001501 testing.expect(alignForward(17, 8) == 24);
15011502}
15021503
1504/// Round an address up to the previous aligned address
1505/// The alignment must be a power of 2 and greater than 0.
15031506pub fn alignBackward(addr: usize, alignment: usize) usize {
1507 assert(@popCount(usize, alignment) == 1);
15041508 // 000010000 // example addr
15051509 // 000001111 // subtract 1
15061510 // 111110000 // binary not
15071511 return addr & ~(alignment - 1);
15081512}
15091513
1514/// Given an address and an alignment, return true if the address is a multiple of the alignment
1515/// The alignment must be a power of 2 and greater than 0.
15101516pub fn isAligned(addr: usize, alignment: usize) bool {
15111517 return alignBackward(addr, alignment) == addr;
15121518}
std/net.zig-1
......@@ -33,7 +33,6 @@ pub const Address = struct {
3333
3434 pub fn initIp6(ip6: *const Ip6Addr, _port: u16) Address {
3535 return Address{
36 .family = os.AF_INET6,
3736 .os_addr = os.sockaddr{
3837 .in6 = os.sockaddr_in6{
3938 .family = os.AF_INET6,
std/os/windows.zig+2
......@@ -348,6 +348,7 @@ pub const DeleteFileError = error{
348348 FileNotFound,
349349 AccessDenied,
350350 NameTooLong,
351 FileBusy,
351352 Unexpected,
352353};
353354
......@@ -363,6 +364,7 @@ pub fn DeleteFileW(filename: [*]const u16) DeleteFileError!void {
363364 ERROR.ACCESS_DENIED => return error.AccessDenied,
364365 ERROR.FILENAME_EXCED_RANGE => return error.NameTooLong,
365366 ERROR.INVALID_PARAMETER => return error.NameTooLong,
367 ERROR.SHARING_VIOLATION => return error.FileBusy,
366368 else => |err| return unexpectedError(err),
367369 }
368370 }
std/special/bootstrap.zig+6-7
......@@ -1,7 +1,6 @@
1// This file is in a package which has the root source file exposed as "@root".
2// It is included in the compilation unit when exporting an executable.
1// This file is included in the compilation unit when exporting an executable.
32
4const root = @import("@root");
3const root = @import("root");
54const std = @import("std");
65const builtin = @import("builtin");
76const assert = std.debug.assert;
......@@ -114,20 +113,20 @@ extern fn main(c_argc: i32, c_argv: [*][*]u8, c_envp: [*]?[*]u8) i32 {
114113// and we want fewer call frames in stack traces.
115114inline fn callMain() u8 {
116115 switch (@typeId(@typeOf(root.main).ReturnType)) {
117 builtin.TypeId.NoReturn => {
116 .NoReturn => {
118117 root.main();
119118 },
120 builtin.TypeId.Void => {
119 .Void => {
121120 root.main();
122121 return 0;
123122 },
124 builtin.TypeId.Int => {
123 .Int => {
125124 if (@typeOf(root.main).ReturnType.bit_count != 8) {
126125 @compileError("expected return type of main to be 'u8', 'noreturn', 'void', or '!void'");
127126 }
128127 return root.main();
129128 },
130 builtin.TypeId.ErrorUnion => {
129 .ErrorUnion => {
131130 root.main() catch |err| {
132131 std.debug.warn("error: {}\n", @errorName(err));
133132 if (builtin.os != builtin.Os.zen) {
std/special/build_runner.zig+2-2
......@@ -167,7 +167,7 @@ fn usage(builder: *Builder, already_ran_build: bool, out_stream: var) !void {
167167
168168 const allocator = builder.allocator;
169169 for (builder.top_level_steps.toSliceConst()) |top_level_step| {
170 try out_stream.print(" {s22} {}\n", top_level_step.step.name, top_level_step.description);
170 try out_stream.print(" {s:22} {}\n", top_level_step.step.name, top_level_step.description);
171171 }
172172
173173 try out_stream.write(
......@@ -188,7 +188,7 @@ fn usage(builder: *Builder, already_ran_build: bool, out_stream: var) !void {
188188 for (builder.available_options_list.toSliceConst()) |option| {
189189 const name = try fmt.allocPrint(allocator, " -D{}=[{}]", option.name, Builder.typeIdName(option.type_id));
190190 defer allocator.free(name);
191 try out_stream.print("{s24} {}\n", name, option.description);
191 try out_stream.print("{s:24} {}\n", name, option.description);
192192 }
193193 }
194194
std/special/c.zig+26-13
......@@ -254,19 +254,32 @@ export fn fmod(x: f64, y: f64) f64 {
254254
255255// TODO add intrinsics for these (and probably the double version too)
256256// and have the math stuff use the intrinsic. same as @mod and @rem
257export fn floorf(x: f32) f32 {
258 return math.floor(x);
259}
260export fn ceilf(x: f32) f32 {
261 return math.ceil(x);
262}
263export fn floor(x: f64) f64 {
264 return math.floor(x);
265}
266export fn ceil(x: f64) f64 {
267 return math.ceil(x);
268}
269
257export fn floorf(x: f32) f32 {return math.floor(x);}
258export fn ceilf(x: f32) f32 {return math.ceil(x);}
259export fn floor(x: f64) f64 {return math.floor(x);}
260export fn ceil(x: f64) f64 {return math.ceil(x);}
261export fn fma(a: f64, b: f64, c: f64) f64 {return math.fma(f64, a, b, c);}
262export fn fmaf(a: f32, b: f32, c: f32) f32 {return math.fma(f32, a, b, c);}
263export fn sin(a: f64) f64 {return math.sin(a);}
264export fn sinf(a: f32) f32 {return math.sin(a);}
265export fn cos(a: f64) f64 {return math.cos(a);}
266export fn cosf(a: f32) f32 {return math.cos(a);}
267export fn exp(a: f64) f64 {return math.exp(a);}
268export fn expf(a: f32) f32 {return math.exp(a);}
269export fn exp2(a: f64) f64 {return math.exp2(a);}
270export fn exp2f(a: f32) f32 {return math.exp2(a);}
271export fn log(a: f64) f64 {return math.ln(a);}
272export fn logf(a: f32) f32 {return math.ln(a);}
273export fn log2(a: f64) f64 {return math.log2(a);}
274export fn log2f(a: f32) f32 {return math.log2(a);}
275export fn log10(a: f64) f64 {return math.log10(a);}
276export fn log10f(a: f32) f32 {return math.log10(a);}
277export fn fabs(a: f64) f64 {return math.fabs(a);}
278export fn fabsf(a: f32) f32 {return math.fabs(a);}
279export fn trunc(a: f64) f64 {return math.trunc(a);}
280export fn truncf(a: f32) f32 {return math.trunc(a);}
281export fn round(a: f64) f64 {return math.round(a);}
282export fn roundf(a: f32) f32 {return math.round(a);}
270283fn generic_fmod(comptime T: type, x: T, y: T) T {
271284 @setRuntimeSafety(false);
272285
std/special/compiler_rt.zig+39-6
......@@ -405,15 +405,15 @@ const use_thumb_1 = usesThumb1(builtin.arch);
405405
406406fn usesThumb1(arch: builtin.Arch) bool {
407407 return switch (arch) {
408 .arm => switch (arch.arm) {
408 .arm => |sub_arch| switch (sub_arch) {
409409 .v6m => true,
410410 else => false,
411411 },
412 .armeb => switch (arch.armeb) {
412 .armeb => |sub_arch| switch (sub_arch) {
413413 .v6m => true,
414414 else => false,
415415 },
416 .thumb => switch (arch.thumb) {
416 .thumb => |sub_arch| switch (sub_arch) {
417417 .v5,
418418 .v5te,
419419 .v4t,
......@@ -423,7 +423,7 @@ fn usesThumb1(arch: builtin.Arch) bool {
423423 => true,
424424 else => false,
425425 },
426 .thumbeb => switch (arch.thumbeb) {
426 .thumbeb => |sub_arch| switch (sub_arch) {
427427 .v5,
428428 .v5te,
429429 .v4t,
......@@ -471,6 +471,22 @@ test "usesThumb1" {
471471 //etc.
472472}
473473
474const use_thumb_1_pre_armv6 = usesThumb1PreArmv6(builtin.arch);
475
476fn usesThumb1PreArmv6(arch: builtin.Arch) bool {
477 return switch (arch) {
478 .thumb => |sub_arch| switch (sub_arch) {
479 .v5, .v5te, .v4t => true,
480 else => false,
481 },
482 .thumbeb => |sub_arch| switch (sub_arch) {
483 .v5, .v5te, .v4t => true,
484 else => false,
485 },
486 else => false,
487 };
488}
489
474490nakedcc fn __aeabi_memcpy() noreturn {
475491 @setRuntimeSafety(false);
476492 if (use_thumb_1) {
......@@ -505,7 +521,16 @@ nakedcc fn __aeabi_memmove() noreturn {
505521
506522nakedcc fn __aeabi_memset() noreturn {
507523 @setRuntimeSafety(false);
508 if (use_thumb_1) {
524 if (use_thumb_1_pre_armv6) {
525 asm volatile (
526 \\ eors r1, r2
527 \\ eors r2, r1
528 \\ eors r1, r2
529 \\ push {r7, lr}
530 \\ b memset
531 \\ pop {r7, pc}
532 );
533 } else if (use_thumb_1) {
509534 asm volatile (
510535 \\ mov r3, r1
511536 \\ mov r1, r2
......@@ -527,7 +552,15 @@ nakedcc fn __aeabi_memset() noreturn {
527552
528553nakedcc fn __aeabi_memclr() noreturn {
529554 @setRuntimeSafety(false);
530 if (use_thumb_1) {
555 if (use_thumb_1_pre_armv6) {
556 asm volatile (
557 \\ adds r2, r1, #0
558 \\ movs r1, #0
559 \\ push {r7, lr}
560 \\ bl memset
561 \\ pop {r7, pc}
562 );
563 } else if (use_thumb_1) {
531564 asm volatile (
532565 \\ mov r2, r1
533566 \\ movs r1, #0
std/special/compiler_rt/comparetf2.zig+9-6
......@@ -73,12 +73,15 @@ pub extern fn __getf2(a: f128, b: f128) c_int {
7373
7474 if (aAbs > infRep or bAbs > infRep) return GE_UNORDERED;
7575 if ((aAbs | bAbs) == 0) return GE_EQUAL;
76 return if ((aInt & bInt) >= 0) if (aInt < bInt)
77 GE_LESS
78 else if (aInt == bInt)
79 GE_EQUAL
80 else
81 GE_GREATER else if (aInt > bInt)
76 // zig fmt issue here, see https://github.com/ziglang/zig/issues/2661
77 return if ((aInt & bInt) >= 0)
78 if (aInt < bInt)
79 GE_LESS
80 else if (aInt == bInt)
81 GE_EQUAL
82 else
83 GE_GREATER
84 else if (aInt > bInt)
8285 GE_LESS
8386 else if (aInt == bInt)
8487 GE_EQUAL
std/special/panic.zig+3-4
......@@ -9,16 +9,15 @@ const std = @import("std");
99pub fn panic(msg: []const u8, error_return_trace: ?*builtin.StackTrace) noreturn {
1010 @setCold(true);
1111 switch (builtin.os) {
12 // TODO: fix panic in zen
13 builtin.Os.freestanding, builtin.Os.zen => {
12 .freestanding => {
1413 while (true) {}
1514 },
16 builtin.Os.wasi => {
15 .wasi => {
1716 std.debug.warn("{}", msg);
1817 _ = std.os.wasi.proc_raise(std.os.wasi.SIGABRT);
1918 unreachable;
2019 },
21 builtin.Os.uefi => {
20 .uefi => {
2221 // TODO look into using the debug info and logging helpful messages
2322 std.os.abort();
2423 },
std/std.zig+2
......@@ -37,6 +37,7 @@ pub const fs = @import("fs.zig");
3737pub const hash = @import("hash.zig");
3838pub const hash_map = @import("hash_map.zig");
3939pub const heap = @import("heap.zig");
40pub const http = @import("http.zig");
4041pub const io = @import("io.zig");
4142pub const json = @import("json.zig");
4243pub const lazyInit = @import("lazy_init.zig").lazyInit;
......@@ -89,6 +90,7 @@ test "std" {
8990 _ = @import("fs.zig");
9091 _ = @import("hash.zig");
9192 _ = @import("heap.zig");
93 _ = @import("http.zig");
9294 _ = @import("io.zig");
9395 _ = @import("json.zig");
9496 _ = @import("lazy_init.zig");
std/zig/parse.zig+2-2
......@@ -2833,8 +2833,8 @@ fn parseIf(arena: *Allocator, it: *TokenIterator, tree: *Tree, bodyParseFn: Node
28332833
28342834 const else_token = eatToken(it, .Keyword_else) orelse return node;
28352835 const payload = try parsePayload(arena, it, tree);
2836 const else_expr = try expectNode(arena, it, tree, parseExpr, AstError{
2837 .ExpectedExpr = AstError.ExpectedExpr{ .token = it.index },
2836 const else_expr = try expectNode(arena, it, tree, bodyParseFn, AstError{
2837 .InvalidToken = AstError.InvalidToken{ .token = it.index },
28382838 });
28392839 const else_node = try arena.create(Node.Else);
28402840 else_node.* = Node.Else{
std/zig/parser_test.zig+14-2
......@@ -1,4 +1,4 @@
1// TODO remove `use` keyword eventually
1// TODO remove `use` keyword eventually: https://github.com/ziglang/zig/issues/2591
22test "zig fmt: change use to usingnamespace" {
33 try testTransform(
44 \\use @import("std");
......@@ -1105,7 +1105,7 @@ test "zig fmt: first line comment in struct initializer" {
11051105 try testCanonical(
11061106 \\pub async fn acquire(self: *Self) HeldLock {
11071107 \\ return HeldLock{
1108 \\ // TODO guaranteed allocation elision
1108 \\ // guaranteed allocation elision
11091109 \\ .held = await (async self.lock.acquire() catch unreachable),
11101110 \\ .value = &self.private_data,
11111111 \\ };
......@@ -2234,6 +2234,18 @@ test "zig fmt: multiline string in array" {
22342234 );
22352235}
22362236
2237test "zig fmt: if type expr" {
2238 try testCanonical(
2239 \\const mycond = true;
2240 \\pub fn foo() if (mycond) i32 else void {
2241 \\ if (mycond) {
2242 \\ return 42;
2243 \\ }
2244 \\}
2245 \\
2246 );
2247}
2248
22372249const std = @import("std");
22382250const mem = std.mem;
22392251const warn = std.debug.warn;
std/zig/render.zig+3-3
......@@ -939,10 +939,10 @@ fn renderExpression(
939939 }
940940
941941 switch (container_decl.init_arg_expr) {
942 ast.Node.ContainerDecl.InitArg.None => {
942 .None => {
943943 try renderToken(tree, stream, container_decl.kind_token, indent, start_col, Space.Space); // union
944944 },
945 ast.Node.ContainerDecl.InitArg.Enum => |enum_tag_type| {
945 .Enum => |enum_tag_type| {
946946 try renderToken(tree, stream, container_decl.kind_token, indent, start_col, Space.None); // union
947947
948948 const lparen = tree.nextToken(container_decl.kind_token);
......@@ -962,7 +962,7 @@ fn renderExpression(
962962 try renderToken(tree, stream, tree.nextToken(enum_token), indent, start_col, Space.Space); // )
963963 }
964964 },
965 ast.Node.ContainerDecl.InitArg.Type => |type_expr| {
965 .Type => |type_expr| {
966966 try renderToken(tree, stream, container_decl.kind_token, indent, start_col, Space.None); // union
967967
968968 const lparen = tree.nextToken(container_decl.kind_token);
test/compare_output.zig+1-1
......@@ -122,7 +122,7 @@ pub fn addCases(cases: *tests.CompareOutputContext) void {
122122 \\
123123 \\pub fn main() void {
124124 \\ const stdout = &(io.getStdOut() catch unreachable).outStream().stream;
125 \\ stdout.print("Hello, world!\n{d4} {x3} {c}\n", u32(12), u16(0x12), u8('a')) catch unreachable;
125 \\ stdout.print("Hello, world!\n{d:4} {x:3} {c}\n", u32(12), u16(0x12), u8('a')) catch unreachable;
126126 \\}
127127 , "Hello, world!\n0012 012 a\n");
128128
test/compile_errors.zig+85-41
......@@ -2,13 +2,22 @@ const tests = @import("tests.zig");
22const builtin = @import("builtin");
33
44pub fn addCases(cases: *tests.CompileErrorContext) void {
5 cases.add(
6 "slice passed as array init type with elems",
7 \\export fn entry() void {
8 \\ const x = []u8{1, 2};
9 \\}
10 ,
11 "tmp.zig:2:15: error: expected array type or [_], found slice",
12 );
13
514 cases.add(
615 "slice passed as array init type",
716 \\export fn entry() void {
817 \\ const x = []u8{};
918 \\}
1019 ,
11 "tmp.zig:2:19: error: expected array type or [_], found slice",
20 "tmp.zig:2:15: error: expected array type or [_], found slice",
1221 );
1322
1423 cases.add(
......@@ -49,16 +58,11 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {
4958 \\const Foo = struct {
5059 \\ a: undefined,
5160 \\};
52 \\const Bar = union {
53 \\ a: undefined,
54 \\};
55 \\pub fn main() void {
61 \\export fn entry1() void {
5662 \\ const foo: Foo = undefined;
57 \\ const bar: Bar = undefined;
5863 \\}
5964 ,
6065 "tmp.zig:2:8: error: expected type 'type', found '(undefined)'",
61 "tmp.zig:5:8: error: expected type 'type', found '(undefined)'",
6266 );
6367
6468 cases.add(
......@@ -461,13 +465,25 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {
461465 \\const G = packed struct {
462466 \\ x: Enum,
463467 \\};
464 \\export fn entry() void {
468 \\export fn entry1() void {
465469 \\ var a: A = undefined;
470 \\}
471 \\export fn entry2() void {
466472 \\ var b: B = undefined;
473 \\}
474 \\export fn entry3() void {
467475 \\ var r: C = undefined;
476 \\}
477 \\export fn entry4() void {
468478 \\ var d: D = undefined;
479 \\}
480 \\export fn entry5() void {
469481 \\ var e: E = undefined;
482 \\}
483 \\export fn entry6() void {
470484 \\ var f: F = undefined;
485 \\}
486 \\export fn entry7() void {
471487 \\ var g: G = undefined;
472488 \\}
473489 \\const S = struct {
......@@ -489,7 +505,7 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {
489505 "tmp.zig:14:5: error: non-packed, non-extern struct 'U' not allowed in packed struct; no guaranteed in-memory representation",
490506 "tmp.zig:17:5: error: type '?anyerror' not allowed in packed struct; no guaranteed in-memory representation",
491507 "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",
508 "tmp.zig:50:14: note: enum declaration does not specify an integer tag type",
493509 );
494510
495511 cases.addCase(x: {
......@@ -721,7 +737,7 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {
721737 \\ var oops = @bitCast(u7, byte);
722738 \\}
723739 ,
724 "tmp.zig:2:16: error: destination type 'u7' has 7 bits but source type 'u8' has 8 bits",
740 "tmp.zig:2:25: error: destination type 'u7' has 7 bits but source type 'u8' has 8 bits",
725741 );
726742
727743 cases.add(
......@@ -1381,7 +1397,7 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {
13811397 \\ for (xx) |f| {}
13821398 \\}
13831399 ,
1384 "tmp.zig:7:15: error: variable of type 'Foo' must be const or comptime",
1400 "tmp.zig:7:5: error: values of type 'Foo' must be comptime known, but index value is runtime known",
13851401 );
13861402
13871403 cases.add(
......@@ -2250,6 +2266,9 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {
22502266 \\}
22512267 \\
22522268 \\extern fn bar(x: *void) void { }
2269 \\export fn entry2() void {
2270 \\ bar(&{});
2271 \\}
22532272 ,
22542273 "tmp.zig:1:30: error: parameter of type '*void' has 0 bits; not allowed in function with calling convention 'ccc'",
22552274 "tmp.zig:7:18: error: parameter of type '*void' has 0 bits; not allowed in function with calling convention 'ccc'",
......@@ -2576,7 +2595,7 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {
25762595 \\
25772596 \\fn b() void {}
25782597 ,
2579 "tmp.zig:3:5: error: unreachable code",
2598 "tmp.zig:3:6: error: unreachable code",
25802599 );
25812600
25822601 cases.add(
......@@ -2596,7 +2615,6 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {
25962615 \\}
25972616 ,
25982617 "tmp.zig:3:5: error: use of undeclared identifier 'b'",
2599 "tmp.zig:4:5: error: use of undeclared identifier 'c'",
26002618 );
26012619
26022620 cases.add(
......@@ -2662,7 +2680,7 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {
26622680 \\ const a: noreturn = {};
26632681 \\}
26642682 ,
2665 "tmp.zig:2:14: error: variable of type 'noreturn' not allowed",
2683 "tmp.zig:2:25: error: expected type 'noreturn', found 'void'",
26662684 );
26672685
26682686 cases.add(
......@@ -2725,9 +2743,13 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {
27252743 \\ var bad : bool = undefined;
27262744 \\ bad[bad] = bad[bad];
27272745 \\}
2746 \\export fn g() void {
2747 \\ var bad : bool = undefined;
2748 \\ _ = bad[bad];
2749 \\}
27282750 ,
27292751 "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'",
2752 "tmp.zig:7:12: error: array access of non-array type 'bool'",
27312753 );
27322754
27332755 cases.add(
......@@ -2737,9 +2759,14 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {
27372759 \\ var bad = false;
27382760 \\ array[bad] = array[bad];
27392761 \\}
2762 \\export fn g() void {
2763 \\ var array = "aoeu";
2764 \\ var bad = false;
2765 \\ _ = array[bad];
2766 \\}
27402767 ,
27412768 "tmp.zig:4:11: error: expected type 'usize', found 'bool'",
2742 "tmp.zig:4:24: error: expected type 'usize', found 'bool'",
2769 "tmp.zig:9:15: error: expected type 'usize', found 'bool'",
27432770 );
27442771
27452772 cases.add(
......@@ -2757,12 +2784,14 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {
27572784 "missing else clause",
27582785 \\fn f(b: bool) void {
27592786 \\ const x : i32 = if (b) h: { break :h 1; };
2787 \\}
2788 \\fn g(b: bool) void {
27602789 \\ const y = if (b) h: { break :h i32(1); };
27612790 \\}
2762 \\export fn entry() void { f(true); }
2791 \\export fn entry() void { f(true); g(true); }
27632792 ,
27642793 "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'",
2794 "tmp.zig:5:15: error: incompatible types: 'i32' and 'void'",
27662795 );
27672796
27682797 cases.add(
......@@ -2773,9 +2802,13 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {
27732802 \\ a.foo = 1;
27742803 \\ const y = a.bar;
27752804 \\}
2805 \\export fn g() void {
2806 \\ var a : A = undefined;
2807 \\ const y = a.bar;
2808 \\}
27762809 ,
27772810 "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'",
2811 "tmp.zig:9:16: error: no member named 'bar' in struct 'A'",
27792812 );
27802813
27812814 cases.add(
......@@ -2920,7 +2953,7 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {
29202953 \\ _ = foo;
29212954 \\}
29222955 ,
2923 "tmp.zig:1:19: error: type '[3]u16' does not support struct initialization syntax",
2956 "tmp.zig:1:21: error: type '[3]u16' does not support struct initialization syntax",
29242957 );
29252958
29262959 cases.add(
......@@ -3239,7 +3272,7 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {
32393272 \\
32403273 \\export fn entry() usize { return @sizeOf(@typeOf(Foo)); }
32413274 ,
3242 "tmp.zig:5:25: error: unable to evaluate constant expression",
3275 "tmp.zig:5:18: error: unable to evaluate constant expression",
32433276 "tmp.zig:2:12: note: called from here",
32443277 "tmp.zig:2:8: note: called from here",
32453278 );
......@@ -3856,7 +3889,7 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {
38563889 \\ return 2;
38573890 \\}
38583891 ,
3859 "tmp.zig:2:15: error: values of type 'comptime_int' must be comptime known",
3892 "tmp.zig:5:17: error: cannot store runtime value in type 'comptime_int'",
38603893 );
38613894
38623895 cases.add(
......@@ -5108,7 +5141,7 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {
51085141 \\ const array = [2]u8{1, 2, 3};
51095142 \\}
51105143 ,
5111 "tmp.zig:2:24: error: expected [2]u8 literal, found [3]u8 literal",
5144 "tmp.zig:2:31: error: index 2 outside array of size 2",
51125145 );
51135146
51145147 cases.add(
......@@ -5125,36 +5158,47 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {
51255158
51265159 cases.add(
51275160 "non-const variables of things that require const variables",
5128 \\const Opaque = @OpaqueType();
5129 \\
5130 \\export fn entry(opaque: *Opaque) void {
5161 \\export fn entry1() void {
51315162 \\ var m2 = &2;
5132 \\ const y: u32 = m2.*;
5133 \\
5163 \\}
5164 \\export fn entry2() void {
51345165 \\ var a = undefined;
5166 \\}
5167 \\export fn entry3() void {
51355168 \\ var b = 1;
5169 \\}
5170 \\export fn entry4() void {
51365171 \\ var c = 1.0;
5172 \\}
5173 \\export fn entry5() void {
51375174 \\ var d = null;
5175 \\}
5176 \\export fn entry6(opaque: *Opaque) void {
51385177 \\ var e = opaque.*;
5178 \\}
5179 \\export fn entry7() void {
51395180 \\ var f = i32;
5181 \\}
5182 \\export fn entry8() void {
51405183 \\ var h = (Foo {}).bar;
5141 \\
5184 \\}
5185 \\export fn entry9() void {
51425186 \\ var z: noreturn = return;
51435187 \\}
5144 \\
5188 \\const Opaque = @OpaqueType();
51455189 \\const Foo = struct {
51465190 \\ fn bar(self: *const Foo) void {}
51475191 \\};
51485192 ,
5149 "tmp.zig:4: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",
5193 "tmp.zig:2:4: error: variable of type '*comptime_int' must be const or comptime",
5194 "tmp.zig:5:4: error: variable of type '(undefined)' must be const or comptime",
51515195 "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",
5153 "tmp.zig:10:4: error: variable of type '(null)' must be const or comptime",
5154 "tmp.zig:11:4: error: variable of type 'Opaque' not allowed",
5155 "tmp.zig:12: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",
5157 "tmp.zig:15:4: error: unreachable code",
5196 "tmp.zig:11:4: error: variable of type 'comptime_float' must be const or comptime",
5197 "tmp.zig:14:4: error: variable of type '(null)' must be const or comptime",
5198 "tmp.zig:17:4: error: variable of type 'Opaque' not allowed",
5199 "tmp.zig:20:4: error: variable of type 'type' must be const or comptime",
5200 "tmp.zig:23:4: error: variable of type '(bound fn(*const Foo) void)' must be const or comptime",
5201 "tmp.zig:26:4: error: unreachable code",
51585202 );
51595203
51605204 cases.add(
......@@ -5300,7 +5344,7 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {
53005344 \\ }
53015345 \\}
53025346 ,
5303 "tmp.zig:37:16: error: cannot store runtime value in compile time variable",
5347 "tmp.zig:37:29: error: cannot store runtime value in compile time variable",
53045348 );
53055349
53065350 cases.add(
......@@ -5924,7 +5968,7 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {
59245968 \\ const foo = Foo { .Bar = x, .Baz = u8 };
59255969 \\}
59265970 ,
5927 "tmp.zig:7:30: error: unable to evaluate constant expression",
5971 "tmp.zig:7:23: error: unable to evaluate constant expression",
59285972 );
59295973
59305974 cases.add(
......@@ -5938,7 +5982,7 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {
59385982 \\ const foo = Foo { .Bar = x };
59395983 \\}
59405984 ,
5941 "tmp.zig:7:30: error: unable to evaluate constant expression",
5985 "tmp.zig:7:23: error: unable to evaluate constant expression",
59425986 );
59435987
59445988 cases.addTest(
test/stage1/behavior.zig+2
......@@ -69,6 +69,8 @@ comptime {
6969 _ = @import("behavior/optional.zig");
7070 _ = @import("behavior/pointers.zig");
7171 _ = @import("behavior/popcount.zig");
72 _ = @import("behavior/muladd.zig");
73 _ = @import("behavior/floatop.zig");
7274 _ = @import("behavior/ptrcast.zig");
7375 _ = @import("behavior/pub_enum.zig");
7476 _ = @import("behavior/ref_var_in_if_after_if_2nd_switch_prong.zig");
test/stage1/behavior/array.zig+8-2
......@@ -172,6 +172,12 @@ fn plusOne(x: u32) u32 {
172172 return x + 1;
173173}
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
175181test "array literal as argument to function" {
176182 const S = struct {
177183 fn entry(two: i32) void {
......@@ -227,7 +233,7 @@ test "double nested array to const slice cast in array literal" {
227233
228234 const cases2 = [_][]const i32{
229235 [_]i32{1},
230 [_]i32{ two, 3 },
236 &[_]i32{ two, 3 },
231237 };
232238 expect(cases2.len == 2);
233239 expect(cases2[0].len == 1);
......@@ -238,7 +244,7 @@ test "double nested array to const slice cast in array literal" {
238244
239245 const cases3 = [_][]const []const i32{
240246 [_][]const i32{[_]i32{1}},
241 [_][]const i32{[_]i32{ two, 3 }},
247 &[_][]const i32{&[_]i32{ two, 3 }},
242248 [_][]const i32{
243249 [_]i32{4},
244250 [_]i32{ 5, 6, 7 },
test/stage1/behavior/bitcast.zig+13
......@@ -112,3 +112,16 @@ test "bitcast packed struct to integer and back" {
112112 S.doTheTest();
113113 comptime S.doTheTest();
114114}
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" {
482482 S.doTheTest(0, 1, 0);
483483 comptime S.doTheTest(0, 1, 0);
484484}
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/defer.zig+17
......@@ -76,3 +76,20 @@ fn testNestedFnErrDefer() anyerror!void {
7676 };
7777 return S.baz();
7878}
79
80test "return variable while defer expression in scope to modify it" {
81 const S = struct {
82 fn doTheTest() void {
83 expect(notNull().? == 1);
84 }
85
86 fn notNull() ?u8 {
87 var res: ?u8 = 1;
88 defer res = null;
89 return res;
90 }
91 };
92
93 S.doTheTest();
94 comptime S.doTheTest();
95}
test/stage1/behavior/error.zig+40
......@@ -335,3 +335,43 @@ test "debug info for optional error set" {
335335 const SomeError = error{Hello};
336336 var a_local_variable: ?SomeError = null;
337337}
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 {
190190 }
191191}
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
193204fn max(comptime T: type, a: T, b: T) T {
194205 if (T == bool) {
195206 return a or b;
......@@ -756,8 +767,7 @@ test "comptime bitwise operators" {
756767test "*align(1) u16 is the same as *align(1:0:2) u16" {
757768 comptime {
758769 expect(*align(1:0:2) u16 == *align(1) u16);
759 // TODO add parsing support for this syntax
760 //expect(*align(:0:2) u16 == *u16);
770 expect(*align(:0:2) u16 == *u16);
761771 }
762772}
763773
test/stage1/behavior/floatop.zig created+243
......@@ -0,0 +1,243 @@
1const expect = @import("std").testing.expect;
2const pi = @import("std").math.pi;
3const e = @import("std").math.e;
4
5test "@sqrt" {
6 comptime testSqrt();
7 testSqrt();
8}
9
10fn testSqrt() void {
11 {
12 var a: f16 = 4;
13 expect(@sqrt(f16, a) == 2);
14 }
15 {
16 var a: f32 = 9;
17 expect(@sqrt(f32, a) == 3);
18 }
19 {
20 var a: f64 = 25;
21 expect(@sqrt(f64, a) == 5);
22 }
23 {
24 const a: comptime_float = 25.0;
25 expect(@sqrt(comptime_float, a) == 5.0);
26 }
27 // Waiting on a c.zig implementation
28 //{
29 // var a: f128 = 49;
30 // expect(@sqrt(f128, a) == 7);
31 //}
32}
33
34test "@sin" {
35 comptime testSin();
36 testSin();
37}
38
39fn testSin() void {
40 // TODO - this is actually useful and should be implemented
41 // (all the trig functions for f16)
42 // but will probably wait till self-hosted
43 //{
44 // var a: f16 = pi;
45 // expect(@sin(f16, a/2) == 1);
46 //}
47 {
48 var a: f32 = 0;
49 expect(@sin(f32, a) == 0);
50 }
51 {
52 var a: f64 = 0;
53 expect(@sin(f64, a) == 0);
54 }
55 // TODO
56 //{
57 // var a: f16 = pi;
58 // expect(@sqrt(f128, a/2) == 1);
59 //}
60}
61
62test "@cos" {
63 comptime testCos();
64 testCos();
65}
66
67fn testCos() void {
68 {
69 var a: f32 = 0;
70 expect(@cos(f32, a) == 1);
71 }
72 {
73 var a: f64 = 0;
74 expect(@cos(f64, a) == 1);
75 }
76}
77
78test "@exp" {
79 comptime testExp();
80 testExp();
81}
82
83fn testExp() void {
84 {
85 var a: f32 = 0;
86 expect(@exp(f32, a) == 1);
87 }
88 {
89 var a: f64 = 0;
90 expect(@exp(f64, a) == 1);
91 }
92}
93
94test "@exp2" {
95 comptime testExp2();
96 testExp2();
97}
98
99fn testExp2() void {
100 {
101 var a: f32 = 2;
102 expect(@exp2(f32, a) == 4);
103 }
104 {
105 var a: f64 = 2;
106 expect(@exp2(f64, a) == 4);
107 }
108}
109
110test "@ln" {
111 // Old musl (and glibc?), and our current math.ln implementation do not return 1
112 // so also accept those values.
113 comptime testLn();
114 testLn();
115}
116
117fn testLn() void {
118 {
119 var a: f32 = e;
120 expect(@ln(f32, a) == 1 or @ln(f32, a) == @bitCast(f32, u32(0x3f7fffff)));
121 }
122 {
123 var a: f64 = e;
124 expect(@ln(f64, a) == 1 or @ln(f64, a) == @bitCast(f64, u64(0x3ff0000000000000)));
125 }
126}
127
128test "@log2" {
129 comptime testLog2();
130 testLog2();
131}
132
133fn testLog2() void {
134 {
135 var a: f32 = 4;
136 expect(@log2(f32, a) == 2);
137 }
138 {
139 var a: f64 = 4;
140 expect(@log2(f64, a) == 2);
141 }
142}
143
144test "@log10" {
145 comptime testLog10();
146 testLog10();
147}
148
149fn testLog10() void {
150 {
151 var a: f32 = 100;
152 expect(@log10(f32, a) == 2);
153 }
154 {
155 var a: f64 = 1000;
156 expect(@log10(f64, a) == 3);
157 }
158}
159
160test "@fabs" {
161 comptime testFabs();
162 testFabs();
163}
164
165fn testFabs() void {
166 {
167 var a: f32 = -2.5;
168 var b: f32 = 2.5;
169 expect(@fabs(f32, a) == 2.5);
170 expect(@fabs(f32, b) == 2.5);
171 }
172 {
173 var a: f64 = -2.5;
174 var b: f64 = 2.5;
175 expect(@fabs(f64, a) == 2.5);
176 expect(@fabs(f64, b) == 2.5);
177 }
178}
179
180test "@floor" {
181 comptime testFloor();
182 testFloor();
183}
184
185fn testFloor() void {
186 {
187 var a: f32 = 2.1;
188 expect(@floor(f32, a) == 2);
189 }
190 {
191 var a: f64 = 3.5;
192 expect(@floor(f64, a) == 3);
193 }
194}
195
196test "@ceil" {
197 comptime testCeil();
198 testCeil();
199}
200
201fn testCeil() void {
202 {
203 var a: f32 = 2.1;
204 expect(@ceil(f32, a) == 3);
205 }
206 {
207 var a: f64 = 3.5;
208 expect(@ceil(f64, a) == 4);
209 }
210}
211
212test "@trunc" {
213 comptime testTrunc();
214 testTrunc();
215}
216
217fn testTrunc() void {
218 {
219 var a: f32 = 2.1;
220 expect(@trunc(f32, a) == 2);
221 }
222 {
223 var a: f64 = -3.5;
224 expect(@trunc(f64, a) == -3);
225 }
226}
227
228// This is waiting on library support for the Windows build (not sure why the other's don't need it)
229//test "@nearbyInt" {
230// comptime testNearbyInt();
231// testNearbyInt();
232//}
233
234//fn testNearbyInt() void {
235// {
236// var a: f32 = 2.1;
237// expect(@nearbyInt(f32, a) == 2);
238// }
239// {
240// var a: f64 = -3.75;
241// expect(@nearbyInt(f64, a) == -4);
242// }
243//}
test/stage1/behavior/fn.zig+23
......@@ -205,3 +205,26 @@ test "extern struct with stdcallcc fn pointer" {
205205 s.ptr = S.foo;
206206 expect(s.ptr() == 1234);
207207}
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+32
......@@ -110,3 +110,35 @@ fn testContinueOuter() void {
110110 }
111111 expect(counter == array.len);
112112}
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}
129
130test "for with null and T peer types and inferred result location type" {
131 const S = struct {
132 fn doTheTest(slice: []const u8) void {
133 if (for (slice) |item| {
134 if (item == 10) {
135 break item;
136 }
137 } else null) |v| {
138 @panic("fail");
139 }
140 }
141 };
142 S.doTheTest([_]u8{ 1, 2 });
143 comptime S.doTheTest([_]u8{ 1, 2 });
144}
test/stage1/behavior/if.zig+11
......@@ -52,3 +52,14 @@ test "unwrap mutable global var" {
5252 expect(e == error.SomeError);
5353 }
5454}
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" {
698698 var a: u24 = '\U01f4a9';
699699 expect(a == 128169);
700700}
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/muladd.zig created+34
......@@ -0,0 +1,34 @@
1const expect = @import("std").testing.expect;
2
3test "@mulAdd" {
4 comptime testMulAdd();
5 testMulAdd();
6}
7
8fn testMulAdd() void {
9 {
10 var a: f16 = 5.5;
11 var b: f16 = 2.5;
12 var c: f16 = 6.25;
13 expect(@mulAdd(f16, a, b, c) == 20);
14 }
15 {
16 var a: f32 = 5.5;
17 var b: f32 = 2.5;
18 var c: f32 = 6.25;
19 expect(@mulAdd(f32, a, b, c) == 20);
20 }
21 {
22 var a: f64 = 5.5;
23 var b: f64 = 2.5;
24 var c: f64 = 6.25;
25 expect(@mulAdd(f64, a, b, c) == 20);
26 }
27 // Awaits implementation in libm.zig
28 //{
29 // var a: f16 = 5.5;
30 // var b: f128 = 2.5;
31 // var c: f128 = 6.25;
32 // expect(@mulAdd(f128, a, b, c) == 20);
33 //}
34}
\ No newline at end of file
test/stage1/behavior/optional.zig+23-2
......@@ -76,6 +76,27 @@ test "unwrap function call with optional pointer return value" {
7676 }
7777 };
7878 S.entry();
79 // TODO https://github.com/ziglang/zig/issues/1901
80 //comptime S.entry();
79 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();
81102}
test/stage1/behavior/struct.zig+21
......@@ -578,3 +578,24 @@ test "default struct initialization fields" {
578578 };
579579 expectEqual(1239, x.a + x.b);
580580}
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+31
......@@ -360,3 +360,34 @@ test "switch prongs with error set cases make a new error set type for capture v
360360 S.doTheTest();
361361 comptime S.doTheTest();
362362}
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}
379
380test "switch with null and T peer types and inferred result location type" {
381 const S = struct {
382 fn doTheTest(c: u8) void {
383 if (switch (c) {
384 0 => true,
385 else => null,
386 }) |v| {
387 @panic("fail");
388 }
389 }
390 };
391 S.doTheTest(1);
392 comptime S.doTheTest(1);
393}
test/stage1/behavior/union.zig+20
......@@ -402,3 +402,23 @@ test "comptime union field value equality" {
402402 expect(a0 != a1);
403403 expect(b0 != b1);
404404}
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" {
6161 S.doTheTest();
6262 comptime S.doTheTest();
6363}
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 {
226226fn returnTrue() bool {
227227 return true;
228228}
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 {
811811 pub fn addCase(self: *CompileErrorContext, case: *const TestCase) void {
812812 const b = self.b;
813813
814 for (self.modes) |mode| {
815 const annotated_case_name = fmt.allocPrint(self.b.allocator, "compile-error {} ({})", case.name, @tagName(mode)) catch unreachable;
816 if (self.test_filter) |filter| {
817 if (mem.indexOf(u8, annotated_case_name, filter) == null) continue;
818 }
814 const annotated_case_name = fmt.allocPrint(self.b.allocator, "compile-error {}", case.name) catch unreachable;
815 if (self.test_filter) |filter| {
816 if (mem.indexOf(u8, annotated_case_name, filter) == null) return;
817 }
819818
820 const compile_and_cmp_errors = CompileCmpOutputStep.create(self, annotated_case_name, case, mode);
821 self.step.dependOn(&compile_and_cmp_errors.step);
819 const compile_and_cmp_errors = CompileCmpOutputStep.create(self, annotated_case_name, case, .Debug);
820 self.step.dependOn(&compile_and_cmp_errors.step);
822821
823 for (case.sources.toSliceConst()) |src_file| {
824 const expanded_src_path = fs.path.join(
825 b.allocator,
826 [_][]const u8{ b.cache_root, src_file.filename },
827 ) catch unreachable;
828 const write_src = b.addWriteFile(expanded_src_path, src_file.source);
829 compile_and_cmp_errors.step.dependOn(&write_src.step);
830 }
822 for (case.sources.toSliceConst()) |src_file| {
823 const expanded_src_path = fs.path.join(
824 b.allocator,
825 [_][]const u8{ b.cache_root, src_file.filename },
826 ) catch unreachable;
827 const write_src = b.addWriteFile(expanded_src_path, src_file.source);
828 compile_and_cmp_errors.step.dependOn(&write_src.step);
831829 }
832830 }
833831};