aboutsummaryrefslogtreecommitdiff
path: root/src/stage1/ir.cpp
diff options
context:
space:
mode:
authorVexu <git@vexu.eu>2020-11-23 03:02:37 +0200
committerVeikka Tuominen <git@vexu.eu>2020-12-25 14:58:13 +0200
commit0bc82a9070b514bf61fb245f906bf03f8e51ce35 (patch)
tree92a37866983537e2c3f0834c23a24eb5fd8e4d46 /src/stage1/ir.cpp
parent990eccf282f278b977f8e232fca5522649eff20f (diff)
downloadzig-0bc82a9070b514bf61fb245f906bf03f8e51ce35.tar.gz
zig-0bc82a9070b514bf61fb245f906bf03f8e51ce35.zip
stage1: validate pointer attributes when coercing anon literals
Diffstat (limited to 'src/stage1/ir.cpp')
-rw-r--r--src/stage1/ir.cpp38
1 files changed, 23 insertions, 15 deletions
diff --git a/src/stage1/ir.cpp b/src/stage1/ir.cpp
index 369886a6b6..7a7e4765ac 100644
--- a/src/stage1/ir.cpp
+++ b/src/stage1/ir.cpp
@@ -15955,38 +15955,46 @@ static IrInstGen *ir_analyze_cast(IrAnalyze *ira, IrInst *source_instr,
anon_type->data.structure.special == StructSpecialInferredTuple;
const uint32_t field_count = anon_type->data.structure.src_field_count;
- if (wanted_type->id == ZigTypeIdPointer) {
+ if (wanted_type->id == ZigTypeIdPointer &&
+ (!actual_type->data.pointer.is_volatile || wanted_type->data.pointer.is_volatile))
+ {
ZigType *wanted_child = wanted_type->data.pointer.child_type;
+ bool const_ok = (!actual_type->data.pointer.is_const || wanted_type->data.pointer.is_const);
if (wanted_child->id == ZigTypeIdArray && (is_array_init || field_count == 0) &&
- wanted_child->data.array.len == field_count)
+ wanted_child->data.array.len == field_count && (const_ok || field_count == 0))
{
IrInstGen *res = ir_analyze_struct_literal_to_array(ira, source_instr, value, anon_type, wanted_child);
if (res->value->type->id == ZigTypeIdPointer)
return res;
- return ir_get_ref(ira, source_instr, res, wanted_type->data.pointer.is_const, wanted_type->data.pointer.is_volatile);
+ return ir_get_ref(ira, source_instr, res, actual_type->data.pointer.is_const, actual_type->data.pointer.is_volatile);
} else if (wanted_child->id == ZigTypeIdStruct && !is_slice(wanted_type) &&
- (!is_array_init || field_count == 0))
+ (!is_array_init || field_count == 0) && const_ok)
{
IrInstGen *res = ir_analyze_struct_literal_to_struct(ira, source_instr, value, anon_type, wanted_child);
if (res->value->type->id == ZigTypeIdPointer)
return res;
- return ir_get_ref(ira, source_instr, res, wanted_type->data.pointer.is_const, wanted_type->data.pointer.is_volatile);
- } else if (wanted_child->id == ZigTypeIdUnion && !is_array_init && field_count == 1) {
+ return ir_get_ref(ira, source_instr, res, actual_type->data.pointer.is_const, actual_type->data.pointer.is_volatile);
+ } else if (wanted_child->id == ZigTypeIdUnion && !is_array_init && field_count == 1 && const_ok) {
IrInstGen *res = ir_analyze_struct_literal_to_union(ira, source_instr, value, anon_type, wanted_child);
if (res->value->type->id == ZigTypeIdPointer)
return res;
- return ir_get_ref(ira, source_instr, res, wanted_type->data.pointer.is_const, wanted_type->data.pointer.is_volatile);
+ return ir_get_ref(ira, source_instr, res, actual_type->data.pointer.is_const, actual_type->data.pointer.is_volatile);
}
} else if (is_slice(wanted_type) && (is_array_init || field_count == 0)) {
- ZigType *slice_child_type = wanted_type->data.structure.fields[slice_ptr_index]->type_entry->data.pointer.child_type;
- ZigType *slice_array_type = get_array_type(ira->codegen, slice_child_type, field_count, nullptr);
- IrInstGen *res = ir_analyze_struct_literal_to_array(ira, source_instr, value, anon_type, slice_array_type);
- if (type_is_invalid(res->value->type))
- return ira->codegen->invalid_inst_gen;
- if (res->value->type->id != ZigTypeIdPointer)
- res = ir_get_ref(ira, source_instr, res, wanted_type->data.pointer.is_const, wanted_type->data.pointer.is_volatile);
+ ZigType *slice_type = wanted_type->data.structure.fields[slice_ptr_index]->type_entry;
+ if ((!actual_type->data.pointer.is_const || slice_type->data.pointer.is_const || field_count == 0) &&
+ (!actual_type->data.pointer.is_volatile || slice_type->data.pointer.is_volatile))
+ {
+ ZigType *slice_child_type = slice_type->data.pointer.child_type;
+ ZigType *slice_array_type = get_array_type(ira->codegen, slice_child_type, field_count, nullptr);
+ IrInstGen *res = ir_analyze_struct_literal_to_array(ira, source_instr, value, anon_type, slice_array_type);
+ if (type_is_invalid(res->value->type))
+ return ira->codegen->invalid_inst_gen;
+ if (res->value->type->id != ZigTypeIdPointer)
+ res = ir_get_ref(ira, source_instr, res, actual_type->data.pointer.is_const, actual_type->data.pointer.is_volatile);
- return ir_resolve_ptr_of_array_to_slice(ira, source_instr, res, wanted_type, nullptr);
+ return ir_resolve_ptr_of_array_to_slice(ira, source_instr, res, wanted_type, nullptr);
+ }
}
}