authorgravatar for robin@voetter.nlRobin Voetter <robin@voetter.nl> 2020-06-21 20:55:44+02:00
committergravatar for noreply@github.comGitHub <noreply@github.com> 2020-06-21 14:55:44-04:00
log8696e52a3d617ce30ec6202adc89cb10c67bcc43
tree6ed5cbd72781165f2831ea3ace5f309689ed4e61
parent126f5702df2ac86ced868d9e532db44313144452
signature Signed by PGP key 4AEE18F83AFDEB23

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

3 files changed, 37 insertions(+), 21 deletions(-)

src/codegen.cpp+6-6
...@@ -3540,7 +3540,7 @@ static LLVMValueRef ir_render_int_to_enum(CodeGen *g, IrExecutableGen *executabl...@@ -3540,7 +3540,7 @@ static LLVMValueRef ir_render_int_to_enum(CodeGen *g, IrExecutableGen *executabl
35403540
3541 for (size_t field_i = 0; field_i < field_count; field_i += 1) {3541 for (size_t field_i = 0; field_i < field_count; field_i += 1) {
3542 TypeEnumField *type_enum_field = &wanted_type->data.enumeration.fields[field_i];3542 TypeEnumField *type_enum_field = &wanted_type->data.enumeration.fields[field_i];
3543 3543
3544 Buf *name = type_enum_field->name;3544 Buf *name = type_enum_field->name;
3545 auto entry = occupied_tag_values.put_unique(type_enum_field->value, name);3545 auto entry = occupied_tag_values.put_unique(type_enum_field->value, name);
3546 if (entry != nullptr) {3546 if (entry != nullptr) {
...@@ -3654,7 +3654,7 @@ static LLVMValueRef ir_gen_negation(CodeGen *g, IrInstGen *inst, IrInstGen *oper...@@ -3654,7 +3654,7 @@ static LLVMValueRef ir_gen_negation(CodeGen *g, IrInstGen *inst, IrInstGen *oper
3654 } else if (scalar_type->data.integral.is_signed) {3654 } else if (scalar_type->data.integral.is_signed) {
3655 return LLVMBuildNSWNeg(g->builder, llvm_operand, "");3655 return LLVMBuildNSWNeg(g->builder, llvm_operand, "");
3656 } else {3656 } else {
3657 return LLVMBuildNUWNeg(g->builder, llvm_operand, "");3657 zig_unreachable();
3658 }3658 }
3659 } else {3659 } else {
3660 zig_unreachable();3660 zig_unreachable();
...@@ -3984,7 +3984,7 @@ static LLVMValueRef ir_render_elem_ptr(CodeGen *g, IrExecutableGen *executable,...@@ -3984,7 +3984,7 @@ static LLVMValueRef ir_render_elem_ptr(CodeGen *g, IrExecutableGen *executable,
3984 assert(array_type->data.pointer.child_type->id == ZigTypeIdArray);3984 assert(array_type->data.pointer.child_type->id == ZigTypeIdArray);
3985 array_type = array_type->data.pointer.child_type;3985 array_type = array_type->data.pointer.child_type;
3986 }3986 }
3987 3987
3988 assert(array_type->data.array.len != 0 || array_type->data.array.sentinel != nullptr);3988 assert(array_type->data.array.len != 0 || array_type->data.array.sentinel != nullptr);
39893989
3990 if (safety_check_on) {3990 if (safety_check_on) {
...@@ -5258,7 +5258,7 @@ static LLVMValueRef get_enum_tag_name_function(CodeGen *g, ZigType *enum_type) {...@@ -5258,7 +5258,7 @@ static LLVMValueRef get_enum_tag_name_function(CodeGen *g, ZigType *enum_type) {
52585258
5259 for (size_t field_i = 0; field_i < field_count; field_i += 1) {5259 for (size_t field_i = 0; field_i < field_count; field_i += 1) {
5260 TypeEnumField *type_enum_field = &enum_type->data.enumeration.fields[field_i];5260 TypeEnumField *type_enum_field = &enum_type->data.enumeration.fields[field_i];
5261 5261
5262 Buf *name = type_enum_field->name;5262 Buf *name = type_enum_field->name;
5263 auto entry = occupied_tag_values.put_unique(type_enum_field->value, name);5263 auto entry = occupied_tag_values.put_unique(type_enum_field->value, name);
5264 if (entry != nullptr) {5264 if (entry != nullptr) {
...@@ -5471,7 +5471,7 @@ static LLVMTypeRef get_atomic_abi_type(CodeGen *g, IrInstGen *instruction) {...@@ -5471,7 +5471,7 @@ static LLVMTypeRef get_atomic_abi_type(CodeGen *g, IrInstGen *instruction) {
5471 }5471 }
5472 auto bit_count = operand_type->data.integral.bit_count;5472 auto bit_count = operand_type->data.integral.bit_count;
5473 bool is_signed = operand_type->data.integral.is_signed;5473 bool is_signed = operand_type->data.integral.is_signed;
5474 5474
5475 ir_assert(bit_count != 0, instruction);5475 ir_assert(bit_count != 0, instruction);
5476 if (bit_count == 1 || !is_power_of_2(bit_count)) {5476 if (bit_count == 1 || !is_power_of_2(bit_count)) {
5477 return get_llvm_type(g, get_int_type(g, is_signed, operand_type->abi_size * 8));5477 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) {...@@ -9265,7 +9265,7 @@ static void init(CodeGen *g) {
9265 abi_name = (g->zig_target->arch == ZigLLVM_riscv32) ? "ilp32" : "lp64";9265 abi_name = (g->zig_target->arch == ZigLLVM_riscv32) ? "ilp32" : "lp64";
9266 }9266 }
9267 }9267 }
9268 9268
9269 g->target_machine = ZigLLVMCreateTargetMachine(target_ref, buf_ptr(&g->llvm_triple_str),9269 g->target_machine = ZigLLVMCreateTargetMachine(target_ref, buf_ptr(&g->llvm_triple_str),
9270 target_specific_cpu_args, target_specific_features, opt_level, reloc_mode,9270 target_specific_cpu_args, target_specific_features, opt_level, reloc_mode,
9271 to_llvm_code_model(g), g->function_sections, float_abi, abi_name);9271 to_llvm_code_model(g), g->function_sections, float_abi, abi_name);
src/ir.cpp+22-15
...@@ -12602,28 +12602,28 @@ static ZigType *ir_resolve_peer_types(IrAnalyze *ira, AstNode *source_node, ZigT...@@ -12602,28 +12602,28 @@ static ZigType *ir_resolve_peer_types(IrAnalyze *ira, AstNode *source_node, ZigT
12602 if (prev_type->id == ZigTypeIdPointer &&12602 if (prev_type->id == ZigTypeIdPointer &&
12603 prev_type->data.pointer.ptr_len == PtrLenSingle &&12603 prev_type->data.pointer.ptr_len == PtrLenSingle &&
12604 prev_type->data.pointer.child_type->id == ZigTypeIdArray &&12604 prev_type->data.pointer.child_type->id == ZigTypeIdArray &&
12605 ((cur_type->id == ZigTypeIdPointer && cur_type->data.pointer.ptr_len == PtrLenUnknown))) 12605 ((cur_type->id == ZigTypeIdPointer && cur_type->data.pointer.ptr_len == PtrLenUnknown)))
12606 {12606 {
12607 prev_inst = cur_inst; 12607 prev_inst = cur_inst;
1260812608
12609 if (prev_type->data.pointer.is_const && !cur_type->data.pointer.is_const) {12609 if (prev_type->data.pointer.is_const && !cur_type->data.pointer.is_const) {
12610 // const array pointer and non-const unknown pointer12610 // const array pointer and non-const unknown pointer
12611 make_the_pointer_const = true;12611 make_the_pointer_const = true;
12612 }12612 }
12613 continue; 12613 continue;
12614 }12614 }
1261512615
12616 // *[N]T to [*]T12616 // *[N]T to [*]T
12617 if (cur_type->id == ZigTypeIdPointer &&12617 if (cur_type->id == ZigTypeIdPointer &&
12618 cur_type->data.pointer.ptr_len == PtrLenSingle &&12618 cur_type->data.pointer.ptr_len == PtrLenSingle &&
12619 cur_type->data.pointer.child_type->id == ZigTypeIdArray &&12619 cur_type->data.pointer.child_type->id == ZigTypeIdArray &&
12620 ((prev_type->id == ZigTypeIdPointer && prev_type->data.pointer.ptr_len == PtrLenUnknown))) 12620 ((prev_type->id == ZigTypeIdPointer && prev_type->data.pointer.ptr_len == PtrLenUnknown)))
12621 {12621 {
12622 if (cur_type->data.pointer.is_const && !prev_type->data.pointer.is_const) {12622 if (cur_type->data.pointer.is_const && !prev_type->data.pointer.is_const) {
12623 // const array pointer and non-const unknown pointer12623 // const array pointer and non-const unknown pointer
12624 make_the_pointer_const = true;12624 make_the_pointer_const = true;
12625 }12625 }
12626 continue; 12626 continue;
12627 }12627 }
1262812628
12629 // *[N]T to []T12629 // *[N]T to []T
...@@ -20987,17 +20987,24 @@ static IrInstGen *ir_analyze_negation(IrAnalyze *ira, IrInstSrcUnOp *instruction...@@ -20987,17 +20987,24 @@ static IrInstGen *ir_analyze_negation(IrAnalyze *ira, IrInstSrcUnOp *instruction
20987 if (type_is_invalid(expr_type))20987 if (type_is_invalid(expr_type))
20988 return ira->codegen->invalid_inst_gen;20988 return ira->codegen->invalid_inst_gen;
2098920989
20990 if (!(expr_type->id == ZigTypeIdInt || expr_type->id == ZigTypeIdComptimeInt ||
20991 expr_type->id == ZigTypeIdFloat || expr_type->id == ZigTypeIdComptimeFloat ||
20992 expr_type->id == ZigTypeIdVector))
20993 {
20994 ir_add_error(ira, &instruction->base.base,
20995 buf_sprintf("negation of type '%s'", buf_ptr(&expr_type->name)));
20996 return ira->codegen->invalid_inst_gen;
20997 }
20998
20999 bool is_wrap_op = (instruction->op_id == IrUnOpNegationWrap);20990 bool is_wrap_op = (instruction->op_id == IrUnOpNegationWrap);
2100020991
20992 switch (expr_type->id) {
20993 case ZigTypeIdComptimeInt:
20994 case ZigTypeIdFloat:
20995 case ZigTypeIdComptimeFloat:
20996 case ZigTypeIdVector:
20997 break;
20998 case ZigTypeIdInt:
20999 if (is_wrap_op || expr_type->data.integral.is_signed)
21000 break;
21001 ZIG_FALLTHROUGH;
21002 default:
21003 ir_add_error(ira, &instruction->base.base,
21004 buf_sprintf("negation of type '%s'", buf_ptr(&expr_type->name)));
21005 return ira->codegen->invalid_inst_gen;
21006 }
21007
21001 ZigType *scalar_type = (expr_type->id == ZigTypeIdVector) ? expr_type->data.vector.elem_type : expr_type;21008 ZigType *scalar_type = (expr_type->id == ZigTypeIdVector) ? expr_type->data.vector.elem_type : expr_type;
2100221009
21003 if (instr_is_comptime(value)) {21010 if (instr_is_comptime(value)) {
...@@ -30380,7 +30387,7 @@ static ErrorMsg *ir_eval_float_op(IrAnalyze *ira, IrInst* source_instr, BuiltinF...@@ -30380,7 +30387,7 @@ static ErrorMsg *ir_eval_float_op(IrAnalyze *ira, IrInst* source_instr, BuiltinF
30380 case BuiltinFnIdTrunc:30387 case BuiltinFnIdTrunc:
30381 f128M_trunc(in, out);30388 f128M_trunc(in, out);
30382 break;30389 break;
30383 case BuiltinFnIdRound: 30390 case BuiltinFnIdRound:
30384 f128M_roundToInt(in, softfloat_round_near_maxMag, false, out);30391 f128M_roundToInt(in, softfloat_round_near_maxMag, false, out);
30385 break;30392 break;
30386 case BuiltinFnIdNearbyInt:30393 case BuiltinFnIdNearbyInt:
test/compile_errors.zig+9
...@@ -7530,4 +7530,13 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {...@@ -7530,4 +7530,13 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {
7530 , &[_][]const u8{7530 , &[_][]const u8{
7531 "tmp.zig:2:9: error: @wasmMemoryGrow is a wasm32 feature only",7531 "tmp.zig:2:9: error: @wasmMemoryGrow is a wasm32 feature only",
7532 });7532 });
7533
7534 cases.add("Issue #5586: Make unary minus for unsigned types a compile error",
7535 \\export fn f(x: u32) u32 {
7536 \\ const y = -%x;
7537 \\ return -y;
7538 \\}
7539 , &[_][]const u8{
7540 "tmp.zig:3:12: error: negation of type 'u32'"
7541 });
7533}7542}