diff options
| author | Andrew Kelley <andrew@ziglang.org> | 2019-04-05 20:18:26 -0400 |
|---|---|---|
| committer | Andrew Kelley <andrew@ziglang.org> | 2019-04-05 20:18:26 -0400 |
| commit | 83390bdfdde211a73be42e16a41cd2102c429bbd (patch) | |
| tree | 17854868d8d75183e653f9ab630f5c8569215ec3 /src/ir.cpp | |
| parent | 3854bb919808b8d86154495fee1acc7e645240a4 (diff) | |
| download | zig-83390bdfdde211a73be42e16a41cd2102c429bbd.tar.gz zig-83390bdfdde211a73be42e16a41cd2102c429bbd.zip | |
fix dereferencing a zero bit type
Before only u0 was special cased in handling a dereference;
now all zero bit types are handled the same way. Dereferencing
a pointer to a zero bit type always gives a comptime-known
result.
This previously had been failing on master branch but went unnoticed
because until 846f72b57cb5 the CI server was mistakenly not actually
running the single-threaded tests with --single-threaded.
This fixes the standard library tests with --single-threaded
--release-fast.
Diffstat (limited to 'src/ir.cpp')
| -rw-r--r-- | src/ir.cpp | 31 |
1 files changed, 17 insertions, 14 deletions
diff --git a/src/ir.cpp b/src/ir.cpp index 3f02d18e8e..1e9cc5d18c 100644 --- a/src/ir.cpp +++ b/src/ir.cpp @@ -10702,15 +10702,6 @@ static IrInstruction *ir_analyze_enum_to_int(IrAnalyze *ira, IrInstruction *sour ZigType *tag_type = enum_type->data.enumeration.tag_int_type; assert(tag_type->id == ZigTypeIdInt || tag_type->id == ZigTypeIdComptimeInt); - if (instr_is_comptime(enum_target)) { - ConstExprValue *val = ir_resolve_const(ira, enum_target, UndefBad); - if (!val) - return ira->codegen->invalid_instruction; - IrInstruction *result = ir_const(ira, source_instr, tag_type); - init_const_bigint(&result->value, tag_type, &val->data.x_enum_tag); - return result; - } - // If there is only one possible tag, then we know at comptime what it is. if (enum_type->data.enumeration.layout == ContainerLayoutAuto && enum_type->data.enumeration.src_field_count == 1) @@ -10722,6 +10713,15 @@ static IrInstruction *ir_analyze_enum_to_int(IrAnalyze *ira, IrInstruction *sour return result; } + if (instr_is_comptime(enum_target)) { + ConstExprValue *val = ir_resolve_const(ira, enum_target, UndefBad); + if (!val) + return ira->codegen->invalid_instruction; + IrInstruction *result = ir_const(ira, source_instr, tag_type); + init_const_bigint(&result->value, tag_type, &val->data.x_enum_tag); + return result; + } + IrInstruction *result = ir_build_widen_or_shorten(&ira->new_irb, source_instr->scope, source_instr->source_node, enum_target); result->value.type = tag_type; @@ -11809,11 +11809,14 @@ static IrInstruction *ir_get_deref(IrAnalyze *ira, IrInstruction *source_instruc return ira->codegen->invalid_instruction; } else if (type_entry->id == ZigTypeIdPointer) { ZigType *child_type = type_entry->data.pointer.child_type; - // dereferencing a *u0 is comptime known to be 0 - if (child_type->id == ZigTypeIdInt && child_type->data.integral.bit_count == 0) { - IrInstruction *result = ir_const(ira, source_instruction, child_type); - init_const_unsigned_negative(&result->value, child_type, 0, false); - return result; + // if the child type has one possible value, the deref is comptime + switch (type_has_one_possible_value(ira->codegen, child_type)) { + case OnePossibleValueInvalid: + return ira->codegen->invalid_instruction; + case OnePossibleValueYes: + return ir_const(ira, source_instruction, child_type); + case OnePossibleValueNo: + break; } if (instr_is_comptime(ptr)) { if (ptr->value.special == ConstValSpecialUndef) { |
