| author | |
| committer | |
| log | 2a256d5ea02c8f520c54fd335c38891d6e05a63f |
| tree | 1ba784027dc33d9e16b4f59319cb752bfc1f204c |
| parent | e51bc19e4a45211476491f29d2beff73ff6be570 |
Validate the vector element type as done for the scalar case.
Fixes #67085 files changed, 19 insertions(+), 61 deletions(-)
src/stage1/all_types.hpp+1-6| ... | ... | @@ -2653,7 +2653,6 @@ enum IrInstGenId { |
| 2653 | 2653 | IrInstGenIdPhi, |
| 2654 | 2654 | IrInstGenIdBinaryNot, |
| 2655 | 2655 | IrInstGenIdNegation, |
| 2656 | IrInstGenIdNegationWrapping, | |
| 2657 | 2656 | IrInstGenIdBinOp, |
| 2658 | 2657 | IrInstGenIdLoadPtr, |
| 2659 | 2658 | IrInstGenIdStorePtr, |
| ... | ... | @@ -2932,11 +2931,7 @@ struct IrInstGenBinaryNot { |
| 2932 | 2931 | struct IrInstGenNegation { |
| 2933 | 2932 | IrInstGen base; |
| 2934 | 2933 | IrInstGen *operand; |
| 2935 | }; | |
| 2936 | ||
| 2937 | struct IrInstGenNegationWrapping { | |
| 2938 | IrInstGen base; | |
| 2939 | IrInstGen *operand; | |
| 2934 | bool wrapping; | |
| 2940 | 2935 | }; |
| 2941 | 2936 | |
| 2942 | 2937 | enum IrBinOp { |
src/stage1/codegen.cpp+1-9| ... | ... | @@ -3564,13 +3564,7 @@ static LLVMValueRef ir_gen_negation(CodeGen *g, IrInstGen *inst, IrInstGen *oper |
| 3564 | 3564 | static LLVMValueRef ir_render_negation(CodeGen *g, IrExecutableGen *executable, |
| 3565 | 3565 | IrInstGenNegation *inst) |
| 3566 | 3566 | { |
| 3567 | return ir_gen_negation(g, &inst->base, inst->operand, false); | |
| 3568 | } | |
| 3569 | ||
| 3570 | static LLVMValueRef ir_render_negation_wrapping(CodeGen *g, IrExecutableGen *executable, | |
| 3571 | IrInstGenNegationWrapping *inst) | |
| 3572 | { | |
| 3573 | return ir_gen_negation(g, &inst->base, inst->operand, true); | |
| 3567 | return ir_gen_negation(g, &inst->base, inst->operand, inst->wrapping); | |
| 3574 | 3568 | } |
| 3575 | 3569 | |
| 3576 | 3570 | 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 |
| 6645 | 6639 | return ir_render_binary_not(g, executable, (IrInstGenBinaryNot *)instruction); |
| 6646 | 6640 | case IrInstGenIdNegation: |
| 6647 | 6641 | return ir_render_negation(g, executable, (IrInstGenNegation *)instruction); |
| 6648 | case IrInstGenIdNegationWrapping: | |
| 6649 | return ir_render_negation_wrapping(g, executable, (IrInstGenNegationWrapping *)instruction); | |
| 6650 | 6642 | case IrInstGenIdLoadPtr: |
| 6651 | 6643 | return ir_render_load_ptr(g, executable, (IrInstGenLoadPtr *)instruction); |
| 6652 | 6644 | case IrInstGenIdStorePtr: |
src/stage1/ir.cpp+9-32| ... | ... | @@ -749,8 +749,6 @@ void destroy_instruction_gen(IrInstGen *inst) { |
| 749 | 749 | return heap::c_allocator.destroy(reinterpret_cast<IrInstGenBinaryNot *>(inst)); |
| 750 | 750 | case IrInstGenIdNegation: |
| 751 | 751 | return heap::c_allocator.destroy(reinterpret_cast<IrInstGenNegation *>(inst)); |
| 752 | case IrInstGenIdNegationWrapping: | |
| 753 | return heap::c_allocator.destroy(reinterpret_cast<IrInstGenNegationWrapping *>(inst)); | |
| 754 | 752 | case IrInstGenIdWasmMemorySize: |
| 755 | 753 | return heap::c_allocator.destroy(reinterpret_cast<IrInstGenWasmMemorySize *>(inst)); |
| 756 | 754 | case IrInstGenIdWasmMemoryGrow: |
| ... | ... | @@ -1672,10 +1670,6 @@ static constexpr IrInstGenId ir_inst_id(IrInstGenNegation *) { |
| 1672 | 1670 | return IrInstGenIdNegation; |
| 1673 | 1671 | } |
| 1674 | 1672 | |
| 1675 | static constexpr IrInstGenId ir_inst_id(IrInstGenNegationWrapping *) { | |
| 1676 | return IrInstGenIdNegationWrapping; | |
| 1677 | } | |
| 1678 | ||
| 1679 | 1673 | static constexpr IrInstGenId ir_inst_id(IrInstGenBinOp *) { |
| 1680 | 1674 | return IrInstGenIdBinOp; |
| 1681 | 1675 | } |
| ... | ... | @@ -2652,24 +2646,12 @@ static IrInstSrc *ir_build_un_op(IrBuilderSrc *irb, Scope *scope, AstNode *sourc |
| 2652 | 2646 | return ir_build_un_op_lval(irb, scope, source_node, op_id, value, LValNone, nullptr); |
| 2653 | 2647 | } |
| 2654 | 2648 | |
| 2655 | static IrInstGen *ir_build_negation(IrAnalyze *ira, IrInst *source_instr, IrInstGen *operand, ZigType *expr_type) { | |
| 2649 | static IrInstGen *ir_build_negation(IrAnalyze *ira, IrInst *source_instr, IrInstGen *operand, ZigType *expr_type, bool wrapping) { | |
| 2656 | 2650 | IrInstGenNegation *instruction = ir_build_inst_gen<IrInstGenNegation>(&ira->new_irb, |
| 2657 | 2651 | source_instr->scope, source_instr->source_node); |
| 2658 | 2652 | instruction->base.value->type = expr_type; |
| 2659 | 2653 | instruction->operand = operand; |
| 2660 | ||
| 2661 | ir_ref_inst_gen(operand); | |
| 2662 | ||
| 2663 | return &instruction->base; | |
| 2664 | } | |
| 2665 | ||
| 2666 | static 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; | |
| 2654 | instruction->wrapping = wrapping; | |
| 2673 | 2655 | |
| 2674 | 2656 | ir_ref_inst_gen(operand); |
| 2675 | 2657 | |
| ... | ... | @@ -21273,24 +21255,24 @@ static IrInstGen *ir_analyze_negation(IrAnalyze *ira, IrInstSrcUnOp *instruction |
| 21273 | 21255 | |
| 21274 | 21256 | bool is_wrap_op = (instruction->op_id == IrUnOpNegationWrap); |
| 21275 | 21257 | |
| 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 | 21262 | case ZigTypeIdComptimeInt: |
| 21278 | 21263 | case ZigTypeIdFloat: |
| 21279 | 21264 | case ZigTypeIdComptimeFloat: |
| 21280 | case ZigTypeIdVector: | |
| 21281 | 21265 | break; |
| 21282 | 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 | 21268 | break; |
| 21285 | 21269 | ZIG_FALLTHROUGH; |
| 21286 | 21270 | default: |
| 21287 | 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 | 21273 | return ira->codegen->invalid_inst_gen; |
| 21290 | 21274 | } |
| 21291 | 21275 | |
| 21292 | ZigType *scalar_type = (expr_type->id == ZigTypeIdVector) ? expr_type->data.vector.elem_type : expr_type; | |
| 21293 | ||
| 21294 | 21276 | if (instr_is_comptime(value)) { |
| 21295 | 21277 | ZigValue *operand_val = ir_resolve_const(ira, value, UndefBad); |
| 21296 | 21278 | if (!operand_val) |
| ... | ... | @@ -21328,11 +21310,7 @@ static IrInstGen *ir_analyze_negation(IrAnalyze *ira, IrInstSrcUnOp *instruction |
| 21328 | 21310 | return result_instruction; |
| 21329 | 21311 | } |
| 21330 | 21312 | |
| 21331 | if (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 | } | |
| 21313 | return ir_build_negation(ira, &instruction->base.base, value, expr_type, is_wrap_op); | |
| 21336 | 21314 | } |
| 21337 | 21315 | |
| 21338 | 21316 | static IrInstGen *ir_analyze_bin_not(IrAnalyze *ira, IrInstSrcUnOp *instruction) { |
| ... | ... | @@ -32214,7 +32192,6 @@ bool ir_inst_gen_has_side_effects(IrInstGen *instruction) { |
| 32214 | 32192 | case IrInstGenIdVectorExtractElem: |
| 32215 | 32193 | case IrInstGenIdBinaryNot: |
| 32216 | 32194 | case IrInstGenIdNegation: |
| 32217 | case IrInstGenIdNegationWrapping: | |
| 32218 | 32195 | case IrInstGenIdWasmMemorySize: |
| 32219 | 32196 | case IrInstGenIdReduce: |
| 32220 | 32197 | return false; |
src/stage1/ir_print.cpp+1-12| ... | ... | @@ -540,8 +540,6 @@ const char* ir_inst_gen_type_str(IrInstGenId id) { |
| 540 | 540 | return "GenBinaryNot"; |
| 541 | 541 | case IrInstGenIdNegation: |
| 542 | 542 | return "GenNegation"; |
| 543 | case IrInstGenIdNegationWrapping: | |
| 544 | return "GenNegationWrapping"; | |
| 545 | 543 | case IrInstGenIdWasmMemorySize: |
| 546 | 544 | return "GenWasmMemorySize"; |
| 547 | 545 | case IrInstGenIdWasmMemoryGrow: |
| ... | ... | @@ -1144,16 +1142,10 @@ static void ir_print_binary_not(IrPrintGen *irp, IrInstGenBinaryNot *instruction |
| 1144 | 1142 | } |
| 1145 | 1143 | |
| 1146 | 1144 | static void ir_print_negation(IrPrintGen *irp, IrInstGenNegation *instruction) { |
| 1147 | fprintf(irp->f, "-"); | |
| 1145 | fprintf(irp->f, instruction->wrapping ? "-%%" : "-"); | |
| 1148 | 1146 | ir_print_other_inst_gen(irp, instruction->operand); |
| 1149 | 1147 | } |
| 1150 | 1148 | |
| 1151 | static 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 | ||
| 1157 | 1149 | static void ir_print_field_ptr(IrPrintSrc *irp, IrInstSrcFieldPtr *instruction) { |
| 1158 | 1150 | if (instruction->field_name_buffer) { |
| 1159 | 1151 | fprintf(irp->f, "fieldptr "); |
| ... | ... | @@ -3294,9 +3286,6 @@ static void ir_print_inst_gen(IrPrintGen *irp, IrInstGen *instruction, bool trai |
| 3294 | 3286 | case IrInstGenIdNegation: |
| 3295 | 3287 | ir_print_negation(irp, (IrInstGenNegation *)instruction); |
| 3296 | 3288 | break; |
| 3297 | case IrInstGenIdNegationWrapping: | |
| 3298 | ir_print_negation_wrapping(irp, (IrInstGenNegationWrapping *)instruction); | |
| 3299 | break; | |
| 3300 | 3289 | case IrInstGenIdWasmMemorySize: |
| 3301 | 3290 | ir_print_wasm_memory_size(irp, (IrInstGenWasmMemorySize *)instruction); |
| 3302 | 3291 | break; |
test/compile_errors.zig+7-2| ... | ... | @@ -8172,14 +8172,19 @@ pub fn addCases(cases: *tests.CompileErrorContext) void { |
| 8172 | 8172 | , &[_][]const u8{ |
| 8173 | 8173 | "tmp.zig:2:9: error: @wasmMemoryGrow is a wasm32 feature only", |
| 8174 | 8174 | }); |
| 8175 | ||
| 8176 | 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 | 8182 | \\ const y = -%x; |
| 8179 | 8183 | \\ return -y; |
| 8180 | 8184 | \\} |
| 8181 | 8185 | , &[_][]const u8{ |
| 8182 | 8186 | "tmp.zig:3:12: error: negation of type 'u32'", |
| 8187 | "tmp.zig:8:12: error: negation of type 'u32'", | |
| 8183 | 8188 | }); |
| 8184 | 8189 | |
| 8185 | 8190 | cases.add("Issue #5618: coercion of ?*c_void to *c_void must fail.", |