mirror of
https://github.com/ziglang/zig.git
synced 2026-01-21 06:45:24 +00:00
Sema: fix compiler crash with comptime arithmetic involving @ptrToInt
This commit is contained in:
parent
a4cdb49a58
commit
288e89b606
52
src/Sema.zig
52
src/Sema.zig
@ -1540,6 +1540,24 @@ fn resolveMaybeUndefVal(
|
||||
}
|
||||
}
|
||||
|
||||
/// Value Tag `variable` results in `null`.
|
||||
/// Value Tag `undef` results in the Value.
|
||||
/// Value Tag `generic_poison` causes `error.GenericPoison` to be returned.
|
||||
/// Value Tag `decl_ref` and `decl_ref_mut` or any nested such value results in `null`.
|
||||
fn resolveMaybeUndefValIntable(
|
||||
sema: *Sema,
|
||||
block: *Block,
|
||||
src: LazySrcLoc,
|
||||
inst: Air.Inst.Ref,
|
||||
) CompileError!?Value {
|
||||
const val = (try sema.resolveMaybeUndefValAllowVariables(block, src, inst)) orelse return null;
|
||||
switch (val.tag()) {
|
||||
.variable, .decl_ref, .decl_ref_mut => return null,
|
||||
.generic_poison => return error.GenericPoison,
|
||||
else => return val,
|
||||
}
|
||||
}
|
||||
|
||||
/// Returns all Value tags including `variable` and `undef`.
|
||||
fn resolveMaybeUndefValAllowVariables(
|
||||
sema: *Sema,
|
||||
@ -9302,19 +9320,27 @@ fn zirBitwise(
|
||||
return sema.fail(block, src, "invalid operands to binary bitwise expression: '{s}' and '{s}'", .{ @tagName(lhs_ty.zigTypeTag()), @tagName(rhs_ty.zigTypeTag()) });
|
||||
}
|
||||
|
||||
if (try sema.resolveMaybeUndefVal(block, lhs_src, casted_lhs)) |lhs_val| {
|
||||
if (try sema.resolveMaybeUndefVal(block, rhs_src, casted_rhs)) |rhs_val| {
|
||||
const result_val = switch (air_tag) {
|
||||
.bit_and => try lhs_val.bitwiseAnd(rhs_val, resolved_type, sema.arena, target),
|
||||
.bit_or => try lhs_val.bitwiseOr(rhs_val, resolved_type, sema.arena, target),
|
||||
.xor => try lhs_val.bitwiseXor(rhs_val, resolved_type, sema.arena, target),
|
||||
else => unreachable,
|
||||
};
|
||||
return sema.addConstant(resolved_type, result_val);
|
||||
const runtime_src = runtime: {
|
||||
// TODO: ask the linker what kind of relocations are available, and
|
||||
// in some cases emit a Value that means "this decl's address AND'd with this operand".
|
||||
if (try sema.resolveMaybeUndefValIntable(block, lhs_src, casted_lhs)) |lhs_val| {
|
||||
if (try sema.resolveMaybeUndefValIntable(block, rhs_src, casted_rhs)) |rhs_val| {
|
||||
const result_val = switch (air_tag) {
|
||||
.bit_and => try lhs_val.bitwiseAnd(rhs_val, resolved_type, sema.arena, target),
|
||||
.bit_or => try lhs_val.bitwiseOr(rhs_val, resolved_type, sema.arena, target),
|
||||
.xor => try lhs_val.bitwiseXor(rhs_val, resolved_type, sema.arena, target),
|
||||
else => unreachable,
|
||||
};
|
||||
return sema.addConstant(resolved_type, result_val);
|
||||
} else {
|
||||
break :runtime rhs_src;
|
||||
}
|
||||
} else {
|
||||
break :runtime lhs_src;
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
try sema.requireRuntimeBlock(block, src);
|
||||
try sema.requireRuntimeBlock(block, runtime_src);
|
||||
return block.addBinOp(air_tag, casted_lhs, casted_rhs);
|
||||
}
|
||||
|
||||
@ -10163,8 +10189,8 @@ fn analyzeArithmetic(
|
||||
|
||||
const mod = sema.mod;
|
||||
const target = mod.getTarget();
|
||||
const maybe_lhs_val = try sema.resolveMaybeUndefVal(block, lhs_src, casted_lhs);
|
||||
const maybe_rhs_val = try sema.resolveMaybeUndefVal(block, rhs_src, casted_rhs);
|
||||
const maybe_lhs_val = try sema.resolveMaybeUndefValIntable(block, lhs_src, casted_lhs);
|
||||
const maybe_rhs_val = try sema.resolveMaybeUndefValIntable(block, rhs_src, casted_rhs);
|
||||
const rs: struct { src: LazySrcLoc, air_tag: Air.Inst.Tag } = rs: {
|
||||
switch (zir_tag) {
|
||||
.add => {
|
||||
|
||||
@ -502,12 +502,9 @@ test "align(@alignOf(T)) T does not force resolution of T" {
|
||||
|
||||
test "align(N) on functions" {
|
||||
if (builtin.zig_backend == .stage1) return error.SkipZigTest;
|
||||
|
||||
if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest;
|
||||
if (builtin.zig_backend == .stage2_llvm) return error.SkipZigTest;
|
||||
if (builtin.zig_backend == .stage2_c) return error.SkipZigTest;
|
||||
if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest;
|
||||
if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest;
|
||||
if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; // TODO
|
||||
if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
|
||||
if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
|
||||
|
||||
// function alignment is a compile error on wasm32/wasm64
|
||||
if (native_arch == .wasm32 or native_arch == .wasm64) return error.SkipZigTest;
|
||||
@ -531,5 +528,5 @@ test "comptime alloc alignment" {
|
||||
|
||||
comptime var bytes2 align(256) = [_]u8{0};
|
||||
var bytes2_addr = @ptrToInt(&bytes2);
|
||||
try std.testing.expect(bytes2_addr & 0xff == 0);
|
||||
try expect(bytes2_addr & 0xff == 0);
|
||||
}
|
||||
|
||||
@ -2,7 +2,10 @@ const std = @import("std");
|
||||
const builtin = @import("builtin");
|
||||
|
||||
test "fixed" {
|
||||
if (builtin.zig_backend != .stage1) return error.SkipZigTest;
|
||||
if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO
|
||||
if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
|
||||
if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
|
||||
|
||||
const x: f32 align(128) = 12.34;
|
||||
try std.testing.expect(@ptrToInt(&x) % 128 == 0);
|
||||
}
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user