| author | |
| committer | |
| log | f736cde397a6abb1399827ed5988c43001706580 |
| tree | c1ce080f82846a4322eac7be653a78044338e740 |
| parent | 017d3864de1f337d01726e87534a4e2093c7265f |
This involved an LLVM backend fix for the aggregate_init instruction.8 files changed, 80 insertions(+), 41 deletions(-)
src/Sema.zig+44-18| ... | @@ -16005,9 +16005,17 @@ fn coerce( | ... | @@ -16005,9 +16005,17 @@ fn coerce( |
| 16005 | return sema.coerceCompatiblePtrs(block, dest_ty, inst, inst_src); | 16005 | return sema.coerceCompatiblePtrs(block, dest_ty, inst, inst_src); |
| 16006 | } | 16006 | } |
| 16007 | 16007 | ||
| 16008 | // coercion to C pointer | 16008 | // cast from *T and [*]T to *anyopaque |
| 16009 | if (dest_info.size == .C) { | 16009 | // but don't do it if the source type is a double pointer |
| 16010 | switch (inst_ty.zigTypeTag()) { | 16010 | if (dest_info.pointee_type.tag() == .anyopaque and inst_ty.zigTypeTag() == .Pointer and |
| 16011 | inst_ty.childType().zigTypeTag() != .Pointer) | ||
| 16012 | { | ||
| 16013 | return sema.coerceCompatiblePtrs(block, dest_ty, inst, inst_src); | ||
| 16014 | } | ||
| 16015 | |||
| 16016 | switch (dest_info.size) { | ||
| 16017 | // coercion to C pointer | ||
| 16018 | .C => switch (inst_ty.zigTypeTag()) { | ||
| 16011 | .Null => { | 16019 | .Null => { |
| 16012 | return sema.addConstant(dest_ty, Value.@"null"); | 16020 | return sema.addConstant(dest_ty, Value.@"null"); |
| 16013 | }, | 16021 | }, |
| ... | @@ -16041,22 +16049,10 @@ fn coerce( | ... | @@ -16041,22 +16049,10 @@ fn coerce( |
| 16041 | return sema.coerceCompatiblePtrs(block, dest_ty, inst, inst_src); | 16049 | return sema.coerceCompatiblePtrs(block, dest_ty, inst, inst_src); |
| 16042 | }, | 16050 | }, |
| 16043 | else => {}, | 16051 | else => {}, |
| 16044 | } | 16052 | }, |
| 16045 | } | ||
| 16046 | |||
| 16047 | // cast from *T and [*]T to *anyopaque | ||
| 16048 | // but don't do it if the source type is a double pointer | ||
| 16049 | if (dest_info.pointee_type.tag() == .anyopaque and inst_ty.zigTypeTag() == .Pointer and | ||
| 16050 | inst_ty.childType().zigTypeTag() != .Pointer) | ||
| 16051 | { | ||
| 16052 | return sema.coerceCompatiblePtrs(block, dest_ty, inst, inst_src); | ||
| 16053 | } | ||
| 16054 | |||
| 16055 | switch (dest_info.size) { | ||
| 16056 | .C, .Many => {}, | ||
| 16057 | .One => switch (dest_info.pointee_type.zigTypeTag()) { | 16053 | .One => switch (dest_info.pointee_type.zigTypeTag()) { |
| 16058 | .Union => { | 16054 | .Union => { |
| 16059 | // cast from pointer to anonymous struct to pointer to union | 16055 | // pointer to anonymous struct to pointer to union |
| 16060 | if (inst_ty.isSinglePointer() and | 16056 | if (inst_ty.isSinglePointer() and |
| 16061 | inst_ty.childType().isAnonStruct() and | 16057 | inst_ty.childType().isAnonStruct() and |
| 16062 | !dest_info.mutable) | 16058 | !dest_info.mutable) |
| ... | @@ -16065,7 +16061,7 @@ fn coerce( | ... | @@ -16065,7 +16061,7 @@ fn coerce( |
| 16065 | } | 16061 | } |
| 16066 | }, | 16062 | }, |
| 16067 | .Struct => { | 16063 | .Struct => { |
| 16068 | // cast from pointer to anonymous struct to pointer to struct | 16064 | // pointer to anonymous struct to pointer to struct |
| 16069 | if (inst_ty.isSinglePointer() and | 16065 | if (inst_ty.isSinglePointer() and |
| 16070 | inst_ty.childType().isAnonStruct() and | 16066 | inst_ty.childType().isAnonStruct() and |
| 16071 | !dest_info.mutable) | 16067 | !dest_info.mutable) |
| ... | @@ -16073,6 +16069,15 @@ fn coerce( | ... | @@ -16073,6 +16069,15 @@ fn coerce( |
| 16073 | return sema.coerceAnonStructToStructPtrs(block, dest_ty, dest_ty_src, inst, inst_src); | 16069 | return sema.coerceAnonStructToStructPtrs(block, dest_ty, dest_ty_src, inst, inst_src); |
| 16074 | } | 16070 | } |
| 16075 | }, | 16071 | }, |
| 16072 | .Array => { | ||
| 16073 | // pointer to tuple to pointer to array | ||
| 16074 | if (inst_ty.isSinglePointer() and | ||
| 16075 | inst_ty.childType().isTuple() and | ||
| 16076 | !dest_info.mutable) | ||
| 16077 | { | ||
| 16078 | return sema.coerceTupleToArrayPtrs(block, dest_ty, dest_ty_src, inst, inst_src); | ||
| 16079 | } | ||
| 16080 | }, | ||
| 16076 | else => {}, | 16081 | else => {}, |
| 16077 | }, | 16082 | }, |
| 16078 | .Slice => { | 16083 | .Slice => { |
| ... | @@ -16084,6 +16089,7 @@ fn coerce( | ... | @@ -16084,6 +16089,7 @@ fn coerce( |
| 16084 | return sema.coerceTupleToSlicePtrs(block, dest_ty, dest_ty_src, inst, inst_src); | 16089 | return sema.coerceTupleToSlicePtrs(block, dest_ty, dest_ty_src, inst, inst_src); |
| 16085 | } | 16090 | } |
| 16086 | }, | 16091 | }, |
| 16092 | .Many => {}, | ||
| 16087 | } | 16093 | } |
| 16088 | 16094 | ||
| 16089 | // This will give an extra hint on top of what the bottom of this func would provide. | 16095 | // This will give an extra hint on top of what the bottom of this func would provide. |
| ... | @@ -17554,6 +17560,26 @@ fn coerceTupleToSlicePtrs( | ... | @@ -17554,6 +17560,26 @@ fn coerceTupleToSlicePtrs( |
| 17554 | return sema.coerceArrayPtrToSlice(block, slice_ty, ptr_array, slice_ty_src); | 17560 | return sema.coerceArrayPtrToSlice(block, slice_ty, ptr_array, slice_ty_src); |
| 17555 | } | 17561 | } |
| 17556 | 17562 | ||
| 17563 | /// If the lengths match, coerces element-wise. | ||
| 17564 | fn coerceTupleToArrayPtrs( | ||
| 17565 | sema: *Sema, | ||
| 17566 | block: *Block, | ||
| 17567 | ptr_array_ty: Type, | ||
| 17568 | array_ty_src: LazySrcLoc, | ||
| 17569 | ptr_tuple: Air.Inst.Ref, | ||
| 17570 | tuple_src: LazySrcLoc, | ||
| 17571 | ) !Air.Inst.Ref { | ||
| 17572 | const tuple = try sema.analyzeLoad(block, tuple_src, ptr_tuple, tuple_src); | ||
| 17573 | const ptr_info = ptr_array_ty.ptrInfo().data; | ||
| 17574 | const array_ty = ptr_info.pointee_type; | ||
| 17575 | const array_inst = try sema.coerceTupleToArray(block, array_ty, array_ty_src, tuple, tuple_src); | ||
| 17576 | if (ptr_info.@"align" != 0) { | ||
| 17577 | return sema.fail(block, array_ty_src, "TODO: override the alignment of the array decl we create here", .{}); | ||
| 17578 | } | ||
| 17579 | const ptr_array = try sema.analyzeRef(block, array_ty_src, array_inst); | ||
| 17580 | return ptr_array; | ||
| 17581 | } | ||
| 17582 | |||
| 17557 | /// Handles both tuples and anon struct literals. Coerces field-wise. Reports | 17583 | /// Handles both tuples and anon struct literals. Coerces field-wise. Reports |
| 17558 | /// errors for both extra fields and missing fields. | 17584 | /// errors for both extra fields and missing fields. |
| 17559 | fn coerceTupleToStruct( | 17585 | fn coerceTupleToStruct( |
src/codegen/llvm.zig+17-4| ... | @@ -5838,8 +5838,15 @@ pub const FuncGen = struct { | ... | @@ -5838,8 +5838,15 @@ pub const FuncGen = struct { |
| 5838 | const llvm_i = llvmFieldIndex(result_ty, i, target, &ptr_ty_buf).?; | 5838 | const llvm_i = llvmFieldIndex(result_ty, i, target, &ptr_ty_buf).?; |
| 5839 | indices[1] = llvm_u32.constInt(llvm_i, .False); | 5839 | indices[1] = llvm_u32.constInt(llvm_i, .False); |
| 5840 | const field_ptr = self.builder.buildInBoundsGEP(alloca_inst, &indices, indices.len, ""); | 5840 | const field_ptr = self.builder.buildInBoundsGEP(alloca_inst, &indices, indices.len, ""); |
| 5841 | const store_inst = self.builder.buildStore(llvm_elem, field_ptr); | 5841 | var field_ptr_payload: Type.Payload.Pointer = .{ |
| 5842 | store_inst.setAlignment(result_ty.structFieldAlign(i, target)); | 5842 | .data = .{ |
| 5843 | .pointee_type = self.air.typeOf(elem), | ||
| 5844 | .@"align" = result_ty.structFieldAlign(i, target), | ||
| 5845 | .@"addrspace" = .generic, | ||
| 5846 | }, | ||
| 5847 | }; | ||
| 5848 | const field_ptr_ty = Type.initPayload(&field_ptr_payload.base); | ||
| 5849 | self.store(field_ptr, field_ptr_ty, llvm_elem, .NotAtomic); | ||
| 5843 | } | 5850 | } |
| 5844 | 5851 | ||
| 5845 | return alloca_inst; | 5852 | return alloca_inst; |
| ... | @@ -5871,8 +5878,14 @@ pub const FuncGen = struct { | ... | @@ -5871,8 +5878,14 @@ pub const FuncGen = struct { |
| 5871 | }; | 5878 | }; |
| 5872 | const elem_ptr = self.builder.buildInBoundsGEP(alloca_inst, &indices, indices.len, ""); | 5879 | const elem_ptr = self.builder.buildInBoundsGEP(alloca_inst, &indices, indices.len, ""); |
| 5873 | const llvm_elem = try self.resolveInst(elem); | 5880 | const llvm_elem = try self.resolveInst(elem); |
| 5874 | const store_inst = self.builder.buildStore(llvm_elem, elem_ptr); | 5881 | var elem_ptr_payload: Type.Payload.Pointer = .{ |
| 5875 | store_inst.setAlignment(elem_ty.abiAlignment(target)); | 5882 | .data = .{ |
| 5883 | .pointee_type = elem_ty, | ||
| 5884 | .@"addrspace" = .generic, | ||
| 5885 | }, | ||
| 5886 | }; | ||
| 5887 | const elem_ptr_ty = Type.initPayload(&elem_ptr_payload.base); | ||
| 5888 | self.store(elem_ptr, elem_ptr_ty, llvm_elem, .NotAtomic); | ||
| 5876 | } | 5889 | } |
| 5877 | 5890 | ||
| 5878 | return alloca_inst; | 5891 | return alloca_inst; |
test/behavior/align.zig+4-6| ... | @@ -193,11 +193,9 @@ test "function alignment" { | ... | @@ -193,11 +193,9 @@ test "function alignment" { |
| 193 | } | 193 | } |
| 194 | 194 | ||
| 195 | test "implicitly decreasing fn alignment" { | 195 | test "implicitly decreasing fn alignment" { |
| 196 | if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; | ||
| 197 | if (builtin.zig_backend == .stage1) return error.SkipZigTest; | 196 | if (builtin.zig_backend == .stage1) return error.SkipZigTest; |
| 198 | if (builtin.zig_backend == .stage2_llvm) return error.SkipZigTest; | ||
| 199 | if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; | 197 | if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; |
| 200 | if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; | 198 | if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; |
| 201 | if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; | 199 | if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; |
| 202 | 200 | ||
| 203 | // function alignment is a compile error on wasm32/wasm64 | 201 | // function alignment is a compile error on wasm32/wasm64 |
| ... | @@ -321,7 +319,6 @@ const DefaultAligned = struct { | ... | @@ -321,7 +319,6 @@ const DefaultAligned = struct { |
| 321 | 319 | ||
| 322 | test "read 128-bit field from default aligned struct in stack memory" { | 320 | test "read 128-bit field from default aligned struct in stack memory" { |
| 323 | if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; | 321 | if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; |
| 324 | if (builtin.zig_backend == .stage2_llvm) return error.SkipZigTest; | ||
| 325 | if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; | 322 | if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; |
| 326 | if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; | 323 | if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; |
| 327 | if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; | 324 | if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; |
| ... | @@ -353,10 +350,10 @@ test "read 128-bit field from default aligned struct in global memory" { | ... | @@ -353,10 +350,10 @@ test "read 128-bit field from default aligned struct in global memory" { |
| 353 | 350 | ||
| 354 | test "struct field explicit alignment" { | 351 | test "struct field explicit alignment" { |
| 355 | if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; | 352 | if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; |
| 356 | if (builtin.zig_backend == .stage2_llvm) return error.SkipZigTest; | ||
| 357 | if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; | 353 | if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; |
| 358 | if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; | 354 | if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; |
| 359 | if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; | 355 | if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; |
| 356 | if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; | ||
| 360 | 357 | ||
| 361 | const S = struct { | 358 | const S = struct { |
| 362 | const Node = struct { | 359 | const Node = struct { |
| ... | @@ -402,8 +399,9 @@ test "align(@alignOf(T)) T does not force resolution of T" { | ... | @@ -402,8 +399,9 @@ test "align(@alignOf(T)) T does not force resolution of T" { |
| 402 | } | 399 | } |
| 403 | 400 | ||
| 404 | test "align(N) on functions" { | 401 | test "align(N) on functions" { |
| 405 | if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; | ||
| 406 | if (builtin.zig_backend == .stage1) return error.SkipZigTest; | 402 | if (builtin.zig_backend == .stage1) return error.SkipZigTest; |
| 403 | |||
| 404 | if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; | ||
| 407 | if (builtin.zig_backend == .stage2_llvm) return error.SkipZigTest; | 405 | if (builtin.zig_backend == .stage2_llvm) return error.SkipZigTest; |
| 408 | if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; | 406 | if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; |
| 409 | if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; | 407 | if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; |
test/behavior/array.zig+2-3| ... | @@ -553,12 +553,11 @@ test "type coercion of anon struct literal to array" { | ... | @@ -553,12 +553,11 @@ test "type coercion of anon struct literal to array" { |
| 553 | } | 553 | } |
| 554 | 554 | ||
| 555 | test "type coercion of pointer to anon struct literal to pointer to array" { | 555 | test "type coercion of pointer to anon struct literal to pointer to array" { |
| 556 | if (builtin.zig_backend == .stage2_llvm) return error.SkipZigTest; // TODO | ||
| 557 | if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO | ||
| 558 | if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO | 556 | if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO |
| 559 | if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; // TODO | 557 | if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; // TODO |
| 560 | if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO | 558 | if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO |
| 561 | if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO | 559 | if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO |
| 560 | if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO | ||
| 562 | 561 | ||
| 563 | const S = struct { | 562 | const S = struct { |
| 564 | const U = union { | 563 | const U = union { |
test/behavior/basic.zig+2-1| ... | @@ -760,7 +760,8 @@ test "pointer to thread local array" { | ... | @@ -760,7 +760,8 @@ test "pointer to thread local array" { |
| 760 | threadlocal var buffer: [11]u8 = undefined; | 760 | threadlocal var buffer: [11]u8 = undefined; |
| 761 | 761 | ||
| 762 | test "auto created variables have correct alignment" { | 762 | test "auto created variables have correct alignment" { |
| 763 | if (builtin.zig_backend != .stage1) return error.SkipZigTest; // TODO | 763 | if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO |
| 764 | if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO | ||
| 764 | 765 | ||
| 765 | const S = struct { | 766 | const S = struct { |
| 766 | fn foo(str: [*]const u8) u32 { | 767 | fn foo(str: [*]const u8) u32 { |
test/behavior/slice.zig+6-4| ... | @@ -518,7 +518,11 @@ test "slice syntax resulting in pointer-to-array" { | ... | @@ -518,7 +518,11 @@ test "slice syntax resulting in pointer-to-array" { |
| 518 | } | 518 | } |
| 519 | 519 | ||
| 520 | test "type coercion of pointer to anon struct literal to pointer to slice" { | 520 | test "type coercion of pointer to anon struct literal to pointer to slice" { |
| 521 | if (builtin.zig_backend != .stage1) return error.SkipZigTest; // TODO | 521 | if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO |
| 522 | if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; // TODO | ||
| 523 | if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO | ||
| 524 | if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO | ||
| 525 | if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO | ||
| 522 | 526 | ||
| 523 | const S = struct { | 527 | const S = struct { |
| 524 | const U = union { | 528 | const U = union { |
| ... | @@ -546,7 +550,7 @@ test "type coercion of pointer to anon struct literal to pointer to slice" { | ... | @@ -546,7 +550,7 @@ test "type coercion of pointer to anon struct literal to pointer to slice" { |
| 546 | try expect(mem.eql(u8, slice2[2], "world!")); | 550 | try expect(mem.eql(u8, slice2[2], "world!")); |
| 547 | } | 551 | } |
| 548 | }; | 552 | }; |
| 549 | // try S.doTheTest(); | 553 | try S.doTheTest(); |
| 550 | comptime try S.doTheTest(); | 554 | comptime try S.doTheTest(); |
| 551 | } | 555 | } |
| 552 | 556 | ||
| ... | @@ -578,8 +582,6 @@ test "slice bounds in comptime concatenation" { | ... | @@ -578,8 +582,6 @@ test "slice bounds in comptime concatenation" { |
| 578 | } | 582 | } |
| 579 | 583 | ||
| 580 | test "slice sentinel access at comptime" { | 584 | test "slice sentinel access at comptime" { |
| 581 | if (builtin.zig_backend != .stage1) return error.SkipZigTest; // TODO | ||
| 582 | |||
| 583 | { | 585 | { |
| 584 | const str0 = &[_:0]u8{ '1', '2', '3' }; | 586 | const str0 = &[_:0]u8{ '1', '2', '3' }; |
| 585 | const slice0: [:0]const u8 = str0; | 587 | const slice0: [:0]const u8 = str0; |
test/behavior/struct.zig+1-1| ... | @@ -426,7 +426,7 @@ test "packed struct 24bits" { | ... | @@ -426,7 +426,7 @@ test "packed struct 24bits" { |
| 426 | if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; // TODO | 426 | if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; // TODO |
| 427 | if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO | 427 | if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO |
| 428 | if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO | 428 | if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO |
| 429 | if (builtin.zig_backend == .stage2_llvm and builtin.stage2_arch == .wasm32) return error.SkipZigTest; // TODO | 429 | if (builtin.cpu.arch == .wasm32) return error.SkipZigTest; // TODO |
| 430 | 430 | ||
| 431 | comptime { | 431 | comptime { |
| 432 | try expect(@sizeOf(Foo24Bits) == 4); | 432 | try expect(@sizeOf(Foo24Bits) == 4); |
test/behavior/while.zig+4-4| ... | @@ -289,9 +289,8 @@ test "while bool 2 break statements and an else" { | ... | @@ -289,9 +289,8 @@ test "while bool 2 break statements and an else" { |
| 289 | } | 289 | } |
| 290 | 290 | ||
| 291 | test "while optional 2 break statements and an else" { | 291 | test "while optional 2 break statements and an else" { |
| 292 | if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; | 292 | if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO |
| 293 | if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; | 293 | if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO |
| 294 | if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; | ||
| 295 | 294 | ||
| 296 | const S = struct { | 295 | const S = struct { |
| 297 | fn entry(opt_t: ?bool, f: bool) !void { | 296 | fn entry(opt_t: ?bool, f: bool) !void { |
| ... | @@ -308,7 +307,8 @@ test "while optional 2 break statements and an else" { | ... | @@ -308,7 +307,8 @@ test "while optional 2 break statements and an else" { |
| 308 | } | 307 | } |
| 309 | 308 | ||
| 310 | test "while error 2 break statements and an else" { | 309 | test "while error 2 break statements and an else" { |
| 311 | if (@import("builtin").zig_backend != .stage1) return error.SkipZigTest; // TODO | 310 | if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO |
| 311 | if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO | ||
| 312 | 312 | ||
| 313 | const S = struct { | 313 | const S = struct { |
| 314 | fn entry(opt_t: anyerror!bool, f: bool) !void { | 314 | fn entry(opt_t: anyerror!bool, f: bool) !void { |