authorgravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2018-09-18 17:51:50-04:00
committergravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2018-09-18 17:51:50-04:00
log345f8db1c49efe3d9ca9859a296f24e728a3b43a
treec0b6d17a4ef6f444365f0af57682bb9a29c5cbd5
parentc1af3605328d21f59ee8ceba3c7350193f0a2429
signaturelock-open Commit is signed but in an unrecognized format.

fix optional pointer to empty struct incorrectly being non-null

closes #1178

4 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}
39733973
3974ZigType *get_codegen_ptr_type(ZigType *type) {3974ZigType *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}
39853985
3986ZigType *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
3986bool type_is_codegen_pointer(ZigType *type) {3993bool type_is_codegen_pointer(ZigType *type) {
3987 return get_codegen_ptr_type(type) == type;3994 return get_codegen_ptr_type(type) == type;
3988}3995}
39893996
3990uint32_t get_ptr_align(CodeGen *g, ZigType *type) {3997uint32_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}
40064014
4007bool get_ptr_const(ZigType *type) {4015bool 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);
53void resolve_top_level_decl(CodeGen *g, Tld *tld, bool pointer_only, AstNode *source_node);53void resolve_top_level_decl(CodeGen *g, Tld *tld, bool pointer_only, AstNode *source_node);
54bool type_is_codegen_pointer(ZigType *type);54bool type_is_codegen_pointer(ZigType *type);
5555
56ZigType *get_src_ptr_type(ZigType *type);
56ZigType *get_codegen_ptr_type(ZigType *type);57ZigType *get_codegen_ptr_type(ZigType *type);
57uint32_t get_ptr_align(CodeGen *g, ZigType *type);58uint32_t get_ptr_align(CodeGen *g, ZigType *type);
58bool get_ptr_const(ZigType *type);59bool 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
155static void buf_write_value_bytes(CodeGen *codegen, uint8_t *buf, ConstExprValue *val);155static void buf_write_value_bytes(CodeGen *codegen, uint8_t *buf, ConstExprValue *val);
156156
157static ConstExprValue *const_ptr_pointee_unchecked(CodeGen *g, ConstExprValue *const_val) {157static 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;
2016320163
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 }
2016820171
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;
2046720470
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
2057120575
20572 ZigType *usize = ira->codegen->builtin_types.entry_usize;20576 ZigType *usize = ira->codegen->builtin_types.entry_usize;
2057320577
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" {
154const StructWithOptionalType = struct {154const StructWithOptionalType = struct {
155 t: ?type,155 t: ?type,
156};156};
157
158test "optional pointer to 0 bit type null value at runtime" {
159 const EmptyStruct = struct {};
160 var x: ?*EmptyStruct = null;
161 assert(x == null);
162}