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
signaturebadge-question-mark 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
35403540
35413541 for (size_t field_i = 0; field_i < field_count; field_i += 1) {
35423542 TypeEnumField *type_enum_field = &wanted_type->data.enumeration.fields[field_i];
3543
3543
35443544 Buf *name = type_enum_field->name;
35453545 auto entry = occupied_tag_values.put_unique(type_enum_field->value, name);
35463546 if (entry != nullptr) {
......@@ -3654,7 +3654,7 @@ static LLVMValueRef ir_gen_negation(CodeGen *g, IrInstGen *inst, IrInstGen *oper
36543654 } else if (scalar_type->data.integral.is_signed) {
36553655 return LLVMBuildNSWNeg(g->builder, llvm_operand, "");
36563656 } else {
3657 return LLVMBuildNUWNeg(g->builder, llvm_operand, "");
3657 zig_unreachable();
36583658 }
36593659 } else {
36603660 zig_unreachable();
......@@ -3984,7 +3984,7 @@ static LLVMValueRef ir_render_elem_ptr(CodeGen *g, IrExecutableGen *executable,
39843984 assert(array_type->data.pointer.child_type->id == ZigTypeIdArray);
39853985 array_type = array_type->data.pointer.child_type;
39863986 }
3987
3987
39883988 assert(array_type->data.array.len != 0 || array_type->data.array.sentinel != nullptr);
39893989
39903990 if (safety_check_on) {
......@@ -5258,7 +5258,7 @@ static LLVMValueRef get_enum_tag_name_function(CodeGen *g, ZigType *enum_type) {
52585258
52595259 for (size_t field_i = 0; field_i < field_count; field_i += 1) {
52605260 TypeEnumField *type_enum_field = &enum_type->data.enumeration.fields[field_i];
5261
5261
52625262 Buf *name = type_enum_field->name;
52635263 auto entry = occupied_tag_values.put_unique(type_enum_field->value, name);
52645264 if (entry != nullptr) {
......@@ -5471,7 +5471,7 @@ static LLVMTypeRef get_atomic_abi_type(CodeGen *g, IrInstGen *instruction) {
54715471 }
54725472 auto bit_count = operand_type->data.integral.bit_count;
54735473 bool is_signed = operand_type->data.integral.is_signed;
5474
5474
54755475 ir_assert(bit_count != 0, instruction);
54765476 if (bit_count == 1 || !is_power_of_2(bit_count)) {
54775477 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) {
92659265 abi_name = (g->zig_target->arch == ZigLLVM_riscv32) ? "ilp32" : "lp64";
92669266 }
92679267 }
9268
9268
92699269 g->target_machine = ZigLLVMCreateTargetMachine(target_ref, buf_ptr(&g->llvm_triple_str),
92709270 target_specific_cpu_args, target_specific_features, opt_level, reloc_mode,
92719271 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
1260212602 if (prev_type->id == ZigTypeIdPointer &&
1260312603 prev_type->data.pointer.ptr_len == PtrLenSingle &&
1260412604 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)))
1260612606 {
12607 prev_inst = cur_inst;
12607 prev_inst = cur_inst;
1260812608
1260912609 if (prev_type->data.pointer.is_const && !cur_type->data.pointer.is_const) {
1261012610 // const array pointer and non-const unknown pointer
1261112611 make_the_pointer_const = true;
1261212612 }
12613 continue;
12613 continue;
1261412614 }
1261512615
1261612616 // *[N]T to [*]T
1261712617 if (cur_type->id == ZigTypeIdPointer &&
1261812618 cur_type->data.pointer.ptr_len == PtrLenSingle &&
1261912619 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)))
1262112621 {
1262212622 if (cur_type->data.pointer.is_const && !prev_type->data.pointer.is_const) {
1262312623 // const array pointer and non-const unknown pointer
1262412624 make_the_pointer_const = true;
1262512625 }
12626 continue;
12626 continue;
1262712627 }
1262812628
1262912629 // *[N]T to []T
......@@ -20987,17 +20987,24 @@ static IrInstGen *ir_analyze_negation(IrAnalyze *ira, IrInstSrcUnOp *instruction
2098720987 if (type_is_invalid(expr_type))
2098820988 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
2099920990 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
2100121008 ZigType *scalar_type = (expr_type->id == ZigTypeIdVector) ? expr_type->data.vector.elem_type : expr_type;
2100221009
2100321010 if (instr_is_comptime(value)) {
......@@ -30380,7 +30387,7 @@ static ErrorMsg *ir_eval_float_op(IrAnalyze *ira, IrInst* source_instr, BuiltinF
3038030387 case BuiltinFnIdTrunc:
3038130388 f128M_trunc(in, out);
3038230389 break;
30383 case BuiltinFnIdRound:
30390 case BuiltinFnIdRound:
3038430391 f128M_roundToInt(in, softfloat_round_near_maxMag, false, out);
3038530392 break;
3038630393 case BuiltinFnIdNearbyInt:
test/compile_errors.zig+9
......@@ -7530,4 +7530,13 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {
75307530 , &[_][]const u8{
75317531 "tmp.zig:2:9: error: @wasmMemoryGrow is a wasm32 feature only",
75327532 });
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 });
75337542}