authorgravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2022-02-26 15:19:13-07:00
committergravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2022-02-26 16:50:35-07:00
log822d29286bd39b7331970e1e641ad240e7b62aee
tree2dd08b9a7d8406e79af61d074d7172196ea0ec7a
parente81b21a0ea955422835fb42a14bfa2db6bd74146

Sema: make `align(a) T` same as `align(a:0:N) T`

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;
1110011100
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;
1110611106
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);
1111111108
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 set2423 /// 1. align: Ref // if `has_align` flag is set
2424 /// 2. address_space: Ref // if `has_addrspace` flag is set2424 /// 2. address_space: Ref // if `has_addrspace` flag is set
2425 /// 3. bit_start: Ref // if `has_bit_range` flag is set2425 /// 3. bit_start: Ref // if `has_bit_range` flag is set
2426 /// 4. bit_end: Ref // if `has_bit_range` flag is set2426 /// 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}
524524
525test "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
532fn fnWithFloatMode() f32 {
533 @setFloatMode(std.builtin.FloatMode.Strict);
534 return 1234.0;
535}
536
537test "call method on bound fn referring to var instance" {525test "call method on bound fn referring to var instance" {
538 if (builtin.zig_backend != .stage1) return error.SkipZigTest; // TODO526 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 }
539531
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}
598590
599test "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
606test "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
612test "string literal used as comptime slice is memoized" {591test "string literal used as comptime slice is memoized" {
613 if (builtin.zig_backend != .stage1) return error.SkipZigTest; // TODO592 if (builtin.zig_backend != .stage1) return error.SkipZigTest; // TODO
614593
...@@ -714,20 +693,7 @@ fn testVarInsideInlineLoop(args: anytype) !void {...@@ -714,20 +693,7 @@ fn testVarInsideInlineLoop(args: anytype) !void {
714 }693 }
715}694}
716695
717test "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
728test "*align(1) u16 is the same as *align(1:0:2) u16" {696test "*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}
736702
737test "array concatenation forces comptime" {703test "array concatenation forces comptime" {
738 if (builtin.zig_backend != .stage1) return error.SkipZigTest; // TODO704 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 }
739709
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}
743713
744test "array multiplication forces comptime" {714test "array multiplication forces comptime" {
745 if (builtin.zig_backend != .stage1) return error.SkipZigTest; // TODO715 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 }
746720
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
470test "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
481fn fnWithFloatMode() f32 {
482 @setFloatMode(std.builtin.FloatMode.Strict);
483 return 1234.0;
484}
485
486test "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
493test "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};
490490
491test "bit shift a u1" {
492 var x: u1 = 1;
493 var y = x << 0;
494 try expect(y == 1);
495}
496
491test "truncating shift right" {497test "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));