mirror of
https://codeberg.org/ziglang/zig.git
synced 2025-12-06 13:54:21 +00:00
stage1: Fix type-checking of unary neg for vector types
Validate the vector element type as done for the scalar case. Fixes #6708
This commit is contained in:
parent
e51bc19e4a
commit
2a256d5ea0
5 changed files with 19 additions and 61 deletions
|
|
@ -2653,7 +2653,6 @@ enum IrInstGenId {
|
||||||
IrInstGenIdPhi,
|
IrInstGenIdPhi,
|
||||||
IrInstGenIdBinaryNot,
|
IrInstGenIdBinaryNot,
|
||||||
IrInstGenIdNegation,
|
IrInstGenIdNegation,
|
||||||
IrInstGenIdNegationWrapping,
|
|
||||||
IrInstGenIdBinOp,
|
IrInstGenIdBinOp,
|
||||||
IrInstGenIdLoadPtr,
|
IrInstGenIdLoadPtr,
|
||||||
IrInstGenIdStorePtr,
|
IrInstGenIdStorePtr,
|
||||||
|
|
@ -2932,11 +2931,7 @@ struct IrInstGenBinaryNot {
|
||||||
struct IrInstGenNegation {
|
struct IrInstGenNegation {
|
||||||
IrInstGen base;
|
IrInstGen base;
|
||||||
IrInstGen *operand;
|
IrInstGen *operand;
|
||||||
};
|
bool wrapping;
|
||||||
|
|
||||||
struct IrInstGenNegationWrapping {
|
|
||||||
IrInstGen base;
|
|
||||||
IrInstGen *operand;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
enum IrBinOp {
|
enum IrBinOp {
|
||||||
|
|
|
||||||
|
|
@ -3564,13 +3564,7 @@ static LLVMValueRef ir_gen_negation(CodeGen *g, IrInstGen *inst, IrInstGen *oper
|
||||||
static LLVMValueRef ir_render_negation(CodeGen *g, IrExecutableGen *executable,
|
static LLVMValueRef ir_render_negation(CodeGen *g, IrExecutableGen *executable,
|
||||||
IrInstGenNegation *inst)
|
IrInstGenNegation *inst)
|
||||||
{
|
{
|
||||||
return ir_gen_negation(g, &inst->base, inst->operand, false);
|
return ir_gen_negation(g, &inst->base, inst->operand, inst->wrapping);
|
||||||
}
|
|
||||||
|
|
||||||
static LLVMValueRef ir_render_negation_wrapping(CodeGen *g, IrExecutableGen *executable,
|
|
||||||
IrInstGenNegationWrapping *inst)
|
|
||||||
{
|
|
||||||
return ir_gen_negation(g, &inst->base, inst->operand, true);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static LLVMValueRef ir_render_bool_not(CodeGen *g, IrExecutableGen *executable, IrInstGenBoolNot *instruction) {
|
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);
|
return ir_render_binary_not(g, executable, (IrInstGenBinaryNot *)instruction);
|
||||||
case IrInstGenIdNegation:
|
case IrInstGenIdNegation:
|
||||||
return ir_render_negation(g, executable, (IrInstGenNegation *)instruction);
|
return ir_render_negation(g, executable, (IrInstGenNegation *)instruction);
|
||||||
case IrInstGenIdNegationWrapping:
|
|
||||||
return ir_render_negation_wrapping(g, executable, (IrInstGenNegationWrapping *)instruction);
|
|
||||||
case IrInstGenIdLoadPtr:
|
case IrInstGenIdLoadPtr:
|
||||||
return ir_render_load_ptr(g, executable, (IrInstGenLoadPtr *)instruction);
|
return ir_render_load_ptr(g, executable, (IrInstGenLoadPtr *)instruction);
|
||||||
case IrInstGenIdStorePtr:
|
case IrInstGenIdStorePtr:
|
||||||
|
|
|
||||||
|
|
@ -749,8 +749,6 @@ void destroy_instruction_gen(IrInstGen *inst) {
|
||||||
return heap::c_allocator.destroy(reinterpret_cast<IrInstGenBinaryNot *>(inst));
|
return heap::c_allocator.destroy(reinterpret_cast<IrInstGenBinaryNot *>(inst));
|
||||||
case IrInstGenIdNegation:
|
case IrInstGenIdNegation:
|
||||||
return heap::c_allocator.destroy(reinterpret_cast<IrInstGenNegation *>(inst));
|
return heap::c_allocator.destroy(reinterpret_cast<IrInstGenNegation *>(inst));
|
||||||
case IrInstGenIdNegationWrapping:
|
|
||||||
return heap::c_allocator.destroy(reinterpret_cast<IrInstGenNegationWrapping *>(inst));
|
|
||||||
case IrInstGenIdWasmMemorySize:
|
case IrInstGenIdWasmMemorySize:
|
||||||
return heap::c_allocator.destroy(reinterpret_cast<IrInstGenWasmMemorySize *>(inst));
|
return heap::c_allocator.destroy(reinterpret_cast<IrInstGenWasmMemorySize *>(inst));
|
||||||
case IrInstGenIdWasmMemoryGrow:
|
case IrInstGenIdWasmMemoryGrow:
|
||||||
|
|
@ -1672,10 +1670,6 @@ static constexpr IrInstGenId ir_inst_id(IrInstGenNegation *) {
|
||||||
return IrInstGenIdNegation;
|
return IrInstGenIdNegation;
|
||||||
}
|
}
|
||||||
|
|
||||||
static constexpr IrInstGenId ir_inst_id(IrInstGenNegationWrapping *) {
|
|
||||||
return IrInstGenIdNegationWrapping;
|
|
||||||
}
|
|
||||||
|
|
||||||
static constexpr IrInstGenId ir_inst_id(IrInstGenBinOp *) {
|
static constexpr IrInstGenId ir_inst_id(IrInstGenBinOp *) {
|
||||||
return IrInstGenIdBinOp;
|
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);
|
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<IrInstGenNegation>(&ira->new_irb,
|
IrInstGenNegation *instruction = ir_build_inst_gen<IrInstGenNegation>(&ira->new_irb,
|
||||||
source_instr->scope, source_instr->source_node);
|
source_instr->scope, source_instr->source_node);
|
||||||
instruction->base.value->type = expr_type;
|
instruction->base.value->type = expr_type;
|
||||||
instruction->operand = operand;
|
instruction->operand = operand;
|
||||||
|
instruction->wrapping = wrapping;
|
||||||
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<IrInstGenNegationWrapping>(&ira->new_irb,
|
|
||||||
source_instr->scope, source_instr->source_node);
|
|
||||||
instruction->base.value->type = expr_type;
|
|
||||||
instruction->operand = operand;
|
|
||||||
|
|
||||||
ir_ref_inst_gen(operand);
|
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);
|
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 ZigTypeIdComptimeInt:
|
||||||
case ZigTypeIdFloat:
|
case ZigTypeIdFloat:
|
||||||
case ZigTypeIdComptimeFloat:
|
case ZigTypeIdComptimeFloat:
|
||||||
case ZigTypeIdVector:
|
|
||||||
break;
|
break;
|
||||||
case ZigTypeIdInt:
|
case ZigTypeIdInt:
|
||||||
if (is_wrap_op || expr_type->data.integral.is_signed)
|
if (is_wrap_op || scalar_type->data.integral.is_signed)
|
||||||
break;
|
break;
|
||||||
ZIG_FALLTHROUGH;
|
ZIG_FALLTHROUGH;
|
||||||
default:
|
default:
|
||||||
ir_add_error(ira, &instruction->base.base,
|
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;
|
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)) {
|
if (instr_is_comptime(value)) {
|
||||||
ZigValue *operand_val = ir_resolve_const(ira, value, UndefBad);
|
ZigValue *operand_val = ir_resolve_const(ira, value, UndefBad);
|
||||||
if (!operand_val)
|
if (!operand_val)
|
||||||
|
|
@ -21328,11 +21310,7 @@ static IrInstGen *ir_analyze_negation(IrAnalyze *ira, IrInstSrcUnOp *instruction
|
||||||
return result_instruction;
|
return result_instruction;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (is_wrap_op) {
|
return ir_build_negation(ira, &instruction->base.base, value, expr_type, 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);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static IrInstGen *ir_analyze_bin_not(IrAnalyze *ira, IrInstSrcUnOp *instruction) {
|
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 IrInstGenIdVectorExtractElem:
|
||||||
case IrInstGenIdBinaryNot:
|
case IrInstGenIdBinaryNot:
|
||||||
case IrInstGenIdNegation:
|
case IrInstGenIdNegation:
|
||||||
case IrInstGenIdNegationWrapping:
|
|
||||||
case IrInstGenIdWasmMemorySize:
|
case IrInstGenIdWasmMemorySize:
|
||||||
case IrInstGenIdReduce:
|
case IrInstGenIdReduce:
|
||||||
return false;
|
return false;
|
||||||
|
|
|
||||||
|
|
@ -540,8 +540,6 @@ const char* ir_inst_gen_type_str(IrInstGenId id) {
|
||||||
return "GenBinaryNot";
|
return "GenBinaryNot";
|
||||||
case IrInstGenIdNegation:
|
case IrInstGenIdNegation:
|
||||||
return "GenNegation";
|
return "GenNegation";
|
||||||
case IrInstGenIdNegationWrapping:
|
|
||||||
return "GenNegationWrapping";
|
|
||||||
case IrInstGenIdWasmMemorySize:
|
case IrInstGenIdWasmMemorySize:
|
||||||
return "GenWasmMemorySize";
|
return "GenWasmMemorySize";
|
||||||
case IrInstGenIdWasmMemoryGrow:
|
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) {
|
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);
|
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) {
|
static void ir_print_field_ptr(IrPrintSrc *irp, IrInstSrcFieldPtr *instruction) {
|
||||||
if (instruction->field_name_buffer) {
|
if (instruction->field_name_buffer) {
|
||||||
fprintf(irp->f, "fieldptr ");
|
fprintf(irp->f, "fieldptr ");
|
||||||
|
|
@ -3294,9 +3286,6 @@ static void ir_print_inst_gen(IrPrintGen *irp, IrInstGen *instruction, bool trai
|
||||||
case IrInstGenIdNegation:
|
case IrInstGenIdNegation:
|
||||||
ir_print_negation(irp, (IrInstGenNegation *)instruction);
|
ir_print_negation(irp, (IrInstGenNegation *)instruction);
|
||||||
break;
|
break;
|
||||||
case IrInstGenIdNegationWrapping:
|
|
||||||
ir_print_negation_wrapping(irp, (IrInstGenNegationWrapping *)instruction);
|
|
||||||
break;
|
|
||||||
case IrInstGenIdWasmMemorySize:
|
case IrInstGenIdWasmMemorySize:
|
||||||
ir_print_wasm_memory_size(irp, (IrInstGenWasmMemorySize *)instruction);
|
ir_print_wasm_memory_size(irp, (IrInstGenWasmMemorySize *)instruction);
|
||||||
break;
|
break;
|
||||||
|
|
|
||||||
|
|
@ -8172,14 +8172,19 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {
|
||||||
, &[_][]const u8{
|
, &[_][]const u8{
|
||||||
"tmp.zig:2:9: error: @wasmMemoryGrow is a wasm32 feature only",
|
"tmp.zig:2:9: error: @wasmMemoryGrow is a wasm32 feature only",
|
||||||
});
|
});
|
||||||
|
|
||||||
cases.add("Issue #5586: Make unary minus for unsigned types a compile error",
|
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;
|
\\ const y = -%x;
|
||||||
\\ return -y;
|
\\ return -y;
|
||||||
\\}
|
\\}
|
||||||
, &[_][]const u8{
|
, &[_][]const u8{
|
||||||
"tmp.zig:3:12: error: negation of type 'u32'",
|
"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.",
|
cases.add("Issue #5618: coercion of ?*c_void to *c_void must fail.",
|
||||||
|
|
|
||||||
Loading…
Add table
Reference in a new issue