| author | |
| committer | |
| log | 345f8db1c49efe3d9ca9859a296f24e728a3b43a |
| tree | c0b6d17a4ef6f444365f0af57682bb9a29c5cbd5 |
| parent | c1af3605328d21f59ee8ceba3c7350193f0a2429 |
| signature |
closes #11784 files changed, 28 insertions(+), 8 deletions(-)
src/analyze.cpp+11-3| ... | @@ -3971,7 +3971,7 @@ void resolve_container_type(CodeGen *g, ZigType *type_entry) { | ... | @@ -3971,7 +3971,7 @@ void resolve_container_type(CodeGen *g, ZigType *type_entry) { |
| 3971 | } | 3971 | } |
| 3972 | } | 3972 | } |
| 3973 | 3973 | ||
| 3974 | ZigType *get_codegen_ptr_type(ZigType *type) { | 3974 | ZigType *get_src_ptr_type(ZigType *type) { |
| 3975 | if (type->id == ZigTypeIdPointer) return type; | 3975 | if (type->id == ZigTypeIdPointer) return type; |
| 3976 | if (type->id == ZigTypeIdFn) return type; | 3976 | if (type->id == ZigTypeIdFn) return type; |
| 3977 | if (type->id == ZigTypeIdPromise) return type; | 3977 | if (type->id == ZigTypeIdPromise) return type; |
| ... | @@ -3983,12 +3983,19 @@ ZigType *get_codegen_ptr_type(ZigType *type) { | ... | @@ -3983,12 +3983,19 @@ ZigType *get_codegen_ptr_type(ZigType *type) { |
| 3983 | return nullptr; | 3983 | return nullptr; |
| 3984 | } | 3984 | } |
| 3985 | 3985 | ||
| 3986 | ZigType *get_codegen_ptr_type(ZigType *type) { | ||
| 3987 | ZigType *ty = get_src_ptr_type(type); | ||
| 3988 | if (ty == nullptr || !type_has_bits(ty)) | ||
| 3989 | return nullptr; | ||
| 3990 | return ty; | ||
| 3991 | } | ||
| 3992 | |||
| 3986 | bool type_is_codegen_pointer(ZigType *type) { | 3993 | bool type_is_codegen_pointer(ZigType *type) { |
| 3987 | return get_codegen_ptr_type(type) == type; | 3994 | return get_codegen_ptr_type(type) == type; |
| 3988 | } | 3995 | } |
| 3989 | 3996 | ||
| 3990 | uint32_t get_ptr_align(CodeGen *g, ZigType *type) { | 3997 | uint32_t get_ptr_align(CodeGen *g, ZigType *type) { |
| 3991 | ZigType *ptr_type = get_codegen_ptr_type(type); | 3998 | ZigType *ptr_type = get_src_ptr_type(type); |
| 3992 | if (ptr_type->id == ZigTypeIdPointer) { | 3999 | if (ptr_type->id == ZigTypeIdPointer) { |
| 3993 | return (ptr_type->data.pointer.explicit_alignment == 0) ? | 4000 | return (ptr_type->data.pointer.explicit_alignment == 0) ? |
| 3994 | get_abi_alignment(g, ptr_type->data.pointer.child_type) : ptr_type->data.pointer.explicit_alignment; | 4001 | 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) { | ... | @@ -3996,6 +4003,7 @@ uint32_t get_ptr_align(CodeGen *g, ZigType *type) { |
| 3996 | // I tried making this use LLVMABIAlignmentOfType but it trips this assertion in LLVM: | 4003 | // I tried making this use LLVMABIAlignmentOfType but it trips this assertion in LLVM: |
| 3997 | // "Cannot getTypeInfo() on a type that is unsized!" | 4004 | // "Cannot getTypeInfo() on a type that is unsized!" |
| 3998 | // when getting the alignment of `?extern fn() void`. | 4005 | // when getting the alignment of `?extern fn() void`. |
| 4006 | // See http://lists.llvm.org/pipermail/llvm-dev/2018-September/126142.html | ||
| 3999 | return (ptr_type->data.fn.fn_type_id.alignment == 0) ? 1 : ptr_type->data.fn.fn_type_id.alignment; | 4007 | return (ptr_type->data.fn.fn_type_id.alignment == 0) ? 1 : ptr_type->data.fn.fn_type_id.alignment; |
| 4000 | } else if (ptr_type->id == ZigTypeIdPromise) { | 4008 | } else if (ptr_type->id == ZigTypeIdPromise) { |
| 4001 | return get_coro_frame_align_bytes(g); | 4009 | return get_coro_frame_align_bytes(g); |
| ... | @@ -4005,7 +4013,7 @@ uint32_t get_ptr_align(CodeGen *g, ZigType *type) { | ... | @@ -4005,7 +4013,7 @@ uint32_t get_ptr_align(CodeGen *g, ZigType *type) { |
| 4005 | } | 4013 | } |
| 4006 | 4014 | ||
| 4007 | bool get_ptr_const(ZigType *type) { | 4015 | bool get_ptr_const(ZigType *type) { |
| 4008 | ZigType *ptr_type = get_codegen_ptr_type(type); | 4016 | ZigType *ptr_type = get_src_ptr_type(type); |
| 4009 | if (ptr_type->id == ZigTypeIdPointer) { | 4017 | if (ptr_type->id == ZigTypeIdPointer) { |
| 4010 | return ptr_type->data.pointer.is_const; | 4018 | return ptr_type->data.pointer.is_const; |
| 4011 | } else if (ptr_type->id == ZigTypeIdFn) { | 4019 | } else if (ptr_type->id == ZigTypeIdFn) { |
src/analyze.hpp+1| ... | @@ -53,6 +53,7 @@ Tld *find_decl(CodeGen *g, Scope *scope, Buf *name); | ... | @@ -53,6 +53,7 @@ Tld *find_decl(CodeGen *g, Scope *scope, Buf *name); |
| 53 | void resolve_top_level_decl(CodeGen *g, Tld *tld, bool pointer_only, AstNode *source_node); | 53 | void resolve_top_level_decl(CodeGen *g, Tld *tld, bool pointer_only, AstNode *source_node); |
| 54 | bool type_is_codegen_pointer(ZigType *type); | 54 | bool type_is_codegen_pointer(ZigType *type); |
| 55 | 55 | ||
| 56 | ZigType *get_src_ptr_type(ZigType *type); | ||
| 56 | ZigType *get_codegen_ptr_type(ZigType *type); | 57 | ZigType *get_codegen_ptr_type(ZigType *type); |
| 57 | uint32_t get_ptr_align(CodeGen *g, ZigType *type); | 58 | uint32_t get_ptr_align(CodeGen *g, ZigType *type); |
| 58 | bool get_ptr_const(ZigType *type); | 59 | bool get_ptr_const(ZigType *type); |
src/ir.cpp+10-5| ... | @@ -155,7 +155,7 @@ static void buf_read_value_bytes(CodeGen *codegen, uint8_t *buf, ConstExprValue | ... | @@ -155,7 +155,7 @@ static void buf_read_value_bytes(CodeGen *codegen, uint8_t *buf, ConstExprValue |
| 155 | static void buf_write_value_bytes(CodeGen *codegen, uint8_t *buf, ConstExprValue *val); | 155 | static void buf_write_value_bytes(CodeGen *codegen, uint8_t *buf, ConstExprValue *val); |
| 156 | 156 | ||
| 157 | static ConstExprValue *const_ptr_pointee_unchecked(CodeGen *g, ConstExprValue *const_val) { | 157 | static ConstExprValue *const_ptr_pointee_unchecked(CodeGen *g, ConstExprValue *const_val) { |
| 158 | assert(get_codegen_ptr_type(const_val->type) != nullptr); | 158 | assert(get_src_ptr_type(const_val->type) != nullptr); |
| 159 | assert(const_val->special == ConstValSpecialStatic); | 159 | assert(const_val->special == ConstValSpecialStatic); |
| 160 | ConstExprValue *result; | 160 | ConstExprValue *result; |
| 161 | switch (const_val->data.x_ptr.special) { | 161 | switch (const_val->data.x_ptr.special) { |
| ... | @@ -20161,12 +20161,15 @@ static ZigType *ir_analyze_instruction_ptr_cast(IrAnalyze *ira, IrInstructionPtr | ... | @@ -20161,12 +20161,15 @@ static ZigType *ir_analyze_instruction_ptr_cast(IrAnalyze *ira, IrInstructionPtr |
| 20161 | if (type_is_invalid(src_type)) | 20161 | if (type_is_invalid(src_type)) |
| 20162 | return ira->codegen->builtin_types.entry_invalid; | 20162 | return ira->codegen->builtin_types.entry_invalid; |
| 20163 | 20163 | ||
| 20164 | if (get_codegen_ptr_type(src_type) == nullptr) { | 20164 | // We have a check for zero bits later so we use get_src_ptr_type to |
| 20165 | // validate src_type and dest_type. | ||
| 20166 | |||
| 20167 | if (get_src_ptr_type(src_type) == nullptr) { | ||
| 20165 | ir_add_error(ira, ptr, buf_sprintf("expected pointer, found '%s'", buf_ptr(&src_type->name))); | 20168 | ir_add_error(ira, ptr, buf_sprintf("expected pointer, found '%s'", buf_ptr(&src_type->name))); |
| 20166 | return ira->codegen->builtin_types.entry_invalid; | 20169 | return ira->codegen->builtin_types.entry_invalid; |
| 20167 | } | 20170 | } |
| 20168 | 20171 | ||
| 20169 | if (get_codegen_ptr_type(dest_type) == nullptr) { | 20172 | if (get_src_ptr_type(dest_type) == nullptr) { |
| 20170 | ir_add_error(ira, dest_type_value, | 20173 | ir_add_error(ira, dest_type_value, |
| 20171 | buf_sprintf("expected pointer, found '%s'", buf_ptr(&dest_type->name))); | 20174 | buf_sprintf("expected pointer, found '%s'", buf_ptr(&dest_type->name))); |
| 20172 | return ira->codegen->builtin_types.entry_invalid; | 20175 | return ira->codegen->builtin_types.entry_invalid; |
| ... | @@ -20465,7 +20468,8 @@ static ZigType *ir_analyze_instruction_int_to_ptr(IrAnalyze *ira, IrInstructionI | ... | @@ -20465,7 +20468,8 @@ static ZigType *ir_analyze_instruction_int_to_ptr(IrAnalyze *ira, IrInstructionI |
| 20465 | if (type_is_invalid(dest_type)) | 20468 | if (type_is_invalid(dest_type)) |
| 20466 | return ira->codegen->builtin_types.entry_invalid; | 20469 | return ira->codegen->builtin_types.entry_invalid; |
| 20467 | 20470 | ||
| 20468 | if (get_codegen_ptr_type(dest_type) == nullptr) { | 20471 | // We explicitly check for the size, so we can use get_src_ptr_type |
| 20472 | if (get_src_ptr_type(dest_type) == nullptr) { | ||
| 20469 | ir_add_error(ira, dest_type_value, buf_sprintf("expected pointer, found '%s'", buf_ptr(&dest_type->name))); | 20473 | ir_add_error(ira, dest_type_value, buf_sprintf("expected pointer, found '%s'", buf_ptr(&dest_type->name))); |
| 20470 | return ira->codegen->builtin_types.entry_invalid; | 20474 | return ira->codegen->builtin_types.entry_invalid; |
| 20471 | } | 20475 | } |
| ... | @@ -20571,7 +20575,8 @@ static ZigType *ir_analyze_instruction_ptr_to_int(IrAnalyze *ira, IrInstructionP | ... | @@ -20571,7 +20575,8 @@ static ZigType *ir_analyze_instruction_ptr_to_int(IrAnalyze *ira, IrInstructionP |
| 20571 | 20575 | ||
| 20572 | ZigType *usize = ira->codegen->builtin_types.entry_usize; | 20576 | ZigType *usize = ira->codegen->builtin_types.entry_usize; |
| 20573 | 20577 | ||
| 20574 | if (get_codegen_ptr_type(target->value.type) == nullptr) { | 20578 | // We check size explicitly so we can use get_src_ptr_type here. |
| 20579 | if (get_src_ptr_type(target->value.type) == nullptr) { | ||
| 20575 | ir_add_error(ira, target, | 20580 | ir_add_error(ira, target, |
| 20576 | buf_sprintf("expected pointer, found '%s'", buf_ptr(&target->value.type->name))); | 20581 | buf_sprintf("expected pointer, found '%s'", buf_ptr(&target->value.type->name))); |
| 20577 | return ira->codegen->builtin_types.entry_invalid; | 20582 | return ira->codegen->builtin_types.entry_invalid; |
test/cases/null.zig+6| ... | @@ -154,3 +154,9 @@ test "optional types" { | ... | @@ -154,3 +154,9 @@ test "optional types" { |
| 154 | const StructWithOptionalType = struct { | 154 | const StructWithOptionalType = struct { |
| 155 | t: ?type, | 155 | t: ?type, |
| 156 | }; | 156 | }; |
| 157 | |||
| 158 | test "optional pointer to 0 bit type null value at runtime" { | ||
| 159 | const EmptyStruct = struct {}; | ||
| 160 | var x: ?*EmptyStruct = null; | ||
| 161 | assert(x == null); | ||
| 162 | } |