aboutsummaryrefslogtreecommitdiff
path: root/src/ir.cpp
diff options
context:
space:
mode:
authorAndrew Kelley <superjoe30@gmail.com>2018-06-12 15:06:02 -0400
committerAndrew Kelley <superjoe30@gmail.com>2018-06-12 15:06:02 -0400
commit259413251df478545948fdbc6213669f88f584bd (patch)
tree4fe63d9ad6c04de532c19e57ef009be0154b59b9 /src/ir.cpp
parent7580e39b388525237a84aabfb41c462376eac28e (diff)
downloadzig-259413251df478545948fdbc6213669f88f584bd.tar.gz
zig-259413251df478545948fdbc6213669f88f584bd.zip
fix ability to call mutating methods on zero size structs
closes #838
Diffstat (limited to 'src/ir.cpp')
-rw-r--r--src/ir.cpp37
1 files changed, 36 insertions, 1 deletions
diff --git a/src/ir.cpp b/src/ir.cpp
index 4b6d5fdcf1..4cebc488b8 100644
--- a/src/ir.cpp
+++ b/src/ir.cpp
@@ -8151,6 +8151,17 @@ static ImplicitCastMatchResult ir_types_match_with_implicit_cast(IrAnalyze *ira,
}
}
+ // implicit T to *T where T is zero bits
+ if (expected_type->id == TypeTableEntryIdPointer && expected_type->data.pointer.ptr_len == PtrLenSingle &&
+ types_match_const_cast_only(ira, expected_type->data.pointer.child_type,
+ actual_type, source_node).id == ConstCastResultIdOk)
+ {
+ type_ensure_zero_bits_known(ira->codegen, actual_type);
+ if (!type_has_bits(actual_type)) {
+ return ImplicitCastMatchResultYes;
+ }
+ }
+
// implicit undefined literal to anything
if (actual_type->id == TypeTableEntryIdUndefined) {
return ImplicitCastMatchResultYes;
@@ -8820,7 +8831,7 @@ static void eval_const_expr_implicit_cast(CastOp cast_op,
static IrInstruction *ir_resolve_cast(IrAnalyze *ira, IrInstruction *source_instr, IrInstruction *value,
TypeTableEntry *wanted_type, CastOp cast_op, bool need_alloca)
{
- if (value->value.special != ConstValSpecialRuntime &&
+ if ((instr_is_comptime(value) || !type_has_bits(wanted_type)) &&
cast_op != CastOpResizeSlice && cast_op != CastOpBytesToSlice)
{
IrInstruction *result = ir_create_const(&ira->new_irb, source_instr->scope,
@@ -9382,9 +9393,19 @@ static IrInstruction *ir_get_ref(IrAnalyze *ira, IrInstruction *source_instructi
if (value->id == IrInstructionIdLoadPtr) {
IrInstructionLoadPtr *load_ptr_inst = (IrInstructionLoadPtr *) value;
+
if (load_ptr_inst->ptr->value.type->data.pointer.is_const) {
return load_ptr_inst->ptr;
}
+
+ type_ensure_zero_bits_known(ira->codegen, value->value.type);
+ if (type_is_invalid(value->value.type)) {
+ return ira->codegen->invalid_instruction;
+ }
+
+ if (!type_has_bits(value->value.type)) {
+ return load_ptr_inst->ptr;
+ }
}
if (instr_is_comptime(value)) {
@@ -10340,6 +10361,20 @@ static IrInstruction *ir_analyze_cast(IrAnalyze *ira, IrInstruction *source_inst
}
}
+ // explicit cast from T to *T where T is zero bits
+ if (wanted_type->id == TypeTableEntryIdPointer && wanted_type->data.pointer.ptr_len == PtrLenSingle &&
+ types_match_const_cast_only(ira, wanted_type->data.pointer.child_type,
+ actual_type, source_node).id == ConstCastResultIdOk)
+ {
+ type_ensure_zero_bits_known(ira->codegen, actual_type);
+ if (type_is_invalid(actual_type)) {
+ return ira->codegen->invalid_instruction;
+ }
+ if (!type_has_bits(actual_type)) {
+ return ir_get_ref(ira, source_instr, value, false, false);
+ }
+ }
+
// explicit cast from undefined to anything
if (actual_type->id == TypeTableEntryIdUndefined) {