authorgravatar for git@vexu.euVeikka Tuominen <git@vexu.eu> 2022-11-16 12:56:51+02:00
committergravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2023-01-09 14:06:50-07:00
log4ed0cd51c0775edb35bb80786176300ecb357724
tree7c7e1d4d721aaea4b94cd7f3e9172c26ef70b0cd
parent9e50cb294b5028a2b4d2ca2b42cd0bd337428bd1

Merge pull request #13558 from Vexu/stage2-fixes

Stage2 bug fixes to get third party projects building

12 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
167167/// Returns a pointer to undefined memory.
168168/// Call `destroy` with the result to free the memory.
169169pub 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));
171171 const slice = try self.allocAdvancedWithRetAddr(T, null, 1, .exact, @returnAddress());
172172 return &slice[0];
173173}
src/Compilation.zig+1-1
......@@ -2361,7 +2361,7 @@ pub fn update(comp: *Compilation) !void {
23612361 // The `test_functions` decl has been intentionally postponed until now,
23622362 // at which point we must populate it with the list of test functions that
23632363 // have been discovered and not filtered out.
2364 try module.populateTestFunctions();
2364 try module.populateTestFunctions(main_progress_node);
23652365 }
23662366
23672367 // 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 {
64316431 }
64326432}
64336433
6434pub fn populateTestFunctions(mod: *Module) !void {
6434pub fn populateTestFunctions(
6435 mod: *Module,
6436 main_progress_node: *std.Progress.Node,
6437) !void {
64356438 const gpa = mod.gpa;
64366439 const builtin_pkg = mod.main_pkg.table.get("builtin").?;
64376440 const builtin_file = (mod.importPkg(builtin_pkg) catch unreachable).file;
64386441 const root_decl = mod.declPtr(builtin_file.root_decl.unwrap().?);
64396442 const builtin_namespace = root_decl.src_namespace;
64406443 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 }
64416455 const decl = mod.declPtr(decl_index);
64426456 var buf: Type.SlicePtrFieldTypeBuffer = undefined;
64436457 const tmp_test_fn_ty = decl.ty.slicePtrFieldType(&buf).elemType();
src/Sema.zig+19-6
......@@ -6361,6 +6361,7 @@ fn analyzeCall(
63616361 is_comptime_call,
63626362 &should_memoize,
63636363 memoized_call_key,
6364 func_ty_info.param_types,
63646365 ) catch |err| switch (err) {
63656366 error.NeededSourceLocation => {
63666367 _ = sema.inst_map.remove(inst);
......@@ -6376,6 +6377,7 @@ fn analyzeCall(
63766377 is_comptime_call,
63776378 &should_memoize,
63786379 memoized_call_key,
6380 func_ty_info.param_types,
63796381 );
63806382 return error.AnalysisFail;
63816383 },
......@@ -6612,6 +6614,7 @@ fn analyzeInlineCallArg(
66126614 is_comptime_call: bool,
66136615 should_memoize: *bool,
66146616 memoized_call_key: Module.MemoizedCall.Key,
6617 raw_param_types: []const Type,
66156618) !void {
66166619 const zir_tags = sema.code.instructions.items(.tag);
66176620 switch (zir_tags[inst]) {
......@@ -6622,8 +6625,12 @@ fn analyzeInlineCallArg(
66226625 const param_src = pl_tok.src();
66236626 const extra = sema.code.extraData(Zir.Inst.Param, pl_tok.payload_index);
66246627 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 };
66276634 new_fn_info.param_types[arg_i.*] = param_ty;
66286635 const uncasted_arg = uncasted_args[arg_i.*];
66296636 if (try sema.typeRequiresComptime(param_ty)) {
......@@ -18754,7 +18761,7 @@ fn zirIntToPtr(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai
1875418761 const addr = val.toUnsignedInt(target);
1875518762 if (!ptr_ty.isAllowzeroPtr() and addr == 0)
1875618763 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)
1875818765 return sema.fail(block, operand_src, "pointer type '{}' requires aligned address", .{ptr_ty.fmt(sema.mod)});
1875918766
1876018767 const val_payload = try sema.arena.create(Value.Payload.U64);
......@@ -22469,13 +22476,12 @@ fn fieldVal(
2246922476 );
2247022477 },
2247122478 .Union => {
22472 const union_ty = try sema.resolveTypeFields(child_type);
22473
22474 if (union_ty.getNamespace()) |namespace| {
22479 if (child_type.getNamespace()) |namespace| {
2247522480 if (try sema.namespaceLookupVal(block, src, namespace, field_name)) |inst| {
2247622481 return inst;
2247722482 }
2247822483 }
22484 const union_ty = try sema.resolveTypeFields(child_type);
2247922485 if (union_ty.unionTagType()) |enum_ty| {
2248022486 if (enum_ty.enumFieldIndex(field_name)) |field_index_usize| {
2248122487 const field_index = @intCast(u32, field_index_usize);
......@@ -27397,6 +27403,13 @@ fn analyzeRef(
2739727403 const operand_ty = sema.typeOf(operand);
2739827404
2739927405 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 }
2740027413 var anon_decl = try block.startAnonDecl();
2740127414 defer anon_decl.deinit();
2740227415 return sema.analyzeDeclRef(try anon_decl.finish(
src/codegen/llvm.zig+26-7
......@@ -1507,6 +1507,11 @@ pub const Object = struct {
15071507 };
15081508 const field_index_val = Value.initPayload(&buf_field_index.base);
15091509
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
15101515 for (field_names) |field_name, i| {
15111516 const field_name_z = try gpa.dupeZ(u8, field_name);
15121517 defer gpa.free(field_name_z);
......@@ -1514,9 +1519,25 @@ pub const Object = struct {
15141519 buf_field_index.data = @intCast(u32, i);
15151520 var buf_u64: Value.Payload.U64 = undefined;
15161521 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");
15201541 }
15211542
15221543 const di_file = try o.getDIFile(gpa, owner_decl.src_namespace.file_scope);
......@@ -1524,8 +1545,6 @@ pub const Object = struct {
15241545
15251546 const name = try ty.nameAlloc(gpa, o.module);
15261547 defer gpa.free(name);
1527 var buffer: Type.Payload.Bits = undefined;
1528 const int_ty = ty.intTagType(&buffer);
15291548
15301549 const enum_di_ty = dib.createEnumerationType(
15311550 di_scope,
......@@ -2118,7 +2137,8 @@ pub const Object = struct {
21182137 break :blk fwd_decl;
21192138 };
21202139
2121 if (!ty.hasRuntimeBitsIgnoreComptime()) {
2140 const union_obj = ty.cast(Type.Payload.Union).?.data;
2141 if (!union_obj.haveFieldTypes() or !ty.hasRuntimeBitsIgnoreComptime()) {
21222142 const union_di_ty = try o.makeEmptyNamespaceDIType(owner_decl_index);
21232143 dib.replaceTemporary(fwd_decl, union_di_ty);
21242144 // The recursive call to `lowerDebugType` via `makeEmptyNamespaceDIType`
......@@ -2128,7 +2148,6 @@ pub const Object = struct {
21282148 }
21292149
21302150 const layout = ty.unionGetLayout(target);
2131 const union_obj = ty.cast(Type.Payload.Union).?.data;
21322151
21332152 if (layout.payload_size == 0) {
21342153 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 {
16621662 extern fn ZigLLVMCreateDebugEnumerator(
16631663 dib: *DIBuilder,
16641664 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,
16661677 ) *DIEnumerator;
16671678
16681679 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
91179117
91189118 // https://github.com/ziglang/zig/issues/645
91199119 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);
91219121 }
91229122
91239123 ZigType *tag_int_type = enum_type->data.enumeration.tag_int_type;
......@@ -9728,10 +9728,10 @@ static void resolve_llvm_types_anyerror(CodeGen *g) {
97289728 entry->llvm_type = get_llvm_type(g, g->err_tag_type);
97299729 ZigList<ZigLLVMDIEnumerator *> err_enumerators = {};
97309730 // 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));
97329732 for (size_t i = 1; i < g->errors_by_index.length; i += 1) {
97339733 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));
97359735 }
97369736
97379737 // create debug type for error sets
src/zig_llvm.cpp+10-2
......@@ -594,8 +594,16 @@ ZigLLVMDIType *ZigLLVMCreateDebugArrayType(ZigLLVMDIBuilder *dibuilder, uint64_t
594594 return reinterpret_cast<ZigLLVMDIType*>(di_type);
595595}
596596
597ZigLLVMDIEnumerator *ZigLLVMCreateDebugEnumerator(ZigLLVMDIBuilder *dibuilder, const char *name, int64_t val) {
598 DIEnumerator *di_enumerator = reinterpret_cast<DIBuilder*>(dibuilder)->createEnumerator(name, val);
597ZigLLVMDIEnumerator *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
602ZigLLVMDIEnumerator *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));
599607 return reinterpret_cast<ZigLLVMDIEnumerator*>(di_enumerator);
600608}
601609
src/zig_llvm.h+5-1
......@@ -176,7 +176,11 @@ ZIG_EXTERN_C struct ZigLLVMDIType *ZigLLVMCreateDebugArrayType(struct ZigLLVMDIB
176176 int elem_count);
177177
178178ZIG_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
182ZIG_EXTERN_C struct ZigLLVMDIEnumerator *ZigLLVMCreateDebugEnumeratorOfArbitraryPrecision(struct ZigLLVMDIBuilder *dibuilder,
183 const char *name, unsigned NumWords, const uint64_t Words[], unsigned int bits, bool isUnsigned);
180184
181185ZIG_EXTERN_C struct ZigLLVMDIType *ZigLLVMCreateDebugEnumerationType(struct ZigLLVMDIBuilder *dibuilder,
182186 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" {
327327 S.foo();
328328 try expect(S.a == std.math.maxInt(u16));
329329}
330
331test "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" {
15071507 };
15081508 try expect(S.T == void);
15091509}
1510
1511test "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" {
13881388 const a: S = .{ .nested = .{ .foo = 123 }, .bar = 5 };
13891389 try expect(a.unpack() == 123);
13901390}
1391
1392test "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}