From 2a256d5ea02c8f520c54fd335c38891d6e05a63f Mon Sep 17 00:00:00 2001 From: LemonBoy Date: Sat, 17 Oct 2020 10:06:14 +0200 Subject: [PATCH] stage1: Fix type-checking of unary neg for vector types Validate the vector element type as done for the scalar case. Fixes #6708 --- src/stage1/all_types.hpp | 7 +------ src/stage1/codegen.cpp | 10 +--------- src/stage1/ir.cpp | 41 +++++++++------------------------------- src/stage1/ir_print.cpp | 13 +------------ test/compile_errors.zig | 9 +++++++-- 5 files changed, 19 insertions(+), 61 deletions(-) diff --git a/src/stage1/all_types.hpp b/src/stage1/all_types.hpp index 89f3693a13..8162d2a537 100644 --- a/src/stage1/all_types.hpp +++ b/src/stage1/all_types.hpp @@ -2653,7 +2653,6 @@ enum IrInstGenId { IrInstGenIdPhi, IrInstGenIdBinaryNot, IrInstGenIdNegation, - IrInstGenIdNegationWrapping, IrInstGenIdBinOp, IrInstGenIdLoadPtr, IrInstGenIdStorePtr, @@ -2932,11 +2931,7 @@ struct IrInstGenBinaryNot { struct IrInstGenNegation { IrInstGen base; IrInstGen *operand; -}; - -struct IrInstGenNegationWrapping { - IrInstGen base; - IrInstGen *operand; + bool wrapping; }; enum IrBinOp { diff --git a/src/stage1/codegen.cpp b/src/stage1/codegen.cpp index b8ac867082..7d27069f7f 100644 --- a/src/stage1/codegen.cpp +++ b/src/stage1/codegen.cpp @@ -3564,13 +3564,7 @@ static LLVMValueRef ir_gen_negation(CodeGen *g, IrInstGen *inst, IrInstGen *oper static LLVMValueRef ir_render_negation(CodeGen *g, IrExecutableGen *executable, IrInstGenNegation *inst) { - return ir_gen_negation(g, &inst->base, inst->operand, false); -} - -static LLVMValueRef ir_render_negation_wrapping(CodeGen *g, IrExecutableGen *executable, - IrInstGenNegationWrapping *inst) -{ - return ir_gen_negation(g, &inst->base, inst->operand, true); + return ir_gen_negation(g, &inst->base, inst->operand, inst->wrapping); } static LLVMValueRef ir_render_bool_not(CodeGen *g, IrExecutableGen *executable, IrInstGenBoolNot *instruction) { @@ -6645,8 +6639,6 @@ static LLVMValueRef ir_render_instruction(CodeGen *g, IrExecutableGen *executabl return ir_render_binary_not(g, executable, (IrInstGenBinaryNot *)instruction); case IrInstGenIdNegation: return ir_render_negation(g, executable, (IrInstGenNegation *)instruction); - case IrInstGenIdNegationWrapping: - return ir_render_negation_wrapping(g, executable, (IrInstGenNegationWrapping *)instruction); case IrInstGenIdLoadPtr: return ir_render_load_ptr(g, executable, (IrInstGenLoadPtr *)instruction); case IrInstGenIdStorePtr: diff --git a/src/stage1/ir.cpp b/src/stage1/ir.cpp index ea9bf6ee8b..dc482a9dd6 100644 --- a/src/stage1/ir.cpp +++ b/src/stage1/ir.cpp @@ -749,8 +749,6 @@ void destroy_instruction_gen(IrInstGen *inst) { return heap::c_allocator.destroy(reinterpret_cast(inst)); case IrInstGenIdNegation: return heap::c_allocator.destroy(reinterpret_cast(inst)); - case IrInstGenIdNegationWrapping: - return heap::c_allocator.destroy(reinterpret_cast(inst)); case IrInstGenIdWasmMemorySize: return heap::c_allocator.destroy(reinterpret_cast(inst)); case IrInstGenIdWasmMemoryGrow: @@ -1672,10 +1670,6 @@ static constexpr IrInstGenId ir_inst_id(IrInstGenNegation *) { return IrInstGenIdNegation; } -static constexpr IrInstGenId ir_inst_id(IrInstGenNegationWrapping *) { - return IrInstGenIdNegationWrapping; -} - static constexpr IrInstGenId ir_inst_id(IrInstGenBinOp *) { return IrInstGenIdBinOp; } @@ -2652,24 +2646,12 @@ static IrInstSrc *ir_build_un_op(IrBuilderSrc *irb, Scope *scope, AstNode *sourc return ir_build_un_op_lval(irb, scope, source_node, op_id, value, LValNone, nullptr); } -static IrInstGen *ir_build_negation(IrAnalyze *ira, IrInst *source_instr, IrInstGen *operand, ZigType *expr_type) { +static IrInstGen *ir_build_negation(IrAnalyze *ira, IrInst *source_instr, IrInstGen *operand, ZigType *expr_type, bool wrapping) { IrInstGenNegation *instruction = ir_build_inst_gen(&ira->new_irb, source_instr->scope, source_instr->source_node); instruction->base.value->type = expr_type; instruction->operand = operand; - - ir_ref_inst_gen(operand); - - return &instruction->base; -} - -static IrInstGen *ir_build_negation_wrapping(IrAnalyze *ira, IrInst *source_instr, IrInstGen *operand, - ZigType *expr_type) -{ - IrInstGenNegationWrapping *instruction = ir_build_inst_gen(&ira->new_irb, - source_instr->scope, source_instr->source_node); - instruction->base.value->type = expr_type; - instruction->operand = operand; + instruction->wrapping = wrapping; ir_ref_inst_gen(operand); @@ -21273,24 +21255,24 @@ static IrInstGen *ir_analyze_negation(IrAnalyze *ira, IrInstSrcUnOp *instruction bool is_wrap_op = (instruction->op_id == IrUnOpNegationWrap); - switch (expr_type->id) { + ZigType *scalar_type = (expr_type->id == ZigTypeIdVector) ? + expr_type->data.vector.elem_type : expr_type; + + switch (scalar_type->id) { case ZigTypeIdComptimeInt: case ZigTypeIdFloat: case ZigTypeIdComptimeFloat: - case ZigTypeIdVector: break; case ZigTypeIdInt: - if (is_wrap_op || expr_type->data.integral.is_signed) + if (is_wrap_op || scalar_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))); + buf_sprintf("negation of type '%s'", buf_ptr(&scalar_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)) { ZigValue *operand_val = ir_resolve_const(ira, value, UndefBad); if (!operand_val) @@ -21328,11 +21310,7 @@ static IrInstGen *ir_analyze_negation(IrAnalyze *ira, IrInstSrcUnOp *instruction return result_instruction; } - if (is_wrap_op) { - return ir_build_negation_wrapping(ira, &instruction->base.base, value, expr_type); - } else { - return ir_build_negation(ira, &instruction->base.base, value, expr_type); - } + return ir_build_negation(ira, &instruction->base.base, value, expr_type, is_wrap_op); } static IrInstGen *ir_analyze_bin_not(IrAnalyze *ira, IrInstSrcUnOp *instruction) { @@ -32214,7 +32192,6 @@ bool ir_inst_gen_has_side_effects(IrInstGen *instruction) { case IrInstGenIdVectorExtractElem: case IrInstGenIdBinaryNot: case IrInstGenIdNegation: - case IrInstGenIdNegationWrapping: case IrInstGenIdWasmMemorySize: case IrInstGenIdReduce: return false; diff --git a/src/stage1/ir_print.cpp b/src/stage1/ir_print.cpp index 7d7fd4c9ea..b357efe3b8 100644 --- a/src/stage1/ir_print.cpp +++ b/src/stage1/ir_print.cpp @@ -540,8 +540,6 @@ const char* ir_inst_gen_type_str(IrInstGenId id) { return "GenBinaryNot"; case IrInstGenIdNegation: return "GenNegation"; - case IrInstGenIdNegationWrapping: - return "GenNegationWrapping"; case IrInstGenIdWasmMemorySize: return "GenWasmMemorySize"; case IrInstGenIdWasmMemoryGrow: @@ -1144,16 +1142,10 @@ static void ir_print_binary_not(IrPrintGen *irp, IrInstGenBinaryNot *instruction } static void ir_print_negation(IrPrintGen *irp, IrInstGenNegation *instruction) { - fprintf(irp->f, "-"); + fprintf(irp->f, instruction->wrapping ? "-%%" : "-"); ir_print_other_inst_gen(irp, instruction->operand); } -static void ir_print_negation_wrapping(IrPrintGen *irp, IrInstGenNegationWrapping *instruction) { - fprintf(irp->f, "-%%"); - ir_print_other_inst_gen(irp, instruction->operand); -} - - static void ir_print_field_ptr(IrPrintSrc *irp, IrInstSrcFieldPtr *instruction) { if (instruction->field_name_buffer) { fprintf(irp->f, "fieldptr "); @@ -3294,9 +3286,6 @@ static void ir_print_inst_gen(IrPrintGen *irp, IrInstGen *instruction, bool trai case IrInstGenIdNegation: ir_print_negation(irp, (IrInstGenNegation *)instruction); break; - case IrInstGenIdNegationWrapping: - ir_print_negation_wrapping(irp, (IrInstGenNegationWrapping *)instruction); - break; case IrInstGenIdWasmMemorySize: ir_print_wasm_memory_size(irp, (IrInstGenWasmMemorySize *)instruction); break; diff --git a/test/compile_errors.zig b/test/compile_errors.zig index 062a357a93..496cbda9fb 100644 --- a/test/compile_errors.zig +++ b/test/compile_errors.zig @@ -8172,14 +8172,19 @@ 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 { + \\export fn f1(x: u32) u32 { + \\ const y = -%x; + \\ return -y; + \\} + \\const V = @import("std").meta.Vector; + \\export fn f2(x: V(4, u32)) V(4, u32) { \\ const y = -%x; \\ return -y; \\} , &[_][]const u8{ "tmp.zig:3:12: error: negation of type 'u32'", + "tmp.zig:8:12: error: negation of type 'u32'", }); cases.add("Issue #5618: coercion of ?*c_void to *c_void must fail.",