authorgravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2017-11-08 21:44:10-05:00
committergravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2017-11-08 21:44:10-05:00
log4f8c26d2c605f24cdeb1a4c7154662b2552640ef
tree926037a3a45f58d191a589d4ed137f4c1bb81bdf
parent53b18c8542d6d40c3aa41e9d97290a4ca46eaa15

fix enum sizes too large

closes #598

3 files changed, 65 insertions(+), 4 deletions(-)

src/analyze.cpp+1-1
...@@ -1389,7 +1389,7 @@ static void resolve_enum_type(CodeGen *g, TypeTableEntry *enum_type) {...@@ -1389,7 +1389,7 @@ static void resolve_enum_type(CodeGen *g, TypeTableEntry *enum_type) {
1389 return;1389 return;
1390 }1390 }
13911391
1392 TypeTableEntry *tag_int_type = get_smallest_unsigned_int_type(g, field_count);1392 TypeTableEntry *tag_int_type = get_smallest_unsigned_int_type(g, field_count - 1);
1393 TypeTableEntry *tag_type_entry = create_enum_tag_type(g, enum_type, tag_int_type);1393 TypeTableEntry *tag_type_entry = create_enum_tag_type(g, enum_type, tag_int_type);
1394 enum_type->data.enumeration.tag_type = tag_type_entry;1394 enum_type->data.enumeration.tag_type = tag_type_entry;
13951395
src/codegen.cpp+10-3
...@@ -2666,9 +2666,16 @@ static LLVMValueRef ir_render_enum_tag_name(CodeGen *g, IrExecutable *executable...@@ -2666,9 +2666,16 @@ static LLVMValueRef ir_render_enum_tag_name(CodeGen *g, IrExecutable *executable
2666 if (ir_want_debug_safety(g, &instruction->base)) {2666 if (ir_want_debug_safety(g, &instruction->base)) {
2667 TypeTableEntry *enum_type = enum_tag_type->data.enum_tag.enum_type;2667 TypeTableEntry *enum_type = enum_tag_type->data.enum_tag.enum_type;
2668 size_t field_count = enum_type->data.enumeration.src_field_count;2668 size_t field_count = enum_type->data.enumeration.src_field_count;
2669 LLVMValueRef zero = LLVMConstNull(LLVMTypeOf(enum_tag_value));2669
2670 LLVMValueRef end_val = LLVMConstInt(LLVMTypeOf(enum_tag_value), field_count, false);2670 // if the field_count can't fit in the bits of the enum_tag_type, then it can't possibly
2671 add_bounds_check(g, enum_tag_value, LLVMIntUGE, zero, LLVMIntULT, end_val);2671 // be the wrong value
2672 BigInt field_bi;
2673 bigint_init_unsigned(&field_bi, field_count);
2674 TypeTableEntry *tag_int_type = enum_tag_type->data.enum_tag.int_type;
2675 if (bigint_fits_in_bits(&field_bi, tag_int_type->data.integral.bit_count, false)) {
2676 LLVMValueRef end_val = LLVMConstInt(LLVMTypeOf(enum_tag_value), field_count, false);
2677 add_bounds_check(g, enum_tag_value, LLVMIntEQ, nullptr, LLVMIntULT, end_val);
2678 }
2672 }2679 }
26732680
2674 LLVMValueRef indices[] = {2681 LLVMValueRef indices[] = {
test/cases/enum.zig+54
...@@ -136,3 +136,57 @@ const AlignTestEnum = enum {...@@ -136,3 +136,57 @@ const AlignTestEnum = enum {
136 A: [9]u8,136 A: [9]u8,
137 B: u64,137 B: u64,
138};138};
139
140const ValueCount0 = enum {};
141const ValueCount1 = enum { I0 };
142const ValueCount2 = enum { I0, I1 };
143const ValueCount256 = enum {
144 I0, I1, I2, I3, I4, I5, I6, I7, I8, I9, I10, I11, I12, I13, I14, I15,
145 I16, I17, I18, I19, I20, I21, I22, I23, I24, I25, I26, I27, I28, I29, I30, I31,
146 I32, I33, I34, I35, I36, I37, I38, I39, I40, I41, I42, I43, I44, I45, I46, I47,
147 I48, I49, I50, I51, I52, I53, I54, I55, I56, I57, I58, I59, I60, I61, I62, I63,
148 I64, I65, I66, I67, I68, I69, I70, I71, I72, I73, I74, I75, I76, I77, I78, I79,
149 I80, I81, I82, I83, I84, I85, I86, I87, I88, I89, I90, I91, I92, I93, I94, I95,
150 I96, I97, I98, I99, I100, I101, I102, I103, I104, I105, I106, I107, I108, I109,
151 I110, I111, I112, I113, I114, I115, I116, I117, I118, I119, I120, I121, I122, I123,
152 I124, I125, I126, I127, I128, I129, I130, I131, I132, I133, I134, I135, I136, I137,
153 I138, I139, I140, I141, I142, I143, I144, I145, I146, I147, I148, I149, I150, I151,
154 I152, I153, I154, I155, I156, I157, I158, I159, I160, I161, I162, I163, I164, I165,
155 I166, I167, I168, I169, I170, I171, I172, I173, I174, I175, I176, I177, I178, I179,
156 I180, I181, I182, I183, I184, I185, I186, I187, I188, I189, I190, I191, I192, I193,
157 I194, I195, I196, I197, I198, I199, I200, I201, I202, I203, I204, I205, I206, I207,
158 I208, I209, I210, I211, I212, I213, I214, I215, I216, I217, I218, I219, I220, I221,
159 I222, I223, I224, I225, I226, I227, I228, I229, I230, I231, I232, I233, I234, I235,
160 I236, I237, I238, I239, I240, I241, I242, I243, I244, I245, I246, I247, I248, I249,
161 I250, I251, I252, I253, I254, I255
162};
163const ValueCount257 = enum {
164 I0, I1, I2, I3, I4, I5, I6, I7, I8, I9, I10, I11, I12, I13, I14, I15,
165 I16, I17, I18, I19, I20, I21, I22, I23, I24, I25, I26, I27, I28, I29, I30, I31,
166 I32, I33, I34, I35, I36, I37, I38, I39, I40, I41, I42, I43, I44, I45, I46, I47,
167 I48, I49, I50, I51, I52, I53, I54, I55, I56, I57, I58, I59, I60, I61, I62, I63,
168 I64, I65, I66, I67, I68, I69, I70, I71, I72, I73, I74, I75, I76, I77, I78, I79,
169 I80, I81, I82, I83, I84, I85, I86, I87, I88, I89, I90, I91, I92, I93, I94, I95,
170 I96, I97, I98, I99, I100, I101, I102, I103, I104, I105, I106, I107, I108, I109,
171 I110, I111, I112, I113, I114, I115, I116, I117, I118, I119, I120, I121, I122, I123,
172 I124, I125, I126, I127, I128, I129, I130, I131, I132, I133, I134, I135, I136, I137,
173 I138, I139, I140, I141, I142, I143, I144, I145, I146, I147, I148, I149, I150, I151,
174 I152, I153, I154, I155, I156, I157, I158, I159, I160, I161, I162, I163, I164, I165,
175 I166, I167, I168, I169, I170, I171, I172, I173, I174, I175, I176, I177, I178, I179,
176 I180, I181, I182, I183, I184, I185, I186, I187, I188, I189, I190, I191, I192, I193,
177 I194, I195, I196, I197, I198, I199, I200, I201, I202, I203, I204, I205, I206, I207,
178 I208, I209, I210, I211, I212, I213, I214, I215, I216, I217, I218, I219, I220, I221,
179 I222, I223, I224, I225, I226, I227, I228, I229, I230, I231, I232, I233, I234, I235,
180 I236, I237, I238, I239, I240, I241, I242, I243, I244, I245, I246, I247, I248, I249,
181 I250, I251, I252, I253, I254, I255, I256
182};
183
184test "enum sizes" {
185 comptime {
186 assert(@sizeOf(ValueCount0) == 0);
187 assert(@sizeOf(ValueCount1) == 0);
188 assert(@sizeOf(ValueCount2) == 1);
189 assert(@sizeOf(ValueCount256) == 1);
190 assert(@sizeOf(ValueCount257) == 2);
191 }
192}