diff options
| author | Andrew Kelley <andrew@ziglang.org> | 2022-02-27 15:29:03 -0500 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2022-02-27 15:29:03 -0500 |
| commit | b5066fdae292f44a6e4c60db9a9db012672dd10e (patch) | |
| tree | 6367bdaa9d4f19ed8905061a670aaff5e6f974f6 /src | |
| parent | c03b733f0999418b234067cac51eac0e4412dfe1 (diff) | |
| parent | 9f59189c954298fd2be576b7e3dd26388d07751d (diff) | |
| download | zig-b5066fdae292f44a6e4c60db9a9db012672dd10e.tar.gz zig-b5066fdae292f44a6e4c60db9a9db012672dd10e.zip | |
Merge pull request #11001 from Vexu/stage2
stage2: make formatted printing work
Diffstat (limited to 'src')
| -rw-r--r-- | src/AstGen.zig | 9 | ||||
| -rw-r--r-- | src/Module.zig | 2 | ||||
| -rw-r--r-- | src/Sema.zig | 32 | ||||
| -rw-r--r-- | src/codegen/llvm.zig | 2 | ||||
| -rw-r--r-- | src/type.zig | 2 |
5 files changed, 34 insertions, 13 deletions
diff --git a/src/AstGen.zig b/src/AstGen.zig index b9ac0b5c43..e8d612fbc7 100644 --- a/src/AstGen.zig +++ b/src/AstGen.zig @@ -244,10 +244,14 @@ pub const ResultLoc = union(enum) { fn strategy(rl: ResultLoc, block_scope: *GenZir) Strategy { switch (rl) { // In this branch there will not be any store_to_block_ptr instructions. - .discard, .none, .ty, .coerced_ty, .ref => return .{ + .none, .ty, .coerced_ty, .ref => return .{ .tag = .break_operand, .elide_store_to_block_ptr_instructions = false, }, + .discard => return .{ + .tag = .break_void, + .elide_store_to_block_ptr_instructions = false, + }, // The pointer got passed through to the sub-expressions, so we will use // break_void here. // In this branch there will not be any store_to_block_ptr instructions. @@ -1766,6 +1770,9 @@ fn breakExpr(parent_gz: *GenZir, parent_scope: *Scope, node: Ast.Node.Index) Inn // we assume the result location is written, and we break with void. _ = try parent_gz.addBreak(break_tag, block_inst, .void_value); }, + .discard => { + _ = try parent_gz.addBreak(break_tag, block_inst, .void_value); + }, else => { _ = try parent_gz.addBreak(break_tag, block_inst, operand); }, diff --git a/src/Module.zig b/src/Module.zig index 048895e5bf..9bc61aa708 100644 --- a/src/Module.zig +++ b/src/Module.zig @@ -3762,7 +3762,7 @@ fn semaDecl(mod: *Module, decl: *Decl) !bool { // Note this resolves the type of the Decl, not the value; if this Decl // is a struct, for example, this resolves `type` (which needs no resolution), // not the struct itself. - try sema.resolveTypeLayout(&block_scope, src, decl_tv.ty); + try sema.resolveTypeFully(&block_scope, src, decl_tv.ty); const decl_arena_state = try decl_arena_allocator.create(std.heap.ArenaAllocator.State); diff --git a/src/Sema.zig b/src/Sema.zig index 8e93d2525b..7570cbb21b 100644 --- a/src/Sema.zig +++ b/src/Sema.zig @@ -4494,6 +4494,10 @@ fn analyzeCall( try sema.emitBackwardBranch(&child_block, call_src); + // Whether this call should be memoized, set to false if the call can mutate + // comptime state. + var should_memoize = true; + // This will have return instructions analyzed as break instructions to // the block_inst above. Here we are performing "comptime/inline semantic analysis" // for a function body, which means we must map the parameter ZIR instructions to @@ -4527,6 +4531,7 @@ fn analyzeCall( }, else => {}, } + should_memoize = should_memoize and !arg_val.isComptimeMutablePtr(); memoized_call_key.args[arg_i] = .{ .ty = param_ty, .val = arg_val, @@ -4552,6 +4557,7 @@ fn analyzeCall( }, else => {}, } + should_memoize = should_memoize and !arg_val.isComptimeMutablePtr(); memoized_call_key.args[arg_i] = .{ .ty = sema.typeOf(uncasted_arg), .val = arg_val, @@ -4597,7 +4603,7 @@ fn analyzeCall( // This `res2` is here instead of directly breaking from `res` due to a stage1 // bug generating invalid LLVM IR. const res2: Air.Inst.Ref = res2: { - if (is_comptime_call) { + if (should_memoize and is_comptime_call) { if (mod.memoized_calls.get(memoized_call_key)) |result| { const ty_inst = try sema.addType(fn_ret_ty); try sema.air_values.append(gpa, result.val); @@ -4621,7 +4627,7 @@ fn analyzeCall( break :result try sema.analyzeBlockBody(block, call_src, &child_block, merges); }; - if (is_comptime_call) { + if (should_memoize and is_comptime_call) { const result_val = try sema.resolveConstMaybeUndefVal(block, call_src, result); // TODO: check whether any external comptime memory was mutated by the @@ -10975,8 +10981,7 @@ fn zirCondbr( if (try sema.resolveDefinedValue(parent_block, src, cond)) |cond_val| { const body = if (cond_val.toBool()) then_body else else_body; - _ = try sema.analyzeBody(parent_block, body); - return always_noreturn; + return sema.analyzeBodyInner(parent_block, body); } const gpa = sema.gpa; @@ -11948,19 +11953,27 @@ fn zirReify(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.I var buffer: Value.ToTypeBuffer = undefined; const child_ty = child_val.toType(&buffer); + const ptr_size = size_val.toEnum(std.builtin.TypeInfo.Pointer.Size); + + var actual_sentinel: ?Value = null; if (!sentinel_val.isNull()) { - return sema.fail(block, src, "TODO: implement zirReify for pointer with non-null sentinel", .{}); + if (ptr_size == .One or ptr_size == .C) { + return sema.fail(block, src, "sentinels are only allowed on slices and unknown-length pointers", .{}); + } + const sentinel_ptr_val = sentinel_val.castTag(.opt_payload).?.data; + const ptr_ty = try Type.ptr(sema.arena, .{ .@"addrspace" = .generic, .pointee_type = child_ty }); + actual_sentinel = (try sema.pointerDeref(block, src, sentinel_ptr_val, ptr_ty)).?; } const ty = try Type.ptr(sema.arena, .{ - .size = size_val.toEnum(std.builtin.TypeInfo.Pointer.Size), + .size = ptr_size, .mutable = !is_const_val.toBool(), .@"volatile" = is_volatile_val.toBool(), .@"align" = @intCast(u8, alignment_val.toUnsignedInt()), // TODO: Validate this value. .@"addrspace" = address_space_val.toEnum(std.builtin.AddressSpace), .pointee_type = try child_ty.copy(sema.arena), .@"allowzero" = is_allowzero_val.toBool(), - .sentinel = null, + .sentinel = actual_sentinel, }); return sema.addType(ty); }, @@ -12070,6 +12083,7 @@ fn zirIntToPtr(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai const type_src: LazySrcLoc = .{ .node_offset_builtin_call_arg0 = inst_data.src_node }; const type_res = try sema.resolveType(block, src, extra.lhs); try sema.checkPtrType(block, type_src, type_res); + _ = try sema.resolveTypeLayout(block, src, type_res.childType()); const ptr_align = type_res.ptrAlignment(sema.mod.getTarget()); if (try sema.resolveDefinedValue(block, operand_src, operand_coerced)) |val| { @@ -17587,7 +17601,7 @@ fn resolvePeerTypes( return chosen_ty; } -pub fn resolveTypeLayout( +fn resolveTypeLayout( sema: *Sema, block: *Block, src: LazySrcLoc, @@ -17660,7 +17674,7 @@ fn resolveUnionLayout( union_obj.status = .have_layout; } -fn resolveTypeFully( +pub fn resolveTypeFully( sema: *Sema, block: *Block, src: LazySrcLoc, diff --git a/src/codegen/llvm.zig b/src/codegen/llvm.zig index c0642a59de..e349f0186e 100644 --- a/src/codegen/llvm.zig +++ b/src/codegen/llvm.zig @@ -3892,7 +3892,7 @@ pub const FuncGen = struct { return self.builder.buildBitCast(operand, llvm_dest_ty.pointerType(0), ""); } - if (operand_ty.zigTypeTag() == .Int and inst_ty.zigTypeTag() == .Pointer) { + if (operand_ty.zigTypeTag() == .Int and inst_ty.isPtrAtRuntime()) { return self.builder.buildIntToPtr(operand, llvm_dest_ty, ""); } diff --git a/src/type.zig b/src/type.zig index 68085500bc..a84a0f4520 100644 --- a/src/type.zig +++ b/src/type.zig @@ -2602,7 +2602,7 @@ pub const Type = extern union { const payload = self.castTag(.pointer).?.data; return payload.@"allowzero"; }, - else => false, + else => return self.zigTypeTag() == .Optional, }; } |
