Commit 069c83d58c
Changed files (10)
lib
std
special
test
lib/std/special/compiler_rt.zig
@@ -81,6 +81,81 @@ comptime {
@export(__mulodi4, .{ .name = "__mulodi4", .linkage = linkage });
}
+ if (builtin.os.tag == .windows) {
+ // Default stack-probe functions emitted by LLVM
+ if (is_mingw) {
+ const _chkstk = @import("compiler_rt/stack_probe.zig")._chkstk;
+ @export(_chkstk, .{ .name = "_alloca", .linkage = strong_linkage });
+ const ___chkstk_ms = @import("compiler_rt/stack_probe.zig").___chkstk_ms;
+ @export(___chkstk_ms, .{ .name = "___chkstk_ms", .linkage = strong_linkage });
+ } else if (!builtin.link_libc) {
+ // This symbols are otherwise exported by MSVCRT.lib
+ const _chkstk = @import("compiler_rt/stack_probe.zig")._chkstk;
+ @export(_chkstk, .{ .name = "_chkstk", .linkage = strong_linkage });
+ const __chkstk = @import("compiler_rt/stack_probe.zig").__chkstk;
+ @export(__chkstk, .{ .name = "__chkstk", .linkage = strong_linkage });
+ }
+
+ switch (arch) {
+ .i386 => {
+ const __divti3 = @import("compiler_rt/divti3.zig").__divti3;
+ @export(__divti3, .{ .name = "__divti3", .linkage = linkage });
+ const __modti3 = @import("compiler_rt/modti3.zig").__modti3;
+ @export(__modti3, .{ .name = "__modti3", .linkage = linkage });
+ const __multi3 = @import("compiler_rt/multi3.zig").__multi3;
+ @export(__multi3, .{ .name = "__multi3", .linkage = linkage });
+ const __udivti3 = @import("compiler_rt/udivti3.zig").__udivti3;
+ @export(__udivti3, .{ .name = "__udivti3", .linkage = linkage });
+ const __udivmodti4 = @import("compiler_rt/udivmodti4.zig").__udivmodti4;
+ @export(__udivmodti4, .{ .name = "__udivmodti4", .linkage = linkage });
+ const __umodti3 = @import("compiler_rt/umodti3.zig").__umodti3;
+ @export(__umodti3, .{ .name = "__umodti3", .linkage = linkage });
+ },
+ .x86_64 => {
+ // The "ti" functions must use Vector(2, u64) parameter types to adhere to the ABI
+ // that LLVM expects compiler-rt to have.
+ const __divti3_windows_x86_64 = @import("compiler_rt/divti3.zig").__divti3_windows_x86_64;
+ @export(__divti3_windows_x86_64, .{ .name = "__divti3", .linkage = linkage });
+ const __modti3_windows_x86_64 = @import("compiler_rt/modti3.zig").__modti3_windows_x86_64;
+ @export(__modti3_windows_x86_64, .{ .name = "__modti3", .linkage = linkage });
+ const __multi3_windows_x86_64 = @import("compiler_rt/multi3.zig").__multi3_windows_x86_64;
+ @export(__multi3_windows_x86_64, .{ .name = "__multi3", .linkage = linkage });
+ const __udivti3_windows_x86_64 = @import("compiler_rt/udivti3.zig").__udivti3_windows_x86_64;
+ @export(__udivti3_windows_x86_64, .{ .name = "__udivti3", .linkage = linkage });
+ const __udivmodti4_windows_x86_64 = @import("compiler_rt/udivmodti4.zig").__udivmodti4_windows_x86_64;
+ @export(__udivmodti4_windows_x86_64, .{ .name = "__udivmodti4", .linkage = linkage });
+ const __umodti3_windows_x86_64 = @import("compiler_rt/umodti3.zig").__umodti3_windows_x86_64;
+ @export(__umodti3_windows_x86_64, .{ .name = "__umodti3", .linkage = linkage });
+ },
+ else => {},
+ }
+ if (arch.isAARCH64()) {
+ const __chkstk = @import("compiler_rt/stack_probe.zig").__chkstk;
+ @export(__chkstk, .{ .name = "__chkstk", .linkage = strong_linkage });
+ const __divti3_windows = @import("compiler_rt/divti3.zig").__divti3;
+ @export(__divti3_windows, .{ .name = "__divti3", .linkage = linkage });
+ const __modti3 = @import("compiler_rt/modti3.zig").__modti3;
+ @export(__modti3, .{ .name = "__modti3", .linkage = linkage });
+ const __udivti3_windows = @import("compiler_rt/udivti3.zig").__udivti3;
+ @export(__udivti3_windows, .{ .name = "__udivti3", .linkage = linkage });
+ const __umodti3 = @import("compiler_rt/umodti3.zig").__umodti3;
+ @export(__umodti3, .{ .name = "__umodti3", .linkage = linkage });
+ }
+ } else {
+ const __divti3 = @import("compiler_rt/divti3.zig").__divti3;
+ @export(__divti3, .{ .name = "__divti3", .linkage = linkage });
+ const __modti3 = @import("compiler_rt/modti3.zig").__modti3;
+ @export(__modti3, .{ .name = "__modti3", .linkage = linkage });
+ const __multi3 = @import("compiler_rt/multi3.zig").__multi3;
+ @export(__multi3, .{ .name = "__multi3", .linkage = linkage });
+ const __udivti3 = @import("compiler_rt/udivti3.zig").__udivti3;
+ @export(__udivti3, .{ .name = "__udivti3", .linkage = linkage });
+ const __udivmodti4 = @import("compiler_rt/udivmodti4.zig").__udivmodti4;
+ @export(__udivmodti4, .{ .name = "__udivmodti4", .linkage = linkage });
+ const __umodti3 = @import("compiler_rt/umodti3.zig").__umodti3;
+ @export(__umodti3, .{ .name = "__umodti3", .linkage = linkage });
+ }
+
if (!builtin.zig_is_stage2) {
if (!long_double_is_f128) {
// TODO implement these
@@ -552,81 +627,6 @@ comptime {
@export(__unordtf2, .{ .name = "__unordkf2", .linkage = linkage });
}
- if (builtin.os.tag == .windows) {
- // Default stack-probe functions emitted by LLVM
- if (is_mingw) {
- const _chkstk = @import("compiler_rt/stack_probe.zig")._chkstk;
- @export(_chkstk, .{ .name = "_alloca", .linkage = strong_linkage });
- const ___chkstk_ms = @import("compiler_rt/stack_probe.zig").___chkstk_ms;
- @export(___chkstk_ms, .{ .name = "___chkstk_ms", .linkage = strong_linkage });
- } else if (!builtin.link_libc) {
- // This symbols are otherwise exported by MSVCRT.lib
- const _chkstk = @import("compiler_rt/stack_probe.zig")._chkstk;
- @export(_chkstk, .{ .name = "_chkstk", .linkage = strong_linkage });
- const __chkstk = @import("compiler_rt/stack_probe.zig").__chkstk;
- @export(__chkstk, .{ .name = "__chkstk", .linkage = strong_linkage });
- }
-
- switch (arch) {
- .i386 => {
- const __divti3 = @import("compiler_rt/divti3.zig").__divti3;
- @export(__divti3, .{ .name = "__divti3", .linkage = linkage });
- const __modti3 = @import("compiler_rt/modti3.zig").__modti3;
- @export(__modti3, .{ .name = "__modti3", .linkage = linkage });
- const __multi3 = @import("compiler_rt/multi3.zig").__multi3;
- @export(__multi3, .{ .name = "__multi3", .linkage = linkage });
- const __udivti3 = @import("compiler_rt/udivti3.zig").__udivti3;
- @export(__udivti3, .{ .name = "__udivti3", .linkage = linkage });
- const __udivmodti4 = @import("compiler_rt/udivmodti4.zig").__udivmodti4;
- @export(__udivmodti4, .{ .name = "__udivmodti4", .linkage = linkage });
- const __umodti3 = @import("compiler_rt/umodti3.zig").__umodti3;
- @export(__umodti3, .{ .name = "__umodti3", .linkage = linkage });
- },
- .x86_64 => {
- // The "ti" functions must use Vector(2, u64) parameter types to adhere to the ABI
- // that LLVM expects compiler-rt to have.
- const __divti3_windows_x86_64 = @import("compiler_rt/divti3.zig").__divti3_windows_x86_64;
- @export(__divti3_windows_x86_64, .{ .name = "__divti3", .linkage = linkage });
- const __modti3_windows_x86_64 = @import("compiler_rt/modti3.zig").__modti3_windows_x86_64;
- @export(__modti3_windows_x86_64, .{ .name = "__modti3", .linkage = linkage });
- const __multi3_windows_x86_64 = @import("compiler_rt/multi3.zig").__multi3_windows_x86_64;
- @export(__multi3_windows_x86_64, .{ .name = "__multi3", .linkage = linkage });
- const __udivti3_windows_x86_64 = @import("compiler_rt/udivti3.zig").__udivti3_windows_x86_64;
- @export(__udivti3_windows_x86_64, .{ .name = "__udivti3", .linkage = linkage });
- const __udivmodti4_windows_x86_64 = @import("compiler_rt/udivmodti4.zig").__udivmodti4_windows_x86_64;
- @export(__udivmodti4_windows_x86_64, .{ .name = "__udivmodti4", .linkage = linkage });
- const __umodti3_windows_x86_64 = @import("compiler_rt/umodti3.zig").__umodti3_windows_x86_64;
- @export(__umodti3_windows_x86_64, .{ .name = "__umodti3", .linkage = linkage });
- },
- else => {},
- }
- if (arch.isAARCH64()) {
- const __chkstk = @import("compiler_rt/stack_probe.zig").__chkstk;
- @export(__chkstk, .{ .name = "__chkstk", .linkage = strong_linkage });
- const __divti3_windows = @import("compiler_rt/divti3.zig").__divti3;
- @export(__divti3_windows, .{ .name = "__divti3", .linkage = linkage });
- const __modti3 = @import("compiler_rt/modti3.zig").__modti3;
- @export(__modti3, .{ .name = "__modti3", .linkage = linkage });
- const __udivti3_windows = @import("compiler_rt/udivti3.zig").__udivti3;
- @export(__udivti3_windows, .{ .name = "__udivti3", .linkage = linkage });
- const __umodti3 = @import("compiler_rt/umodti3.zig").__umodti3;
- @export(__umodti3, .{ .name = "__umodti3", .linkage = linkage });
- }
- } else {
- const __divti3 = @import("compiler_rt/divti3.zig").__divti3;
- @export(__divti3, .{ .name = "__divti3", .linkage = linkage });
- const __modti3 = @import("compiler_rt/modti3.zig").__modti3;
- @export(__modti3, .{ .name = "__modti3", .linkage = linkage });
- const __multi3 = @import("compiler_rt/multi3.zig").__multi3;
- @export(__multi3, .{ .name = "__multi3", .linkage = linkage });
- const __udivti3 = @import("compiler_rt/udivti3.zig").__udivti3;
- @export(__udivti3, .{ .name = "__udivti3", .linkage = linkage });
- const __udivmodti4 = @import("compiler_rt/udivmodti4.zig").__udivmodti4;
- @export(__udivmodti4, .{ .name = "__udivmodti4", .linkage = linkage });
- const __umodti3 = @import("compiler_rt/umodti3.zig").__umodti3;
- @export(__umodti3, .{ .name = "__umodti3", .linkage = linkage });
- }
-
_ = @import("compiler_rt/atomics.zig");
@export(fmaq, .{ .name = "fmaq", .linkage = linkage });
src/AstGen.zig
@@ -276,17 +276,30 @@ fn typeExpr(gz: *GenZir, scope: *Scope, type_node: Ast.Node.Index) InnerError!Zi
return expr(gz, scope, coerced_type_rl, type_node);
}
+fn reachableTypeExpr(
+ gz: *GenZir,
+ scope: *Scope,
+ type_node: Ast.Node.Index,
+ reachable_node: Ast.Node.Index,
+) InnerError!Zir.Inst.Ref {
+ const prev_force_comptime = gz.force_comptime;
+ gz.force_comptime = true;
+ defer gz.force_comptime = prev_force_comptime;
+
+ return reachableExpr(gz, scope, coerced_type_rl, type_node, reachable_node);
+}
+
/// Same as `expr` but fails with a compile error if the result type is `noreturn`.
fn reachableExpr(
gz: *GenZir,
scope: *Scope,
rl: ResultLoc,
node: Ast.Node.Index,
- src_node: Ast.Node.Index,
+ reachable_node: Ast.Node.Index,
) InnerError!Zir.Inst.Ref {
const result_inst = try expr(gz, scope, rl, node);
if (gz.refIsNoReturn(result_inst)) {
- return gz.astgen.failNodeNotes(src_node, "unreachable code", .{}, &[_]u32{
+ return gz.astgen.failNodeNotes(reachable_node, "unreachable code", .{}, &[_]u32{
try gz.astgen.errNoteNode(node, "control flow is diverted here", .{}),
});
}
@@ -2040,7 +2053,6 @@ fn unusedResultExpr(gz: *GenZir, scope: *Scope, statement: Ast.Node.Index) Inner
.as_node,
.bit_and,
.bitcast,
- .bitcast_result_ptr,
.bit_or,
.block,
.block_inline,
@@ -7160,42 +7172,13 @@ fn bitCast(
lhs: Ast.Node.Index,
rhs: Ast.Node.Index,
) InnerError!Zir.Inst.Ref {
- const astgen = gz.astgen;
- const dest_type = try typeExpr(gz, scope, lhs);
- switch (rl) {
- .none, .discard, .ty, .coerced_ty => {
- const operand = try expr(gz, scope, .none, rhs);
- const result = try gz.addPlNode(.bitcast, node, Zir.Inst.Bin{
- .lhs = dest_type,
- .rhs = operand,
- });
- return rvalue(gz, rl, result, node);
- },
- .ref => {
- return astgen.failNode(node, "cannot take address of `@bitCast` result", .{});
- },
- .ptr, .inferred_ptr => |result_ptr| {
- return bitCastRlPtr(gz, scope, node, dest_type, result_ptr, rhs);
- },
- .block_ptr => |block| {
- return bitCastRlPtr(gz, scope, node, dest_type, block.rl_ptr, rhs);
- },
- }
-}
-
-fn bitCastRlPtr(
- gz: *GenZir,
- scope: *Scope,
- node: Ast.Node.Index,
- dest_type: Zir.Inst.Ref,
- result_ptr: Zir.Inst.Ref,
- rhs: Ast.Node.Index,
-) InnerError!Zir.Inst.Ref {
- const casted_result_ptr = try gz.addPlNode(.bitcast_result_ptr, node, Zir.Inst.Bin{
+ const dest_type = try reachableTypeExpr(gz, scope, lhs, node);
+ const operand = try reachableExpr(gz, scope, .none, rhs, node);
+ const result = try gz.addPlNode(.bitcast, node, Zir.Inst.Bin{
.lhs = dest_type,
- .rhs = result_ptr,
+ .rhs = operand,
});
- return expr(gz, scope, .{ .ptr = casted_result_ptr }, rhs);
+ return rvalue(gz, rl, result, node);
}
fn typeOf(
src/Module.zig
@@ -317,6 +317,7 @@ pub const WipCaptureScope = struct {
assert(!self.finalized);
// use a temp to avoid unintentional aliasing due to RLS
const tmp = try self.scope.captures.clone(self.perm_arena);
+ self.scope.captures.deinit(self.gpa);
self.scope.captures = tmp;
self.finalized = true;
}
src/print_zir.zig
@@ -349,7 +349,6 @@ const Writer = struct {
.reduce,
.atomic_load,
.bitcast,
- .bitcast_result_ptr,
.vector_type,
.maximum,
.minimum,
src/Sema.zig
@@ -513,7 +513,6 @@ pub fn analyzeBody(
.bit_not => try sema.zirBitNot(block, inst),
.bit_or => try sema.zirBitwise(block, inst, .bit_or),
.bitcast => try sema.zirBitcast(block, inst),
- .bitcast_result_ptr => try sema.zirBitcastResultPtr(block, inst),
.suspend_block => try sema.zirSuspendBlock(block, inst),
.bool_not => try sema.zirBoolNot(block, inst),
.bool_br_and => try sema.zirBoolBr(block, inst, false),
@@ -1385,12 +1384,6 @@ pub fn resolveInstValue(
};
}
-fn zirBitcastResultPtr(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.Inst.Ref {
- const inst_data = sema.code.instructions.items(.data)[inst].pl_node;
- const src = inst_data.src();
- return sema.fail(block, src, "TODO implement zir_sema.zirBitcastResultPtr", .{});
-}
-
fn zirCoerceResultPtr(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.Inst.Ref {
const tracy = trace(@src());
defer tracy.end();
src/value.zig
@@ -1015,6 +1015,14 @@ pub const Value = extern union {
const bits = ty.intInfo(target).bits;
bigint.writeTwosComplement(buffer, bits, target.cpu.arch.endian());
},
+ .Enum => {
+ var enum_buffer: Payload.U64 = undefined;
+ const int_val = val.enumToInt(ty, &enum_buffer);
+ var bigint_buffer: BigIntSpace = undefined;
+ const bigint = int_val.toBigInt(&bigint_buffer);
+ const bits = ty.intInfo(target).bits;
+ bigint.writeTwosComplement(buffer, bits, target.cpu.arch.endian());
+ },
.Float => switch (ty.floatBits(target)) {
16 => return floatWriteToMemory(f16, val.toFloat(f16), target, buffer),
32 => return floatWriteToMemory(f32, val.toFloat(f32), target, buffer),
@@ -1022,6 +1030,19 @@ pub const Value = extern union {
128 => return floatWriteToMemory(f128, val.toFloat(f128), target, buffer),
else => unreachable,
},
+ .Array, .Vector => {
+ const len = ty.arrayLen();
+ const elem_ty = ty.childType();
+ const elem_size = elem_ty.abiSize(target);
+ var elem_i: usize = 0;
+ var elem_value_buf: ElemValueBuffer = undefined;
+ var buf_off: usize = 0;
+ while (elem_i < len) : (elem_i += 1) {
+ const elem_val = val.elemValueBuffer(elem_i, &elem_value_buf);
+ writeToMemory(elem_val, elem_ty, target, buffer[buf_off..]);
+ buf_off += elem_size;
+ }
+ },
else => @panic("TODO implement writeToMemory for more types"),
}
}
src/Zir.zig
@@ -240,10 +240,6 @@ pub const Inst = struct {
/// Reinterpret the memory representation of a value as a different type.
/// Uses the pl_node field with payload `Bin`.
bitcast,
- /// A typed result location pointer is bitcasted to a new result location pointer.
- /// The new result location pointer has an inferred type.
- /// Uses the pl_node field with payload `Bin`.
- bitcast_result_ptr,
/// Bitwise NOT. `~`
/// Uses `un_node`.
bit_not,
@@ -977,7 +973,6 @@ pub const Inst = struct {
.as_node,
.bit_and,
.bitcast,
- .bitcast_result_ptr,
.bit_or,
.block,
.block_inline,
@@ -1235,7 +1230,6 @@ pub const Inst = struct {
.as_node = .pl_node,
.bit_and = .pl_node,
.bitcast = .pl_node,
- .bitcast_result_ptr = .pl_node,
.bit_not = .un_node,
.bit_or = .pl_node,
.block = .pl_node,
test/behavior/bitcast.zig
@@ -42,3 +42,25 @@ test "nested bitcast" {
try S.foo(42);
comptime try S.foo(42);
}
+
+test "@bitCast enum to its integer type" {
+ const SOCK = enum(c_int) {
+ A,
+ B,
+
+ fn testBitCastExternEnum() !void {
+ var SOCK_DGRAM = @This().B;
+ var sock_dgram = @bitCast(c_int, SOCK_DGRAM);
+ try expect(sock_dgram == 1);
+ }
+ };
+
+ try SOCK.testBitCastExternEnum();
+ comptime try SOCK.testBitCastExternEnum();
+}
+
+// issue #3010: compiler segfault
+test "bitcast literal [4]u8 param to u32" {
+ const ip = @bitCast(u32, [_]u8{ 255, 255, 255, 255 });
+ try expect(ip == maxInt(u32));
+}
test/behavior/bitcast_stage1.zig
@@ -5,22 +5,6 @@ const expectEqual = std.testing.expectEqual;
const maxInt = std.math.maxInt;
const native_endian = builtin.target.cpu.arch.endian();
-test "@bitCast enum to its integer type" {
- const SOCK = enum(c_int) {
- A,
- B,
-
- fn testBitCastExternEnum() !void {
- var SOCK_DGRAM = @This().B;
- var sock_dgram = @bitCast(c_int, SOCK_DGRAM);
- try expect(sock_dgram == 1);
- }
- };
-
- try SOCK.testBitCastExternEnum();
- comptime try SOCK.testBitCastExternEnum();
-}
-
test "@bitCast packed structs at runtime and comptime" {
const Full = packed struct {
number: u16,
@@ -111,12 +95,6 @@ test "implicit cast to error union by returning" {
comptime try S.entry();
}
-// issue #3010: compiler segfault
-test "bitcast literal [4]u8 param to u32" {
- const ip = @bitCast(u32, [_]u8{ 255, 255, 255, 255 });
- try expect(ip == maxInt(u32));
-}
-
test "bitcast packed struct literal to byte" {
const Foo = packed struct {
value: u8,
test/behavior.zig
@@ -47,6 +47,7 @@ test {
_ = @import("behavior/pointers.zig");
_ = @import("behavior/ptrcast.zig");
_ = @import("behavior/pub_enum.zig");
+ _ = @import("behavior/saturating_arithmetic.zig");
_ = @import("behavior/sizeof_and_typeof.zig");
_ = @import("behavior/slice.zig");
_ = @import("behavior/struct.zig");
@@ -150,11 +151,6 @@ test {
_ = @import("behavior/ptrcast_stage1.zig");
_ = @import("behavior/ref_var_in_if_after_if_2nd_switch_prong.zig");
_ = @import("behavior/reflection.zig");
- {
- // Checklist for getting saturating_arithmetic.zig passing for stage2:
- // * add __udivti3 to compiler-rt
- _ = @import("behavior/saturating_arithmetic.zig");
- }
_ = @import("behavior/select.zig");
_ = @import("behavior/shuffle.zig");
_ = @import("behavior/sizeof_and_typeof_stage1.zig");