parent
c1af360532
commit
345f8db1c4
|
@ -3971,7 +3971,7 @@ void resolve_container_type(CodeGen *g, ZigType *type_entry) {
|
|||
}
|
||||
}
|
||||
|
||||
ZigType *get_codegen_ptr_type(ZigType *type) {
|
||||
ZigType *get_src_ptr_type(ZigType *type) {
|
||||
if (type->id == ZigTypeIdPointer) return type;
|
||||
if (type->id == ZigTypeIdFn) return type;
|
||||
if (type->id == ZigTypeIdPromise) return type;
|
||||
|
@ -3983,12 +3983,19 @@ ZigType *get_codegen_ptr_type(ZigType *type) {
|
|||
return nullptr;
|
||||
}
|
||||
|
||||
ZigType *get_codegen_ptr_type(ZigType *type) {
|
||||
ZigType *ty = get_src_ptr_type(type);
|
||||
if (ty == nullptr || !type_has_bits(ty))
|
||||
return nullptr;
|
||||
return ty;
|
||||
}
|
||||
|
||||
bool type_is_codegen_pointer(ZigType *type) {
|
||||
return get_codegen_ptr_type(type) == type;
|
||||
}
|
||||
|
||||
uint32_t get_ptr_align(CodeGen *g, ZigType *type) {
|
||||
ZigType *ptr_type = get_codegen_ptr_type(type);
|
||||
ZigType *ptr_type = get_src_ptr_type(type);
|
||||
if (ptr_type->id == ZigTypeIdPointer) {
|
||||
return (ptr_type->data.pointer.explicit_alignment == 0) ?
|
||||
get_abi_alignment(g, ptr_type->data.pointer.child_type) : ptr_type->data.pointer.explicit_alignment;
|
||||
|
@ -3996,6 +4003,7 @@ uint32_t get_ptr_align(CodeGen *g, ZigType *type) {
|
|||
// I tried making this use LLVMABIAlignmentOfType but it trips this assertion in LLVM:
|
||||
// "Cannot getTypeInfo() on a type that is unsized!"
|
||||
// when getting the alignment of `?extern fn() void`.
|
||||
// See http://lists.llvm.org/pipermail/llvm-dev/2018-September/126142.html
|
||||
return (ptr_type->data.fn.fn_type_id.alignment == 0) ? 1 : ptr_type->data.fn.fn_type_id.alignment;
|
||||
} else if (ptr_type->id == ZigTypeIdPromise) {
|
||||
return get_coro_frame_align_bytes(g);
|
||||
|
@ -4005,7 +4013,7 @@ uint32_t get_ptr_align(CodeGen *g, ZigType *type) {
|
|||
}
|
||||
|
||||
bool get_ptr_const(ZigType *type) {
|
||||
ZigType *ptr_type = get_codegen_ptr_type(type);
|
||||
ZigType *ptr_type = get_src_ptr_type(type);
|
||||
if (ptr_type->id == ZigTypeIdPointer) {
|
||||
return ptr_type->data.pointer.is_const;
|
||||
} else if (ptr_type->id == ZigTypeIdFn) {
|
||||
|
|
|
@ -53,6 +53,7 @@ Tld *find_decl(CodeGen *g, Scope *scope, Buf *name);
|
|||
void resolve_top_level_decl(CodeGen *g, Tld *tld, bool pointer_only, AstNode *source_node);
|
||||
bool type_is_codegen_pointer(ZigType *type);
|
||||
|
||||
ZigType *get_src_ptr_type(ZigType *type);
|
||||
ZigType *get_codegen_ptr_type(ZigType *type);
|
||||
uint32_t get_ptr_align(CodeGen *g, ZigType *type);
|
||||
bool get_ptr_const(ZigType *type);
|
||||
|
|
15
src/ir.cpp
15
src/ir.cpp
|
@ -155,7 +155,7 @@ static void buf_read_value_bytes(CodeGen *codegen, uint8_t *buf, ConstExprValue
|
|||
static void buf_write_value_bytes(CodeGen *codegen, uint8_t *buf, ConstExprValue *val);
|
||||
|
||||
static ConstExprValue *const_ptr_pointee_unchecked(CodeGen *g, ConstExprValue *const_val) {
|
||||
assert(get_codegen_ptr_type(const_val->type) != nullptr);
|
||||
assert(get_src_ptr_type(const_val->type) != nullptr);
|
||||
assert(const_val->special == ConstValSpecialStatic);
|
||||
ConstExprValue *result;
|
||||
switch (const_val->data.x_ptr.special) {
|
||||
|
@ -20161,12 +20161,15 @@ static ZigType *ir_analyze_instruction_ptr_cast(IrAnalyze *ira, IrInstructionPtr
|
|||
if (type_is_invalid(src_type))
|
||||
return ira->codegen->builtin_types.entry_invalid;
|
||||
|
||||
if (get_codegen_ptr_type(src_type) == nullptr) {
|
||||
// We have a check for zero bits later so we use get_src_ptr_type to
|
||||
// validate src_type and dest_type.
|
||||
|
||||
if (get_src_ptr_type(src_type) == nullptr) {
|
||||
ir_add_error(ira, ptr, buf_sprintf("expected pointer, found '%s'", buf_ptr(&src_type->name)));
|
||||
return ira->codegen->builtin_types.entry_invalid;
|
||||
}
|
||||
|
||||
if (get_codegen_ptr_type(dest_type) == nullptr) {
|
||||
if (get_src_ptr_type(dest_type) == nullptr) {
|
||||
ir_add_error(ira, dest_type_value,
|
||||
buf_sprintf("expected pointer, found '%s'", buf_ptr(&dest_type->name)));
|
||||
return ira->codegen->builtin_types.entry_invalid;
|
||||
|
@ -20465,7 +20468,8 @@ static ZigType *ir_analyze_instruction_int_to_ptr(IrAnalyze *ira, IrInstructionI
|
|||
if (type_is_invalid(dest_type))
|
||||
return ira->codegen->builtin_types.entry_invalid;
|
||||
|
||||
if (get_codegen_ptr_type(dest_type) == nullptr) {
|
||||
// We explicitly check for the size, so we can use get_src_ptr_type
|
||||
if (get_src_ptr_type(dest_type) == nullptr) {
|
||||
ir_add_error(ira, dest_type_value, buf_sprintf("expected pointer, found '%s'", buf_ptr(&dest_type->name)));
|
||||
return ira->codegen->builtin_types.entry_invalid;
|
||||
}
|
||||
|
@ -20571,7 +20575,8 @@ static ZigType *ir_analyze_instruction_ptr_to_int(IrAnalyze *ira, IrInstructionP
|
|||
|
||||
ZigType *usize = ira->codegen->builtin_types.entry_usize;
|
||||
|
||||
if (get_codegen_ptr_type(target->value.type) == nullptr) {
|
||||
// We check size explicitly so we can use get_src_ptr_type here.
|
||||
if (get_src_ptr_type(target->value.type) == nullptr) {
|
||||
ir_add_error(ira, target,
|
||||
buf_sprintf("expected pointer, found '%s'", buf_ptr(&target->value.type->name)));
|
||||
return ira->codegen->builtin_types.entry_invalid;
|
||||
|
|
|
@ -154,3 +154,9 @@ test "optional types" {
|
|||
const StructWithOptionalType = struct {
|
||||
t: ?type,
|
||||
};
|
||||
|
||||
test "optional pointer to 0 bit type null value at runtime" {
|
||||
const EmptyStruct = struct {};
|
||||
var x: ?*EmptyStruct = null;
|
||||
assert(x == null);
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue