| author | |
| committer | |
| log | 4ed0cd51c0775edb35bb80786176300ecb357724 |
| tree | 7c7e1d4d721aaea4b94cd7f3e9172c26ef70b0cd |
| parent | 9e50cb294b5028a2b4d2ca2b42cd0bd337428bd1 |
Stage2 bug fixes to get third party projects building12 files changed, 146 insertions(+), 23 deletions(-)
lib/std/mem/Allocator.zig+1-1| ... | ... | @@ -167,7 +167,7 @@ pub inline fn rawFree(self: Allocator, buf: []u8, buf_align: u29, ret_addr: usiz |
| 167 | 167 | /// Returns a pointer to undefined memory. |
| 168 | 168 | /// Call `destroy` with the result to free the memory. |
| 169 | 169 | pub fn create(self: Allocator, comptime T: type) Error!*T { |
| 170 | if (@sizeOf(T) == 0) return @as(*T, undefined); | |
| 170 | if (@sizeOf(T) == 0) return @intToPtr(*T, std.math.maxInt(usize)); | |
| 171 | 171 | const slice = try self.allocAdvancedWithRetAddr(T, null, 1, .exact, @returnAddress()); |
| 172 | 172 | return &slice[0]; |
| 173 | 173 | } |
src/Compilation.zig+1-1| ... | ... | @@ -2361,7 +2361,7 @@ pub fn update(comp: *Compilation) !void { |
| 2361 | 2361 | // The `test_functions` decl has been intentionally postponed until now, |
| 2362 | 2362 | // at which point we must populate it with the list of test functions that |
| 2363 | 2363 | // have been discovered and not filtered out. |
| 2364 | try module.populateTestFunctions(); | |
| 2364 | try module.populateTestFunctions(main_progress_node); | |
| 2365 | 2365 | } |
| 2366 | 2366 | |
| 2367 | 2367 | // Process the deletion set. We use a while loop here because the |
src/Module.zig+15-1| ... | ... | @@ -6431,13 +6431,27 @@ pub fn processExports(mod: *Module) !void { |
| 6431 | 6431 | } |
| 6432 | 6432 | } |
| 6433 | 6433 | |
| 6434 | pub fn populateTestFunctions(mod: *Module) !void { | |
| 6434 | pub fn populateTestFunctions( | |
| 6435 | mod: *Module, | |
| 6436 | main_progress_node: *std.Progress.Node, | |
| 6437 | ) !void { | |
| 6435 | 6438 | const gpa = mod.gpa; |
| 6436 | 6439 | const builtin_pkg = mod.main_pkg.table.get("builtin").?; |
| 6437 | 6440 | const builtin_file = (mod.importPkg(builtin_pkg) catch unreachable).file; |
| 6438 | 6441 | const root_decl = mod.declPtr(builtin_file.root_decl.unwrap().?); |
| 6439 | 6442 | const builtin_namespace = root_decl.src_namespace; |
| 6440 | 6443 | const decl_index = builtin_namespace.decls.getKeyAdapted(@as([]const u8, "test_functions"), DeclAdapter{ .mod = mod }).?; |
| 6444 | { | |
| 6445 | // We have to call `ensureDeclAnalyzed` here in case `builtin.test_functions` | |
| 6446 | // was not referenced by start code. | |
| 6447 | mod.sema_prog_node = main_progress_node.start("Semantic Analysis", 0); | |
| 6448 | mod.sema_prog_node.activate(); | |
| 6449 | defer { | |
| 6450 | mod.sema_prog_node.end(); | |
| 6451 | mod.sema_prog_node = undefined; | |
| 6452 | } | |
| 6453 | try mod.ensureDeclAnalyzed(decl_index); | |
| 6454 | } | |
| 6441 | 6455 | const decl = mod.declPtr(decl_index); |
| 6442 | 6456 | var buf: Type.SlicePtrFieldTypeBuffer = undefined; |
| 6443 | 6457 | const tmp_test_fn_ty = decl.ty.slicePtrFieldType(&buf).elemType(); |
src/Sema.zig+19-6| ... | ... | @@ -6361,6 +6361,7 @@ fn analyzeCall( |
| 6361 | 6361 | is_comptime_call, |
| 6362 | 6362 | &should_memoize, |
| 6363 | 6363 | memoized_call_key, |
| 6364 | func_ty_info.param_types, | |
| 6364 | 6365 | ) catch |err| switch (err) { |
| 6365 | 6366 | error.NeededSourceLocation => { |
| 6366 | 6367 | _ = sema.inst_map.remove(inst); |
| ... | ... | @@ -6376,6 +6377,7 @@ fn analyzeCall( |
| 6376 | 6377 | is_comptime_call, |
| 6377 | 6378 | &should_memoize, |
| 6378 | 6379 | memoized_call_key, |
| 6380 | func_ty_info.param_types, | |
| 6379 | 6381 | ); |
| 6380 | 6382 | return error.AnalysisFail; |
| 6381 | 6383 | }, |
| ... | ... | @@ -6612,6 +6614,7 @@ fn analyzeInlineCallArg( |
| 6612 | 6614 | is_comptime_call: bool, |
| 6613 | 6615 | should_memoize: *bool, |
| 6614 | 6616 | memoized_call_key: Module.MemoizedCall.Key, |
| 6617 | raw_param_types: []const Type, | |
| 6615 | 6618 | ) !void { |
| 6616 | 6619 | const zir_tags = sema.code.instructions.items(.tag); |
| 6617 | 6620 | switch (zir_tags[inst]) { |
| ... | ... | @@ -6622,8 +6625,12 @@ fn analyzeInlineCallArg( |
| 6622 | 6625 | const param_src = pl_tok.src(); |
| 6623 | 6626 | const extra = sema.code.extraData(Zir.Inst.Param, pl_tok.payload_index); |
| 6624 | 6627 | const param_body = sema.code.extra[extra.end..][0..extra.data.body_len]; |
| 6625 | const param_ty_inst = try sema.resolveBody(param_block, param_body, inst); | |
| 6626 | const param_ty = try sema.analyzeAsType(param_block, param_src, param_ty_inst); | |
| 6628 | const param_ty = param_ty: { | |
| 6629 | const raw_param_ty = raw_param_types[arg_i.*]; | |
| 6630 | if (raw_param_ty.tag() != .generic_poison) break :param_ty raw_param_ty; | |
| 6631 | const param_ty_inst = try sema.resolveBody(param_block, param_body, inst); | |
| 6632 | break :param_ty try sema.analyzeAsType(param_block, param_src, param_ty_inst); | |
| 6633 | }; | |
| 6627 | 6634 | new_fn_info.param_types[arg_i.*] = param_ty; |
| 6628 | 6635 | const uncasted_arg = uncasted_args[arg_i.*]; |
| 6629 | 6636 | if (try sema.typeRequiresComptime(param_ty)) { |
| ... | ... | @@ -18754,7 +18761,7 @@ fn zirIntToPtr(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai |
| 18754 | 18761 | const addr = val.toUnsignedInt(target); |
| 18755 | 18762 | if (!ptr_ty.isAllowzeroPtr() and addr == 0) |
| 18756 | 18763 | return sema.fail(block, operand_src, "pointer type '{}' does not allow address zero", .{ptr_ty.fmt(sema.mod)}); |
| 18757 | if (addr != 0 and addr % ptr_align != 0) | |
| 18764 | if (addr != 0 and ptr_align != 0 and addr % ptr_align != 0) | |
| 18758 | 18765 | return sema.fail(block, operand_src, "pointer type '{}' requires aligned address", .{ptr_ty.fmt(sema.mod)}); |
| 18759 | 18766 | |
| 18760 | 18767 | const val_payload = try sema.arena.create(Value.Payload.U64); |
| ... | ... | @@ -22469,13 +22476,12 @@ fn fieldVal( |
| 22469 | 22476 | ); |
| 22470 | 22477 | }, |
| 22471 | 22478 | .Union => { |
| 22472 | const union_ty = try sema.resolveTypeFields(child_type); | |
| 22473 | ||
| 22474 | if (union_ty.getNamespace()) |namespace| { | |
| 22479 | if (child_type.getNamespace()) |namespace| { | |
| 22475 | 22480 | if (try sema.namespaceLookupVal(block, src, namespace, field_name)) |inst| { |
| 22476 | 22481 | return inst; |
| 22477 | 22482 | } |
| 22478 | 22483 | } |
| 22484 | const union_ty = try sema.resolveTypeFields(child_type); | |
| 22479 | 22485 | if (union_ty.unionTagType()) |enum_ty| { |
| 22480 | 22486 | if (enum_ty.enumFieldIndex(field_name)) |field_index_usize| { |
| 22481 | 22487 | const field_index = @intCast(u32, field_index_usize); |
| ... | ... | @@ -27397,6 +27403,13 @@ fn analyzeRef( |
| 27397 | 27403 | const operand_ty = sema.typeOf(operand); |
| 27398 | 27404 | |
| 27399 | 27405 | if (try sema.resolveMaybeUndefVal(operand)) |val| { |
| 27406 | switch (val.tag()) { | |
| 27407 | .extern_fn, .function => { | |
| 27408 | const decl_index = val.pointerDecl().?; | |
| 27409 | return sema.analyzeDeclRef(decl_index); | |
| 27410 | }, | |
| 27411 | else => {}, | |
| 27412 | } | |
| 27400 | 27413 | var anon_decl = try block.startAnonDecl(); |
| 27401 | 27414 | defer anon_decl.deinit(); |
| 27402 | 27415 | return sema.analyzeDeclRef(try anon_decl.finish( |
src/codegen/llvm.zig+26-7| ... | ... | @@ -1507,6 +1507,11 @@ pub const Object = struct { |
| 1507 | 1507 | }; |
| 1508 | 1508 | const field_index_val = Value.initPayload(&buf_field_index.base); |
| 1509 | 1509 | |
| 1510 | var buffer: Type.Payload.Bits = undefined; | |
| 1511 | const int_ty = ty.intTagType(&buffer); | |
| 1512 | const int_info = ty.intInfo(target); | |
| 1513 | assert(int_info.bits != 0); | |
| 1514 | ||
| 1510 | 1515 | for (field_names) |field_name, i| { |
| 1511 | 1516 | const field_name_z = try gpa.dupeZ(u8, field_name); |
| 1512 | 1517 | defer gpa.free(field_name_z); |
| ... | ... | @@ -1514,9 +1519,25 @@ pub const Object = struct { |
| 1514 | 1519 | buf_field_index.data = @intCast(u32, i); |
| 1515 | 1520 | var buf_u64: Value.Payload.U64 = undefined; |
| 1516 | 1521 | const field_int_val = field_index_val.enumToInt(ty, &buf_u64); |
| 1517 | // See https://github.com/ziglang/zig/issues/645 | |
| 1518 | const field_int = field_int_val.toSignedInt(); | |
| 1519 | enumerators[i] = dib.createEnumerator(field_name_z, field_int); | |
| 1522 | ||
| 1523 | var bigint_space: Value.BigIntSpace = undefined; | |
| 1524 | const bigint = field_int_val.toBigInt(&bigint_space, target); | |
| 1525 | ||
| 1526 | if (bigint.limbs.len == 1) { | |
| 1527 | enumerators[i] = dib.createEnumerator(field_name_z, bigint.limbs[0], int_info.signedness == .unsigned); | |
| 1528 | continue; | |
| 1529 | } | |
| 1530 | if (@sizeOf(usize) == @sizeOf(u64)) { | |
| 1531 | enumerators[i] = dib.createEnumerator2( | |
| 1532 | field_name_z, | |
| 1533 | @intCast(c_uint, bigint.limbs.len), | |
| 1534 | bigint.limbs.ptr, | |
| 1535 | int_info.bits, | |
| 1536 | int_info.signedness == .unsigned, | |
| 1537 | ); | |
| 1538 | continue; | |
| 1539 | } | |
| 1540 | @panic("TODO implement bigint debug enumerators to llvm int for 32-bit compiler builds"); | |
| 1520 | 1541 | } |
| 1521 | 1542 | |
| 1522 | 1543 | const di_file = try o.getDIFile(gpa, owner_decl.src_namespace.file_scope); |
| ... | ... | @@ -1524,8 +1545,6 @@ pub const Object = struct { |
| 1524 | 1545 | |
| 1525 | 1546 | const name = try ty.nameAlloc(gpa, o.module); |
| 1526 | 1547 | defer gpa.free(name); |
| 1527 | var buffer: Type.Payload.Bits = undefined; | |
| 1528 | const int_ty = ty.intTagType(&buffer); | |
| 1529 | 1548 | |
| 1530 | 1549 | const enum_di_ty = dib.createEnumerationType( |
| 1531 | 1550 | di_scope, |
| ... | ... | @@ -2118,7 +2137,8 @@ pub const Object = struct { |
| 2118 | 2137 | break :blk fwd_decl; |
| 2119 | 2138 | }; |
| 2120 | 2139 | |
| 2121 | if (!ty.hasRuntimeBitsIgnoreComptime()) { | |
| 2140 | const union_obj = ty.cast(Type.Payload.Union).?.data; | |
| 2141 | if (!union_obj.haveFieldTypes() or !ty.hasRuntimeBitsIgnoreComptime()) { | |
| 2122 | 2142 | const union_di_ty = try o.makeEmptyNamespaceDIType(owner_decl_index); |
| 2123 | 2143 | dib.replaceTemporary(fwd_decl, union_di_ty); |
| 2124 | 2144 | // The recursive call to `lowerDebugType` via `makeEmptyNamespaceDIType` |
| ... | ... | @@ -2128,7 +2148,6 @@ pub const Object = struct { |
| 2128 | 2148 | } |
| 2129 | 2149 | |
| 2130 | 2150 | const layout = ty.unionGetLayout(target); |
| 2131 | const union_obj = ty.cast(Type.Payload.Union).?.data; | |
| 2132 | 2151 | |
| 2133 | 2152 | if (layout.payload_size == 0) { |
| 2134 | 2153 | const tag_di_ty = try o.lowerDebugType(union_obj.tag_ty, .full); |
src/codegen/llvm/bindings.zig+12-1| ... | ... | @@ -1662,7 +1662,18 @@ pub const DIBuilder = opaque { |
| 1662 | 1662 | extern fn ZigLLVMCreateDebugEnumerator( |
| 1663 | 1663 | dib: *DIBuilder, |
| 1664 | 1664 | name: [*:0]const u8, |
| 1665 | val: i64, | |
| 1665 | val: u64, | |
| 1666 | is_unsigned: bool, | |
| 1667 | ) *DIEnumerator; | |
| 1668 | ||
| 1669 | pub const createEnumerator2 = ZigLLVMCreateDebugEnumeratorOfArbitraryPrecision; | |
| 1670 | extern fn ZigLLVMCreateDebugEnumeratorOfArbitraryPrecision( | |
| 1671 | dib: *DIBuilder, | |
| 1672 | name: [*:0]const u8, | |
| 1673 | num_words: c_uint, | |
| 1674 | words: [*]const u64, | |
| 1675 | bits: c_uint, | |
| 1676 | is_unsigned: bool, | |
| 1666 | 1677 | ) *DIEnumerator; |
| 1667 | 1678 | |
| 1668 | 1679 | pub const createEnumerationType = ZigLLVMCreateDebugEnumerationType; |
src/stage1/analyze.cpp+3-3| ... | ... | @@ -9117,7 +9117,7 @@ static void resolve_llvm_types_enum(CodeGen *g, ZigType *enum_type, ResolveStatu |
| 9117 | 9117 | |
| 9118 | 9118 | // https://github.com/ziglang/zig/issues/645 |
| 9119 | 9119 | di_enumerators[i] = ZigLLVMCreateDebugEnumerator(g->dbuilder, buf_ptr(enum_field->name), |
| 9120 | bigint_as_signed(&enum_field->value)); | |
| 9120 | bigint_as_signed(&enum_field->value), false); | |
| 9121 | 9121 | } |
| 9122 | 9122 | |
| 9123 | 9123 | ZigType *tag_int_type = enum_type->data.enumeration.tag_int_type; |
| ... | ... | @@ -9728,10 +9728,10 @@ static void resolve_llvm_types_anyerror(CodeGen *g) { |
| 9728 | 9728 | entry->llvm_type = get_llvm_type(g, g->err_tag_type); |
| 9729 | 9729 | ZigList<ZigLLVMDIEnumerator *> err_enumerators = {}; |
| 9730 | 9730 | // reserve index 0 to indicate no error |
| 9731 | err_enumerators.append(ZigLLVMCreateDebugEnumerator(g->dbuilder, "(none)", 0)); | |
| 9731 | err_enumerators.append(ZigLLVMCreateDebugEnumerator(g->dbuilder, "(none)", 0, false)); | |
| 9732 | 9732 | for (size_t i = 1; i < g->errors_by_index.length; i += 1) { |
| 9733 | 9733 | ErrorTableEntry *error_entry = g->errors_by_index.at(i); |
| 9734 | err_enumerators.append(ZigLLVMCreateDebugEnumerator(g->dbuilder, buf_ptr(&error_entry->name), i)); | |
| 9734 | err_enumerators.append(ZigLLVMCreateDebugEnumerator(g->dbuilder, buf_ptr(&error_entry->name), i, false)); | |
| 9735 | 9735 | } |
| 9736 | 9736 | |
| 9737 | 9737 | // create debug type for error sets |
src/zig_llvm.cpp+10-2| ... | ... | @@ -594,8 +594,16 @@ ZigLLVMDIType *ZigLLVMCreateDebugArrayType(ZigLLVMDIBuilder *dibuilder, uint64_t |
| 594 | 594 | return reinterpret_cast<ZigLLVMDIType*>(di_type); |
| 595 | 595 | } |
| 596 | 596 | |
| 597 | ZigLLVMDIEnumerator *ZigLLVMCreateDebugEnumerator(ZigLLVMDIBuilder *dibuilder, const char *name, int64_t val) { | |
| 598 | DIEnumerator *di_enumerator = reinterpret_cast<DIBuilder*>(dibuilder)->createEnumerator(name, val); | |
| 597 | ZigLLVMDIEnumerator *ZigLLVMCreateDebugEnumerator(ZigLLVMDIBuilder *dibuilder, const char *name, uint64_t val, bool isUnsigned) { | |
| 598 | DIEnumerator *di_enumerator = reinterpret_cast<DIBuilder*>(dibuilder)->createEnumerator(name, val, isUnsigned); | |
| 599 | return reinterpret_cast<ZigLLVMDIEnumerator*>(di_enumerator); | |
| 600 | } | |
| 601 | ||
| 602 | ZigLLVMDIEnumerator *ZigLLVMCreateDebugEnumeratorOfArbitraryPrecision(ZigLLVMDIBuilder *dibuilder, | |
| 603 | const char *name, unsigned NumWords, const uint64_t Words[], unsigned int bits, bool isUnsigned) | |
| 604 | { | |
| 605 | DIEnumerator *di_enumerator = reinterpret_cast<DIBuilder*>(dibuilder)->createEnumerator(name, | |
| 606 | APSInt(APInt(bits, makeArrayRef(Words, NumWords)), isUnsigned)); | |
| 599 | 607 | return reinterpret_cast<ZigLLVMDIEnumerator*>(di_enumerator); |
| 600 | 608 | } |
| 601 | 609 |
src/zig_llvm.h+5-1| ... | ... | @@ -176,7 +176,11 @@ ZIG_EXTERN_C struct ZigLLVMDIType *ZigLLVMCreateDebugArrayType(struct ZigLLVMDIB |
| 176 | 176 | int elem_count); |
| 177 | 177 | |
| 178 | 178 | ZIG_EXTERN_C struct ZigLLVMDIEnumerator *ZigLLVMCreateDebugEnumerator(struct ZigLLVMDIBuilder *dibuilder, |
| 179 | const char *name, int64_t val); | |
| 179 | const char *name, uint64_t val, bool isUnsigned); | |
| 180 | ||
| 181 | ||
| 182 | ZIG_EXTERN_C struct ZigLLVMDIEnumerator *ZigLLVMCreateDebugEnumeratorOfArbitraryPrecision(struct ZigLLVMDIBuilder *dibuilder, | |
| 183 | const char *name, unsigned NumWords, const uint64_t Words[], unsigned int bits, bool isUnsigned); | |
| 180 | 184 | |
| 181 | 185 | ZIG_EXTERN_C struct ZigLLVMDIType *ZigLLVMCreateDebugEnumerationType(struct ZigLLVMDIBuilder *dibuilder, |
| 182 | 186 | struct ZigLLVMDIScope *scope, const char *name, struct ZigLLVMDIFile *file, unsigned line_number, |
test/behavior/call.zig+17| ... | ... | @@ -327,3 +327,20 @@ test "inline call preserves tail call" { |
| 327 | 327 | S.foo(); |
| 328 | 328 | try expect(S.a == std.math.maxInt(u16)); |
| 329 | 329 | } |
| 330 | ||
| 331 | test "inline call doesn't re-evaluate non generic struct" { | |
| 332 | if (builtin.zig_backend == .stage1) return error.SkipZigTest; | |
| 333 | if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO | |
| 334 | if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO | |
| 335 | if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO | |
| 336 | ||
| 337 | const S = struct { | |
| 338 | fn foo(f: struct { a: u8, b: u8 }) !void { | |
| 339 | try expect(f.a == 123); | |
| 340 | try expect(f.b == 45); | |
| 341 | } | |
| 342 | }; | |
| 343 | const ArgTuple = std.meta.ArgsTuple(@TypeOf(S.foo)); | |
| 344 | try @call(.{ .modifier = .always_inline }, S.foo, ArgTuple{.{ .a = 123, .b = 45 }}); | |
| 345 | comptime try @call(.{ .modifier = .always_inline }, S.foo, ArgTuple{.{ .a = 123, .b = 45 }}); | |
| 346 | } |
test/behavior/eval.zig+15| ... | ... | @@ -1507,3 +1507,18 @@ test "inline call in @TypeOf inherits is_inline property" { |
| 1507 | 1507 | }; |
| 1508 | 1508 | try expect(S.T == void); |
| 1509 | 1509 | } |
| 1510 | ||
| 1511 | test "comptime function turns function value to function pointer" { | |
| 1512 | const S = struct { | |
| 1513 | fn fnPtr(function: anytype) *const @TypeOf(function) { | |
| 1514 | return &function; | |
| 1515 | } | |
| 1516 | fn Nil() u8 { | |
| 1517 | return 0; | |
| 1518 | } | |
| 1519 | const foo = &[_]*const fn () u8{ | |
| 1520 | fnPtr(Nil), | |
| 1521 | }; | |
| 1522 | }; | |
| 1523 | comptime try expect(S.foo[0] == &S.Nil); | |
| 1524 | } |
test/behavior/union.zig+22| ... | ... | @@ -1388,3 +1388,25 @@ test "packed union in packed struct" { |
| 1388 | 1388 | const a: S = .{ .nested = .{ .foo = 123 }, .bar = 5 }; |
| 1389 | 1389 | try expect(a.unpack() == 123); |
| 1390 | 1390 | } |
| 1391 | ||
| 1392 | test "Namespace-like union" { | |
| 1393 | const DepType = enum { | |
| 1394 | git, | |
| 1395 | http, | |
| 1396 | const DepType = @This(); | |
| 1397 | const Version = union(DepType) { | |
| 1398 | git: Git, | |
| 1399 | http: void, | |
| 1400 | const Git = enum { | |
| 1401 | branch, | |
| 1402 | tag, | |
| 1403 | commit, | |
| 1404 | fn frozen(self: Git) bool { | |
| 1405 | return self == .tag; | |
| 1406 | } | |
| 1407 | }; | |
| 1408 | }; | |
| 1409 | }; | |
| 1410 | var a: DepType.Version.Git = .tag; | |
| 1411 | try expect(a.frozen()); | |
| 1412 | } |