mirror of
https://github.com/ziglang/zig.git
synced 2025-12-25 23:53:15 +00:00
207 lines
5.7 KiB
Zig
207 lines
5.7 KiB
Zig
const std = @import("std");
|
|
const expect = std.testing.expect;
|
|
const builtin = @import("builtin");
|
|
const native_arch = builtin.target.cpu.arch;
|
|
|
|
var foo: u8 align(4) = 100;
|
|
|
|
test "global variable alignment" {
|
|
if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest;
|
|
|
|
comptime try expect(@typeInfo(@TypeOf(&foo)).Pointer.alignment == 4);
|
|
comptime try expect(@TypeOf(&foo) == *align(4) u8);
|
|
{
|
|
const slice = @as(*[1]u8, &foo)[0..];
|
|
comptime try expect(@TypeOf(slice) == *align(4) [1]u8);
|
|
}
|
|
{
|
|
var runtime_zero: usize = 0;
|
|
const slice = @as(*[1]u8, &foo)[runtime_zero..];
|
|
comptime try expect(@TypeOf(slice) == []align(4) u8);
|
|
}
|
|
}
|
|
|
|
test "default alignment allows unspecified in type syntax" {
|
|
if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest;
|
|
|
|
try expect(*u32 == *align(@alignOf(u32)) u32);
|
|
}
|
|
|
|
test "implicitly decreasing pointer alignment" {
|
|
if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest;
|
|
|
|
const a: u32 align(4) = 3;
|
|
const b: u32 align(8) = 4;
|
|
try expect(addUnaligned(&a, &b) == 7);
|
|
}
|
|
|
|
fn addUnaligned(a: *align(1) const u32, b: *align(1) const u32) u32 {
|
|
return a.* + b.*;
|
|
}
|
|
|
|
test "@alignCast pointers" {
|
|
if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest;
|
|
|
|
var x: u32 align(4) = 1;
|
|
expectsOnly1(&x);
|
|
try expect(x == 2);
|
|
}
|
|
fn expectsOnly1(x: *align(1) u32) void {
|
|
expects4(@alignCast(4, x));
|
|
}
|
|
fn expects4(x: *align(4) u32) void {
|
|
x.* += 1;
|
|
}
|
|
|
|
test "alignment of structs" {
|
|
if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest;
|
|
|
|
try expect(@alignOf(struct {
|
|
a: i32,
|
|
b: *i32,
|
|
}) == @alignOf(usize));
|
|
}
|
|
|
|
test "alignment of >= 128-bit integer type" {
|
|
if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest;
|
|
|
|
try expect(@alignOf(u128) == 16);
|
|
try expect(@alignOf(u129) == 16);
|
|
}
|
|
|
|
test "alignment of struct with 128-bit field" {
|
|
if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest;
|
|
|
|
try expect(@alignOf(struct {
|
|
x: u128,
|
|
}) == 16);
|
|
|
|
comptime {
|
|
try expect(@alignOf(struct {
|
|
x: u128,
|
|
}) == 16);
|
|
}
|
|
}
|
|
|
|
test "size of extern struct with 128-bit field" {
|
|
if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest;
|
|
|
|
try expect(@sizeOf(extern struct {
|
|
x: u128,
|
|
y: u8,
|
|
}) == 32);
|
|
|
|
comptime {
|
|
try expect(@sizeOf(extern struct {
|
|
x: u128,
|
|
y: u8,
|
|
}) == 32);
|
|
}
|
|
}
|
|
|
|
test "@ptrCast preserves alignment of bigger source" {
|
|
if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest;
|
|
|
|
var x: u32 align(16) = 1234;
|
|
const ptr = @ptrCast(*u8, &x);
|
|
try expect(@TypeOf(ptr) == *align(16) u8);
|
|
}
|
|
|
|
test "alignstack" {
|
|
if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest;
|
|
|
|
try expect(fnWithAlignedStack() == 1234);
|
|
}
|
|
|
|
fn fnWithAlignedStack() i32 {
|
|
@setAlignStack(256);
|
|
return 1234;
|
|
}
|
|
|
|
test "implicitly decreasing slice alignment" {
|
|
if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest;
|
|
|
|
const a: u32 align(4) = 3;
|
|
const b: u32 align(8) = 4;
|
|
try expect(addUnalignedSlice(@as(*const [1]u32, &a)[0..], @as(*const [1]u32, &b)[0..]) == 7);
|
|
}
|
|
fn addUnalignedSlice(a: []align(1) const u32, b: []align(1) const u32) u32 {
|
|
return a[0] + b[0];
|
|
}
|
|
|
|
test "specifying alignment allows pointer cast" {
|
|
if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest;
|
|
|
|
try testBytesAlign(0x33);
|
|
}
|
|
fn testBytesAlign(b: u8) !void {
|
|
var bytes align(4) = [_]u8{ b, b, b, b };
|
|
const ptr = @ptrCast(*u32, &bytes[0]);
|
|
try expect(ptr.* == 0x33333333);
|
|
}
|
|
|
|
test "@alignCast slices" {
|
|
if (builtin.zig_backend == .stage2_x86_64 or builtin.zig_backend == .stage2_arm) return error.SkipZigTest;
|
|
|
|
var array align(4) = [_]u32{ 1, 1 };
|
|
const slice = array[0..];
|
|
sliceExpectsOnly1(slice);
|
|
try expect(slice[0] == 2);
|
|
}
|
|
fn sliceExpectsOnly1(slice: []align(1) u32) void {
|
|
sliceExpects4(@alignCast(4, slice));
|
|
}
|
|
fn sliceExpects4(slice: []align(4) u32) void {
|
|
slice[0] += 1;
|
|
}
|
|
|
|
test "return error union with 128-bit integer" {
|
|
if (builtin.zig_backend == .stage2_x86_64 or builtin.zig_backend == .stage2_arm) return error.SkipZigTest;
|
|
|
|
try expect(3 == try give());
|
|
}
|
|
fn give() anyerror!u128 {
|
|
return 3;
|
|
}
|
|
|
|
test "page aligned array on stack" {
|
|
if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest;
|
|
if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest;
|
|
if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest;
|
|
|
|
// Large alignment value to make it hard to accidentally pass.
|
|
var array align(0x1000) = [_]u8{ 1, 2, 3, 4, 5, 6, 7, 8 };
|
|
var number1: u8 align(16) = 42;
|
|
var number2: u8 align(16) = 43;
|
|
|
|
try expect(@ptrToInt(&array[0]) & 0xFFF == 0);
|
|
try expect(array[3] == 4);
|
|
|
|
try expect(@truncate(u4, @ptrToInt(&number1)) == 0);
|
|
try expect(@truncate(u4, @ptrToInt(&number2)) == 0);
|
|
try expect(number1 == 42);
|
|
try expect(number2 == 43);
|
|
}
|
|
|
|
fn derp() align(@sizeOf(usize) * 2) i32 {
|
|
return 1234;
|
|
}
|
|
fn noop1() align(1) void {}
|
|
fn noop4() align(4) void {}
|
|
|
|
test "function alignment" {
|
|
if (builtin.zig_backend == .stage2_c) return error.SkipZigTest;
|
|
if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest;
|
|
if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest;
|
|
if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest;
|
|
|
|
// function alignment is a compile error on wasm32/wasm64
|
|
if (native_arch == .wasm32 or native_arch == .wasm64) return error.SkipZigTest;
|
|
|
|
try expect(derp() == 1234);
|
|
try expect(@TypeOf(noop1) == fn () align(1) void);
|
|
try expect(@TypeOf(noop4) == fn () align(4) void);
|
|
noop1();
|
|
noop4();
|
|
}
|