mirror of
https://github.com/ziglang/zig.git
synced 2026-01-10 09:25:11 +00:00
Merge remote-tracking branch 'origin/master' into llvm6
This commit is contained in:
commit
96c9a9bdb3
@ -362,8 +362,10 @@ TypeTableEntry *get_pointer_to_type_extra(CodeGen *g, TypeTableEntry *child_type
|
||||
} else {
|
||||
assert(bit_offset == 0);
|
||||
parent_pointer = &child_type->pointer_parent[(is_const ? 1 : 0)];
|
||||
if (*parent_pointer)
|
||||
if (*parent_pointer) {
|
||||
assert((*parent_pointer)->data.pointer.alignment == byte_alignment);
|
||||
return *parent_pointer;
|
||||
}
|
||||
}
|
||||
|
||||
type_ensure_zero_bits_known(g, child_type);
|
||||
@ -1240,16 +1242,16 @@ static bool type_allowed_in_extern(CodeGen *g, TypeTableEntry *type_entry) {
|
||||
case TypeTableEntryIdPointer:
|
||||
return type_allowed_in_extern(g, type_entry->data.pointer.child_type);
|
||||
case TypeTableEntryIdStruct:
|
||||
return type_entry->data.structure.layout == ContainerLayoutExtern;
|
||||
return type_entry->data.structure.layout == ContainerLayoutExtern || type_entry->data.structure.layout == ContainerLayoutPacked;
|
||||
case TypeTableEntryIdMaybe:
|
||||
{
|
||||
TypeTableEntry *child_type = type_entry->data.maybe.child_type;
|
||||
return child_type->id == TypeTableEntryIdPointer || child_type->id == TypeTableEntryIdFn;
|
||||
}
|
||||
case TypeTableEntryIdEnum:
|
||||
return type_entry->data.enumeration.layout == ContainerLayoutExtern;
|
||||
return type_entry->data.enumeration.layout == ContainerLayoutExtern || type_entry->data.enumeration.layout == ContainerLayoutPacked;
|
||||
case TypeTableEntryIdUnion:
|
||||
return type_entry->data.unionation.layout == ContainerLayoutExtern;
|
||||
return type_entry->data.unionation.layout == ContainerLayoutExtern || type_entry->data.unionation.layout == ContainerLayoutPacked;
|
||||
}
|
||||
zig_unreachable();
|
||||
}
|
||||
@ -1376,6 +1378,10 @@ static TypeTableEntry *analyze_fn_type(CodeGen *g, AstNode *proto_node, Scope *c
|
||||
fn_type_id.return_type = (fn_proto->return_type == nullptr) ?
|
||||
g->builtin_types.entry_void : analyze_type_expr(g, child_scope, fn_proto->return_type);
|
||||
|
||||
if (type_is_invalid(fn_type_id.return_type)) {
|
||||
return g->builtin_types.entry_invalid;
|
||||
}
|
||||
|
||||
if (fn_type_id.cc != CallingConventionUnspecified && !type_allowed_in_extern(g, fn_type_id.return_type)) {
|
||||
add_node_error(g, fn_proto->return_type,
|
||||
buf_sprintf("return type '%s' not allowed in function with calling convention '%s'",
|
||||
@ -1386,7 +1392,7 @@ static TypeTableEntry *analyze_fn_type(CodeGen *g, AstNode *proto_node, Scope *c
|
||||
|
||||
switch (fn_type_id.return_type->id) {
|
||||
case TypeTableEntryIdInvalid:
|
||||
return g->builtin_types.entry_invalid;
|
||||
zig_unreachable();
|
||||
|
||||
case TypeTableEntryIdUndefLit:
|
||||
case TypeTableEntryIdNullLit:
|
||||
@ -2352,6 +2358,7 @@ static void resolve_union_zero_bits(CodeGen *g, TypeTableEntry *union_type) {
|
||||
bool create_enum_type = decl_node->data.container_decl.auto_enum || (enum_type_node == nullptr && want_safety);
|
||||
bool *covered_enum_fields;
|
||||
ZigLLVMDIEnumerator **di_enumerators;
|
||||
uint32_t abi_alignment_so_far;
|
||||
if (create_enum_type) {
|
||||
occupied_tag_values.init(field_count);
|
||||
|
||||
@ -2373,7 +2380,7 @@ static void resolve_union_zero_bits(CodeGen *g, TypeTableEntry *union_type) {
|
||||
} else {
|
||||
tag_int_type = get_smallest_unsigned_int_type(g, field_count - 1);
|
||||
}
|
||||
union_type->data.unionation.abi_alignment = get_abi_alignment(g, tag_int_type);
|
||||
abi_alignment_so_far = get_abi_alignment(g, tag_int_type);
|
||||
|
||||
tag_type = new_type_table_entry(TypeTableEntryIdEnum);
|
||||
buf_resize(&tag_type->name, 0);
|
||||
@ -2404,9 +2411,10 @@ static void resolve_union_zero_bits(CodeGen *g, TypeTableEntry *union_type) {
|
||||
}
|
||||
tag_type = enum_type;
|
||||
covered_enum_fields = allocate<bool>(enum_type->data.enumeration.src_field_count);
|
||||
union_type->data.unionation.abi_alignment = get_abi_alignment(g, enum_type);
|
||||
abi_alignment_so_far = get_abi_alignment(g, enum_type);
|
||||
} else {
|
||||
tag_type = nullptr;
|
||||
abi_alignment_so_far = 0;
|
||||
}
|
||||
union_type->data.unionation.tag_type = tag_type;
|
||||
|
||||
@ -2504,12 +2512,14 @@ static void resolve_union_zero_bits(CodeGen *g, TypeTableEntry *union_type) {
|
||||
uint32_t field_align_bytes = get_abi_alignment(g, field_type);
|
||||
if (field_align_bytes > biggest_align_bytes) {
|
||||
biggest_align_bytes = field_align_bytes;
|
||||
if (biggest_align_bytes > union_type->data.unionation.abi_alignment) {
|
||||
union_type->data.unionation.abi_alignment = biggest_align_bytes;
|
||||
if (biggest_align_bytes > abi_alignment_so_far) {
|
||||
abi_alignment_so_far = biggest_align_bytes;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
union_type->data.unionation.abi_alignment = abi_alignment_so_far;
|
||||
|
||||
if (union_type->data.unionation.is_invalid)
|
||||
return;
|
||||
|
||||
|
||||
@ -42,7 +42,7 @@ pub fn map(v_addr: usize, p_addr: usize, size: usize, writable: bool) bool {
|
||||
return syscall4(SYS_map, v_addr, p_addr, size, usize(writable)) != 0;
|
||||
}
|
||||
|
||||
pub fn createThread(function: fn()) u16 {
|
||||
pub fn createThread(function: fn()void) u16 {
|
||||
return u16(syscall1(SYS_createThread, @ptrToInt(function)));
|
||||
}
|
||||
|
||||
|
||||
@ -617,3 +617,19 @@ test "cold function" {
|
||||
fn thisIsAColdFn() void {
|
||||
@setCold(true);
|
||||
}
|
||||
|
||||
|
||||
const PackedStruct = packed struct { a: u8, b: u8, };
|
||||
const PackedUnion = packed union { a: u8, b: u32, };
|
||||
const PackedEnum = packed enum { A, B, };
|
||||
|
||||
test "packed struct, enum, union parameters in extern function" {
|
||||
testPackedStuff(
|
||||
PackedStruct{.a = 1, .b = 2},
|
||||
PackedUnion{.a = 1},
|
||||
PackedEnum.A,
|
||||
);
|
||||
}
|
||||
|
||||
export fn testPackedStuff(a: &const PackedStruct, b: &const PackedUnion, c: PackedEnum) void {
|
||||
}
|
||||
|
||||
@ -404,3 +404,17 @@ test "native bit field understands endianness" {
|
||||
assert(bitfields.f6 == 0x6);
|
||||
assert(bitfields.f7 == 0x77);
|
||||
}
|
||||
|
||||
test "align 1 field before self referential align 8 field as slice return type" {
|
||||
const result = alloc(Expr);
|
||||
assert(result.len == 0);
|
||||
}
|
||||
|
||||
const Expr = union(enum) {
|
||||
Literal: u8,
|
||||
Question: &Expr,
|
||||
};
|
||||
|
||||
fn alloc(comptime T: type) []T {
|
||||
return []T{};
|
||||
}
|
||||
|
||||
@ -1,12 +1,16 @@
|
||||
const tests = @import("tests.zig");
|
||||
|
||||
pub fn addCases(cases: &tests.CompileErrorContext) void {
|
||||
cases.add("function with non-extern enum parameter",
|
||||
cases.add("function with invalid return type",
|
||||
\\export fn foo() boid {}
|
||||
, ".tmp_source.zig:1:17: error: use of undeclared identifier 'boid'");
|
||||
|
||||
cases.add("function with non-extern non-packed enum parameter",
|
||||
\\const Foo = enum { A, B, C };
|
||||
\\export fn entry(foo: Foo) void { }
|
||||
, ".tmp_source.zig:2:22: error: parameter of type 'Foo' not allowed in function with calling convention 'ccc'");
|
||||
|
||||
cases.add("function with non-extern struct parameter",
|
||||
cases.add("function with non-extern non-packed struct parameter",
|
||||
\\const Foo = struct {
|
||||
\\ A: i32,
|
||||
\\ B: f32,
|
||||
@ -15,7 +19,7 @@ pub fn addCases(cases: &tests.CompileErrorContext) void {
|
||||
\\export fn entry(foo: Foo) void { }
|
||||
, ".tmp_source.zig:6:22: error: parameter of type 'Foo' not allowed in function with calling convention 'ccc'");
|
||||
|
||||
cases.add("function with non-extern union parameter",
|
||||
cases.add("function with non-extern non-packed union parameter",
|
||||
\\const Foo = union {
|
||||
\\ A: i32,
|
||||
\\ B: f32,
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user