Skip to content

Commit 2a256d5

Browse files
LemonBoyandrewrk
authored andcommitted
stage1: Fix type-checking of unary neg for vector types
Validate the vector element type as done for the scalar case. Fixes #6708
1 parent e51bc19 commit 2a256d5

File tree

5 files changed

+19
-61
lines changed

5 files changed

+19
-61
lines changed

src/stage1/all_types.hpp

Lines changed: 1 addition & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -2653,7 +2653,6 @@ enum IrInstGenId {
26532653
IrInstGenIdPhi,
26542654
IrInstGenIdBinaryNot,
26552655
IrInstGenIdNegation,
2656-
IrInstGenIdNegationWrapping,
26572656
IrInstGenIdBinOp,
26582657
IrInstGenIdLoadPtr,
26592658
IrInstGenIdStorePtr,
@@ -2932,11 +2931,7 @@ struct IrInstGenBinaryNot {
29322931
struct IrInstGenNegation {
29332932
IrInstGen base;
29342933
IrInstGen *operand;
2935-
};
2936-
2937-
struct IrInstGenNegationWrapping {
2938-
IrInstGen base;
2939-
IrInstGen *operand;
2934+
bool wrapping;
29402935
};
29412936

29422937
enum IrBinOp {

src/stage1/codegen.cpp

Lines changed: 1 addition & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -3564,13 +3564,7 @@ static LLVMValueRef ir_gen_negation(CodeGen *g, IrInstGen *inst, IrInstGen *oper
35643564
static LLVMValueRef ir_render_negation(CodeGen *g, IrExecutableGen *executable,
35653565
IrInstGenNegation *inst)
35663566
{
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);
35743568
}
35753569

35763570
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
66456639
return ir_render_binary_not(g, executable, (IrInstGenBinaryNot *)instruction);
66466640
case IrInstGenIdNegation:
66476641
return ir_render_negation(g, executable, (IrInstGenNegation *)instruction);
6648-
case IrInstGenIdNegationWrapping:
6649-
return ir_render_negation_wrapping(g, executable, (IrInstGenNegationWrapping *)instruction);
66506642
case IrInstGenIdLoadPtr:
66516643
return ir_render_load_ptr(g, executable, (IrInstGenLoadPtr *)instruction);
66526644
case IrInstGenIdStorePtr:

src/stage1/ir.cpp

Lines changed: 9 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -749,8 +749,6 @@ void destroy_instruction_gen(IrInstGen *inst) {
749749
return heap::c_allocator.destroy(reinterpret_cast<IrInstGenBinaryNot *>(inst));
750750
case IrInstGenIdNegation:
751751
return heap::c_allocator.destroy(reinterpret_cast<IrInstGenNegation *>(inst));
752-
case IrInstGenIdNegationWrapping:
753-
return heap::c_allocator.destroy(reinterpret_cast<IrInstGenNegationWrapping *>(inst));
754752
case IrInstGenIdWasmMemorySize:
755753
return heap::c_allocator.destroy(reinterpret_cast<IrInstGenWasmMemorySize *>(inst));
756754
case IrInstGenIdWasmMemoryGrow:
@@ -1672,10 +1670,6 @@ static constexpr IrInstGenId ir_inst_id(IrInstGenNegation *) {
16721670
return IrInstGenIdNegation;
16731671
}
16741672

1675-
static constexpr IrInstGenId ir_inst_id(IrInstGenNegationWrapping *) {
1676-
return IrInstGenIdNegationWrapping;
1677-
}
1678-
16791673
static constexpr IrInstGenId ir_inst_id(IrInstGenBinOp *) {
16801674
return IrInstGenIdBinOp;
16811675
}
@@ -2652,24 +2646,12 @@ static IrInstSrc *ir_build_un_op(IrBuilderSrc *irb, Scope *scope, AstNode *sourc
26522646
return ir_build_un_op_lval(irb, scope, source_node, op_id, value, LValNone, nullptr);
26532647
}
26542648

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) {
26562650
IrInstGenNegation *instruction = ir_build_inst_gen<IrInstGenNegation>(&ira->new_irb,
26572651
source_instr->scope, source_instr->source_node);
26582652
instruction->base.value->type = expr_type;
26592653
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;
26732655

26742656
ir_ref_inst_gen(operand);
26752657

@@ -21273,24 +21255,24 @@ static IrInstGen *ir_analyze_negation(IrAnalyze *ira, IrInstSrcUnOp *instruction
2127321255

2127421256
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) {
2127721262
case ZigTypeIdComptimeInt:
2127821263
case ZigTypeIdFloat:
2127921264
case ZigTypeIdComptimeFloat:
21280-
case ZigTypeIdVector:
2128121265
break;
2128221266
case ZigTypeIdInt:
21283-
if (is_wrap_op || expr_type->data.integral.is_signed)
21267+
if (is_wrap_op || scalar_type->data.integral.is_signed)
2128421268
break;
2128521269
ZIG_FALLTHROUGH;
2128621270
default:
2128721271
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)));
2128921273
return ira->codegen->invalid_inst_gen;
2129021274
}
2129121275

21292-
ZigType *scalar_type = (expr_type->id == ZigTypeIdVector) ? expr_type->data.vector.elem_type : expr_type;
21293-
2129421276
if (instr_is_comptime(value)) {
2129521277
ZigValue *operand_val = ir_resolve_const(ira, value, UndefBad);
2129621278
if (!operand_val)
@@ -21328,11 +21310,7 @@ static IrInstGen *ir_analyze_negation(IrAnalyze *ira, IrInstSrcUnOp *instruction
2132821310
return result_instruction;
2132921311
}
2133021312

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);
2133621314
}
2133721315

