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

@ -3540,7 +3540,7 @@ static LLVMValueRef ir_render_int_to_enum(CodeGen *g, IrExecutableGen *executabl
for (size_t field_i = 0; field_i < field_count; field_i += 1) { for (size_t field_i = 0; field_i < field_count; field_i += 1) {
TypeEnumField *type_enum_field = &wanted_type->data.enumeration.fields[field_i]; TypeEnumField *type_enum_field = &wanted_type->data.enumeration.fields[field_i];
Buf *name = type_enum_field->name; Buf *name = type_enum_field->name;
auto entry = occupied_tag_values.put_unique(type_enum_field->value, name); auto entry = occupied_tag_values.put_unique(type_enum_field->value, name);
if (entry != nullptr) { if (entry != nullptr) {
@ -3654,7 +3654,7 @@ static LLVMValueRef ir_gen_negation(CodeGen *g, IrInstGen *inst, IrInstGen *oper
} else if (scalar_type->data.integral.is_signed) { } else if (scalar_type->data.integral.is_signed) {
return LLVMBuildNSWNeg(g->builder, llvm_operand, ""); return LLVMBuildNSWNeg(g->builder, llvm_operand, "");
} else { } else {
return LLVMBuildNUWNeg(g->builder, llvm_operand, ""); zig_unreachable();
} }
} else { } else {
zig_unreachable(); zig_unreachable();
@ -3984,7 +3984,7 @@ static LLVMValueRef ir_render_elem_ptr(CodeGen *g, IrExecutableGen *executable,
assert(array_type->data.pointer.child_type->id == ZigTypeIdArray); assert(array_type->data.pointer.child_type->id == ZigTypeIdArray);
array_type = array_type->data.pointer.child_type; array_type = array_type->data.pointer.child_type;
} }
assert(array_type->data.array.len != 0 || array_type->data.array.sentinel != nullptr); assert(array_type->data.array.len != 0 || array_type->data.array.sentinel != nullptr);
if (safety_check_on) { if (safety_check_on) {
@ -5258,7 +5258,7 @@ static LLVMValueRef get_enum_tag_name_function(CodeGen *g, ZigType *enum_type) {
for (size_t field_i = 0; field_i < field_count; field_i += 1) { for (size_t field_i = 0; field_i < field_count; field_i += 1) {
TypeEnumField *type_enum_field = &enum_type->data.enumeration.fields[field_i]; TypeEnumField *type_enum_field = &enum_type->data.enumeration.fields[field_i];
Buf *name = type_enum_field->name; Buf *name = type_enum_field->name;
auto entry = occupied_tag_values.put_unique(type_enum_field->value, name); auto entry = occupied_tag_values.put_unique(type_enum_field->value, name);
if (entry != nullptr) { if (entry != nullptr) {
@ -5471,7 +5471,7 @@ static LLVMTypeRef get_atomic_abi_type(CodeGen *g, IrInstGen *instruction) {
} }
auto bit_count = operand_type->data.integral.bit_count; auto bit_count = operand_type->data.integral.bit_count;
bool is_signed = operand_type->data.integral.is_signed; bool is_signed = operand_type->data.integral.is_signed;
ir_assert(bit_count != 0, instruction); ir_assert(bit_count != 0, instruction);
if (bit_count == 1 || !is_power_of_2(bit_count)) { if (bit_count == 1 || !is_power_of_2(bit_count)) {
return get_llvm_type(g, get_int_type(g, is_signed, operand_type->abi_size * 8)); return get_llvm_type(g, get_int_type(g, is_signed, operand_type->abi_size * 8));
@ -9265,7 +9265,7 @@ static void init(CodeGen *g) {
abi_name = (g->zig_target->arch == ZigLLVM_riscv32) ? "ilp32" : "lp64"; abi_name = (g->zig_target->arch == ZigLLVM_riscv32) ? "ilp32" : "lp64";
} }
} }
g->target_machine = ZigLLVMCreateTargetMachine(target_ref, buf_ptr(&g->llvm_triple_str), g->target_machine = ZigLLVMCreateTargetMachine(target_ref, buf_ptr(&g->llvm_triple_str),
target_specific_cpu_args, target_specific_features, opt_level, reloc_mode, target_specific_cpu_args, target_specific_features, opt_level, reloc_mode,
to_llvm_code_model(g), g->function_sections, float_abi, abi_name); to_llvm_code_model(g), g->function_sections, float_abi, abi_name);

View file

@ -12602,28 +12602,28 @@ static ZigType *ir_resolve_peer_types(IrAnalyze *ira, AstNode *source_node, ZigT
if (prev_type->id == ZigTypeIdPointer && if (prev_type->id == ZigTypeIdPointer &&
prev_type->data.pointer.ptr_len == PtrLenSingle && prev_type->data.pointer.ptr_len == PtrLenSingle &&
prev_type->data.pointer.child_type->id == ZigTypeIdArray && prev_type->data.pointer.child_type->id == ZigTypeIdArray &&
((cur_type->id == ZigTypeIdPointer && cur_type->data.pointer.ptr_len == PtrLenUnknown))) ((cur_type->id == ZigTypeIdPointer && cur_type->data.pointer.ptr_len == PtrLenUnknown)))
{ {
prev_inst = cur_inst; prev_inst = cur_inst;
if (prev_type->data.pointer.is_const && !cur_type->data.pointer.is_const) { if (prev_type->data.pointer.is_const && !cur_type->data.pointer.is_const) {
// const array pointer and non-const unknown pointer // const array pointer and non-const unknown pointer
make_the_pointer_const = true; make_the_pointer_const = true;
} }
continue; continue;
} }
// *[N]T to [*]T // *[N]T to [*]T
if (cur_type->id == ZigTypeIdPointer && if (cur_type->id == ZigTypeIdPointer &&
cur_type->data.pointer.ptr_len == PtrLenSingle && cur_type->data.pointer.ptr_len == PtrLenSingle &&
cur_type->data.pointer.child_type->id == ZigTypeIdArray && cur_type->data.pointer.child_type->id == ZigTypeIdArray &&
((prev_type->id == ZigTypeIdPointer && prev_type->data.pointer.ptr_len == PtrLenUnknown))) ((prev_type->id == ZigTypeIdPointer && prev_type->data.pointer.ptr_len == PtrLenUnknown)))
{ {
if (cur_type->data.pointer.is_const && !prev_type->data.pointer.is_const) { if (cur_type->data.pointer.is_const && !prev_type->data.pointer.is_const) {
// const array pointer and non-const unknown pointer // const array pointer and non-const unknown pointer
make_the_pointer_const = true; make_the_pointer_const = true;
} }
continue; continue;
} }
// *[N]T to []T // *[N]T to []T
@ -20987,17 +20987,24 @@ static IrInstGen *ir_analyze_negation(IrAnalyze *ira, IrInstSrcUnOp *instruction
if (type_is_invalid(expr_type)) if (type_is_invalid(expr_type))
return ira->codegen->invalid_inst_gen; 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))
{
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); 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;
}
ZigType *scalar_type = (expr_type->id == ZigTypeIdVector) ? expr_type->data.vector.elem_type : expr_type; ZigType *scalar_type = (expr_type->id == ZigTypeIdVector) ? expr_type->data.vector.elem_type : expr_type;
if (instr_is_comptime(value)) { if (instr_is_comptime(value)) {
@ -30380,7 +30387,7 @@ static ErrorMsg *ir_eval_float_op(IrAnalyze *ira, IrInst* source_instr, BuiltinF
case BuiltinFnIdTrunc: case BuiltinFnIdTrunc:
f128M_trunc(in, out); f128M_trunc(in, out);
break; break;
case BuiltinFnIdRound: case BuiltinFnIdRound:
f128M_roundToInt(in, softfloat_round_near_maxMag, false, out); f128M_roundToInt(in, softfloat_round_near_maxMag, false, out);
break; break;
case BuiltinFnIdNearbyInt: case BuiltinFnIdNearbyInt:

View file

@ -7530,4 +7530,13 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {
, &[_][]const u8{ , &[_][]const u8{
"tmp.zig:2:9: error: @wasmMemoryGrow is a wasm32 feature only", "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'"
});
} }