| author | |
| committer | |
| log | 7f604b6f48905faf0bbe1ad795b53aeb11332063 |
| tree | 578b321a86fad4e0a4f016f48df5753800a1cc9f |
| parent | 73827d2ea9a1275d2351b80fc357896793e7c9c6 |
| parent | 841b38aae8913972d12b08cf3e0e497be305efb1 |
| signature |
Misc fixes11 files changed, 150 insertions(+), 27 deletions(-)
lib/std/zig/tokenizer.zig+10-1| ... | @@ -1151,7 +1151,13 @@ pub const Tokenizer = struct { | ... | @@ -1151,7 +1151,13 @@ pub const Tokenizer = struct { |
| 1151 | }, | 1151 | }, |
| 1152 | }, | 1152 | }, |
| 1153 | .line_comment => switch (c) { | 1153 | .line_comment => switch (c) { |
| 1154 | 0 => break, | 1154 | 0 => { |
| 1155 | if (self.index != self.buffer.len) { | ||
| 1156 | result.tag = .invalid; | ||
| 1157 | self.index += 1; | ||
| 1158 | } | ||
| 1159 | break; | ||
| 1160 | }, | ||
| 1155 | '\n' => { | 1161 | '\n' => { |
| 1156 | state = .start; | 1162 | state = .start; |
| 1157 | result.loc.start = self.index + 1; | 1163 | result.loc.start = self.index + 1; |
| ... | @@ -1865,6 +1871,9 @@ test "null byte before eof" { | ... | @@ -1865,6 +1871,9 @@ test "null byte before eof" { |
| 1865 | try testTokenize("//\x00", &.{.invalid}); | 1871 | try testTokenize("//\x00", &.{.invalid}); |
| 1866 | try testTokenize("\\\\\x00", &.{ .multiline_string_literal_line, .invalid }); | 1872 | try testTokenize("\\\\\x00", &.{ .multiline_string_literal_line, .invalid }); |
| 1867 | try testTokenize("\x00", &.{.invalid}); | 1873 | try testTokenize("\x00", &.{.invalid}); |
| 1874 | try testTokenize("// NUL\x00\n", &.{.invalid}); | ||
| 1875 | try testTokenize("///\x00\n", &.{ .doc_comment, .invalid }); | ||
| 1876 | try testTokenize("/// NUL\x00\n", &.{ .doc_comment, .invalid }); | ||
| 1868 | } | 1877 | } |
| 1869 | 1878 | ||
| 1870 | fn testTokenize(source: [:0]const u8, expected_token_tags: []const Token.Tag) !void { | 1879 | fn testTokenize(source: [:0]const u8, expected_token_tags: []const Token.Tag) !void { |
src/AstGen.zig+21-4| ... | @@ -3341,6 +3341,9 @@ fn ptrType( | ... | @@ -3341,6 +3341,9 @@ fn ptrType( |
| 3341 | return gz.astgen.failTok(ptr_info.allowzero_token.?, "C pointers always allow address zero", .{}); | 3341 | return gz.astgen.failTok(ptr_info.allowzero_token.?, "C pointers always allow address zero", .{}); |
| 3342 | } | 3342 | } |
| 3343 | 3343 | ||
| 3344 | const source_offset = gz.astgen.source_offset; | ||
| 3345 | const source_line = gz.astgen.source_line; | ||
| 3346 | const source_column = gz.astgen.source_column; | ||
| 3344 | const elem_type = try typeExpr(gz, scope, ptr_info.ast.child_type); | 3347 | const elem_type = try typeExpr(gz, scope, ptr_info.ast.child_type); |
| 3345 | 3348 | ||
| 3346 | var sentinel_ref: Zir.Inst.Ref = .none; | 3349 | var sentinel_ref: Zir.Inst.Ref = .none; |
| ... | @@ -3351,17 +3354,31 @@ fn ptrType( | ... | @@ -3351,17 +3354,31 @@ fn ptrType( |
| 3351 | var trailing_count: u32 = 0; | 3354 | var trailing_count: u32 = 0; |
| 3352 | 3355 | ||
| 3353 | if (ptr_info.ast.sentinel != 0) { | 3356 | if (ptr_info.ast.sentinel != 0) { |
| 3357 | // These attributes can appear in any order and they all come before the | ||
| 3358 | // element type so we need to reset the source cursor before generating them. | ||
| 3359 | gz.astgen.source_offset = source_offset; | ||
| 3360 | gz.astgen.source_line = source_line; | ||
| 3361 | gz.astgen.source_column = source_column; | ||
| 3362 | |||
| 3354 | sentinel_ref = try comptimeExpr(gz, scope, .{ .rl = .{ .ty = elem_type } }, ptr_info.ast.sentinel); | 3363 | sentinel_ref = try comptimeExpr(gz, scope, .{ .rl = .{ .ty = elem_type } }, ptr_info.ast.sentinel); |
| 3355 | trailing_count += 1; | 3364 | trailing_count += 1; |
| 3356 | } | 3365 | } |
| 3357 | if (ptr_info.ast.align_node != 0) { | ||
| 3358 | align_ref = try expr(gz, scope, coerced_align_ri, ptr_info.ast.align_node); | ||
| 3359 | trailing_count += 1; | ||
| 3360 | } | ||
| 3361 | if (ptr_info.ast.addrspace_node != 0) { | 3366 | if (ptr_info.ast.addrspace_node != 0) { |
| 3367 | gz.astgen.source_offset = source_offset; | ||
| 3368 | gz.astgen.source_line = source_line; | ||
| 3369 | gz.astgen.source_column = source_column; | ||
| 3370 | |||
| 3362 | addrspace_ref = try expr(gz, scope, .{ .rl = .{ .ty = .address_space_type } }, ptr_info.ast.addrspace_node); | 3371 | addrspace_ref = try expr(gz, scope, .{ .rl = .{ .ty = .address_space_type } }, ptr_info.ast.addrspace_node); |
| 3363 | trailing_count += 1; | 3372 | trailing_count += 1; |
| 3364 | } | 3373 | } |
| 3374 | if (ptr_info.ast.align_node != 0) { | ||
| 3375 | gz.astgen.source_offset = source_offset; | ||
| 3376 | gz.astgen.source_line = source_line; | ||
| 3377 | gz.astgen.source_column = source_column; | ||
| 3378 | |||
| 3379 | align_ref = try expr(gz, scope, coerced_align_ri, ptr_info.ast.align_node); | ||
| 3380 | trailing_count += 1; | ||
| 3381 | } | ||
| 3365 | if (ptr_info.ast.bit_range_start != 0) { | 3382 | if (ptr_info.ast.bit_range_start != 0) { |
| 3366 | assert(ptr_info.ast.bit_range_end != 0); | 3383 | assert(ptr_info.ast.bit_range_end != 0); |
| 3367 | bit_start_ref = try expr(gz, scope, .{ .rl = .{ .coerced_ty = .u16_type } }, ptr_info.ast.bit_range_start); | 3384 | bit_start_ref = try expr(gz, scope, .{ .rl = .{ .coerced_ty = .u16_type } }, ptr_info.ast.bit_range_start); |
src/Sema.zig+22-3| ... | @@ -11288,6 +11288,7 @@ fn resolveSwitchItemVal( | ... | @@ -11288,6 +11288,7 @@ fn resolveSwitchItemVal( |
| 11288 | // Only if we know for sure we need to report a compile error do we resolve the | 11288 | // Only if we know for sure we need to report a compile error do we resolve the |
| 11289 | // full source locations. | 11289 | // full source locations. |
| 11290 | if (sema.resolveConstValue(block, .unneeded, item, "")) |val| { | 11290 | if (sema.resolveConstValue(block, .unneeded, item, "")) |val| { |
| 11291 | try sema.resolveLazyValue(val); | ||
| 11291 | return TypedValue{ .ty = item_ty, .val = val }; | 11292 | return TypedValue{ .ty = item_ty, .val = val }; |
| 11292 | } else |err| switch (err) { | 11293 | } else |err| switch (err) { |
| 11293 | error.NeededSourceLocation => { | 11294 | error.NeededSourceLocation => { |
| ... | @@ -16258,6 +16259,7 @@ fn typeInfoNamespaceDecls( | ... | @@ -16258,6 +16259,7 @@ fn typeInfoNamespaceDecls( |
| 16258 | for (decls) |decl_index| { | 16259 | for (decls) |decl_index| { |
| 16259 | const decl = sema.mod.declPtr(decl_index); | 16260 | const decl = sema.mod.declPtr(decl_index); |
| 16260 | if (decl.kind == .@"usingnamespace") { | 16261 | if (decl.kind == .@"usingnamespace") { |
| 16262 | if (decl.analysis == .in_progress) continue; | ||
| 16261 | try sema.mod.ensureDeclAnalyzed(decl_index); | 16263 | try sema.mod.ensureDeclAnalyzed(decl_index); |
| 16262 | var buf: Value.ToTypeBuffer = undefined; | 16264 | var buf: Value.ToTypeBuffer = undefined; |
| 16263 | const new_ns = decl.val.toType(&buf).getNamespace().?; | 16265 | const new_ns = decl.val.toType(&buf).getNamespace().?; |
| ... | @@ -24820,8 +24822,13 @@ fn coerceExtra( | ... | @@ -24820,8 +24822,13 @@ fn coerceExtra( |
| 24820 | // empty tuple to zero-length slice | 24822 | // empty tuple to zero-length slice |
| 24821 | // note that this allows coercing to a mutable slice. | 24823 | // note that this allows coercing to a mutable slice. |
| 24822 | if (inst_child_ty.structFieldCount() == 0) { | 24824 | if (inst_child_ty.structFieldCount() == 0) { |
| 24825 | // Optional slice is represented with a null pointer so | ||
| 24826 | // we use a dummy pointer value with the required alignment. | ||
| 24823 | const slice_val = try Value.Tag.slice.create(sema.arena, .{ | 24827 | const slice_val = try Value.Tag.slice.create(sema.arena, .{ |
| 24824 | .ptr = Value.undef, | 24828 | .ptr = if (dest_info.@"align" != 0) |
| 24829 | try Value.Tag.int_u64.create(sema.arena, dest_info.@"align") | ||
| 24830 | else | ||
| 24831 | try inst_child_ty.lazyAbiAlignment(target, sema.arena), | ||
| 24825 | .len = Value.zero, | 24832 | .len = Value.zero, |
| 24826 | }); | 24833 | }); |
| 24827 | return sema.addConstant(dest_ty, slice_val); | 24834 | return sema.addConstant(dest_ty, slice_val); |
| ... | @@ -26065,7 +26072,8 @@ fn coerceVarArgParam( | ... | @@ -26065,7 +26072,8 @@ fn coerceVarArgParam( |
| 26065 | ) !Air.Inst.Ref { | 26072 | ) !Air.Inst.Ref { |
| 26066 | if (block.is_typeof) return inst; | 26073 | if (block.is_typeof) return inst; |
| 26067 | 26074 | ||
| 26068 | const coerced = switch (sema.typeOf(inst).zigTypeTag()) { | 26075 | const uncasted_ty = sema.typeOf(inst); |
| 26076 | const coerced = switch (uncasted_ty.zigTypeTag()) { | ||
| 26069 | // TODO consider casting to c_int/f64 if they fit | 26077 | // TODO consider casting to c_int/f64 if they fit |
| 26070 | .ComptimeInt, .ComptimeFloat => return sema.fail( | 26078 | .ComptimeInt, .ComptimeFloat => return sema.fail( |
| 26071 | block, | 26079 | block, |
| ... | @@ -26079,6 +26087,17 @@ fn coerceVarArgParam( | ... | @@ -26079,6 +26087,17 @@ fn coerceVarArgParam( |
| 26079 | break :blk try sema.analyzeDeclRef(fn_decl); | 26087 | break :blk try sema.analyzeDeclRef(fn_decl); |
| 26080 | }, | 26088 | }, |
| 26081 | .Array => return sema.fail(block, inst_src, "arrays must be passed by reference to variadic function", .{}), | 26089 | .Array => return sema.fail(block, inst_src, "arrays must be passed by reference to variadic function", .{}), |
| 26090 | .Float => float: { | ||
| 26091 | const target = sema.mod.getTarget(); | ||
| 26092 | const double_bits = @import("type.zig").CType.sizeInBits(.double, target); | ||
| 26093 | const inst_bits = uncasted_ty.floatBits(sema.mod.getTarget()); | ||
| 26094 | if (inst_bits >= double_bits) break :float inst; | ||
| 26095 | switch (double_bits) { | ||
| 26096 | 32 => break :float try sema.coerce(block, Type.f32, inst, inst_src), | ||
| 26097 | 64 => break :float try sema.coerce(block, Type.f64, inst, inst_src), | ||
| 26098 | else => unreachable, | ||
| 26099 | } | ||
| 26100 | }, | ||
| 26082 | else => inst, | 26101 | else => inst, |
| 26083 | }; | 26102 | }; |
| 26084 | 26103 | ||
| ... | @@ -27316,7 +27335,7 @@ fn coerceCompatiblePtrs( | ... | @@ -27316,7 +27335,7 @@ fn coerceCompatiblePtrs( |
| 27316 | return sema.addConstant(dest_ty, val); | 27335 | return sema.addConstant(dest_ty, val); |
| 27317 | } | 27336 | } |
| 27318 | try sema.requireRuntimeBlock(block, inst_src, null); | 27337 | try sema.requireRuntimeBlock(block, inst_src, null); |
| 27319 | const inst_allows_zero = (inst_ty.zigTypeTag() == .Pointer and inst_ty.ptrAllowsZero()) or true; | 27338 | const inst_allows_zero = inst_ty.zigTypeTag() != .Pointer or inst_ty.ptrAllowsZero(); |
| 27320 | if (block.wantSafety() and inst_allows_zero and !dest_ty.ptrAllowsZero() and | 27339 | if (block.wantSafety() and inst_allows_zero and !dest_ty.ptrAllowsZero() and |
| 27321 | try sema.typeHasRuntimeBits(dest_ty.elemType2())) | 27340 | try sema.typeHasRuntimeBits(dest_ty.elemType2())) |
| 27322 | { | 27341 | { |
src/codegen/llvm.zig+9-9| ... | @@ -3370,7 +3370,7 @@ pub const DeclGen = struct { | ... | @@ -3370,7 +3370,7 @@ pub const DeclGen = struct { |
| 3370 | return llvm_int.constIntToPtr(try dg.lowerType(tv.ty)); | 3370 | return llvm_int.constIntToPtr(try dg.lowerType(tv.ty)); |
| 3371 | }, | 3371 | }, |
| 3372 | .field_ptr, .opt_payload_ptr, .eu_payload_ptr, .elem_ptr => { | 3372 | .field_ptr, .opt_payload_ptr, .eu_payload_ptr, .elem_ptr => { |
| 3373 | return dg.lowerParentPtr(tv.val); | 3373 | return dg.lowerParentPtr(tv.val, tv.ty.ptrInfo().data.bit_offset % 8 == 0); |
| 3374 | }, | 3374 | }, |
| 3375 | .null_value, .zero => { | 3375 | .null_value, .zero => { |
| 3376 | const llvm_type = try dg.lowerType(tv.ty); | 3376 | const llvm_type = try dg.lowerType(tv.ty); |
| ... | @@ -3378,7 +3378,7 @@ pub const DeclGen = struct { | ... | @@ -3378,7 +3378,7 @@ pub const DeclGen = struct { |
| 3378 | }, | 3378 | }, |
| 3379 | .opt_payload => { | 3379 | .opt_payload => { |
| 3380 | const payload = tv.val.castTag(.opt_payload).?.data; | 3380 | const payload = tv.val.castTag(.opt_payload).?.data; |
| 3381 | return dg.lowerParentPtr(payload); | 3381 | return dg.lowerParentPtr(payload, tv.ty.ptrInfo().data.bit_offset % 8 == 0); |
| 3382 | }, | 3382 | }, |
| 3383 | else => |tag| return dg.todo("implement const of pointer type '{}' ({})", .{ | 3383 | else => |tag| return dg.todo("implement const of pointer type '{}' ({})", .{ |
| 3384 | tv.ty.fmtDebug(), tag, | 3384 | tv.ty.fmtDebug(), tag, |
| ... | @@ -3967,7 +3967,7 @@ pub const DeclGen = struct { | ... | @@ -3967,7 +3967,7 @@ pub const DeclGen = struct { |
| 3967 | return try dg.lowerDeclRefValue(.{ .ty = ptr_ty, .val = ptr_val }, decl_index); | 3967 | return try dg.lowerDeclRefValue(.{ .ty = ptr_ty, .val = ptr_val }, decl_index); |
| 3968 | } | 3968 | } |
| 3969 | 3969 | ||
| 3970 | fn lowerParentPtr(dg: *DeclGen, ptr_val: Value) Error!*llvm.Value { | 3970 | fn lowerParentPtr(dg: *DeclGen, ptr_val: Value, byte_aligned: bool) Error!*llvm.Value { |
| 3971 | const target = dg.module.getTarget(); | 3971 | const target = dg.module.getTarget(); |
| 3972 | switch (ptr_val.tag()) { | 3972 | switch (ptr_val.tag()) { |
| 3973 | .decl_ref_mut => { | 3973 | .decl_ref_mut => { |
| ... | @@ -3996,7 +3996,7 @@ pub const DeclGen = struct { | ... | @@ -3996,7 +3996,7 @@ pub const DeclGen = struct { |
| 3996 | }, | 3996 | }, |
| 3997 | .field_ptr => { | 3997 | .field_ptr => { |
| 3998 | const field_ptr = ptr_val.castTag(.field_ptr).?.data; | 3998 | const field_ptr = ptr_val.castTag(.field_ptr).?.data; |
| 3999 | const parent_llvm_ptr = try dg.lowerParentPtr(field_ptr.container_ptr); | 3999 | const parent_llvm_ptr = try dg.lowerParentPtr(field_ptr.container_ptr, byte_aligned); |
| 4000 | const parent_ty = field_ptr.container_ty; | 4000 | const parent_ty = field_ptr.container_ty; |
| 4001 | 4001 | ||
| 4002 | const field_index = @intCast(u32, field_ptr.field_index); | 4002 | const field_index = @intCast(u32, field_ptr.field_index); |
| ... | @@ -4026,6 +4026,7 @@ pub const DeclGen = struct { | ... | @@ -4026,6 +4026,7 @@ pub const DeclGen = struct { |
| 4026 | }, | 4026 | }, |
| 4027 | .Struct => { | 4027 | .Struct => { |
| 4028 | if (parent_ty.containerLayout() == .Packed) { | 4028 | if (parent_ty.containerLayout() == .Packed) { |
| 4029 | if (!byte_aligned) return parent_llvm_ptr; | ||
| 4029 | const llvm_usize = dg.context.intType(target.cpu.arch.ptrBitWidth()); | 4030 | const llvm_usize = dg.context.intType(target.cpu.arch.ptrBitWidth()); |
| 4030 | const base_addr = parent_llvm_ptr.constPtrToInt(llvm_usize); | 4031 | const base_addr = parent_llvm_ptr.constPtrToInt(llvm_usize); |
| 4031 | // count bits of fields before this one | 4032 | // count bits of fields before this one |
| ... | @@ -4072,7 +4073,7 @@ pub const DeclGen = struct { | ... | @@ -4072,7 +4073,7 @@ pub const DeclGen = struct { |
| 4072 | }, | 4073 | }, |
| 4073 | .elem_ptr => { | 4074 | .elem_ptr => { |
| 4074 | const elem_ptr = ptr_val.castTag(.elem_ptr).?.data; | 4075 | const elem_ptr = ptr_val.castTag(.elem_ptr).?.data; |
| 4075 | const parent_llvm_ptr = try dg.lowerParentPtr(elem_ptr.array_ptr); | 4076 | const parent_llvm_ptr = try dg.lowerParentPtr(elem_ptr.array_ptr, true); |
| 4076 | 4077 | ||
| 4077 | const llvm_usize = try dg.lowerType(Type.usize); | 4078 | const llvm_usize = try dg.lowerType(Type.usize); |
| 4078 | const indices: [1]*llvm.Value = .{ | 4079 | const indices: [1]*llvm.Value = .{ |
| ... | @@ -4083,7 +4084,7 @@ pub const DeclGen = struct { | ... | @@ -4083,7 +4084,7 @@ pub const DeclGen = struct { |
| 4083 | }, | 4084 | }, |
| 4084 | .opt_payload_ptr => { | 4085 | .opt_payload_ptr => { |
| 4085 | const opt_payload_ptr = ptr_val.castTag(.opt_payload_ptr).?.data; | 4086 | const opt_payload_ptr = ptr_val.castTag(.opt_payload_ptr).?.data; |
| 4086 | const parent_llvm_ptr = try dg.lowerParentPtr(opt_payload_ptr.container_ptr); | 4087 | const parent_llvm_ptr = try dg.lowerParentPtr(opt_payload_ptr.container_ptr, true); |
| 4087 | var buf: Type.Payload.ElemType = undefined; | 4088 | var buf: Type.Payload.ElemType = undefined; |
| 4088 | 4089 | ||
| 4089 | const payload_ty = opt_payload_ptr.container_ty.optionalChild(&buf); | 4090 | const payload_ty = opt_payload_ptr.container_ty.optionalChild(&buf); |
| ... | @@ -4105,7 +4106,7 @@ pub const DeclGen = struct { | ... | @@ -4105,7 +4106,7 @@ pub const DeclGen = struct { |
| 4105 | }, | 4106 | }, |
| 4106 | .eu_payload_ptr => { | 4107 | .eu_payload_ptr => { |
| 4107 | const eu_payload_ptr = ptr_val.castTag(.eu_payload_ptr).?.data; | 4108 | const eu_payload_ptr = ptr_val.castTag(.eu_payload_ptr).?.data; |
| 4108 | const parent_llvm_ptr = try dg.lowerParentPtr(eu_payload_ptr.container_ptr); | 4109 | const parent_llvm_ptr = try dg.lowerParentPtr(eu_payload_ptr.container_ptr, true); |
| 4109 | 4110 | ||
| 4110 | const payload_ty = eu_payload_ptr.container_ty.errorUnionPayload(); | 4111 | const payload_ty = eu_payload_ptr.container_ty.errorUnionPayload(); |
| 4111 | if (!payload_ty.hasRuntimeBitsIgnoreComptime()) { | 4112 | if (!payload_ty.hasRuntimeBitsIgnoreComptime()) { |
| ... | @@ -10667,8 +10668,7 @@ const ParamTypeIterator = struct { | ... | @@ -10667,8 +10668,7 @@ const ParamTypeIterator = struct { |
| 10667 | .memory => { | 10668 | .memory => { |
| 10668 | it.zig_index += 1; | 10669 | it.zig_index += 1; |
| 10669 | it.llvm_index += 1; | 10670 | it.llvm_index += 1; |
| 10670 | it.byval_attr = true; | 10671 | return .byref_mut; |
| 10671 | return .byref; | ||
| 10672 | }, | 10672 | }, |
| 10673 | .sse => { | 10673 | .sse => { |
| 10674 | it.zig_index += 1; | 10674 | it.zig_index += 1; |
test/behavior/packed-struct.zig+26| ... | @@ -599,3 +599,29 @@ test "packed struct initialized in bitcast" { | ... | @@ -599,3 +599,29 @@ test "packed struct initialized in bitcast" { |
| 599 | const t = @bitCast(u8, T{ .val = val }); | 599 | const t = @bitCast(u8, T{ .val = val }); |
| 600 | try expect(t == val); | 600 | try expect(t == val); |
| 601 | } | 601 | } |
| 602 | |||
| 603 | test "pointer to container level packed struct field" { | ||
| 604 | if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; | ||
| 605 | if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; | ||
| 606 | if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; | ||
| 607 | if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; | ||
| 608 | if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; | ||
| 609 | |||
| 610 | const S = packed struct(u32) { | ||
| 611 | test_bit: bool, | ||
| 612 | someother_data: u12, | ||
| 613 | other_test_bit: bool, | ||
| 614 | someother_more_different_data: u12, | ||
| 615 | other_bits: packed struct(u6) { | ||
| 616 | enable_1: bool, | ||
| 617 | enable_2: bool, | ||
| 618 | enable_3: bool, | ||
| 619 | enable_4: bool, | ||
| 620 | enable_5: bool, | ||
| 621 | enable_6: bool, | ||
| 622 | }, | ||
| 623 | var arr = [_]u32{0} ** 2; | ||
| 624 | }; | ||
| 625 | @ptrCast(*S, &S.arr[0]).other_bits.enable_3 = true; | ||
| 626 | try expect(S.arr[0] == 0x10000000); | ||
| 627 | } |
test/behavior/pointers.zig+10| ... | @@ -522,3 +522,13 @@ test "ptrToInt on a generic function" { | ... | @@ -522,3 +522,13 @@ test "ptrToInt on a generic function" { |
| 522 | }; | 522 | }; |
| 523 | try S.doTheTest(&S.generic); | 523 | try S.doTheTest(&S.generic); |
| 524 | } | 524 | } |
| 525 | |||
| 526 | test "pointer alignment and element type include call expression" { | ||
| 527 | const S = struct { | ||
| 528 | fn T() type { | ||
| 529 | return struct { _: i32 }; | ||
| 530 | } | ||
| 531 | const P = *align(@alignOf(T())) [@sizeOf(T())]u8; | ||
| 532 | }; | ||
| 533 | try expect(@alignOf(S.P) > 0); | ||
| 534 | } |
test/behavior/switch.zig+14| ... | @@ -686,3 +686,17 @@ test "enum value without tag name used as switch item" { | ... | @@ -686,3 +686,17 @@ test "enum value without tag name used as switch item" { |
| 686 | _ => return error.TestFailed, | 686 | _ => return error.TestFailed, |
| 687 | } | 687 | } |
| 688 | } | 688 | } |
| 689 | |||
| 690 | test "switch item sizeof" { | ||
| 691 | const S = struct { | ||
| 692 | fn doTheTest() !void { | ||
| 693 | var a: usize = 0; | ||
| 694 | switch (a) { | ||
| 695 | @sizeOf(struct {}) => {}, | ||
| 696 | else => return error.TestFailed, | ||
| 697 | } | ||
| 698 | } | ||
| 699 | }; | ||
| 700 | try S.doTheTest(); | ||
| 701 | comptime try S.doTheTest(); | ||
| 702 | } |
test/behavior/type_info.zig+13| ... | @@ -590,3 +590,16 @@ test "@typeInfo decls and usingnamespace" { | ... | @@ -590,3 +590,16 @@ test "@typeInfo decls and usingnamespace" { |
| 590 | try expectEqualStrings(decls[1].name, "y"); | 590 | try expectEqualStrings(decls[1].name, "y"); |
| 591 | try expectEqualStrings(decls[2].name, "z"); | 591 | try expectEqualStrings(decls[2].name, "z"); |
| 592 | } | 592 | } |
| 593 | |||
| 594 | test "@typeInfo decls ignore dependency loops" { | ||
| 595 | const S = struct { | ||
| 596 | fn Def(comptime T: type) type { | ||
| 597 | std.debug.assert(@typeInfo(T).Struct.decls.len == 1); | ||
| 598 | return struct { | ||
| 599 | const foo = u32; | ||
| 600 | }; | ||
| 601 | } | ||
| 602 | usingnamespace Def(@This()); | ||
| 603 | }; | ||
| 604 | _ = S.foo; | ||
| 605 | } |
test/c_abi/main.zig-1| ... | @@ -1032,7 +1032,6 @@ extern fn c_modify_by_ref_param(ByRef) ByRef; | ... | @@ -1032,7 +1032,6 @@ extern fn c_modify_by_ref_param(ByRef) ByRef; |
| 1032 | 1032 | ||
| 1033 | test "C function modifies by ref param" { | 1033 | test "C function modifies by ref param" { |
| 1034 | if (comptime builtin.cpu.arch.isPPC()) return error.SkipZigTest; | 1034 | if (comptime builtin.cpu.arch.isPPC()) return error.SkipZigTest; |
| 1035 | if (builtin.cpu.arch == .x86_64 and builtin.os.tag == .windows and builtin.mode != .Debug) return error.SkipZigTest; | ||
| 1036 | 1035 | ||
| 1037 | const res = c_modify_by_ref_param(.{ .val = 1, .arr = undefined }); | 1036 | const res = c_modify_by_ref_param(.{ .val = 1, .arr = undefined }); |
| 1038 | try expect(res.val == 42); | 1037 | try expect(res.val == 42); |
test/cases/compile_errors/invalid_store_to_comptime_field.zig+10-9| ... | @@ -44,15 +44,15 @@ pub export fn entry5() void { | ... | @@ -44,15 +44,15 @@ pub export fn entry5() void { |
| 44 | comptime var y = .{ 1, 2 }; | 44 | comptime var y = .{ 1, 2 }; |
| 45 | y = .{ 3, 4 }; | 45 | y = .{ 3, 4 }; |
| 46 | } | 46 | } |
| 47 | // pub export fn entry5() void { | ||
| 48 | // var x: u32 = 15; | ||
| 49 | // const T = @TypeOf(.{ @as(i32, -1234), @as(u32, 5678), x }); | ||
| 50 | // const S = struct { | ||
| 51 | // fn foo(_: T) void {} | ||
| 52 | // }; | ||
| 53 | // _ = S.foo(.{ -1234, 5679, x }); | ||
| 54 | // } | ||
| 55 | pub export fn entry6() void { | 47 | pub export fn entry6() void { |
| 48 | var x: u32 = 15; | ||
| 49 | const T = @TypeOf(.{ @as(i32, -1234), @as(u32, 5678), x }); | ||
| 50 | const S = struct { | ||
| 51 | fn foo(_: T) void {} | ||
| 52 | }; | ||
| 53 | _ = S.foo(.{ -1234, 5679, x }); | ||
| 54 | } | ||
| 55 | pub export fn entry7() void { | ||
| 56 | const State = struct { | 56 | const State = struct { |
| 57 | comptime id: bool = true, | 57 | comptime id: bool = true, |
| 58 | fn init(comptime id: bool) @This() { | 58 | fn init(comptime id: bool) @This() { |
| ... | @@ -61,7 +61,7 @@ pub export fn entry6() void { | ... | @@ -61,7 +61,7 @@ pub export fn entry6() void { |
| 61 | }; | 61 | }; |
| 62 | _ = State.init(false); | 62 | _ = State.init(false); |
| 63 | } | 63 | } |
| 64 | pub export fn entry7() void { | 64 | pub export fn entry8() void { |
| 65 | const list1 = .{ "sss", 1, 2, 3 }; | 65 | const list1 = .{ "sss", 1, 2, 3 }; |
| 66 | const list2 = @TypeOf(list1){ .@"0" = "xxx", .@"1" = 4, .@"2" = 5, .@"3" = 6 }; | 66 | const list2 = @TypeOf(list1){ .@"0" = "xxx", .@"1" = 4, .@"2" = 5, .@"3" = 6 }; |
| 67 | _ = list2; | 67 | _ = list2; |
| ... | @@ -73,6 +73,7 @@ pub export fn entry7() void { | ... | @@ -73,6 +73,7 @@ pub export fn entry7() void { |
| 73 | // | 73 | // |
| 74 | // :6:19: error: value stored in comptime field does not match the default value of the field | 74 | // :6:19: error: value stored in comptime field does not match the default value of the field |
| 75 | // :14:19: error: value stored in comptime field does not match the default value of the field | 75 | // :14:19: error: value stored in comptime field does not match the default value of the field |
| 76 | // :53:16: error: value stored in comptime field does not match the default value of the field | ||
| 76 | // :19:38: error: value stored in comptime field does not match the default value of the field | 77 | // :19:38: error: value stored in comptime field does not match the default value of the field |
| 77 | // :31:19: error: value stored in comptime field does not match the default value of the field | 78 | // :31:19: error: value stored in comptime field does not match the default value of the field |
| 78 | // :25:29: note: default value set here | 79 | // :25:29: note: default value set here |
test/cases/f32_passed_to_variadic_fn.zig created+15| ... | @@ -0,0 +1,15 @@ | ||
| 1 | extern fn printf(format: [*:0]const u8, ...) c_int; | ||
| 2 | pub fn main() void { | ||
| 3 | var a: f64 = 2.0; | ||
| 4 | var b: f32 = 10.0; | ||
| 5 | _ = printf("f64: %f\n", a); | ||
| 6 | _ = printf("f32: %f\n", b); | ||
| 7 | } | ||
| 8 | |||
| 9 | // run | ||
| 10 | // backend=llvm | ||
| 11 | // target=x86_64-linux-gnu | ||
| 12 | // | ||
| 13 | // f64: 2.000000 | ||
| 14 | // f32: 10.000000 | ||
| 15 | // | ||
| \ No newline at end of file | |||