Skip to content

Commit dd75e7b

Browse files
committed
Sema: add missing error and test for bool not on vector of ints
1 parent dcdb442 commit dd75e7b

File tree

3 files changed

+63
-31
lines changed

3 files changed

+63
-31
lines changed

src/Sema.zig

Lines changed: 52 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -1171,11 +1171,11 @@ fn analyzeBodyInner(
11711171
.as_node => try sema.zirAsNode(block, inst),
11721172
.as_shift_operand => try sema.zirAsShiftOperand(block, inst),
11731173
.bit_and => try sema.zirBitwise(block, inst, .bit_and),
1174-
.bit_not => try sema.zirBitNot(block, inst, false),
1174+
.bit_not => try sema.zirBitNot(block, inst),
11751175
.bit_or => try sema.zirBitwise(block, inst, .bit_or),
11761176
.bitcast => try sema.zirBitcast(block, inst),
11771177
.suspend_block => try sema.zirSuspendBlock(block, inst),
1178-
.bool_not => try sema.zirBitNot(block, inst, true),
1178+
.bool_not => try sema.zirBoolNot(block, inst),
11791179
.bool_br_and => try sema.zirBoolBr(block, inst, false),
11801180
.bool_br_or => try sema.zirBoolBr(block, inst, true),
11811181
.c_import => try sema.zirCImport(block, inst),
@@ -14464,57 +14464,55 @@ fn zirBitwise(
1446414464
return block.addBinOp(air_tag, casted_lhs, casted_rhs);
1446514465
}
1446614466

14467-
fn zirBitNot(
14468-
sema: *Sema,
14469-
block: *Block,
14470-
inst: Zir.Inst.Index,
14471-
is_bool_not: bool,
14472-
) CompileError!Air.Inst.Ref {
14473-
const tracy = trace(@src());
14474-
defer tracy.end();
14475-
14467+
fn zirBitNot(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.Inst.Ref {
1447614468
const pt = sema.pt;
1447714469
const zcu = pt.zcu;
1447814470
const inst_data = sema.code.instructions.items(.data)[@intFromEnum(inst)].un_node;
14479-
const src = block.nodeOffset(inst_data.src_node);
1448014471
const operand_src = block.src(.{ .node_offset_un_op = inst_data.src_node });
14481-
14472+
const src = block.nodeOffset(inst_data.src_node);
1448214473
const operand = try sema.resolveInst(inst_data.operand);
14483-
const operand_type = sema.typeOf(operand);
14484-
const scalar_type = operand_type.scalarType(zcu);
14485-
const scalar_tag = scalar_type.zigTypeTag(zcu);
14474+
const operand_ty = sema.typeOf(operand);
14475+
const scalar_ty = operand_ty.scalarType(zcu);
14476+
const scalar_tag = scalar_ty.zigTypeTag(zcu);
1448614477

14487-
const is_finite_int_or_bool = scalar_tag == .int or scalar_tag == .bool;
14488-
const is_allowed_type = if (is_bool_not) scalar_tag == .bool else is_finite_int_or_bool;
14478+
if (scalar_tag != .int and scalar_tag != .bool)
14479+
return sema.fail(block, operand_src, "bitwise not operation on type '{}'", .{operand_ty.fmt(pt)});
1448914480

14490-
if (!is_allowed_type) {
14491-
return sema.fail(block, src, "unable to perform {s} not operation on type '{}'", .{
14492-
if (is_bool_not) "boolean" else "binary", operand_type.fmt(pt),
14493-
});
14494-
}
14481+
return analyzeBitNot(sema, block, operand, src);
14482+
}
1449514483

14484+
fn analyzeBitNot(
14485+
sema: *Sema,
14486+
block: *Block,
14487+
operand: Air.Inst.Ref,
14488+
src: LazySrcLoc,
14489+
) CompileError!Air.Inst.Ref {
14490+
const pt = sema.pt;
14491+
const zcu = pt.zcu;
14492+
const operand_ty = sema.typeOf(operand);
14493+
const scalar_ty = operand_ty.scalarType(zcu);
1449614494
if (try sema.resolveValue(operand)) |val| {
1449714495
if (val.isUndef(zcu)) {
14498-
return pt.undefRef(operand_type);
14499-
} else if (operand_type.zigTypeTag(zcu) == .vector) {
14500-
const vec_len = try sema.usizeCast(block, operand_src, operand_type.vectorLen(zcu));
14496+
return pt.undefRef(operand_ty);
14497+
} else if (operand_ty.zigTypeTag(zcu) == .vector) {
14498+
const vec_len = try sema.usizeCast(block, src, operand_ty.vectorLen(zcu));
1450114499
const elems = try sema.arena.alloc(InternPool.Index, vec_len);
1450214500
for (elems, 0..) |*elem, i| {
1450314501
const elem_val = try val.elemValue(pt, i);
14504-
elem.* = (try elem_val.bitwiseNot(scalar_type, sema.arena, pt)).toIntern();
14502+
elem.* = (try elem_val.bitwiseNot(scalar_ty, sema.arena, pt)).toIntern();
1450514503
}
1450614504
return Air.internedToRef((try pt.intern(.{ .aggregate = .{
14507-
.ty = operand_type.toIntern(),
14505+
.ty = operand_ty.toIntern(),
1450814506
.storage = .{ .elems = elems },
1450914507
} })));
1451014508
} else {
14511-
const result_val = try val.bitwiseNot(operand_type, sema.arena, pt);
14509+
const result_val = try val.bitwiseNot(operand_ty, sema.arena, pt);
1451214510
return Air.internedToRef(result_val.toIntern());
1451314511
}
1451414512
}
1451514513

1451614514
try sema.requireRuntimeBlock(block, src, null);
14517-
return block.addTyOp(.not, operand_type, operand);
14515+
return block.addTyOp(.not, operand_ty, operand);
1451814516
}
1451914517

1452014518
fn analyzeTupleCat(
@@ -18367,6 +18365,30 @@ fn zirTypeofPeer(
1836718365
return Air.internedToRef(result_type.toIntern());
1836818366
}
1836918367

18368+
fn zirBoolNot(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.Inst.Ref {
18369+
const pt = sema.pt;
18370+
const zcu = pt.zcu;
18371+
const inst_data = sema.code.instructions.items(.data)[@intFromEnum(inst)].un_node;
18372+
const src = block.nodeOffset(inst_data.src_node);
18373+
const operand_src = block.src(.{ .node_offset_un_op = inst_data.src_node });
18374+
const uncasted_operand = try sema.resolveInst(inst_data.operand);
18375+
const uncasted_ty = sema.typeOf(uncasted_operand);
18376+
if (uncasted_ty.isVector(zcu)) {
18377+
if (uncasted_ty.scalarType(zcu).zigTypeTag(zcu) != .bool) {
18378+
return sema.fail(block, operand_src, "boolean not operation on type '{}'", .{
18379+
uncasted_ty.fmt(pt),
18380+
});
18381+
}
18382+
return analyzeBitNot(sema, block, uncasted_operand, src);
18383+
}
18384+
const operand = try sema.coerce(block, .bool, uncasted_operand, operand_src);
18385+
if (try sema.resolveValue(operand)) |val| {
18386+
return if (val.isUndef(zcu)) .undef_bool else if (val.toBool()) .bool_false else .bool_true;
18387+
}
18388+
try sema.requireRuntimeBlock(block, src, null);
18389+
return block.addTyOp(.not, .bool, operand);
18390+
}
18391+
1837018392
fn zirBoolBr(
1837118393
sema: *Sema,
1837218394
parent_block: *Block,

test/cases/compile_errors/binary_not_on_number_literal.zig

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,4 +10,4 @@ export fn entry() usize {
1010
// backend=stage2
1111
// target=native
1212
//
13-
// :3:60: error: unable to perform binary not operation on type 'comptime_int'
13+
// :3:61: error: bitwise not operation on type 'comptime_int'
Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
export fn foo() void {
2+
var x: @Vector(2, u1) = .{ 0, 1 };
3+
x = !x;
4+
}
5+
6+
// error
7+
// backend=stage2
8+
// target=native
9+
//
10+
// :3:10: error: boolean not operation on type '@Vector(2, u1)'

0 commit comments

Comments
 (0)