authorgravatar for thatlemon@gmail.comLemonBoy <thatlemon@gmail.com> 2020-10-17 10:06:14+02:00
committergravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2020-10-17 21:08:39-04:00
log2a256d5ea02c8f520c54fd335c38891d6e05a63f
tree1ba784027dc33d9e16b4f59319cb752bfc1f204c
parente51bc19e4a45211476491f29d2beff73ff6be570

stage1: Fix type-checking of unary neg for vector types

Validate the vector element type as done for the scalar case. Fixes #6708

5 files changed, 19 insertions(+), 61 deletions(-)

src/stage1/all_types.hpp+1-6
...@@ -2653,7 +2653,6 @@ enum IrInstGenId {...@@ -2653,7 +2653,6 @@ enum IrInstGenId {
2653 IrInstGenIdPhi,2653 IrInstGenIdPhi,
2654 IrInstGenIdBinaryNot,2654 IrInstGenIdBinaryNot,
2655 IrInstGenIdNegation,2655 IrInstGenIdNegation,
2656 IrInstGenIdNegationWrapping,
2657 IrInstGenIdBinOp,2656 IrInstGenIdBinOp,
2658 IrInstGenIdLoadPtr,2657 IrInstGenIdLoadPtr,
2659 IrInstGenIdStorePtr,2658 IrInstGenIdStorePtr,
...@@ -2932,11 +2931,7 @@ struct IrInstGenBinaryNot {...@@ -2932,11 +2931,7 @@ struct IrInstGenBinaryNot {
2932struct IrInstGenNegation {2931struct IrInstGenNegation {
2933 IrInstGen base;2932 IrInstGen base;
2934 IrInstGen *operand;2933 IrInstGen *operand;
2935};2934 bool wrapping;
2936
2937struct IrInstGenNegationWrapping {
2938 IrInstGen base;
2939 IrInstGen *operand;
2940};2935};
29412936
2942enum IrBinOp {2937enum IrBinOp {
src/stage1/codegen.cpp+1-9
...@@ -3564,13 +3564,7 @@ static LLVMValueRef ir_gen_negation(CodeGen *g, IrInstGen *inst, IrInstGen *oper...@@ -3564,13 +3564,7 @@ static LLVMValueRef ir_gen_negation(CodeGen *g, IrInstGen *inst, IrInstGen *oper
3564static LLVMValueRef ir_render_negation(CodeGen *g, IrExecutableGen *executable,3564static LLVMValueRef ir_render_negation(CodeGen *g, IrExecutableGen *executable,
3565 IrInstGenNegation *inst)3565 IrInstGenNegation *inst)
3566{3566{
3567 return ir_gen_negation(g, &inst->base, inst->operand, false);3567 return ir_gen_negation(g, &inst->base, inst->operand, inst->wrapping);
3568}
3569
3570static LLVMValueRef ir_render_negation_wrapping(CodeGen *g, IrExecutableGen *executable,
3571 IrInstGenNegationWrapping *inst)
3572{
3573 return ir_gen_negation(g, &inst->base, inst->operand, true);
3574}3568}
35753569
3576static LLVMValueRef ir_render_bool_not(CodeGen *g, IrExecutableGen *executable, IrInstGenBoolNot *instruction) {3570static LLVMValueRef ir_render_bool_not(CodeGen *g, IrExecutableGen *executable, IrInstGenBoolNot *instruction) {
...@@ -6645,8 +6639,6 @@ static LLVMValueRef ir_render_instruction(CodeGen *g, IrExecutableGen *executabl...@@ -6645,8 +6639,6 @@ static LLVMValueRef ir_render_instruction(CodeGen *g, IrExecutableGen *executabl
6645 return ir_render_binary_not(g, executable, (IrInstGenBinaryNot *)instruction);6639 return ir_render_binary_not(g, executable, (IrInstGenBinaryNot *)instruction);
6646 case IrInstGenIdNegation:6640 case IrInstGenIdNegation:
6647 return ir_render_negation(g, executable, (IrInstGenNegation *)instruction);6641 return ir_render_negation(g, executable, (IrInstGenNegation *)instruction);
6648 case IrInstGenIdNegationWrapping:
6649 return ir_render_negation_wrapping(g, executable, (IrInstGenNegationWrapping *)instruction);
6650 case IrInstGenIdLoadPtr:6642 case IrInstGenIdLoadPtr:
6651 return ir_render_load_ptr(g, executable, (IrInstGenLoadPtr *)instruction);6643 return ir_render_load_ptr(g, executable, (IrInstGenLoadPtr *)instruction);
6652 case IrInstGenIdStorePtr:6644 case IrInstGenIdStorePtr:
src/stage1/ir.cpp+9-32
...@@ -749,8 +749,6 @@ void destroy_instruction_gen(IrInstGen *inst) {...@@ -749,8 +749,6 @@ void destroy_instruction_gen(IrInstGen *inst) {
749 return heap::c_allocator.destroy(reinterpret_cast<IrInstGenBinaryNot *>(inst));749 return heap::c_allocator.destroy(reinterpret_cast<IrInstGenBinaryNot *>(inst));
750 case IrInstGenIdNegation:750 case IrInstGenIdNegation:
751 return heap::c_allocator.destroy(reinterpret_cast<IrInstGenNegation *>(inst));751 return heap::c_allocator.destroy(reinterpret_cast<IrInstGenNegation *>(inst));
752 case IrInstGenIdNegationWrapping:
753 return heap::c_allocator.destroy(reinterpret_cast<IrInstGenNegationWrapping *>(inst));
754 case IrInstGenIdWasmMemorySize:752 case IrInstGenIdWasmMemorySize:
755 return heap::c_allocator.destroy(reinterpret_cast<IrInstGenWasmMemorySize *>(inst));753 return heap::c_allocator.destroy(reinterpret_cast<IrInstGenWasmMemorySize *>(inst));
756 case IrInstGenIdWasmMemoryGrow:754 case IrInstGenIdWasmMemoryGrow:
...@@ -1672,10 +1670,6 @@ static constexpr IrInstGenId ir_inst_id(IrInstGenNegation *) {...@@ -1672,10 +1670,6 @@ static constexpr IrInstGenId ir_inst_id(IrInstGenNegation *) {
1672 return IrInstGenIdNegation;1670 return IrInstGenIdNegation;
1673}1671}
16741672
1675static constexpr IrInstGenId ir_inst_id(IrInstGenNegationWrapping *) {
1676 return IrInstGenIdNegationWrapping;
1677}
1678
1679static constexpr IrInstGenId ir_inst_id(IrInstGenBinOp *) {1673static constexpr IrInstGenId ir_inst_id(IrInstGenBinOp *) {
1680 return IrInstGenIdBinOp;1674 return IrInstGenIdBinOp;
1681}1675}
...@@ -2652,24 +2646,12 @@ static IrInstSrc *ir_build_un_op(IrBuilderSrc *irb, Scope *scope, AstNode *sourc...@@ -2652,24 +2646,12 @@ static IrInstSrc *ir_build_un_op(IrBuilderSrc *irb, Scope *scope, AstNode *sourc
2652 return ir_build_un_op_lval(irb, scope, source_node, op_id, value, LValNone, nullptr);2646 return ir_build_un_op_lval(irb, scope, source_node, op_id, value, LValNone, nullptr);
2653}2647}
26542648
2655static IrInstGen *ir_build_negation(IrAnalyze *ira, IrInst *source_instr, IrInstGen *operand, ZigType *expr_type) {2649static IrInstGen *ir_build_negation(IrAnalyze *ira, IrInst *source_instr, IrInstGen *operand, ZigType *expr_type, bool wrapping) {
2656 IrInstGenNegation *instruction = ir_build_inst_gen<IrInstGenNegation>(&ira->new_irb,2650 IrInstGenNegation *instruction = ir_build_inst_gen<IrInstGenNegation>(&ira->new_irb,
2657 source_instr->scope, source_instr->source_node);2651 source_instr->scope, source_instr->source_node);
2658 instruction->base.value->type = expr_type;2652 instruction->base.value->type = expr_type;
2659 instruction->operand = operand;2653 instruction->operand = operand;
26602654 instruction->wrapping = wrapping;
2661 ir_ref_inst_gen(operand);
2662
2663 return &instruction->base;
2664}
2665
2666static IrInstGen *ir_build_negation_wrapping(IrAnalyze *ira, IrInst *source_instr, IrInstGen *operand,
2667 ZigType *expr_type)
2668{
2669 IrInstGenNegationWrapping *instruction = ir_build_inst_gen<IrInstGenNegationWrapping>(&ira->new_irb,
2670 source_instr->scope, source_instr->source_node);
2671 instruction->base.value->type = expr_type;
2672 instruction->operand = operand;
26732655
2674 ir_ref_inst_gen(operand);2656 ir_ref_inst_gen(operand);
26752657
...@@ -21273,24 +21255,24 @@ static IrInstGen *ir_analyze_negation(IrAnalyze *ira, IrInstSrcUnOp *instruction...@@ -21273,24 +21255,24 @@ static IrInstGen *ir_analyze_negation(IrAnalyze *ira, IrInstSrcUnOp *instruction
2127321255
21274 bool is_wrap_op = (instruction->op_id == IrUnOpNegationWrap);21256 bool is_wrap_op = (instruction->op_id == IrUnOpNegationWrap);
2127521257
21276 switch (expr_type->id) {21258 ZigType *scalar_type = (expr_type->id == ZigTypeIdVector) ?
21259 expr_type->data.vector.elem_type : expr_type;
21260
21261 switch (scalar_type->id) {
21277 case ZigTypeIdComptimeInt:21262 case ZigTypeIdComptimeInt:
21278 case ZigTypeIdFloat:21263 case ZigTypeIdFloat:
21279 case ZigTypeIdComptimeFloat:21264 case ZigTypeIdComptimeFloat:
21280 case ZigTypeIdVector:
21281 break;21265 break;
21282 case ZigTypeIdInt:21266 case ZigTypeIdInt:
21283 if (is_wrap_op || expr_type->data.integral.is_signed)21267 if (is_wrap_op || scalar_type->data.integral.is_signed)
21284 break;21268 break;
21285 ZIG_FALLTHROUGH;21269 ZIG_FALLTHROUGH;
21286 default:21270 default:
21287 ir_add_error(ira, &instruction->base.base,21271 ir_add_error(ira, &instruction->base.base,
21288 buf_sprintf("negation of type '%s'", buf_ptr(&expr_type->name)));21272 buf_sprintf("negation of type '%s'", buf_ptr(&scalar_type->name)));
21289 return ira->codegen->invalid_inst_gen;21273 return ira->codegen->invalid_inst_gen;
21290 }21274 }
2129121275
21292 ZigType *scalar_type = (expr_type->id == ZigTypeIdVector) ? expr_type->data.vector.elem_type : expr_type;
21293
21294 if (instr_is_comptime(value)) {21276 if (instr_is_comptime(value)) {
21295 ZigValue *operand_val = ir_resolve_const(ira, value, UndefBad);21277 ZigValue *operand_val = ir_resolve_const(ira, value, UndefBad);
21296 if (!operand_val)21278 if (!operand_val)
...@@ -21328,11 +21310,7 @@ static IrInstGen *ir_analyze_negation(IrAnalyze *ira, IrInstSrcUnOp *instruction...@@ -21328,11 +21310,7 @@ static IrInstGen *ir_analyze_negation(IrAnalyze *ira, IrInstSrcUnOp *instruction
21328 return result_instruction;21310 return result_instruction;
21329 }21311 }
2133021312
21331 if (is_wrap_op) {21313 return ir_build_negation(ira, &instruction->base.base, value, expr_type, is_wrap_op);
21332 return ir_build_negation_wrapping(ira, &instruction->base.base, value, expr_type);
21333 } else {
21334 return ir_build_negation(ira, &instruction->base.base, value, expr_type);
21335 }
21336}21314}
2133721315
21338static IrInstGen *ir_analyze_bin_not(IrAnalyze *ira, IrInstSrcUnOp *instruction) {21316static IrInstGen *ir_analyze_bin_not(IrAnalyze *ira, IrInstSrcUnOp *instruction) {
...@@ -32214,7 +32192,6 @@ bool ir_inst_gen_has_side_effects(IrInstGen *instruction) {...@@ -32214,7 +32192,6 @@ bool ir_inst_gen_has_side_effects(IrInstGen *instruction) {
32214 case IrInstGenIdVectorExtractElem:32192 case IrInstGenIdVectorExtractElem:
32215 case IrInstGenIdBinaryNot:32193 case IrInstGenIdBinaryNot:
32216 case IrInstGenIdNegation:32194 case IrInstGenIdNegation:
32217 case IrInstGenIdNegationWrapping:
32218 case IrInstGenIdWasmMemorySize:32195 case IrInstGenIdWasmMemorySize:
32219 case IrInstGenIdReduce:32196 case IrInstGenIdReduce:
32220 return false;32197 return false;
src/stage1/ir_print.cpp+1-12
...@@ -540,8 +540,6 @@ const char* ir_inst_gen_type_str(IrInstGenId id) {...@@ -540,8 +540,6 @@ const char* ir_inst_gen_type_str(IrInstGenId id) {
540 return "GenBinaryNot";540 return "GenBinaryNot";
541 case IrInstGenIdNegation:541 case IrInstGenIdNegation:
542 return "GenNegation";542 return "GenNegation";
543 case IrInstGenIdNegationWrapping:
544 return "GenNegationWrapping";
545 case IrInstGenIdWasmMemorySize:543 case IrInstGenIdWasmMemorySize:
546 return "GenWasmMemorySize";544 return "GenWasmMemorySize";
547 case IrInstGenIdWasmMemoryGrow:545 case IrInstGenIdWasmMemoryGrow:
...@@ -1144,16 +1142,10 @@ static void ir_print_binary_not(IrPrintGen *irp, IrInstGenBinaryNot *instruction...@@ -1144,16 +1142,10 @@ static void ir_print_binary_not(IrPrintGen *irp, IrInstGenBinaryNot *instruction
1144}1142}
11451143
1146static void ir_print_negation(IrPrintGen *irp, IrInstGenNegation *instruction) {1144static void ir_print_negation(IrPrintGen *irp, IrInstGenNegation *instruction) {
1147 fprintf(irp->f, "-");1145 fprintf(irp->f, instruction->wrapping ? "-%%" : "-");
1148 ir_print_other_inst_gen(irp, instruction->operand);1146 ir_print_other_inst_gen(irp, instruction->operand);
1149}1147}
11501148
1151static void ir_print_negation_wrapping(IrPrintGen *irp, IrInstGenNegationWrapping *instruction) {
1152 fprintf(irp->f, "-%%");
1153 ir_print_other_inst_gen(irp, instruction->operand);
1154}
1155
1156
1157static void ir_print_field_ptr(IrPrintSrc *irp, IrInstSrcFieldPtr *instruction) {1149static void ir_print_field_ptr(IrPrintSrc *irp, IrInstSrcFieldPtr *instruction) {
1158 if (instruction->field_name_buffer) {1150 if (instruction->field_name_buffer) {
1159 fprintf(irp->f, "fieldptr ");1151 fprintf(irp->f, "fieldptr ");
...@@ -3294,9 +3286,6 @@ static void ir_print_inst_gen(IrPrintGen *irp, IrInstGen *instruction, bool trai...@@ -3294,9 +3286,6 @@ static void ir_print_inst_gen(IrPrintGen *irp, IrInstGen *instruction, bool trai
3294 case IrInstGenIdNegation:3286 case IrInstGenIdNegation:
3295 ir_print_negation(irp, (IrInstGenNegation *)instruction);3287 ir_print_negation(irp, (IrInstGenNegation *)instruction);
3296 break;3288 break;
3297 case IrInstGenIdNegationWrapping:
3298 ir_print_negation_wrapping(irp, (IrInstGenNegationWrapping *)instruction);
3299 break;
3300 case IrInstGenIdWasmMemorySize:3289 case IrInstGenIdWasmMemorySize:
3301 ir_print_wasm_memory_size(irp, (IrInstGenWasmMemorySize *)instruction);3290 ir_print_wasm_memory_size(irp, (IrInstGenWasmMemorySize *)instruction);
3302 break;3291 break;
test/compile_errors.zig+7-2
...@@ -8172,14 +8172,19 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {...@@ -8172,14 +8172,19 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {
8172 , &[_][]const u8{8172 , &[_][]const u8{
8173 "tmp.zig:2:9: error: @wasmMemoryGrow is a wasm32 feature only",8173 "tmp.zig:2:9: error: @wasmMemoryGrow is a wasm32 feature only",
8174 });8174 });
8175
8176 cases.add("Issue #5586: Make unary minus for unsigned types a compile error",8175 cases.add("Issue #5586: Make unary minus for unsigned types a compile error",
8177 \\export fn f(x: u32) u32 {8176 \\export fn f1(x: u32) u32 {
8177 \\ const y = -%x;
8178 \\ return -y;
8179 \\}
8180 \\const V = @import("std").meta.Vector;
8181 \\export fn f2(x: V(4, u32)) V(4, u32) {
8178 \\ const y = -%x;8182 \\ const y = -%x;
8179 \\ return -y;8183 \\ return -y;
8180 \\}8184 \\}
8181 , &[_][]const u8{8185 , &[_][]const u8{
8182 "tmp.zig:3:12: error: negation of type 'u32'",8186 "tmp.zig:3:12: error: negation of type 'u32'",
8187 "tmp.zig:8:12: error: negation of type 'u32'",
8183 });8188 });
81848189
8185 cases.add("Issue #5618: coercion of ?*c_void to *c_void must fail.",8190 cases.add("Issue #5618: coercion of ?*c_void to *c_void must fail.",