Merge branch 'master' into fbsd2

master
Marcio Giaxa 2018-12-23 23:21:59 -02:00
commit 773bf80133
19 changed files with 233 additions and 53 deletions

22
.builds/freebsd.yml Normal file
View File

@ -0,0 +1,22 @@
arch: x86_64
image: freebsd
packages:
- cmake
- ninja
- llvm70
sources:
- https://github.com/ziglang/zig.git
tasks:
- build: |
cd zig && mkdir build && cd build
cmake .. -GNinja -DCMAKE_BUILD_TYPE=Release
ninja install
- test: |
cd zig/build
bin/zig test ../test/behavior.zig
# TODO enable all tests
#bin/zig build --build-file ../build.zig test
# TODO integrate with the download page updater and make a
# static build available to download for FreeBSD.
# This will require setting up a cache of LLVM/Clang built
# statically.

View File

@ -165,7 +165,7 @@ const std = @import("std");
pub fn main() !void { pub fn main() !void {
// If this program is run without stdout attached, exit with an error. // If this program is run without stdout attached, exit with an error.
var stdout_file = try std.io.getStdOut(); const stdout_file = try std.io.getStdOut();
// If this program encounters pipe failure when printing to stdout, exit // If this program encounters pipe failure when printing to stdout, exit
// with an error. // with an error.
try stdout_file.write("Hello, world!\n"); try stdout_file.write("Hello, world!\n");

View File

@ -2,7 +2,7 @@ const std = @import("std");
pub fn main() !void { pub fn main() !void {
// If this program is run without stdout attached, exit with an error. // If this program is run without stdout attached, exit with an error.
var stdout_file = try std.io.getStdOut(); const stdout_file = try std.io.getStdOut();
// If this program encounters pipe failure when printing to stdout, exit // If this program encounters pipe failure when printing to stdout, exit
// with an error. // with an error.
try stdout_file.write("Hello, world!\n"); try stdout_file.write("Hello, world!\n");

View File

@ -300,6 +300,7 @@ pub const Compilation = struct {
UserResourceLimitReached, UserResourceLimitReached,
InvalidUtf8, InvalidUtf8,
BadPathName, BadPathName,
DeviceBusy,
}; };
pub const Event = union(enum) { pub const Event = union(enum) {

View File

@ -2681,39 +2681,50 @@ static Error resolve_struct_alignment(CodeGen *g, ZigType *struct_type) {
assert(decl_node->type == NodeTypeContainerDecl); assert(decl_node->type == NodeTypeContainerDecl);
assert(struct_type->di_type); assert(struct_type->di_type);
size_t field_count = struct_type->data.structure.src_field_count;
if (struct_type->data.structure.layout == ContainerLayoutPacked) { if (struct_type->data.structure.layout == ContainerLayoutPacked) {
struct_type->data.structure.abi_alignment = 1; struct_type->data.structure.abi_alignment = 1;
} for (size_t i = 0; i < field_count; i += 1) {
TypeStructField *field = &struct_type->data.structure.fields[i];
size_t field_count = struct_type->data.structure.src_field_count; if (field->type_entry != nullptr && type_is_invalid(field->type_entry)) {
for (size_t i = 0; i < field_count; i += 1) { struct_type->data.structure.resolve_status = ResolveStatusInvalid;
TypeStructField *field = &struct_type->data.structure.fields[i]; break;
}
// If this assertion trips, look up the call stack. Probably something is
// calling type_resolve with ResolveStatusAlignmentKnown when it should only
// be resolving ResolveStatusZeroBitsKnown
assert(field->type_entry != nullptr);
if (type_is_invalid(field->type_entry)) {
struct_type->data.structure.resolve_status = ResolveStatusInvalid;
break;
} }
} else for (size_t i = 0; i < field_count; i += 1) {
TypeStructField *field = &struct_type->data.structure.fields[i];
uint32_t this_field_align;
if (!type_has_bits(field->type_entry)) // TODO If we have no type_entry for the field, we've already failed to
continue; // compile the program correctly. This stage1 compiler needs a deeper
// reworking to make this correct, or we can ignore the problem
// and make sure it is fixed in stage2. This workaround is for when
// there is a false positive of a dependency loop, of alignment depending
// on itself. When this false positive happens we assume a pointer-aligned
// field, which is usually fine but could be incorrectly over-aligned or
// even under-aligned. See https://github.com/ziglang/zig/issues/1512
if (field->type_entry == nullptr) {
this_field_align = LLVMABIAlignmentOfType(g->target_data_ref, LLVMPointerType(LLVMInt8Type(), 0));
} else {
if (type_is_invalid(field->type_entry)) {
struct_type->data.structure.resolve_status = ResolveStatusInvalid;
break;
}
if (!type_has_bits(field->type_entry))
continue;
// alignment of structs is the alignment of the most-aligned field
if (struct_type->data.structure.layout != ContainerLayoutPacked) {
if ((err = type_resolve(g, field->type_entry, ResolveStatusAlignmentKnown))) { if ((err = type_resolve(g, field->type_entry, ResolveStatusAlignmentKnown))) {
struct_type->data.structure.resolve_status = ResolveStatusInvalid; struct_type->data.structure.resolve_status = ResolveStatusInvalid;
break; break;
} }
uint32_t this_field_align = get_abi_alignment(g, field->type_entry); this_field_align = get_abi_alignment(g, field->type_entry);
assert(this_field_align != 0); assert(this_field_align != 0);
if (this_field_align > struct_type->data.structure.abi_alignment) { }
struct_type->data.structure.abi_alignment = this_field_align; // alignment of structs is the alignment of the most-aligned field
} if (this_field_align > struct_type->data.structure.abi_alignment) {
struct_type->data.structure.abi_alignment = this_field_align;
} }
} }

View File

@ -159,7 +159,7 @@ static ZigType *ir_resolve_atomic_operand_type(IrAnalyze *ira, IrInstruction *op
static IrInstruction *ir_lval_wrap(IrBuilder *irb, Scope *scope, IrInstruction *value, LVal lval); static IrInstruction *ir_lval_wrap(IrBuilder *irb, Scope *scope, IrInstruction *value, LVal lval);
static ZigType *adjust_ptr_align(CodeGen *g, ZigType *ptr_type, uint32_t new_align); static ZigType *adjust_ptr_align(CodeGen *g, ZigType *ptr_type, uint32_t new_align);
static ZigType *adjust_slice_align(CodeGen *g, ZigType *slice_type, uint32_t new_align); static ZigType *adjust_slice_align(CodeGen *g, ZigType *slice_type, uint32_t new_align);
static void buf_read_value_bytes(CodeGen *codegen, uint8_t *buf, ConstExprValue *val); static Error buf_read_value_bytes(IrAnalyze *ira, AstNode *source_node, uint8_t *buf, ConstExprValue *val);
static void buf_write_value_bytes(CodeGen *codegen, uint8_t *buf, ConstExprValue *val); static void buf_write_value_bytes(CodeGen *codegen, uint8_t *buf, ConstExprValue *val);
static Error ir_read_const_ptr(IrAnalyze *ira, AstNode *source_node, static Error ir_read_const_ptr(IrAnalyze *ira, AstNode *source_node,
ConstExprValue *out_val, ConstExprValue *ptr_val); ConstExprValue *out_val, ConstExprValue *ptr_val);
@ -12495,6 +12495,7 @@ static IrInstruction *ir_analyze_instruction_decl_var(IrAnalyze *ira, IrInstruct
case ReqCompTimeNo: case ReqCompTimeNo:
if (casted_init_value->value.special == ConstValSpecialStatic && if (casted_init_value->value.special == ConstValSpecialStatic &&
casted_init_value->value.type->id == ZigTypeIdFn && casted_init_value->value.type->id == ZigTypeIdFn &&
casted_init_value->value.data.x_ptr.special != ConstPtrSpecialHardCodedAddr &&
casted_init_value->value.data.x_ptr.data.fn.fn_entry->fn_inline == FnInlineAlways) casted_init_value->value.data.x_ptr.data.fn.fn_entry->fn_inline == FnInlineAlways)
{ {
var_class_requires_const = true; var_class_requires_const = true;
@ -13724,7 +13725,8 @@ static Error ir_read_const_ptr(IrAnalyze *ira, AstNode *source_node,
Buf buf = BUF_INIT; Buf buf = BUF_INIT;
buf_resize(&buf, src_size); buf_resize(&buf, src_size);
buf_write_value_bytes(ira->codegen, (uint8_t*)buf_ptr(&buf), pointee); buf_write_value_bytes(ira->codegen, (uint8_t*)buf_ptr(&buf), pointee);
buf_read_value_bytes(ira->codegen, (uint8_t*)buf_ptr(&buf), out_val); if ((err = buf_read_value_bytes(ira, source_node, (uint8_t*)buf_ptr(&buf), out_val)))
return err;
return ErrorNone; return ErrorNone;
} }
@ -13758,7 +13760,8 @@ static Error ir_read_const_ptr(IrAnalyze *ira, AstNode *source_node,
ConstExprValue *elem_val = &array_val->data.x_array.data.s_none.elements[elem_index + i]; ConstExprValue *elem_val = &array_val->data.x_array.data.s_none.elements[elem_index + i];
buf_write_value_bytes(ira->codegen, (uint8_t*)buf_ptr(&buf) + (i * elem_size), elem_val); buf_write_value_bytes(ira->codegen, (uint8_t*)buf_ptr(&buf) + (i * elem_size), elem_val);
} }
buf_read_value_bytes(ira->codegen, (uint8_t*)buf_ptr(&buf), out_val); if ((err = buf_read_value_bytes(ira, source_node, (uint8_t*)buf_ptr(&buf), out_val)))
return err;
return ErrorNone; return ErrorNone;
} }
case ConstPtrSpecialBaseStruct: case ConstPtrSpecialBaseStruct:
@ -20076,7 +20079,8 @@ static void buf_write_value_bytes(CodeGen *codegen, uint8_t *buf, ConstExprValue
zig_unreachable(); zig_unreachable();
} }
static void buf_read_value_bytes(CodeGen *codegen, uint8_t *buf, ConstExprValue *val) { static Error buf_read_value_bytes(IrAnalyze *ira, AstNode *source_node, uint8_t *buf, ConstExprValue *val) {
Error err;
assert(val->special == ConstValSpecialStatic); assert(val->special == ConstValSpecialStatic);
switch (val->type->id) { switch (val->type->id) {
case ZigTypeIdInvalid: case ZigTypeIdInvalid:
@ -20093,30 +20097,60 @@ static void buf_read_value_bytes(CodeGen *codegen, uint8_t *buf, ConstExprValue
case ZigTypeIdPromise: case ZigTypeIdPromise:
zig_unreachable(); zig_unreachable();
case ZigTypeIdVoid: case ZigTypeIdVoid:
return; return ErrorNone;
case ZigTypeIdBool: case ZigTypeIdBool:
val->data.x_bool = (buf[0] != 0); val->data.x_bool = (buf[0] != 0);
return; return ErrorNone;
case ZigTypeIdInt: case ZigTypeIdInt:
bigint_read_twos_complement(&val->data.x_bigint, buf, val->type->data.integral.bit_count, bigint_read_twos_complement(&val->data.x_bigint, buf, val->type->data.integral.bit_count,
codegen->is_big_endian, val->type->data.integral.is_signed); ira->codegen->is_big_endian, val->type->data.integral.is_signed);
return; return ErrorNone;
case ZigTypeIdFloat: case ZigTypeIdFloat:
float_read_ieee597(val, buf, codegen->is_big_endian); float_read_ieee597(val, buf, ira->codegen->is_big_endian);
return; return ErrorNone;
case ZigTypeIdPointer: case ZigTypeIdPointer:
{ {
val->data.x_ptr.special = ConstPtrSpecialHardCodedAddr; val->data.x_ptr.special = ConstPtrSpecialHardCodedAddr;
BigInt bn; BigInt bn;
bigint_read_twos_complement(&bn, buf, codegen->builtin_types.entry_usize->data.integral.bit_count, bigint_read_twos_complement(&bn, buf, ira->codegen->builtin_types.entry_usize->data.integral.bit_count,
codegen->is_big_endian, false); ira->codegen->is_big_endian, false);
val->data.x_ptr.data.hard_coded_addr.addr = bigint_as_unsigned(&bn); val->data.x_ptr.data.hard_coded_addr.addr = bigint_as_unsigned(&bn);
return; return ErrorNone;
} }
case ZigTypeIdArray: case ZigTypeIdArray:
zig_panic("TODO buf_read_value_bytes array type"); zig_panic("TODO buf_read_value_bytes array type");
case ZigTypeIdStruct: case ZigTypeIdStruct:
zig_panic("TODO buf_read_value_bytes struct type"); switch (val->type->data.structure.layout) {
case ContainerLayoutAuto: {
ErrorMsg *msg = ir_add_error_node(ira, source_node,
buf_sprintf("non-extern, non-packed struct '%s' cannot have its bytes reinterpreted",
buf_ptr(&val->type->name)));
add_error_note(ira->codegen, msg, val->type->data.structure.decl_node,
buf_sprintf("declared here"));
return ErrorSemanticAnalyzeFail;
}
case ContainerLayoutExtern: {
size_t src_field_count = val->type->data.structure.src_field_count;
val->data.x_struct.fields = create_const_vals(src_field_count);
for (size_t field_i = 0; field_i < src_field_count; field_i += 1) {
ConstExprValue *field_val = &val->data.x_struct.fields[field_i];
field_val->special = ConstValSpecialStatic;
TypeStructField *type_field = &val->type->data.structure.fields[field_i];
field_val->type = type_field->type_entry;
if (type_field->gen_index == SIZE_MAX)
continue;
size_t offset = LLVMOffsetOfElement(ira->codegen->target_data_ref, val->type->type_ref,
type_field->gen_index);
uint8_t *new_buf = buf + offset;
if ((err = buf_read_value_bytes(ira, source_node, new_buf, field_val)))
return err;
}
return ErrorNone;
}
case ContainerLayoutPacked:
zig_panic("TODO buf_read_value_bytes packed struct");
}
zig_unreachable();
case ZigTypeIdOptional: case ZigTypeIdOptional:
zig_panic("TODO buf_read_value_bytes maybe type"); zig_panic("TODO buf_read_value_bytes maybe type");
case ZigTypeIdErrorUnion: case ZigTypeIdErrorUnion:
@ -20219,7 +20253,8 @@ static IrInstruction *ir_analyze_instruction_bit_cast(IrAnalyze *ira, IrInstruct
IrInstruction *result = ir_const(ira, &instruction->base, dest_type); IrInstruction *result = ir_const(ira, &instruction->base, dest_type);
uint8_t *buf = allocate_nonzero<uint8_t>(src_size_bytes); uint8_t *buf = allocate_nonzero<uint8_t>(src_size_bytes);
buf_write_value_bytes(ira->codegen, buf, val); buf_write_value_bytes(ira->codegen, buf, val);
buf_read_value_bytes(ira->codegen, buf, &result->value); if ((err = buf_read_value_bytes(ira, instruction->base.source_node, buf, &result->value)))
return ira->codegen->invalid_instruction;
return result; return result;
} }

View File

@ -4776,6 +4776,14 @@ Error parse_h_file(ImportTableEntry *import, ZigList<ErrorMsg *> *errors, const
clang_argv.append(target_file); clang_argv.append(target_file);
if (codegen->verbose_cimport) {
fprintf(stderr, "clang");
for (size_t i = 0; i < clang_argv.length; i += 1) {
fprintf(stderr, " %s", clang_argv.at(i));
}
fprintf(stderr, "\n");
}
// to make the [start...end] argument work // to make the [start...end] argument work
clang_argv.append(nullptr); clang_argv.append(nullptr);

View File

@ -398,3 +398,14 @@ test "std.ArrayList.insertSlice" {
assert(list.len == 6); assert(list.len == 6);
assert(list.items[0] == 1); assert(list.items[0] == 1);
} }
const Item = struct {
integer: i32,
sub_items: ArrayList(Item),
};
test "std.ArrayList: ArrayList(T) of struct T" {
var root = Item{ .integer = 1, .sub_items = ArrayList(Item).init(debug.global_allocator) };
try root.sub_items.append( Item{ .integer = 42, .sub_items = ArrayList(Item).init(debug.global_allocator) } );
assert(root.sub_items.items[0].integer == 42);
}

View File

@ -19,7 +19,6 @@ pub const DynLib = switch (builtin.os) {
}; };
pub const LinuxDynLib = struct { pub const LinuxDynLib = struct {
allocator: *mem.Allocator,
elf_lib: ElfLib, elf_lib: ElfLib,
fd: i32, fd: i32,
map_addr: usize, map_addr: usize,
@ -27,7 +26,7 @@ pub const LinuxDynLib = struct {
/// Trusts the file /// Trusts the file
pub fn open(allocator: *mem.Allocator, path: []const u8) !DynLib { pub fn open(allocator: *mem.Allocator, path: []const u8) !DynLib {
const fd = try std.os.posixOpen(allocator, path, 0, linux.O_RDONLY | linux.O_CLOEXEC); const fd = try std.os.posixOpen(path, 0, linux.O_RDONLY | linux.O_CLOEXEC);
errdefer std.os.close(fd); errdefer std.os.close(fd);
const size = @intCast(usize, (try std.os.posixFStat(fd)).size); const size = @intCast(usize, (try std.os.posixFStat(fd)).size);
@ -45,7 +44,6 @@ pub const LinuxDynLib = struct {
const bytes = @intToPtr([*]align(std.os.page_size) u8, addr)[0..size]; const bytes = @intToPtr([*]align(std.os.page_size) u8, addr)[0..size];
return DynLib{ return DynLib{
.allocator = allocator,
.elf_lib = try ElfLib.init(bytes), .elf_lib = try ElfLib.init(bytes),
.fd = fd, .fd = fd,
.map_addr = addr, .map_addr = addr,

View File

@ -243,6 +243,9 @@ pub fn formatType(
} }
return format(context, Errors, output, "{}@{x}", @typeName(T.Child), @ptrToInt(&value)); return format(context, Errors, output, "{}@{x}", @typeName(T.Child), @ptrToInt(&value));
}, },
builtin.TypeId.Fn => {
return format(context, Errors, output, "{}@{x}", @typeName(T), @ptrToInt(value));
},
else => @compileError("Unable to format type '" ++ @typeName(T) ++ "'"), else => @compileError("Unable to format type '" ++ @typeName(T) ++ "'"),
} }
} }
@ -1013,6 +1016,10 @@ test "fmt.format" {
const value = @intToPtr(fn () void, 0xdeadbeef); const value = @intToPtr(fn () void, 0xdeadbeef);
try testFmt("pointer: fn() void@deadbeef\n", "pointer: {}\n", value); try testFmt("pointer: fn() void@deadbeef\n", "pointer: {}\n", value);
} }
{
const value = @intToPtr(fn () void, 0xdeadbeef);
try testFmt("pointer: fn() void@deadbeef\n", "pointer: {}\n", value);
}
try testFmt("buf: Test \n", "buf: {s5}\n", "Test"); try testFmt("buf: Test \n", "buf: {s5}\n", "Test");
try testFmt("buf: Test\n Other text", "buf: {s}\n Other text", "Test"); try testFmt("buf: Test\n Other text", "buf: {s}\n Other text", "Test");
try testFmt("cstr: Test C\n", "cstr: {s}\n", c"Test C"); try testFmt("cstr: Test C\n", "cstr: {s}\n", c"Test C");

View File

@ -57,7 +57,8 @@ test "std" {
_ = @import("mutex.zig"); _ = @import("mutex.zig");
_ = @import("segmented_list.zig"); _ = @import("segmented_list.zig");
_ = @import("spinlock.zig"); _ = @import("spinlock.zig");
_ = @import("dynamic_library.zig");
_ = @import("base64.zig"); _ = @import("base64.zig");
_ = @import("build.zig"); _ = @import("build.zig");
_ = @import("c/index.zig"); _ = @import("c/index.zig");

View File

@ -155,32 +155,32 @@ pub fn InStream(comptime ReadError: type) type {
pub fn readIntNative(self: *Self, comptime T: type) !T { pub fn readIntNative(self: *Self, comptime T: type) !T {
var bytes: [@sizeOf(T)]u8 = undefined; var bytes: [@sizeOf(T)]u8 = undefined;
try self.readNoEof(bytes[0..]); try self.readNoEof(bytes[0..]);
return mem.readIntSliceNative(T, bytes); return mem.readIntNative(T, &bytes);
} }
/// Reads a foreign-endian integer /// Reads a foreign-endian integer
pub fn readIntForeign(self: *Self, comptime T: type) !T { pub fn readIntForeign(self: *Self, comptime T: type) !T {
var bytes: [@sizeOf(T)]u8 = undefined; var bytes: [@sizeOf(T)]u8 = undefined;
try self.readNoEof(bytes[0..]); try self.readNoEof(bytes[0..]);
return mem.readIntSliceForeign(T, bytes); return mem.readIntForeign(T, &bytes);
} }
pub fn readIntLittle(self: *Self, comptime T: type) !T { pub fn readIntLittle(self: *Self, comptime T: type) !T {
var bytes: [@sizeOf(T)]u8 = undefined; var bytes: [@sizeOf(T)]u8 = undefined;
try self.readNoEof(bytes[0..]); try self.readNoEof(bytes[0..]);
return mem.readIntSliceLittle(T, bytes); return mem.readIntLittle(T, &bytes);
} }
pub fn readIntBig(self: *Self, comptime T: type) !T { pub fn readIntBig(self: *Self, comptime T: type) !T {
var bytes: [@sizeOf(T)]u8 = undefined; var bytes: [@sizeOf(T)]u8 = undefined;
try self.readNoEof(bytes[0..]); try self.readNoEof(bytes[0..]);
return mem.readIntSliceBig(T, bytes); return mem.readIntBig(T, &bytes);
} }
pub fn readInt(self: *Self, comptime T: type, endian: builtin.Endian) !T { pub fn readInt(self: *Self, comptime T: type, endian: builtin.Endian) !T {
var bytes: [@sizeOf(T)]u8 = undefined; var bytes: [@sizeOf(T)]u8 = undefined;
try self.readNoEof(bytes[0..]); try self.readNoEof(bytes[0..]);
return mem.readIntSlice(T, bytes, endian); return mem.readInt(T, &bytes, endian);
} }
pub fn readVarInt(self: *Self, comptime ReturnType: type, endian: builtin.Endian, size: usize) !ReturnType { pub fn readVarInt(self: *Self, comptime ReturnType: type, endian: builtin.Endian, size: usize) !ReturnType {

View File

@ -459,6 +459,7 @@ pub const PosixOpenError = error{
NoSpaceLeft, NoSpaceLeft,
NotDir, NotDir,
PathAlreadyExists, PathAlreadyExists,
DeviceBusy,
/// See https://github.com/ziglang/zig/issues/1396 /// See https://github.com/ziglang/zig/issues/1396
Unexpected, Unexpected,
@ -497,6 +498,7 @@ pub fn posixOpenC(file_path: [*]const u8, flags: u32, perm: usize) !i32 {
posix.ENOTDIR => return PosixOpenError.NotDir, posix.ENOTDIR => return PosixOpenError.NotDir,
posix.EPERM => return PosixOpenError.AccessDenied, posix.EPERM => return PosixOpenError.AccessDenied,
posix.EEXIST => return PosixOpenError.PathAlreadyExists, posix.EEXIST => return PosixOpenError.PathAlreadyExists,
posix.EBUSY => return PosixOpenError.DeviceBusy,
else => return unexpectedErrorPosix(err), else => return unexpectedErrorPosix(err),
} }
} }
@ -1402,6 +1404,7 @@ const DeleteTreeError = error{
FileSystem, FileSystem,
FileBusy, FileBusy,
DirNotEmpty, DirNotEmpty,
DeviceBusy,
/// On Windows, file paths must be valid Unicode. /// On Windows, file paths must be valid Unicode.
InvalidUtf8, InvalidUtf8,
@ -1463,6 +1466,7 @@ pub fn deleteTree(allocator: *Allocator, full_path: []const u8) DeleteTreeError!
error.Unexpected, error.Unexpected,
error.InvalidUtf8, error.InvalidUtf8,
error.BadPathName, error.BadPathName,
error.DeviceBusy,
=> return err, => return err,
}; };
defer dir.close(); defer dir.close();
@ -1545,6 +1549,7 @@ pub const Dir = struct {
OutOfMemory, OutOfMemory,
InvalidUtf8, InvalidUtf8,
BadPathName, BadPathName,
DeviceBusy,
/// See https://github.com/ziglang/zig/issues/1396 /// See https://github.com/ziglang/zig/issues/1396
Unexpected, Unexpected,

View File

@ -1093,6 +1093,7 @@ pub const RealError = error{
NoSpaceLeft, NoSpaceLeft,
FileSystem, FileSystem,
BadPathName, BadPathName,
DeviceBusy,
/// On Windows, file paths must be valid Unicode. /// On Windows, file paths must be valid Unicode.
InvalidUtf8, InvalidUtf8,

View File

@ -42,6 +42,7 @@ comptime {
_ = @import("cases/if.zig"); _ = @import("cases/if.zig");
_ = @import("cases/import.zig"); _ = @import("cases/import.zig");
_ = @import("cases/incomplete_struct_param_tld.zig"); _ = @import("cases/incomplete_struct_param_tld.zig");
_ = @import("cases/inttoptr.zig");
_ = @import("cases/ir_block_deps.zig"); _ = @import("cases/ir_block_deps.zig");
_ = @import("cases/math.zig"); _ = @import("cases/math.zig");
_ = @import("cases/merge_error_sets.zig"); _ = @import("cases/merge_error_sets.zig");

13
test/cases/inttoptr.zig Normal file
View File

@ -0,0 +1,13 @@
const builtin = @import("builtin");
const std = @import("std");
const assertOrPanic = std.debug.assertOrPanic;
test "casting random address to function pointer" {
randomAddressToFunction();
comptime randomAddressToFunction();
}
fn randomAddressToFunction() void {
var addr: usize = 0xdeadbeef;
var ptr = @intToPtr(fn () void, addr);
}

View File

@ -15,3 +15,22 @@ fn testReinterpretBytesAsInteger() void {
}; };
assertOrPanic(@ptrCast(*align(1) const u32, bytes[1..5].ptr).* == expected); assertOrPanic(@ptrCast(*align(1) const u32, bytes[1..5].ptr).* == expected);
} }
test "reinterpret bytes of an array into an extern struct" {
testReinterpretBytesAsExternStruct();
comptime testReinterpretBytesAsExternStruct();
}
fn testReinterpretBytesAsExternStruct() void {
var bytes align(2) = []u8{ 1, 2, 3, 4, 5, 6 };
const S = extern struct {
a: u8,
b: u16,
c: u8,
};
var ptr = @ptrCast(*const S, &bytes);
var val = ptr.c;
assertOrPanic(val == 5);
}

View File

@ -5,6 +5,11 @@ const Node = struct {
children: []Node, children: []Node,
}; };
const NodeAligned = struct {
payload: i32,
children: []align(@alignOf(NodeAligned)) NodeAligned,
};
test "struct contains slice of itself" { test "struct contains slice of itself" {
var other_nodes = []Node{ var other_nodes = []Node{
Node{ Node{
@ -41,3 +46,40 @@ test "struct contains slice of itself" {
assert(root.children[2].children[0].payload == 31); assert(root.children[2].children[0].payload == 31);
assert(root.children[2].children[1].payload == 32); assert(root.children[2].children[1].payload == 32);
} }
test "struct contains aligned slice of itself" {
var other_nodes = []NodeAligned{
NodeAligned{
.payload = 31,
.children = []NodeAligned{},
},
NodeAligned{
.payload = 32,
.children = []NodeAligned{},
},
};
var nodes = []NodeAligned{
NodeAligned{
.payload = 1,
.children = []NodeAligned{},
},
NodeAligned{
.payload = 2,
.children = []NodeAligned{},
},
NodeAligned{
.payload = 3,
.children = other_nodes[0..],
},
};
const root = NodeAligned{
.payload = 1234,
.children = nodes[0..],
};
assert(root.payload == 1234);
assert(root.children[0].payload == 1);
assert(root.children[1].payload == 2);
assert(root.children[2].payload == 3);
assert(root.children[2].children[0].payload == 31);
assert(root.children[2].children[1].payload == 32);
}

View File

@ -144,15 +144,20 @@ test "type info: enum info" {
} }
fn testEnum() void { fn testEnum() void {
const Os = @import("builtin").Os; const Os = enum {
Windows,
Macos,
Linux,
FreeBSD,
};
const os_info = @typeInfo(Os); const os_info = @typeInfo(Os);
assert(TypeId(os_info) == TypeId.Enum); assert(TypeId(os_info) == TypeId.Enum);
assert(os_info.Enum.layout == TypeInfo.ContainerLayout.Auto); assert(os_info.Enum.layout == TypeInfo.ContainerLayout.Auto);
assert(os_info.Enum.fields.len == 32); assert(os_info.Enum.fields.len == 4);
assert(mem.eql(u8, os_info.Enum.fields[1].name, "ananas")); assert(mem.eql(u8, os_info.Enum.fields[1].name, "Macos"));
assert(os_info.Enum.fields[10].value == 10); assert(os_info.Enum.fields[3].value == 3);
assert(os_info.Enum.tag_type == u5); assert(os_info.Enum.tag_type == u2);
assert(os_info.Enum.defs.len == 0); assert(os_info.Enum.defs.len == 0);
} }