authorgravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2018-01-29 13:26:09-05:00
committergravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2018-01-29 13:26:09-05:00
log96c9a9bdb3f7b10aa1ce4833bf6adb0af1c82dc9
tree419c1a869db10a5d911503ea3fdf8fa1777f177a
parent47be64af5add5c146541c16dbb043ddf97f97d34
parent2b5e0b66a27d2a83cb596a28c9792a86523401b3

Merge remote-tracking branch 'origin/master' into llvm6


5 files changed, 57 insertions(+), 13 deletions(-)

src/analyze.cpp+19-9
...@@ -362,8 +362,10 @@ TypeTableEntry *get_pointer_to_type_extra(CodeGen *g, TypeTableEntry *child_type...@@ -362,8 +362,10 @@ TypeTableEntry *get_pointer_to_type_extra(CodeGen *g, TypeTableEntry *child_type
362 } else {362 } else {
363 assert(bit_offset == 0);363 assert(bit_offset == 0);
364 parent_pointer = &child_type->pointer_parent[(is_const ? 1 : 0)];364 parent_pointer = &child_type->pointer_parent[(is_const ? 1 : 0)];
365 if (*parent_pointer)365 if (*parent_pointer) {
366 assert((*parent_pointer)->data.pointer.alignment == byte_alignment);
366 return *parent_pointer;367 return *parent_pointer;
368 }
367 }369 }
368370
369 type_ensure_zero_bits_known(g, child_type);371 type_ensure_zero_bits_known(g, child_type);
...@@ -1240,16 +1242,16 @@ static bool type_allowed_in_extern(CodeGen *g, TypeTableEntry *type_entry) {...@@ -1240,16 +1242,16 @@ static bool type_allowed_in_extern(CodeGen *g, TypeTableEntry *type_entry) {
1240 case TypeTableEntryIdPointer:1242 case TypeTableEntryIdPointer:
1241 return type_allowed_in_extern(g, type_entry->data.pointer.child_type);1243 return type_allowed_in_extern(g, type_entry->data.pointer.child_type);
1242 case TypeTableEntryIdStruct:1244 case TypeTableEntryIdStruct:
1243 return type_entry->data.structure.layout == ContainerLayoutExtern;1245 return type_entry->data.structure.layout == ContainerLayoutExtern || type_entry->data.structure.layout == ContainerLayoutPacked;
1244 case TypeTableEntryIdMaybe:1246 case TypeTableEntryIdMaybe:
1245 {1247 {
1246 TypeTableEntry *child_type = type_entry->data.maybe.child_type;1248 TypeTableEntry *child_type = type_entry->data.maybe.child_type;
1247 return child_type->id == TypeTableEntryIdPointer || child_type->id == TypeTableEntryIdFn;1249 return child_type->id == TypeTableEntryIdPointer || child_type->id == TypeTableEntryIdFn;
1248 }1250 }
1249 case TypeTableEntryIdEnum:1251 case TypeTableEntryIdEnum:
1250 return type_entry->data.enumeration.layout == ContainerLayoutExtern;1252 return type_entry->data.enumeration.layout == ContainerLayoutExtern || type_entry->data.enumeration.layout == ContainerLayoutPacked;
1251 case TypeTableEntryIdUnion:1253 case TypeTableEntryIdUnion:
1252 return type_entry->data.unionation.layout == ContainerLayoutExtern;1254 return type_entry->data.unionation.layout == ContainerLayoutExtern || type_entry->data.unionation.layout == ContainerLayoutPacked;
1253 }1255 }
1254 zig_unreachable();1256 zig_unreachable();
1255}1257}
...@@ -1376,6 +1378,10 @@ static TypeTableEntry *analyze_fn_type(CodeGen *g, AstNode *proto_node, Scope *c...@@ -1376,6 +1378,10 @@ static TypeTableEntry *analyze_fn_type(CodeGen *g, AstNode *proto_node, Scope *c
1376 fn_type_id.return_type = (fn_proto->return_type == nullptr) ?1378 fn_type_id.return_type = (fn_proto->return_type == nullptr) ?
1377 g->builtin_types.entry_void : analyze_type_expr(g, child_scope, fn_proto->return_type);1379 g->builtin_types.entry_void : analyze_type_expr(g, child_scope, fn_proto->return_type);
13781380
1381 if (type_is_invalid(fn_type_id.return_type)) {
1382 return g->builtin_types.entry_invalid;
1383 }
1384
1379 if (fn_type_id.cc != CallingConventionUnspecified && !type_allowed_in_extern(g, fn_type_id.return_type)) {1385 if (fn_type_id.cc != CallingConventionUnspecified && !type_allowed_in_extern(g, fn_type_id.return_type)) {
1380 add_node_error(g, fn_proto->return_type,1386 add_node_error(g, fn_proto->return_type,
1381 buf_sprintf("return type '%s' not allowed in function with calling convention '%s'",1387 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...@@ -1386,7 +1392,7 @@ static TypeTableEntry *analyze_fn_type(CodeGen *g, AstNode *proto_node, Scope *c
13861392
1387 switch (fn_type_id.return_type->id) {1393 switch (fn_type_id.return_type->id) {
1388 case TypeTableEntryIdInvalid:1394 case TypeTableEntryIdInvalid:
1389 return g->builtin_types.entry_invalid;1395 zig_unreachable();
13901396
1391 case TypeTableEntryIdUndefLit:1397 case TypeTableEntryIdUndefLit:
1392 case TypeTableEntryIdNullLit:1398 case TypeTableEntryIdNullLit:
...@@ -2352,6 +2358,7 @@ static void resolve_union_zero_bits(CodeGen *g, TypeTableEntry *union_type) {...@@ -2352,6 +2358,7 @@ static void resolve_union_zero_bits(CodeGen *g, TypeTableEntry *union_type) {
2352 bool create_enum_type = decl_node->data.container_decl.auto_enum || (enum_type_node == nullptr && want_safety);2358 bool create_enum_type = decl_node->data.container_decl.auto_enum || (enum_type_node == nullptr && want_safety);
2353 bool *covered_enum_fields;2359 bool *covered_enum_fields;
2354 ZigLLVMDIEnumerator **di_enumerators;2360 ZigLLVMDIEnumerator **di_enumerators;
2361 uint32_t abi_alignment_so_far;
2355 if (create_enum_type) {2362 if (create_enum_type) {
2356 occupied_tag_values.init(field_count);2363 occupied_tag_values.init(field_count);
23572364
...@@ -2373,7 +2380,7 @@ static void resolve_union_zero_bits(CodeGen *g, TypeTableEntry *union_type) {...@@ -2373,7 +2380,7 @@ static void resolve_union_zero_bits(CodeGen *g, TypeTableEntry *union_type) {
2373 } else {2380 } else {
2374 tag_int_type = get_smallest_unsigned_int_type(g, field_count - 1);2381 tag_int_type = get_smallest_unsigned_int_type(g, field_count - 1);
2375 }2382 }
2376 union_type->data.unionation.abi_alignment = get_abi_alignment(g, tag_int_type);2383 abi_alignment_so_far = get_abi_alignment(g, tag_int_type);
23772384
2378 tag_type = new_type_table_entry(TypeTableEntryIdEnum);2385 tag_type = new_type_table_entry(TypeTableEntryIdEnum);
2379 buf_resize(&tag_type->name, 0);2386 buf_resize(&tag_type->name, 0);
...@@ -2404,9 +2411,10 @@ static void resolve_union_zero_bits(CodeGen *g, TypeTableEntry *union_type) {...@@ -2404,9 +2411,10 @@ static void resolve_union_zero_bits(CodeGen *g, TypeTableEntry *union_type) {
2404 }2411 }
2405 tag_type = enum_type;2412 tag_type = enum_type;
2406 covered_enum_fields = allocate<bool>(enum_type->data.enumeration.src_field_count);2413 covered_enum_fields = allocate<bool>(enum_type->data.enumeration.src_field_count);
2407 union_type->data.unionation.abi_alignment = get_abi_alignment(g, enum_type);2414 abi_alignment_so_far = get_abi_alignment(g, enum_type);
2408 } else {2415 } else {
2409 tag_type = nullptr;2416 tag_type = nullptr;
2417 abi_alignment_so_far = 0;
2410 }2418 }
2411 union_type->data.unionation.tag_type = tag_type;2419 union_type->data.unionation.tag_type = tag_type;
24122420
...@@ -2504,12 +2512,14 @@ static void resolve_union_zero_bits(CodeGen *g, TypeTableEntry *union_type) {...@@ -2504,12 +2512,14 @@ static void resolve_union_zero_bits(CodeGen *g, TypeTableEntry *union_type) {
2504 uint32_t field_align_bytes = get_abi_alignment(g, field_type);2512 uint32_t field_align_bytes = get_abi_alignment(g, field_type);
2505 if (field_align_bytes > biggest_align_bytes) {2513 if (field_align_bytes > biggest_align_bytes) {
2506 biggest_align_bytes = field_align_bytes;2514 biggest_align_bytes = field_align_bytes;
2507 if (biggest_align_bytes > union_type->data.unionation.abi_alignment) {2515 if (biggest_align_bytes > abi_alignment_so_far) {
2508 union_type->data.unionation.abi_alignment = biggest_align_bytes;2516 abi_alignment_so_far = biggest_align_bytes;
2509 }2517 }
2510 }2518 }
2511 }2519 }
25122520
2521 union_type->data.unionation.abi_alignment = abi_alignment_so_far;
2522
2513 if (union_type->data.unionation.is_invalid)2523 if (union_type->data.unionation.is_invalid)
2514 return;2524 return;
25152525
std/os/zen.zig+1-1
...@@ -42,7 +42,7 @@ pub fn map(v_addr: usize, p_addr: usize, size: usize, writable: bool) bool {...@@ -42,7 +42,7 @@ pub fn map(v_addr: usize, p_addr: usize, size: usize, writable: bool) bool {
42 return syscall4(SYS_map, v_addr, p_addr, size, usize(writable)) != 0;42 return syscall4(SYS_map, v_addr, p_addr, size, usize(writable)) != 0;
43}43}
4444
45pub fn createThread(function: fn()) u16 {45pub fn createThread(function: fn()void) u16 {
46 return u16(syscall1(SYS_createThread, @ptrToInt(function)));46 return u16(syscall1(SYS_createThread, @ptrToInt(function)));
47}47}
4848
test/cases/misc.zig+16
...@@ -617,3 +617,19 @@ test "cold function" {...@@ -617,3 +617,19 @@ test "cold function" {
617fn thisIsAColdFn() void {617fn thisIsAColdFn() void {
618 @setCold(true);618 @setCold(true);
619}619}
620
621
622const PackedStruct = packed struct { a: u8, b: u8, };
623const PackedUnion = packed union { a: u8, b: u32, };
624const PackedEnum = packed enum { A, B, };
625
626test "packed struct, enum, union parameters in extern function" {
627 testPackedStuff(
628 PackedStruct{.a = 1, .b = 2},
629 PackedUnion{.a = 1},
630 PackedEnum.A,
631 );
632}
633
634export fn testPackedStuff(a: &const PackedStruct, b: &const PackedUnion, c: PackedEnum) void {
635}
test/cases/struct.zig+14
...@@ -404,3 +404,17 @@ test "native bit field understands endianness" {...@@ -404,3 +404,17 @@ test "native bit field understands endianness" {
404 assert(bitfields.f6 == 0x6);404 assert(bitfields.f6 == 0x6);
405 assert(bitfields.f7 == 0x77);405 assert(bitfields.f7 == 0x77);
406}406}
407
408test "align 1 field before self referential align 8 field as slice return type" {
409 const result = alloc(Expr);
410 assert(result.len == 0);
411}
412
413const Expr = union(enum) {
414 Literal: u8,
415 Question: &Expr,
416};
417
418fn alloc(comptime T: type) []T {
419 return []T{};
420}
test/compile_errors.zig+7-3
...@@ -1,12 +1,16 @@...@@ -1,12 +1,16 @@
1const tests = @import("tests.zig");1const tests = @import("tests.zig");
22
3pub fn addCases(cases: &tests.CompileErrorContext) void {3pub fn addCases(cases: &tests.CompileErrorContext) void {
4 cases.add("function with non-extern enum parameter",4 cases.add("function with invalid return type",
5 \\export fn foo() boid {}
6 , ".tmp_source.zig:1:17: error: use of undeclared identifier 'boid'");
7
8 cases.add("function with non-extern non-packed enum parameter",
5 \\const Foo = enum { A, B, C };9 \\const Foo = enum { A, B, C };
6 \\export fn entry(foo: Foo) void { }10 \\export fn entry(foo: Foo) void { }
7 , ".tmp_source.zig:2:22: error: parameter of type 'Foo' not allowed in function with calling convention 'ccc'");11 , ".tmp_source.zig:2:22: error: parameter of type 'Foo' not allowed in function with calling convention 'ccc'");
812
9 cases.add("function with non-extern struct parameter",13 cases.add("function with non-extern non-packed struct parameter",
10 \\const Foo = struct {14 \\const Foo = struct {
11 \\ A: i32,15 \\ A: i32,
12 \\ B: f32,16 \\ B: f32,
...@@ -15,7 +19,7 @@ pub fn addCases(cases: &tests.CompileErrorContext) void {...@@ -15,7 +19,7 @@ pub fn addCases(cases: &tests.CompileErrorContext) void {
15 \\export fn entry(foo: Foo) void { }19 \\export fn entry(foo: Foo) void { }
16 , ".tmp_source.zig:6:22: error: parameter of type 'Foo' not allowed in function with calling convention 'ccc'");20 , ".tmp_source.zig:6:22: error: parameter of type 'Foo' not allowed in function with calling convention 'ccc'");
1721
18 cases.add("function with non-extern union parameter",22 cases.add("function with non-extern non-packed union parameter",
19 \\const Foo = union {23 \\const Foo = union {
20 \\ A: i32,24 \\ A: i32,
21 \\ B: f32,25 \\ B: f32,