authorgravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2019-08-23 15:05:15-04:00
committergravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2019-08-23 15:05:15-04:00
logbe0a9a72772566667d4c225972c6bc7c17b751ef
tree5d02227f3d2bd0f4e5441707ba927cb96bfde39d
parent1dd658d1d02f8dfc432bcda88fdb542189c31725
signaturelock-open Commit is signed but in an unrecognized format.

pointer types lazily evaluate their element type


3 files changed, 68 insertions(+), 42 deletions(-)

src/all_types.hpp+2-1
...@@ -332,7 +332,8 @@ struct LazyValuePtrType {...@@ -332,7 +332,8 @@ struct LazyValuePtrType {
332 bool is_volatile;332 bool is_volatile;
333 bool is_allowzero;333 bool is_allowzero;
334334
335 ZigType *elem_type;335 ConstExprValue *elem_type_val;
336 AstNode *elem_type_src_node;
336 ConstExprValue *align_val; // can be null337 ConstExprValue *align_val; // can be null
337 PtrLen ptr_len;338 PtrLen ptr_len;
338 uint32_t bit_offset_in_host;339 uint32_t bit_offset_in_host;
src/analyze.cpp+11-11
...@@ -956,7 +956,7 @@ ConstExprValue *analyze_const_value(CodeGen *g, Scope *scope, AstNode *node, Zig...@@ -956,7 +956,7 @@ ConstExprValue *analyze_const_value(CodeGen *g, Scope *scope, AstNode *node, Zig
956}956}
957957
958static Error type_val_resolve_zero_bits(CodeGen *g, ConstExprValue *type_val, ZigType *parent_type,958static Error type_val_resolve_zero_bits(CodeGen *g, ConstExprValue *type_val, ZigType *parent_type,
959 bool *is_zero_bits)959 ConstExprValue *parent_type_val, bool *is_zero_bits)
960{960{
961 Error err;961 Error err;
962 if (type_val->special != ConstValSpecialLazy) {962 if (type_val->special != ConstValSpecialLazy) {
...@@ -972,15 +972,17 @@ static Error type_val_resolve_zero_bits(CodeGen *g, ConstExprValue *type_val, Zi...@@ -972,15 +972,17 @@ static Error type_val_resolve_zero_bits(CodeGen *g, ConstExprValue *type_val, Zi
972 zig_unreachable();972 zig_unreachable();
973 case LazyValueIdPtrType: {973 case LazyValueIdPtrType: {
974 LazyValuePtrType *lazy_ptr_type = reinterpret_cast<LazyValuePtrType *>(type_val->data.x_lazy);974 LazyValuePtrType *lazy_ptr_type = reinterpret_cast<LazyValuePtrType *>(type_val->data.x_lazy);
975 if (lazy_ptr_type->elem_type == parent_type) {975
976 if (parent_type_val == lazy_ptr_type->elem_type_val) {
976 // Does a struct which contains a pointer field to itself have bits? Yes.977 // Does a struct which contains a pointer field to itself have bits? Yes.
977 *is_zero_bits = false;978 *is_zero_bits = false;
978 return ErrorNone;979 return ErrorNone;
979 } else {980 } else {
980 if ((err = type_resolve(g, lazy_ptr_type->elem_type, ResolveStatusZeroBitsKnown)))981 if (parent_type_val == nullptr) {
981 return err;982 parent_type_val = type_val;
982 *is_zero_bits = type_has_bits(lazy_ptr_type->elem_type);983 }
983 return ErrorNone;984 return type_val_resolve_zero_bits(g, lazy_ptr_type->elem_type_val, parent_type,
985 parent_type_val, is_zero_bits);
984 }986 }
985 }987 }
986 case LazyValueIdSliceType:988 case LazyValueIdSliceType:
...@@ -1030,9 +1032,7 @@ static ReqCompTime type_val_resolve_requires_comptime(CodeGen *g, ConstExprValue...@@ -1030,9 +1032,7 @@ static ReqCompTime type_val_resolve_requires_comptime(CodeGen *g, ConstExprValue
1030 }1032 }
1031 case LazyValueIdPtrType: {1033 case LazyValueIdPtrType: {
1032 LazyValuePtrType *lazy_ptr_type = reinterpret_cast<LazyValuePtrType *>(type_val->data.x_lazy);1034 LazyValuePtrType *lazy_ptr_type = reinterpret_cast<LazyValuePtrType *>(type_val->data.x_lazy);
1033 if (type_is_invalid(lazy_ptr_type->elem_type))1035 return type_val_resolve_requires_comptime(g, lazy_ptr_type->elem_type_val, parent_type);
1034 return ReqCompTimeInvalid;
1035 return type_requires_comptime(g, lazy_ptr_type->elem_type, parent_type);
1036 }1036 }
1037 case LazyValueIdFnType: {1037 case LazyValueIdFnType: {
1038 LazyValueFnType *lazy_fn_type = reinterpret_cast<LazyValueFnType *>(type_val->data.x_lazy);1038 LazyValueFnType *lazy_fn_type = reinterpret_cast<LazyValueFnType *>(type_val->data.x_lazy);
...@@ -1102,7 +1102,7 @@ static OnePossibleValue type_val_resolve_has_one_possible_value(CodeGen *g, Cons...@@ -1102,7 +1102,7 @@ static OnePossibleValue type_val_resolve_has_one_possible_value(CodeGen *g, Cons
1102 case LazyValueIdPtrType: {1102 case LazyValueIdPtrType: {
1103 Error err;1103 Error err;
1104 bool zero_bits;1104 bool zero_bits;
1105 if ((err = type_val_resolve_zero_bits(g, type_val, nullptr, &zero_bits))) {1105 if ((err = type_val_resolve_zero_bits(g, type_val, nullptr, nullptr, &zero_bits))) {
1106 return OnePossibleValueInvalid;1106 return OnePossibleValueInvalid;
1107 }1107 }
1108 if (zero_bits) {1108 if (zero_bits) {
...@@ -2359,7 +2359,7 @@ static Error resolve_struct_zero_bits(CodeGen *g, ZigType *struct_type) {...@@ -2359,7 +2359,7 @@ static Error resolve_struct_zero_bits(CodeGen *g, ZigType *struct_type) {
2359 }2359 }
23602360
2361 bool field_is_zero_bits;2361 bool field_is_zero_bits;
2362 if ((err = type_val_resolve_zero_bits(g, field_type_val, struct_type, &field_is_zero_bits))) {2362 if ((err = type_val_resolve_zero_bits(g, field_type_val, struct_type, nullptr, &field_is_zero_bits))) {
2363 struct_type->data.structure.resolve_status = ResolveStatusInvalid;2363 struct_type->data.structure.resolve_status = ResolveStatusInvalid;
2364 return ErrorSemanticAnalyzeFail;2364 return ErrorSemanticAnalyzeFail;
2365 }2365 }
src/ir.cpp+55-30
...@@ -10850,17 +10850,32 @@ static ZigType *ir_resolve_const_type(CodeGen *codegen, IrExecutable *exec, AstN...@@ -10850,17 +10850,32 @@ static ZigType *ir_resolve_const_type(CodeGen *codegen, IrExecutable *exec, AstN
10850 return val->data.x_type;10850 return val->data.x_type;
10851}10851}
1085210852
10853static ZigType *ir_resolve_type(IrAnalyze *ira, IrInstruction *type_value) {10853static ConstExprValue *ir_resolve_type_lazy(IrAnalyze *ira, IrInstruction *type_value) {
10854 if (type_is_invalid(type_value->value.type))10854 if (type_is_invalid(type_value->value.type))
10855 return ira->codegen->builtin_types.entry_invalid;10855 return nullptr;
1085610856
10857 if (type_value->value.type->id != ZigTypeIdMetaType) {10857 if (type_value->value.type->id != ZigTypeIdMetaType) {
10858 ir_add_error(ira, type_value,10858 ir_add_error(ira, type_value,
10859 buf_sprintf("expected type 'type', found '%s'", buf_ptr(&type_value->value.type->name)));10859 buf_sprintf("expected type 'type', found '%s'", buf_ptr(&type_value->value.type->name)));
10860 return ira->codegen->builtin_types.entry_invalid;10860 return nullptr;
10861 }
10862
10863 Error err;
10864 if ((err = ir_resolve_const_val(ira->codegen, ira->new_irb.exec, type_value->source_node,
10865 &type_value->value, LazyOk)))
10866 {
10867 return nullptr;
10861 }10868 }
1086210869
10863 return ir_resolve_const_type(ira->codegen, ira->new_irb.exec, type_value->source_node, &type_value->value);10870 return &type_value->value;
10871}
10872
10873static ZigType *ir_resolve_type(IrAnalyze *ira, IrInstruction *type_value) {
10874 ConstExprValue *val = ir_resolve_type_lazy(ira, type_value);
10875 if (val == nullptr)
10876 return ira->codegen->builtin_types.entry_invalid;
10877
10878 return ir_resolve_const_type(ira->codegen, ira->new_irb.exec, type_value->source_node, val);
10864}10879}
1086510880
10866static ZigType *ir_resolve_int_type(IrAnalyze *ira, IrInstruction *type_value) {10881static ZigType *ir_resolve_int_type(IrAnalyze *ira, IrInstruction *type_value) {
...@@ -23907,30 +23922,10 @@ static IrInstruction *ir_analyze_instruction_ptr_type(IrAnalyze *ira, IrInstruct...@@ -23907,30 +23922,10 @@ static IrInstruction *ir_analyze_instruction_ptr_type(IrAnalyze *ira, IrInstruct
23907 lazy_ptr_type->base.id = LazyValueIdPtrType;23922 lazy_ptr_type->base.id = LazyValueIdPtrType;
23908 lazy_ptr_type->base.exec = ira->new_irb.exec;23923 lazy_ptr_type->base.exec = ira->new_irb.exec;
2390923924
23910 ZigType *child_type = ir_resolve_type(ira, instruction->child_type->child);23925 lazy_ptr_type->elem_type_val = ir_resolve_type_lazy(ira, instruction->child_type->child);
23911 if (type_is_invalid(child_type))23926 if (lazy_ptr_type->elem_type_val == nullptr)
23912 return ira->codegen->invalid_instruction;23927 return ira->codegen->invalid_instruction;
23913 lazy_ptr_type->elem_type = child_type;23928 lazy_ptr_type->elem_type_src_node = instruction->child_type->source_node;
23914
23915 if (child_type->id == ZigTypeIdUnreachable) {
23916 ir_add_error(ira, &instruction->base, buf_sprintf("pointer to noreturn not allowed"));
23917 return ira->codegen->invalid_instruction;
23918 } else if (child_type->id == ZigTypeIdOpaque && instruction->ptr_len == PtrLenUnknown) {
23919 ir_add_error(ira, &instruction->base, buf_sprintf("unknown-length pointer to opaque"));
23920 return ira->codegen->invalid_instruction;
23921 } else if (instruction->ptr_len == PtrLenC) {
23922 if (!type_allowed_in_extern(ira->codegen, child_type)) {
23923 ir_add_error(ira, &instruction->base,
23924 buf_sprintf("C pointers cannot point to non-C-ABI-compatible type '%s'", buf_ptr(&child_type->name)));
23925 return ira->codegen->invalid_instruction;
23926 } else if (child_type->id == ZigTypeIdOpaque) {
23927 ir_add_error(ira, &instruction->base, buf_sprintf("C pointers cannot point opaque types"));
23928 return ira->codegen->invalid_instruction;
23929 } else if (instruction->is_allow_zero) {
23930 ir_add_error(ira, &instruction->base, buf_sprintf("C pointers always allow address zero"));
23931 return ira->codegen->invalid_instruction;
23932 }
23933 }
2393423929
23935 if (instruction->align_value != nullptr) {23930 if (instruction->align_value != nullptr) {
23936 lazy_ptr_type->align_val = ir_resolve_const(ira, instruction->align_value->child, LazyOk);23931 lazy_ptr_type->align_val = ir_resolve_const(ira, instruction->align_value->child, LazyOk);
...@@ -25593,15 +25588,45 @@ static Error ir_resolve_lazy_raw(CodeGen *codegen, AstNode *source_node, ConstEx...@@ -25593,15 +25588,45 @@ static Error ir_resolve_lazy_raw(CodeGen *codegen, AstNode *source_node, ConstEx
25593 if (!ir_resolve_const_align(codegen, exec, source_node, lazy_ptr_type->align_val, &align_bytes))25588 if (!ir_resolve_const_align(codegen, exec, source_node, lazy_ptr_type->align_val, &align_bytes))
25594 return ErrorSemanticAnalyzeFail;25589 return ErrorSemanticAnalyzeFail;
25595 }25590 }
25591 ZigType *elem_type = ir_resolve_const_type(codegen, exec, lazy_ptr_type->elem_type_src_node,
25592 lazy_ptr_type->elem_type_val);
25593 if (type_is_invalid(elem_type))
25594 return ErrorSemanticAnalyzeFail;
25595
25596 if (elem_type->id == ZigTypeIdUnreachable) {
25597 exec_add_error_node(codegen, exec, lazy_ptr_type->elem_type_src_node,
25598 buf_create_from_str("pointer to noreturn not allowed"));
25599 return ErrorSemanticAnalyzeFail;
25600 } else if (elem_type->id == ZigTypeIdOpaque && lazy_ptr_type->ptr_len == PtrLenUnknown) {
25601 exec_add_error_node(codegen, exec, lazy_ptr_type->elem_type_src_node,
25602 buf_create_from_str("unknown-length pointer to opaque"));
25603 return ErrorSemanticAnalyzeFail;
25604 } else if (lazy_ptr_type->ptr_len == PtrLenC) {
25605 if (!type_allowed_in_extern(codegen, elem_type)) {
25606 exec_add_error_node(codegen, exec, lazy_ptr_type->elem_type_src_node,
25607 buf_sprintf("C pointers cannot point to non-C-ABI-compatible type '%s'",
25608 buf_ptr(&elem_type->name)));
25609 return ErrorSemanticAnalyzeFail;
25610 } else if (elem_type->id == ZigTypeIdOpaque) {
25611 exec_add_error_node(codegen, exec, lazy_ptr_type->elem_type_src_node,
25612 buf_sprintf("C pointers cannot point opaque types"));
25613 return ErrorSemanticAnalyzeFail;
25614 } else if (lazy_ptr_type->is_allowzero) {
25615 exec_add_error_node(codegen, exec, lazy_ptr_type->elem_type_src_node,
25616 buf_sprintf("C pointers always allow address zero"));
25617 return ErrorSemanticAnalyzeFail;
25618 }
25619 }
25620
25596 ResolveStatus needed_status = (align_bytes == 0) ?25621 ResolveStatus needed_status = (align_bytes == 0) ?
25597 ResolveStatusZeroBitsKnown : ResolveStatusAlignmentKnown;25622 ResolveStatusZeroBitsKnown : ResolveStatusAlignmentKnown;
25598 if ((err = type_resolve(codegen, lazy_ptr_type->elem_type, needed_status)))25623 if ((err = type_resolve(codegen, elem_type, needed_status)))
25599 return err;25624 return err;
25600 if (!type_has_bits(lazy_ptr_type->elem_type))25625 if (!type_has_bits(elem_type))
25601 align_bytes = 0;25626 align_bytes = 0;
25602 bool allow_zero = lazy_ptr_type->is_allowzero || lazy_ptr_type->ptr_len == PtrLenC;25627 bool allow_zero = lazy_ptr_type->is_allowzero || lazy_ptr_type->ptr_len == PtrLenC;
25603 assert(val->type->id == ZigTypeIdMetaType);25628 assert(val->type->id == ZigTypeIdMetaType);
25604 val->data.x_type = get_pointer_to_type_extra(codegen, lazy_ptr_type->elem_type,25629 val->data.x_type = get_pointer_to_type_extra(codegen, elem_type,
25605 lazy_ptr_type->is_const, lazy_ptr_type->is_volatile, lazy_ptr_type->ptr_len, align_bytes,25630 lazy_ptr_type->is_const, lazy_ptr_type->is_volatile, lazy_ptr_type->ptr_len, align_bytes,
25606 lazy_ptr_type->bit_offset_in_host, lazy_ptr_type->host_int_bytes,25631 lazy_ptr_type->bit_offset_in_host, lazy_ptr_type->host_int_bytes,
25607 allow_zero);25632 allow_zero);