Make unary minus for unsigned types a compile error (#5654)

* Make unary minus for unsigned types a compile error

* Add unreachable when generating unsigned negate
This commit is contained in:
Robin Voetter 2020-06-21 20:55:44 +02:00 committed by GitHub
parent 126f5702df
commit 8696e52a3d
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
3 changed files with 37 additions and 21 deletions

View file

@ -3654,7 +3654,7 @@ static LLVMValueRef ir_gen_negation(CodeGen *g, IrInstGen *inst, IrInstGen *oper
} else if (scalar_type->data.integral.is_signed) {
return LLVMBuildNSWNeg(g->builder, llvm_operand, "");
} else {
return LLVMBuildNUWNeg(g->builder, llvm_operand, "");
zig_unreachable();
}
} else {
zig_unreachable();

View file

@ -20987,17 +20987,24 @@ static IrInstGen *ir_analyze_negation(IrAnalyze *ira, IrInstSrcUnOp *instruction
if (type_is_invalid(expr_type))
return ira->codegen->invalid_inst_gen;
if (!(expr_type->id == ZigTypeIdInt || expr_type->id == ZigTypeIdComptimeInt ||
expr_type->id == ZigTypeIdFloat || expr_type->id == ZigTypeIdComptimeFloat ||
expr_type->id == ZigTypeIdVector))
{
bool is_wrap_op = (instruction->op_id == IrUnOpNegationWrap);
switch (expr_type->id) {
case ZigTypeIdComptimeInt:
case ZigTypeIdFloat:
case ZigTypeIdComptimeFloat:
case ZigTypeIdVector:
break;
case ZigTypeIdInt:
if (is_wrap_op || expr_type->data.integral.is_signed)
break;
ZIG_FALLTHROUGH;
default:
ir_add_error(ira, &instruction->base.base,
buf_sprintf("negation of type '%s'", buf_ptr(&expr_type->name)));
return ira->codegen->invalid_inst_gen;
}
bool is_wrap_op = (instruction->op_id == IrUnOpNegationWrap);
ZigType *scalar_type = (expr_type->id == ZigTypeIdVector) ? expr_type->data.vector.elem_type : expr_type;
if (instr_is_comptime(value)) {

View file

@ -7530,4 +7530,13 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {
, &[_][]const u8{
"tmp.zig:2:9: error: @wasmMemoryGrow is a wasm32 feature only",
});
cases.add("Issue #5586: Make unary minus for unsigned types a compile error",
\\export fn f(x: u32) u32 {
\\ const y = -%x;
\\ return -y;
\\}
, &[_][]const u8{
"tmp.zig:3:12: error: negation of type 'u32'"
});
}