authorgravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2022-06-01 16:45:28-07:00
committergravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2022-06-01 16:45:28-07:00
log288e89b606b46328a5ab358b2eef2c5dc277bc8f
treece898990af2eec71a7d515cc317b7e7b096d76b5
parenta4cdb49a58f62776b73ad873b25243e65ac29266

Sema: fix compiler crash with comptime arithmetic involving `@ptrToInt`


3 files changed, 47 insertions(+), 21 deletions(-)

src/Sema.zig+39-13
...@@ -1540,6 +1540,24 @@ fn resolveMaybeUndefVal(...@@ -1540,6 +1540,24 @@ fn resolveMaybeUndefVal(
1540 }1540 }
1541}1541}
15421542
1543/// Value Tag `variable` results in `null`.
1544/// Value Tag `undef` results in the Value.
1545/// Value Tag `generic_poison` causes `error.GenericPoison` to be returned.
1546/// Value Tag `decl_ref` and `decl_ref_mut` or any nested such value results in `null`.
1547fn resolveMaybeUndefValIntable(
1548 sema: *Sema,
1549 block: *Block,
1550 src: LazySrcLoc,
1551 inst: Air.Inst.Ref,
1552) CompileError!?Value {
1553 const val = (try sema.resolveMaybeUndefValAllowVariables(block, src, inst)) orelse return null;
1554 switch (val.tag()) {
1555 .variable, .decl_ref, .decl_ref_mut => return null,
1556 .generic_poison => return error.GenericPoison,
1557 else => return val,
1558 }
1559}
1560
1543/// Returns all Value tags including `variable` and `undef`.1561/// Returns all Value tags including `variable` and `undef`.
1544fn resolveMaybeUndefValAllowVariables(1562fn resolveMaybeUndefValAllowVariables(
1545 sema: *Sema,1563 sema: *Sema,
...@@ -9302,19 +9320,27 @@ fn zirBitwise(...@@ -9302,19 +9320,27 @@ fn zirBitwise(
9302 return sema.fail(block, src, "invalid operands to binary bitwise expression: '{s}' and '{s}'", .{ @tagName(lhs_ty.zigTypeTag()), @tagName(rhs_ty.zigTypeTag()) });9320 return sema.fail(block, src, "invalid operands to binary bitwise expression: '{s}' and '{s}'", .{ @tagName(lhs_ty.zigTypeTag()), @tagName(rhs_ty.zigTypeTag()) });
9303 }9321 }
93049322
9305 if (try sema.resolveMaybeUndefVal(block, lhs_src, casted_lhs)) |lhs_val| {9323 const runtime_src = runtime: {
9306 if (try sema.resolveMaybeUndefVal(block, rhs_src, casted_rhs)) |rhs_val| {9324 // TODO: ask the linker what kind of relocations are available, and
9307 const result_val = switch (air_tag) {9325 // in some cases emit a Value that means "this decl's address AND'd with this operand".
9308 .bit_and => try lhs_val.bitwiseAnd(rhs_val, resolved_type, sema.arena, target),9326 if (try sema.resolveMaybeUndefValIntable(block, lhs_src, casted_lhs)) |lhs_val| {
9309 .bit_or => try lhs_val.bitwiseOr(rhs_val, resolved_type, sema.arena, target),9327 if (try sema.resolveMaybeUndefValIntable(block, rhs_src, casted_rhs)) |rhs_val| {
9310 .xor => try lhs_val.bitwiseXor(rhs_val, resolved_type, sema.arena, target),9328 const result_val = switch (air_tag) {
9311 else => unreachable,9329 .bit_and => try lhs_val.bitwiseAnd(rhs_val, resolved_type, sema.arena, target),
9312 };9330 .bit_or => try lhs_val.bitwiseOr(rhs_val, resolved_type, sema.arena, target),
9313 return sema.addConstant(resolved_type, result_val);9331 .xor => try lhs_val.bitwiseXor(rhs_val, resolved_type, sema.arena, target),
9332 else => unreachable,
9333 };
9334 return sema.addConstant(resolved_type, result_val);
9335 } else {
9336 break :runtime rhs_src;
9337 }
9338 } else {
9339 break :runtime lhs_src;
9314 }9340 }
9315 }9341 };
93169342
9317 try sema.requireRuntimeBlock(block, src);9343 try sema.requireRuntimeBlock(block, runtime_src);
9318 return block.addBinOp(air_tag, casted_lhs, casted_rhs);9344 return block.addBinOp(air_tag, casted_lhs, casted_rhs);
9319}9345}
93209346
...@@ -10163,8 +10189,8 @@ fn analyzeArithmetic(...@@ -10163,8 +10189,8 @@ fn analyzeArithmetic(
1016310189
10164 const mod = sema.mod;10190 const mod = sema.mod;
10165 const target = mod.getTarget();10191 const target = mod.getTarget();
10166 const maybe_lhs_val = try sema.resolveMaybeUndefVal(block, lhs_src, casted_lhs);10192 const maybe_lhs_val = try sema.resolveMaybeUndefValIntable(block, lhs_src, casted_lhs);
10167 const maybe_rhs_val = try sema.resolveMaybeUndefVal(block, rhs_src, casted_rhs);10193 const maybe_rhs_val = try sema.resolveMaybeUndefValIntable(block, rhs_src, casted_rhs);
10168 const rs: struct { src: LazySrcLoc, air_tag: Air.Inst.Tag } = rs: {10194 const rs: struct { src: LazySrcLoc, air_tag: Air.Inst.Tag } = rs: {
10169 switch (zir_tag) {10195 switch (zir_tag) {
10170 .add => {10196 .add => {
test/behavior/align.zig+4-7
...@@ -502,12 +502,9 @@ test "align(@alignOf(T)) T does not force resolution of T" {...@@ -502,12 +502,9 @@ test "align(@alignOf(T)) T does not force resolution of T" {
502502
503test "align(N) on functions" {503test "align(N) on functions" {
504 if (builtin.zig_backend == .stage1) return error.SkipZigTest;504 if (builtin.zig_backend == .stage1) return error.SkipZigTest;
505505 if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; // TODO
506 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest;506 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
507 if (builtin.zig_backend == .stage2_llvm) return error.SkipZigTest;507 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
508 if (builtin.zig_backend == .stage2_c) return error.SkipZigTest;
509 if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest;
510 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest;
511508
512 // function alignment is a compile error on wasm32/wasm64509 // function alignment is a compile error on wasm32/wasm64
513 if (native_arch == .wasm32 or native_arch == .wasm64) return error.SkipZigTest;510 if (native_arch == .wasm32 or native_arch == .wasm64) return error.SkipZigTest;
...@@ -531,5 +528,5 @@ test "comptime alloc alignment" {...@@ -531,5 +528,5 @@ test "comptime alloc alignment" {
531528
532 comptime var bytes2 align(256) = [_]u8{0};529 comptime var bytes2 align(256) = [_]u8{0};
533 var bytes2_addr = @ptrToInt(&bytes2);530 var bytes2_addr = @ptrToInt(&bytes2);
534 try std.testing.expect(bytes2_addr & 0xff == 0);531 try expect(bytes2_addr & 0xff == 0);
535}532}
test/behavior/bugs/1741.zig+4-1
...@@ -2,7 +2,10 @@ const std = @import("std");...@@ -2,7 +2,10 @@ const std = @import("std");
2const builtin = @import("builtin");2const builtin = @import("builtin");
33
4test "fixed" {4test "fixed" {
5 if (builtin.zig_backend != .stage1) return error.SkipZigTest;5 if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO
6 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
7 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
8
6 const x: f32 align(128) = 12.34;9 const x: f32 align(128) = 12.34;
7 try std.testing.expect(@ptrToInt(&x) % 128 == 0);10 try std.testing.expect(@ptrToInt(&x) % 128 == 0);
8}11}