authorgravatar for thatlemon@gmail.comLemonBoy <thatlemon@gmail.com> 2020-02-26 10:05:04+01:00
committergravatar for thatlemon@gmail.comLemonBoy <thatlemon@gmail.com> 2020-02-26 10:05:04+01:00
logd2535c003c6188fcc362028e01ef9f7fb3356727
treed6cb0c35e9d541af21ce2ed015e6f2b33a29c9c7
parentb46efcde82436e73c73dab132f73aeff98673894

ir: Fix regression with self-referencing containers


2 files changed, 36 insertions(+), 5 deletions(-)

src/analyze.cpp+14-5
...@@ -1131,17 +1131,26 @@ Error type_val_resolve_zero_bits(CodeGen *g, ZigValue *type_val, ZigType *parent...@@ -1131,17 +1131,26 @@ Error type_val_resolve_zero_bits(CodeGen *g, ZigValue *type_val, ZigType *parent
1131 Error err;1131 Error err;
1132 if (type_val->special != ConstValSpecialLazy) {1132 if (type_val->special != ConstValSpecialLazy) {
1133 assert(type_val->special == ConstValSpecialStatic);1133 assert(type_val->special == ConstValSpecialStatic);
1134 if ((type_val->data.x_type->id == ZigTypeIdStruct &&1134
1135 type_val->data.x_type->data.structure.resolve_loop_flag_zero_bits) ||1135 // Self-referencing types via pointers are allowed and have non-zero size
1136 (type_val->data.x_type->id == ZigTypeIdUnion &&1136 ZigType *ty = type_val->data.x_type;
1137 type_val->data.x_type->data.unionation.resolve_loop_flag_zero_bits))1137 while (ty->id == ZigTypeIdPointer &&
1138 !ty->data.unionation.resolve_loop_flag_zero_bits)
1139 {
1140 ty = ty->data.pointer.child_type;
1141 }
1142
1143 if ((ty->id == ZigTypeIdStruct && ty->data.structure.resolve_loop_flag_zero_bits) ||
1144 (ty->id == ZigTypeIdUnion && ty->data.unionation.resolve_loop_flag_zero_bits) ||
1145 (ty->id == ZigTypeIdPointer && ty->data.pointer.resolve_loop_flag_zero_bits))
1138 {1146 {
1139 // Does a struct/union which contains a pointer field to itself have bits? Yes.
1140 *is_zero_bits = false;1147 *is_zero_bits = false;
1141 return ErrorNone;1148 return ErrorNone;
1142 }1149 }
1150
1143 if ((err = type_resolve(g, type_val->data.x_type, ResolveStatusZeroBitsKnown)))1151 if ((err = type_resolve(g, type_val->data.x_type, ResolveStatusZeroBitsKnown)))
1144 return err;1152 return err;
1153
1145 *is_zero_bits = (type_val->data.x_type->abi_size == 0);1154 *is_zero_bits = (type_val->data.x_type->abi_size == 0);
1146 return ErrorNone;1155 return ErrorNone;
1147 }1156 }
test/stage1/behavior/sizeof_and_typeof.zig+22
...@@ -145,6 +145,26 @@ test "@sizeOf comparison against zero" {...@@ -145,6 +145,26 @@ test "@sizeOf comparison against zero" {
145 const U0 = union {145 const U0 = union {
146 f: *@This(),146 f: *@This(),
147 };147 };
148 const S1 = struct {
149 fn H(comptime T: type) type {
150 return struct {
151 x: T,
152 };
153 }
154 f0: H(*@This()),
155 f1: H(**@This()),
156 f2: H(***@This()),
157 };
158 const U1 = union {
159 fn H(comptime T: type) type {
160 return struct {
161 x: T,
162 };
163 }
164 f0: H(*@This()),
165 f1: H(**@This()),
166 f2: H(***@This()),
167 };
148 const S = struct {168 const S = struct {
149 fn doTheTest(comptime T: type, comptime result: bool) void {169 fn doTheTest(comptime T: type, comptime result: bool) void {
150 expectEqual(result, @sizeOf(T) > 0);170 expectEqual(result, @sizeOf(T) > 0);
...@@ -164,4 +184,6 @@ test "@sizeOf comparison against zero" {...@@ -164,4 +184,6 @@ test "@sizeOf comparison against zero" {
164 // Container with ptr pointing to themselves184 // Container with ptr pointing to themselves
165 S.doTheTest(S0, true);185 S.doTheTest(S0, true);
166 S.doTheTest(U0, true);186 S.doTheTest(U0, true);
187 S.doTheTest(S1, true);
188 S.doTheTest(U1, true);
167}189}