2133821316
static IrInstGen *ir_analyze_bin_not(IrAnalyze *ira, IrInstSrcUnOp *instruction) {
@@ -32214,7 +32192,6 @@ bool ir_inst_gen_has_side_effects(IrInstGen *instruction) {
3221432192
case IrInstGenIdVectorExtractElem:
3221532193
case IrInstGenIdBinaryNot:
3221632194
case IrInstGenIdNegation:
32217-
case IrInstGenIdNegationWrapping:
3221832195
case IrInstGenIdWasmMemorySize:
3221932196
case IrInstGenIdReduce:
3222032197
return false;

src/stage1/ir_print.cpp

Lines changed: 1 addition & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -540,8 +540,6 @@ const char* ir_inst_gen_type_str(IrInstGenId id) {
540540
return "GenBinaryNot";
541541
case IrInstGenIdNegation:
542542
return "GenNegation";
543-
case IrInstGenIdNegationWrapping:
544-
return "GenNegationWrapping";
545543
case IrInstGenIdWasmMemorySize:
546544
return "GenWasmMemorySize";
547545
case IrInstGenIdWasmMemoryGrow:
@@ -1144,16 +1142,10 @@ static void ir_print_binary_not(IrPrintGen *irp, IrInstGenBinaryNot *instruction
11441142
}
11451143

11461144
static void ir_print_negation(IrPrintGen *irp, IrInstGenNegation *instruction) {
1147-
fprintf(irp->f, "-");
1145+
fprintf(irp->f, instruction->wrapping ? "-%%" : "-");
11481146
ir_print_other_inst_gen(irp, instruction->operand);
11491147
}
11501148

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-
11571149
static void ir_print_field_ptr(IrPrintSrc *irp, IrInstSrcFieldPtr *instruction) {
11581150
if (instruction->field_name_buffer) {
11591151
fprintf(irp->f, "fieldptr ");
@@ -3294,9 +3286,6 @@ static void ir_print_inst_gen(IrPrintGen *irp, IrInstGen *instruction, bool trai
32943286
case IrInstGenIdNegation:
32953287
ir_print_negation(irp, (IrInstGenNegation *)instruction);
32963288
break;
3297-
case IrInstGenIdNegationWrapping:
3298-
ir_print_negation_wrapping(irp, (IrInstGenNegationWrapping *)instruction);
3299-
break;
33003289
case IrInstGenIdWasmMemorySize:
33013290
ir_print_wasm_memory_size(irp, (IrInstGenWasmMemorySize *)instruction);
33023291
break;

test/compile_errors.zig

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -8172,14 +8172,19 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {
81728172
, &[_][]const u8{
81738173
"tmp.zig:2:9: error: @wasmMemoryGrow is a wasm32 feature only",
81748174
});
8175-
81768175
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) {
81788182
\\ const y = -%x;
81798183
\\ return -y;
81808184
\\}
81818185
, &[_][]const u8{
81828186
"tmp.zig:3:12: error: negation of type 'u32'",
8187+
"tmp.zig:8:12: error: negation of type 'u32'",
81838188
});
81848189

81858190
cases.add("Issue #5618: coercion of ?*c_void to *c_void must fail.",

0 commit comments

Comments
 (0)