From fec4555476e38d2eeb1dfb02572404b243acd0b2 Mon Sep 17 00:00:00 2001 From: Andrew Kelley Date: Sun, 10 Mar 2019 18:02:59 -0400 Subject: [PATCH] fix inconsistent type information of optional C pointers solves an assertion failure in LLVM --- src/analyze.cpp | 10 +++------- src/analyze.hpp | 1 - src/codegen.cpp | 12 ++++++------ 3 files changed, 9 insertions(+), 14 deletions(-) diff --git a/src/analyze.cpp b/src/analyze.cpp index 6cbcc311efd3..79a723b2e5e0 100644 --- a/src/analyze.cpp +++ b/src/analyze.cpp @@ -601,7 +601,7 @@ ZigType *get_optional_type(CodeGen *g, ZigType *child_type) { if (child_type->zero_bits) { entry->type_ref = LLVMInt1Type(); entry->di_type = g->builtin_types.entry_bool->di_type; - } else if (type_is_non_optional_pointer(child_type) || child_type->id == ZigTypeIdErrorSet) { + } else if (type_is_nonnull_ptr(child_type) || child_type->id == ZigTypeIdErrorSet) { assert(child_type->di_type); // this is an optimization but also is necessary for calling C // functions where all pointers are maybe pointers @@ -4145,11 +4145,7 @@ ZigType *get_codegen_ptr_type(ZigType *type) { } bool type_is_nonnull_ptr(ZigType *type) { - return type_is_non_optional_pointer(type) && !ptr_allows_addr_zero(type); -} - -bool type_is_non_optional_pointer(ZigType *type) { - return get_codegen_ptr_type(type) == type; + return get_codegen_ptr_type(type) == type && !ptr_allows_addr_zero(type); } uint32_t get_ptr_align(CodeGen *g, ZigType *type) { @@ -4667,7 +4663,7 @@ bool handle_is_ptr(ZigType *type_entry) { return type_has_bits(type_entry->data.error_union.payload_type); case ZigTypeIdOptional: return type_has_bits(type_entry->data.maybe.child_type) && - !type_is_non_optional_pointer(type_entry->data.maybe.child_type) && + !type_is_nonnull_ptr(type_entry->data.maybe.child_type) && type_entry->data.maybe.child_type->id != ZigTypeIdErrorSet; case ZigTypeIdUnion: assert(type_entry->data.unionation.zero_bits_known); diff --git a/src/analyze.hpp b/src/analyze.hpp index 22e44ebd3ff9..3b4f6b711845 100644 --- a/src/analyze.hpp +++ b/src/analyze.hpp @@ -60,7 +60,6 @@ ZigVar *find_variable(CodeGen *g, Scope *orig_context, Buf *name, ScopeFnDef **c Tld *find_decl(CodeGen *g, Scope *scope, Buf *name); Tld *find_container_decl(CodeGen *g, ScopeDecls *decls_scope, Buf *name); void resolve_top_level_decl(CodeGen *g, Tld *tld, AstNode *source_node); -bool type_is_non_optional_pointer(ZigType *type); ZigType *get_src_ptr_type(ZigType *type); ZigType *get_codegen_ptr_type(ZigType *type); diff --git a/src/codegen.cpp b/src/codegen.cpp index 719eead7f2ab..71f9f0217b39 100644 --- a/src/codegen.cpp +++ b/src/codegen.cpp @@ -3948,10 +3948,10 @@ static LLVMValueRef ir_render_asm(CodeGen *g, IrExecutable *executable, IrInstru static LLVMValueRef gen_non_null_bit(CodeGen *g, ZigType *maybe_type, LLVMValueRef maybe_handle) { assert(maybe_type->id == ZigTypeIdOptional); ZigType *child_type = maybe_type->data.maybe.child_type; - if (child_type->zero_bits) { + if (!type_has_bits(child_type)) { return maybe_handle; } else { - bool is_scalar = type_is_non_optional_pointer(child_type) || child_type->id == ZigTypeIdErrorSet; + bool is_scalar = !handle_is_ptr(maybe_type); if (is_scalar) { return LLVMBuildICmp(g->builder, LLVMIntNE, maybe_handle, LLVMConstNull(maybe_type->type_ref), ""); } else { @@ -3991,7 +3991,7 @@ static LLVMValueRef ir_render_optional_unwrap_ptr(CodeGen *g, IrExecutable *exec if (child_type->zero_bits) { return nullptr; } else { - bool is_scalar = type_is_non_optional_pointer(child_type) || child_type->id == ZigTypeIdErrorSet; + bool is_scalar = !handle_is_ptr(maybe_type); if (is_scalar) { return maybe_ptr; } else { @@ -4854,7 +4854,7 @@ static LLVMValueRef ir_render_maybe_wrap(CodeGen *g, IrExecutable *executable, I } LLVMValueRef payload_val = ir_llvm_value(g, instruction->value); - if (type_is_non_optional_pointer(child_type) || child_type->id == ZigTypeIdErrorSet) { + if (!handle_is_ptr(wanted_type)) { return payload_val; } @@ -8690,10 +8690,10 @@ static void get_c_type(CodeGen *g, GenH *gen_h, ZigType *type_entry, Buf *out_bu case ZigTypeIdOptional: { ZigType *child_type = type_entry->data.maybe.child_type; - if (child_type->zero_bits) { + if (!type_has_bits(child_type)) { buf_init_from_str(out_buf, "bool"); return; - } else if (type_is_non_optional_pointer(child_type)) { + } else if (type_is_nonnull_ptr(child_type)) { return get_c_type(g, gen_h, child_type, out_buf); } else { zig_unreachable();