| author | |
| committer | |
| log | 822d29286bd39b7331970e1e641ad240e7b62aee |
| tree | 2dd08b9a7d8406e79af61d074d7172196ea0ec7a |
| parent | e81b21a0ea955422835fb42a14bfa2db6bd74146 |
where `@sizeOf(T) == N`.5 files changed, 65 insertions(+), 47 deletions(-)
src/Sema.zig+14-5| ... | @@ -11098,24 +11098,33 @@ fn zirPtrType(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air | ... | @@ -11098,24 +11098,33 @@ fn zirPtrType(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air |
| 11098 | break :blk try sema.resolveAlreadyCoercedInt(block, .unneeded, ref, u16); | 11098 | break :blk try sema.resolveAlreadyCoercedInt(block, .unneeded, ref, u16); |
| 11099 | } else 0; | 11099 | } else 0; |
| 11100 | 11100 | ||
| 11101 | const bit_end = if (inst_data.flags.has_bit_range) blk: { | 11101 | var host_size: u16 = if (inst_data.flags.has_bit_range) blk: { |
| 11102 | const ref = @intToEnum(Zir.Inst.Ref, sema.code.extra[extra_i]); | 11102 | const ref = @intToEnum(Zir.Inst.Ref, sema.code.extra[extra_i]); |
| 11103 | extra_i += 1; | 11103 | extra_i += 1; |
| 11104 | break :blk try sema.resolveAlreadyCoercedInt(block, .unneeded, ref, u16); | 11104 | break :blk try sema.resolveAlreadyCoercedInt(block, .unneeded, ref, u16); |
| 11105 | } else 0; | 11105 | } else 0; |
| 11106 | 11106 | ||
| 11107 | if (bit_end != 0 and bit_start >= bit_end * 8) | ||
| 11108 | return sema.fail(block, src, "bit offset starts after end of host integer", .{}); | ||
| 11109 | |||
| 11110 | const elem_type = try sema.resolveType(block, .unneeded, extra.data.elem_type); | 11107 | const elem_type = try sema.resolveType(block, .unneeded, extra.data.elem_type); |
| 11111 | 11108 | ||
| 11109 | if (host_size != 0) { | ||
| 11110 | if (bit_start >= host_size * 8) { | ||
| 11111 | return sema.fail(block, src, "bit offset starts after end of host integer", .{}); | ||
| 11112 | } | ||
| 11113 | const target = sema.mod.getTarget(); | ||
| 11114 | const elem_type_bits = elem_type.bitSize(target); | ||
| 11115 | if (host_size * 8 == elem_type_bits) { | ||
| 11116 | assert(bit_start == 0); | ||
| 11117 | host_size = 0; | ||
| 11118 | } | ||
| 11119 | } | ||
| 11120 | |||
| 11112 | const ty = try Type.ptr(sema.arena, .{ | 11121 | const ty = try Type.ptr(sema.arena, .{ |
| 11113 | .pointee_type = elem_type, | 11122 | .pointee_type = elem_type, |
| 11114 | .sentinel = sentinel, | 11123 | .sentinel = sentinel, |
| 11115 | .@"align" = abi_align, | 11124 | .@"align" = abi_align, |
| 11116 | .@"addrspace" = address_space, | 11125 | .@"addrspace" = address_space, |
| 11117 | .bit_offset = bit_start, | 11126 | .bit_offset = bit_start, |
| 11118 | .host_size = bit_end, | 11127 | .host_size = host_size, |
| 11119 | .mutable = inst_data.flags.is_mutable, | 11128 | .mutable = inst_data.flags.is_mutable, |
| 11120 | .@"allowzero" = inst_data.flags.is_allowzero or inst_data.size == .C, | 11129 | .@"allowzero" = inst_data.flags.is_allowzero or inst_data.size == .C, |
| 11121 | .@"volatile" = inst_data.flags.is_volatile, | 11130 | .@"volatile" = inst_data.flags.is_volatile, |
src/Zir.zig+1-1| ... | @@ -2423,7 +2423,7 @@ pub const Inst = struct { | ... | @@ -2423,7 +2423,7 @@ pub const Inst = struct { |
| 2423 | /// 1. align: Ref // if `has_align` flag is set | 2423 | /// 1. align: Ref // if `has_align` flag is set |
| 2424 | /// 2. address_space: Ref // if `has_addrspace` flag is set | 2424 | /// 2. address_space: Ref // if `has_addrspace` flag is set |
| 2425 | /// 3. bit_start: Ref // if `has_bit_range` flag is set | 2425 | /// 3. bit_start: Ref // if `has_bit_range` flag is set |
| 2426 | /// 4. bit_end: Ref // if `has_bit_range` flag is set | 2426 | /// 4. host_size: Ref // if `has_bit_range` flag is set |
| 2427 | pub const PtrType = struct { | 2427 | pub const PtrType = struct { |
| 2428 | elem_type: Ref, | 2428 | elem_type: Ref, |
| 2429 | }; | 2429 | }; |
test/behavior/eval.zig+15-41| ... | @@ -522,20 +522,12 @@ test "inlined loop has array literal with elided runtime scope on first iteratio | ... | @@ -522,20 +522,12 @@ test "inlined loop has array literal with elided runtime scope on first iteratio |
| 522 | } | 522 | } |
| 523 | } | 523 | } |
| 524 | 524 | ||
| 525 | test "eval @setFloatMode at compile-time" { | ||
| 526 | if (builtin.zig_backend != .stage1) return error.SkipZigTest; // TODO | ||
| 527 | |||
| 528 | const result = comptime fnWithFloatMode(); | ||
| 529 | try expect(result == 1234.0); | ||
| 530 | } | ||
| 531 | |||
| 532 | fn fnWithFloatMode() f32 { | ||
| 533 | @setFloatMode(std.builtin.FloatMode.Strict); | ||
| 534 | return 1234.0; | ||
| 535 | } | ||
| 536 | |||
| 537 | test "call method on bound fn referring to var instance" { | 525 | test "call method on bound fn referring to var instance" { |
| 538 | if (builtin.zig_backend != .stage1) return error.SkipZigTest; // TODO | 526 | if (builtin.zig_backend != .stage1) { |
| 527 | // Let's delay solving this one; I want to try to eliminate bound functions from | ||
| 528 | // the language. | ||
| 529 | return error.SkipZigTest; // TODO | ||
| 530 | } | ||
| 539 | 531 | ||
| 540 | try expect(bound_fn() == 1237); | 532 | try expect(bound_fn() == 1237); |
| 541 | } | 533 | } |
| ... | @@ -596,19 +588,6 @@ fn assertEqualPtrs(ptr1: *const u8, ptr2: *const u8) !void { | ... | @@ -596,19 +588,6 @@ fn assertEqualPtrs(ptr1: *const u8, ptr2: *const u8) !void { |
| 596 | try expect(ptr1 == ptr2); | 588 | try expect(ptr1 == ptr2); |
| 597 | } | 589 | } |
| 598 | 590 | ||
| 599 | test "float literal at compile time not lossy" { | ||
| 600 | if (builtin.zig_backend != .stage1) return error.SkipZigTest; // TODO | ||
| 601 | |||
| 602 | try expect(16777216.0 + 1.0 == 16777217.0); | ||
| 603 | try expect(9007199254740992.0 + 1.0 == 9007199254740993.0); | ||
| 604 | } | ||
| 605 | |||
| 606 | test "f128 at compile time is lossy" { | ||
| 607 | if (builtin.zig_backend != .stage1) return error.SkipZigTest; // TODO | ||
| 608 | |||
| 609 | try expect(@as(f128, 10384593717069655257060992658440192.0) + 1 == 10384593717069655257060992658440192.0); | ||
| 610 | } | ||
| 611 | |||
| 612 | test "string literal used as comptime slice is memoized" { | 591 | test "string literal used as comptime slice is memoized" { |
| 613 | if (builtin.zig_backend != .stage1) return error.SkipZigTest; // TODO | 592 | if (builtin.zig_backend != .stage1) return error.SkipZigTest; // TODO |
| 614 | 593 | ||
| ... | @@ -714,20 +693,7 @@ fn testVarInsideInlineLoop(args: anytype) !void { | ... | @@ -714,20 +693,7 @@ fn testVarInsideInlineLoop(args: anytype) !void { |
| 714 | } | 693 | } |
| 715 | } | 694 | } |
| 716 | 695 | ||
| 717 | test "bit shift a u1" { | ||
| 718 | // note: when debugging this test case for stage2, be sure to run it | ||
| 719 | // in valgrind. I noticed the rhs value is undefined in the lowering | ||
| 720 | // of the const value. | ||
| 721 | if (builtin.zig_backend != .stage1) return error.SkipZigTest; // TODO | ||
| 722 | |||
| 723 | var x: u1 = 1; | ||
| 724 | var y = x << 0; | ||
| 725 | try expect(y == 1); | ||
| 726 | } | ||
| 727 | |||
| 728 | test "*align(1) u16 is the same as *align(1:0:2) u16" { | 696 | test "*align(1) u16 is the same as *align(1:0:2) u16" { |
| 729 | if (builtin.zig_backend != .stage1) return error.SkipZigTest; // TODO | ||
| 730 | |||
| 731 | comptime { | 697 | comptime { |
| 732 | try expect(*align(1:0:2) u16 == *align(1) u16); | 698 | try expect(*align(1:0:2) u16 == *align(1) u16); |
| 733 | try expect(*align(2:0:2) u16 == *u16); | 699 | try expect(*align(2:0:2) u16 == *u16); |
| ... | @@ -735,14 +701,22 @@ test "*align(1) u16 is the same as *align(1:0:2) u16" { | ... | @@ -735,14 +701,22 @@ test "*align(1) u16 is the same as *align(1:0:2) u16" { |
| 735 | } | 701 | } |
| 736 | 702 | ||
| 737 | test "array concatenation forces comptime" { | 703 | test "array concatenation forces comptime" { |
| 738 | if (builtin.zig_backend != .stage1) return error.SkipZigTest; // TODO | 704 | if (builtin.zig_backend != .stage1) { |
| 705 | // note: our plan is to change the language to support runtime array | ||
| 706 | // concatenation instead of making this test pass. | ||
| 707 | return error.SkipZigTest; // TODO | ||
| 708 | } | ||
| 739 | 709 | ||
| 740 | var a = oneItem(3) ++ oneItem(4); | 710 | var a = oneItem(3) ++ oneItem(4); |
| 741 | try expect(std.mem.eql(i32, &a, &[_]i32{ 3, 4 })); | 711 | try expect(std.mem.eql(i32, &a, &[_]i32{ 3, 4 })); |
| 742 | } | 712 | } |
| 743 | 713 | ||
| 744 | test "array multiplication forces comptime" { | 714 | test "array multiplication forces comptime" { |
| 745 | if (builtin.zig_backend != .stage1) return error.SkipZigTest; // TODO | 715 | if (builtin.zig_backend != .stage1) { |
| 716 | // note: our plan is to change the language to support runtime array | ||
| 717 | // multiplication instead of making this test pass. | ||
| 718 | return error.SkipZigTest; // TODO | ||
| 719 | } | ||
| 746 | 720 | ||
| 747 | var a = oneItem(3) ** scalar(2); | 721 | var a = oneItem(3) ** scalar(2); |
| 748 | try expect(std.mem.eql(i32, &a, &[_]i32{ 3, 3 })); | 722 | try expect(std.mem.eql(i32, &a, &[_]i32{ 3, 3 })); |
test/behavior/floatop.zig+29| ... | @@ -466,3 +466,32 @@ test "negation" { | ... | @@ -466,3 +466,32 @@ test "negation" { |
| 466 | try S.doTheTest(); | 466 | try S.doTheTest(); |
| 467 | comptime try S.doTheTest(); | 467 | comptime try S.doTheTest(); |
| 468 | } | 468 | } |
| 469 | |||
| 470 | test "eval @setFloatMode at compile-time" { | ||
| 471 | if (builtin.zig_backend != .stage1) { | ||
| 472 | // let's delay solving this one; I want to re-evaluate this language feature, and | ||
| 473 | // we don't rely on it for self-hosted. | ||
| 474 | return error.SkipZigTest; // TODO | ||
| 475 | } | ||
| 476 | |||
| 477 | const result = comptime fnWithFloatMode(); | ||
| 478 | try expect(result == 1234.0); | ||
| 479 | } | ||
| 480 | |||
| 481 | fn fnWithFloatMode() f32 { | ||
| 482 | @setFloatMode(std.builtin.FloatMode.Strict); | ||
| 483 | return 1234.0; | ||
| 484 | } | ||
| 485 | |||
| 486 | test "float literal at compile time not lossy" { | ||
| 487 | if (builtin.zig_backend != .stage1) return error.SkipZigTest; // TODO | ||
| 488 | |||
| 489 | try expect(16777216.0 + 1.0 == 16777217.0); | ||
| 490 | try expect(9007199254740992.0 + 1.0 == 9007199254740993.0); | ||
| 491 | } | ||
| 492 | |||
| 493 | test "f128 at compile time is lossy" { | ||
| 494 | if (builtin.zig_backend != .stage1) return error.SkipZigTest; // TODO | ||
| 495 | |||
| 496 | try expect(@as(f128, 10384593717069655257060992658440192.0) + 1 == 10384593717069655257060992658440192.0); | ||
| 497 | } |
test/behavior/math.zig+6| ... | @@ -488,6 +488,12 @@ const DivResult = struct { | ... | @@ -488,6 +488,12 @@ const DivResult = struct { |
| 488 | remainder: u64, | 488 | remainder: u64, |
| 489 | }; | 489 | }; |
| 490 | 490 | ||
| 491 | test "bit shift a u1" { | ||
| 492 | var x: u1 = 1; | ||
| 493 | var y = x << 0; | ||
| 494 | try expect(y == 1); | ||
| 495 | } | ||
| 496 | |||
| 491 | test "truncating shift right" { | 497 | test "truncating shift right" { |
| 492 | try testShrTrunc(maxInt(u16)); | 498 | try testShrTrunc(maxInt(u16)); |
| 493 | comptime try testShrTrunc(maxInt(u16)); | 499 | comptime try testShrTrunc(maxInt(u16)); |