Skip to content

Commit bf3d1c1

Browse files
committedJun 8, 2018
Allow access of array.len through a pointer
·
0.15.20.3.0
1 parent ffb089a commit bf3d1c1

File tree

4 files changed

+29
-5
lines changed

4 files changed

+29
-5
lines changed
 

‎src/analyze.cpp‎

Lines changed: 12 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3761,14 +3761,24 @@ static bool is_container(TypeTableEntry *type_entry) {
37613761
zig_unreachable();
37623762
}
37633763

3764+
bool is_ref(TypeTableEntry *type_entry) {
3765+
return type_entry->id == TypeTableEntryIdPointer && type_entry->data.pointer.ptr_len == PtrLenSingle;
3766+
}
3767+
3768+
bool is_array_ref(TypeTableEntry *type_entry) {
3769+
TypeTableEntry *array = is_ref(type_entry) ?
3770+
type_entry->data.pointer.child_type : type_entry;
3771+
return array->id == TypeTableEntryIdArray;
3772+
}
3773+
37643774
bool is_container_ref(TypeTableEntry *type_entry) {
3765-
return (type_entry->id == TypeTableEntryIdPointer && type_entry->data.pointer.ptr_len == PtrLenSingle) ?
3775+
return is_ref(type_entry) ?
37663776
is_container(type_entry->data.pointer.child_type) : is_container(type_entry);
37673777
}
37683778

37693779
TypeTableEntry *container_ref_type(TypeTableEntry *type_entry) {
37703780
assert(is_container_ref(type_entry));
3771-
return (type_entry->id == TypeTableEntryIdPointer && type_entry->data.pointer.ptr_len == PtrLenSingle) ?
3781+
return is_ref(type_entry) ?
37723782
type_entry->data.pointer.child_type : type_entry;
37733783
}
37743784

‎src/analyze.hpp‎

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -70,6 +70,8 @@ TypeUnionField *find_union_type_field(TypeTableEntry *type_entry, Buf *name);
7070
TypeEnumField *find_enum_field_by_tag(TypeTableEntry *enum_type, const BigInt *tag);
7171
TypeUnionField *find_union_field_by_tag(TypeTableEntry *type_entry, const BigInt *tag);
7272

73+
bool is_ref(TypeTableEntry *type_entry);
74+
bool is_array_ref(TypeTableEntry *type_entry);
7375
bool is_container_ref(TypeTableEntry *type_entry);
7476
void scan_decls(CodeGen *g, ScopeDecls *decls_scope, AstNode *node);
7577
void scan_import(CodeGen *g, ImportTableEntry *import);

‎src/ir.cpp‎

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -13846,10 +13846,14 @@ static TypeTableEntry *ir_analyze_instruction_field_ptr(IrAnalyze *ira, IrInstru
1384613846
ir_link_new_instruction(result, &field_ptr_instruction->base);
1384713847
return result->value.type;
1384813848
}
13849-
} else if (container_type->id == TypeTableEntryIdArray) {
13849+
} else if (is_array_ref(container_type)) {
1385013850
if (buf_eql_str(field_name, "len")) {
1385113851
ConstExprValue *len_val = create_const_vals(1);
13852-
init_const_usize(ira->codegen, len_val, container_type->data.array.len);
13852+
if (container_type->id == TypeTableEntryIdPointer) {
13853+
init_const_usize(ira->codegen, len_val, container_type->data.pointer.child_type->data.array.len);
13854+
} else {
13855+
init_const_usize(ira->codegen, len_val, container_type->data.array.len);
13856+
}
1385313857

1385413858
TypeTableEntry *usize = ira->codegen->builtin_types.entry_usize;
1385513859
bool ptr_is_const = true;

‎test/cases/array.zig‎

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -116,6 +116,15 @@ test "array len property" {
116116
assert(@typeOf(x).len == 5);
117117
}
118118

119+
test "array len field" {
120+
var arr = [4]u8{ 0, 0, 0, 0 };
121+
var ptr = &arr;
122+
assert(arr.len == 4);
123+
comptime assert(arr.len == 4);
124+
assert(ptr.len == 4);
125+
comptime assert(ptr.len == 4);
126+
}
127+
119128
test "single-item pointer to array indexing and slicing" {
120129
testSingleItemPtrArrayIndexSlice();
121130
comptime testSingleItemPtrArrayIndexSlice();
@@ -143,4 +152,3 @@ fn testImplicitCastSingleItemPtr() void {
143152
slice[0] += 1;
144153
assert(byte == 101);
145154
}
146-

0 commit comments

Comments
 (0)
Please sign in to comment.