diff --git a/src/codegen.cpp b/src/codegen.cpp index e20d6d60f5..f7c3575f86 100644 --- a/src/codegen.cpp +++ b/src/codegen.cpp @@ -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) { TypeEnumField *type_enum_field = &wanted_type->data.enumeration.fields[field_i]; - + Buf *name = type_enum_field->name; auto entry = occupied_tag_values.put_unique(type_enum_field->value, name); 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) { return LLVMBuildNSWNeg(g->builder, llvm_operand, ""); } else { - return LLVMBuildNUWNeg(g->builder, llvm_operand, ""); + zig_unreachable(); } } else { 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); array_type = array_type->data.pointer.child_type; } - + assert(array_type->data.array.len != 0 || array_type->data.array.sentinel != nullptr); 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) { TypeEnumField *type_enum_field = &enum_type->data.enumeration.fields[field_i]; - + Buf *name = type_enum_field->name; auto entry = occupied_tag_values.put_unique(type_enum_field->value, name); 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; bool is_signed = operand_type->data.integral.is_signed; - + ir_assert(bit_count != 0, instruction); 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)); @@ -9265,7 +9265,7 @@ static void init(CodeGen *g) { abi_name = (g->zig_target->arch == ZigLLVM_riscv32) ? "ilp32" : "lp64"; } } - + g->target_machine = ZigLLVMCreateTargetMachine(target_ref, buf_ptr(&g->llvm_triple_str), target_specific_cpu_args, target_specific_features, opt_level, reloc_mode, to_llvm_code_model(g), g->function_sections, float_abi, abi_name); diff --git a/src/ir.cpp b/src/ir.cpp index 635af397c4..bb6ca554df 100644 --- a/src/ir.cpp +++ b/src/ir.cpp @@ -12602,28 +12602,28 @@ static ZigType *ir_resolve_peer_types(IrAnalyze *ira, AstNode *source_node, ZigT if (prev_type->id == ZigTypeIdPointer && prev_type->data.pointer.ptr_len == PtrLenSingle && 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) { // const array pointer and non-const unknown pointer make_the_pointer_const = true; } - continue; + continue; } // *[N]T to [*]T if (cur_type->id == ZigTypeIdPointer && cur_type->data.pointer.ptr_len == PtrLenSingle && 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) { // const array pointer and non-const unknown pointer make_the_pointer_const = true; } - continue; + continue; } // *[N]T to []T @@ -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)) - { - 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); + 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; if (instr_is_comptime(value)) { @@ -30380,7 +30387,7 @@ static ErrorMsg *ir_eval_float_op(IrAnalyze *ira, IrInst* source_instr, BuiltinF case BuiltinFnIdTrunc: f128M_trunc(in, out); break; - case BuiltinFnIdRound: + case BuiltinFnIdRound: f128M_roundToInt(in, softfloat_round_near_maxMag, false, out); break; case BuiltinFnIdNearbyInt: diff --git a/test/compile_errors.zig b/test/compile_errors.zig index 3f898cc337..e3dd1f0d8f 100644 --- a/test/compile_errors.zig +++ b/test/compile_errors.zig @@ -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'" + }); }