authorgravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2017-05-07 18:09:45-04:00
committergravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2017-05-07 18:09:45-04:00
loge485af94d404792f7f695fcbc7ee8f9fb986291b
tree0e9f802efb0b6f300d411fa55f9a1ef66c9fb75e
parentb7579f5f7d4f3295187f7901d97361a63a484d77

fix inability to initialize global pointer to global array element

closes #366

2 files changed, 54 insertions(+), 41 deletions(-)

src/ir.cpp+1-1
...@@ -9753,7 +9753,7 @@ static TypeTableEntry *ir_analyze_instruction_elem_ptr(IrAnalyze *ira, IrInstruc...@@ -9753,7 +9753,7 @@ static TypeTableEntry *ir_analyze_instruction_elem_ptr(IrAnalyze *ira, IrInstruc
97539753
9754 ConstExprValue *array_ptr_val;9754 ConstExprValue *array_ptr_val;
9755 if (array_ptr->value.special != ConstValSpecialRuntime &&9755 if (array_ptr->value.special != ConstValSpecialRuntime &&
9756 array_ptr->value.data.x_ptr.mut != ConstPtrMutRuntimeVar &&9756 (array_ptr->value.data.x_ptr.mut != ConstPtrMutRuntimeVar || array_type->id == TypeTableEntryIdArray) &&
9757 (array_ptr_val = const_ptr_pointee(ira->codegen, &array_ptr->value)) &&9757 (array_ptr_val = const_ptr_pointee(ira->codegen, &array_ptr->value)) &&
9758 array_ptr_val->special != ConstValSpecialRuntime &&9758 array_ptr_val->special != ConstValSpecialRuntime &&
9759 (array_type->id != TypeTableEntryIdPointer ||9759 (array_type->id != TypeTableEntryIdPointer ||
test/cases/misc.zig+53-40
...@@ -8,7 +8,7 @@ const builtin = @import("builtin");...@@ -8,7 +8,7 @@ const builtin = @import("builtin");
8/// doc comment line 28/// doc comment line 2
9fn emptyFunctionWithComments() {}9fn emptyFunctionWithComments() {}
1010
11test "emptyFunctionWithComments" {11test "empty function with comments" {
12 emptyFunctionWithComments();12 emptyFunctionWithComments();
13}13}
1414
...@@ -16,7 +16,7 @@ export fn disabledExternFn() {...@@ -16,7 +16,7 @@ export fn disabledExternFn() {
16 @setGlobalLinkage(disabledExternFn, builtin.GlobalLinkage.Internal);16 @setGlobalLinkage(disabledExternFn, builtin.GlobalLinkage.Internal);
17}17}
1818
19test "callDisabledExternFn" {19test "call disabled extern fn" {
20 disabledExternFn();20 disabledExternFn();
21}21}
2222
...@@ -59,7 +59,7 @@ const u63 = @IntType(false, 63);...@@ -59,7 +59,7 @@ const u63 = @IntType(false, 63);
59const i1 = @IntType(true, 1);59const i1 = @IntType(true, 1);
60const i63 = @IntType(true, 63);60const i63 = @IntType(true, 63);
6161
62test "minValueAndMaxValue" {62test "@minValue and @maxValue" {
63 assert(@maxValue(u1) == 1);63 assert(@maxValue(u1) == 1);
64 assert(@maxValue(u8) == 255);64 assert(@maxValue(u8) == 255);
65 assert(@maxValue(u16) == 65535);65 assert(@maxValue(u16) == 65535);
...@@ -88,7 +88,7 @@ test "minValueAndMaxValue" {...@@ -88,7 +88,7 @@ test "minValueAndMaxValue" {
88 assert(@minValue(i64) == -9223372036854775808);88 assert(@minValue(i64) == -9223372036854775808);
89}89}
9090
91test "maxValueType" {91test "max value type" {
92 // If the type of @maxValue(i32) was i32 then this implicit cast to92 // If the type of @maxValue(i32) was i32 then this implicit cast to
93 // u32 would not work. But since the value is a number literal,93 // u32 would not work. But since the value is a number literal,
94 // it works fine.94 // it works fine.
...@@ -96,8 +96,9 @@ test "maxValueType" {...@@ -96,8 +96,9 @@ test "maxValueType" {
96 assert(x == 2147483647);96 assert(x == 2147483647);
97}97}
9898
99test "shortCircuit" {99test "short circuit" {
100 testShortCircuit(false, true);100 testShortCircuit(false, true);
101 comptime testShortCircuit(false, true);
101}102}
102103
103fn testShortCircuit(f: bool, t: bool) {104fn testShortCircuit(f: bool, t: bool) {
...@@ -138,21 +139,21 @@ fn first4KeysOfHomeRow() -> []const u8 {...@@ -138,21 +139,21 @@ fn first4KeysOfHomeRow() -> []const u8 {
138 "aoeu"139 "aoeu"
139}140}
140141
141test "ReturnStringFromFunction" {142test "return string from function" {
142 assert(mem.eql(u8, first4KeysOfHomeRow(), "aoeu"));143 assert(mem.eql(u8, first4KeysOfHomeRow(), "aoeu"));
143}144}
144145
145const g1 : i32 = 1233 + 1;146const g1 : i32 = 1233 + 1;
146var g2 : i32 = 0;147var g2 : i32 = 0;
147148
148test "globalVariables" {149test "global variables" {
149 assert(g2 == 0);150 assert(g2 == 0);
150 g2 = g1;151 g2 = g1;
151 assert(g2 == 1234);152 assert(g2 == 1234);
152}153}
153154
154155
155test "memcpyAndMemsetIntrinsics" {156test "memcpy and memset intrinsics" {
156 var foo : [20]u8 = undefined;157 var foo : [20]u8 = undefined;
157 var bar : [20]u8 = undefined;158 var bar : [20]u8 = undefined;
158159
...@@ -162,7 +163,7 @@ test "memcpyAndMemsetIntrinsics" {...@@ -162,7 +163,7 @@ test "memcpyAndMemsetIntrinsics" {
162 if (bar[11] != 'A') unreachable;163 if (bar[11] != 'A') unreachable;
163}164}
164165
165test "builtinStaticEval" {166test "builtin static eval" {
166 const x : i32 = comptime {1 + 2 + 3};167 const x : i32 = comptime {1 + 2 + 3};
167 assert(x == comptime 6);168 assert(x == comptime 6);
168}169}
...@@ -184,7 +185,7 @@ test "slicing" {...@@ -184,7 +185,7 @@ test "slicing" {
184}185}
185186
186187
187test "constantEqualFunctionPointers" {188test "constant equal function pointers" {
188 const alias = emptyFn;189 const alias = emptyFn;
189 assert(comptime {emptyFn == alias});190 assert(comptime {emptyFn == alias});
190}191}
...@@ -192,19 +193,19 @@ test "constantEqualFunctionPointers" {...@@ -192,19 +193,19 @@ test "constantEqualFunctionPointers" {
192fn emptyFn() {}193fn emptyFn() {}
193194
194195
195test "hexEscape" {196test "hex escape" {
196 assert(mem.eql(u8, "\x68\x65\x6c\x6c\x6f", "hello"));197 assert(mem.eql(u8, "\x68\x65\x6c\x6c\x6f", "hello"));
197}198}
198199
199test "stringConcatenation" {200test "string concatenation" {
200 assert(mem.eql(u8, "OK" ++ " IT " ++ "WORKED", "OK IT WORKED"));201 assert(mem.eql(u8, "OK" ++ " IT " ++ "WORKED", "OK IT WORKED"));
201}202}
202203
203test "arrayMultOperator" {204test "array mult operator" {
204 assert(mem.eql(u8, "ab" ** 5, "ababababab"));205 assert(mem.eql(u8, "ab" ** 5, "ababababab"));
205}206}
206207
207test "stringEscapes" {208test "string escapes" {
208 assert(mem.eql(u8, "\"", "\x22"));209 assert(mem.eql(u8, "\"", "\x22"));
209 assert(mem.eql(u8, "\'", "\x27"));210 assert(mem.eql(u8, "\'", "\x27"));
210 assert(mem.eql(u8, "\n", "\x0a"));211 assert(mem.eql(u8, "\n", "\x0a"));
...@@ -214,7 +215,7 @@ test "stringEscapes" {...@@ -214,7 +215,7 @@ test "stringEscapes" {
214 assert(mem.eql(u8, "\u1234\u0069", "\xe1\x88\xb4\x69"));215 assert(mem.eql(u8, "\u1234\u0069", "\xe1\x88\xb4\x69"));
215}216}
216217
217test "multilineString" {218test "multiline string" {
218 const s1 =219 const s1 =
219 \\one220 \\one
220 \\two)221 \\two)
...@@ -224,7 +225,7 @@ test "multilineString" {...@@ -224,7 +225,7 @@ test "multilineString" {
224 assert(mem.eql(u8, s1, s2));225 assert(mem.eql(u8, s1, s2));
225}226}
226227
227test "multilineCString" {228test "multiline C string" {
228 const s1 =229 const s1 =
229 c\\one230 c\\one
230 c\\two)231 c\\two)
...@@ -235,7 +236,7 @@ test "multilineCString" {...@@ -235,7 +236,7 @@ test "multilineCString" {
235}236}
236237
237238
238test "typeEquality" {239test "type equality" {
239 assert(&const u8 != &u8);240 assert(&const u8 != &u8);
240}241}
241242
...@@ -243,17 +244,17 @@ test "typeEquality" {...@@ -243,17 +244,17 @@ test "typeEquality" {
243const global_a: i32 = 1234;244const global_a: i32 = 1234;
244const global_b: &const i32 = &global_a;245const global_b: &const i32 = &global_a;
245const global_c: &const f32 = @ptrCast(&const f32, global_b);246const global_c: &const f32 = @ptrCast(&const f32, global_b);
246test "compileTimeGlobalReinterpret" {247test "compile time global reinterpret" {
247 const d = @ptrCast(&const i32, global_c);248 const d = @ptrCast(&const i32, global_c);
248 assert(*d == 1234);249 assert(*d == 1234);
249}250}
250251
251test "explicitCastMaybePointers" {252test "explicit cast maybe pointers" {
252 const a: ?&i32 = undefined;253 const a: ?&i32 = undefined;
253 const b: ?&f32 = @ptrCast(?&f32, a);254 const b: ?&f32 = @ptrCast(?&f32, a);
254}255}
255256
256test "genericMallocFree" {257test "generic malloc free" {
257 const a = %%memAlloc(u8, 10);258 const a = %%memAlloc(u8, 10);
258 memFree(u8, a);259 memFree(u8, a);
259}260}
...@@ -264,7 +265,7 @@ fn memAlloc(comptime T: type, n: usize) -> %[]T {...@@ -264,7 +265,7 @@ fn memAlloc(comptime T: type, n: usize) -> %[]T {
264fn memFree(comptime T: type, memory: []T) { }265fn memFree(comptime T: type, memory: []T) { }
265266
266267
267test "castUndefined" {268test "cast undefined" {
268 const array: [100]u8 = undefined;269 const array: [100]u8 = undefined;
269 const slice = ([]const u8)(array);270 const slice = ([]const u8)(array);
270 testCastUndefined(slice);271 testCastUndefined(slice);
...@@ -272,7 +273,7 @@ test "castUndefined" {...@@ -272,7 +273,7 @@ test "castUndefined" {
272fn testCastUndefined(x: []const u8) {}273fn testCastUndefined(x: []const u8) {}
273274
274275
275test "castSmallUnsignedToLargerSigned" {276test "cast small unsigned to larger signed" {
276 assert(castSmallUnsignedToLargerSigned1(200) == i16(200));277 assert(castSmallUnsignedToLargerSigned1(200) == i16(200));
277 assert(castSmallUnsignedToLargerSigned2(9999) == i64(9999));278 assert(castSmallUnsignedToLargerSigned2(9999) == i64(9999));
278}279}
...@@ -280,7 +281,7 @@ fn castSmallUnsignedToLargerSigned1(x: u8) -> i16 { x }...@@ -280,7 +281,7 @@ fn castSmallUnsignedToLargerSigned1(x: u8) -> i16 { x }
280fn castSmallUnsignedToLargerSigned2(x: u16) -> i64 { x }281fn castSmallUnsignedToLargerSigned2(x: u16) -> i64 { x }
281282
282283
283test "implicitCastAfterUnreachable" {284test "implicit cast after unreachable" {
284 assert(outer() == 1234);285 assert(outer() == 1234);
285}286}
286fn inner() -> i32 { 1234 }287fn inner() -> i32 { 1234 }
...@@ -289,7 +290,7 @@ fn outer() -> i64 {...@@ -289,7 +290,7 @@ fn outer() -> i64 {
289}290}
290291
291292
292test "pointerDereferencing" {293test "pointer dereferencing" {
293 var x = i32(3);294 var x = i32(3);
294 const y = &x;295 const y = &x;
295296
...@@ -299,7 +300,7 @@ test "pointerDereferencing" {...@@ -299,7 +300,7 @@ test "pointerDereferencing" {
299 assert(*y == 4);300 assert(*y == 4);
300}301}
301302
302test "callResultOfIfElseExpression" {303test "call result of if else expression" {
303 assert(mem.eql(u8, f2(true), "a"));304 assert(mem.eql(u8, f2(true), "a"));
304 assert(mem.eql(u8, f2(false), "b"));305 assert(mem.eql(u8, f2(false), "b"));
305}306}
...@@ -310,7 +311,7 @@ fn fA() -> []const u8 { "a" }...@@ -310,7 +311,7 @@ fn fA() -> []const u8 { "a" }
310fn fB() -> []const u8 { "b" }311fn fB() -> []const u8 { "b" }
311312
312313
313test "constExpressionEvalHandlingOfVariables" {314test "const expression eval handling of variables" {
314 var x = true;315 var x = true;
315 while (x) {316 while (x) {
316 x = false;317 x = false;
...@@ -319,7 +320,7 @@ test "constExpressionEvalHandlingOfVariables" {...@@ -319,7 +320,7 @@ test "constExpressionEvalHandlingOfVariables" {
319320
320321
321322
322test "constantEnumInitializationWithDifferingSizes" {323test "constant enum initialization with differing sizes" {
323 test3_1(test3_foo);324 test3_1(test3_foo);
324 test3_2(test3_bar);325 test3_2(test3_bar);
325}326}
...@@ -353,14 +354,14 @@ fn test3_2(f: &const Test3Foo) {...@@ -353,14 +354,14 @@ fn test3_2(f: &const Test3Foo) {
353}354}
354355
355356
356test "characterLiterals" {357test "character literals" {
357 assert('\'' == single_quote);358 assert('\'' == single_quote);
358}359}
359const single_quote = '\'';360const single_quote = '\'';
360361
361362
362363
363test "takeAddressOfParameter" {364test "take address of parameter" {
364 testTakeAddressOfParameter(12.34);365 testTakeAddressOfParameter(12.34);
365}366}
366fn testTakeAddressOfParameter(f: f32) {367fn testTakeAddressOfParameter(f: f32) {
...@@ -369,7 +370,7 @@ fn testTakeAddressOfParameter(f: f32) {...@@ -369,7 +370,7 @@ fn testTakeAddressOfParameter(f: f32) {
369}370}
370371
371372
372test "pointerComparison" {373test "pointer comparison" {
373 const a = ([]const u8)("a");374 const a = ([]const u8)("a");
374 const b = &a;375 const b = &a;
375 assert(ptrEql(b, b));376 assert(ptrEql(b, b));
...@@ -379,7 +380,7 @@ fn ptrEql(a: &const []const u8, b: &const []const u8) -> bool {...@@ -379,7 +380,7 @@ fn ptrEql(a: &const []const u8, b: &const []const u8) -> bool {
379}380}
380381
381382
382test "cStringConcatenation" {383test "C string concatenation" {
383 const a = c"OK" ++ c" IT " ++ c"WORKED";384 const a = c"OK" ++ c" IT " ++ c"WORKED";
384 const b = c"OK IT WORKED";385 const b = c"OK IT WORKED";
385386
...@@ -392,7 +393,7 @@ test "cStringConcatenation" {...@@ -392,7 +393,7 @@ test "cStringConcatenation" {
392 assert(b[len] == 0);393 assert(b[len] == 0);
393}394}
394395
395test "castSliceToU8Slice" {396test "cast slice to u8 slice" {
396 assert(@sizeOf(i32) == 4);397 assert(@sizeOf(i32) == 4);
397 var big_thing_array = []i32{1, 2, 3, 4};398 var big_thing_array = []i32{1, 2, 3, 4};
398 const big_thing_slice: []i32 = big_thing_array[0...];399 const big_thing_slice: []i32 = big_thing_array[0...];
...@@ -412,7 +413,7 @@ test "castSliceToU8Slice" {...@@ -412,7 +413,7 @@ test "castSliceToU8Slice" {
412 assert(bytes[11] == @maxValue(u8));413 assert(bytes[11] == @maxValue(u8));
413}414}
414415
415test "pointerToVoidReturnType" {416test "pointer to void return type" {
416 %%testPointerToVoidReturnType();417 %%testPointerToVoidReturnType();
417}418}
418fn testPointerToVoidReturnType() -> %void {419fn testPointerToVoidReturnType() -> %void {
...@@ -425,14 +426,14 @@ fn testPointerToVoidReturnType2() -> &const void {...@@ -425,14 +426,14 @@ fn testPointerToVoidReturnType2() -> &const void {
425}426}
426427
427428
428test "nonConstPtrToAliasedType" {429test "non const ptr to aliased type" {
429 const int = i32;430 const int = i32;
430 assert(?&int == ?&i32);431 assert(?&int == ?&i32);
431}432}
432433
433434
434435
435test "array2DConstDoublePtr" {436test "array 2D const double ptr" {
436 const rect_2d_vertexes = [][1]f32 {437 const rect_2d_vertexes = [][1]f32 {
437 []f32{1.0},438 []f32{1.0},
438 []f32{2.0},439 []f32{2.0},
...@@ -445,7 +446,7 @@ fn testArray2DConstDoublePtr(ptr: &const f32) {...@@ -445,7 +446,7 @@ fn testArray2DConstDoublePtr(ptr: &const f32) {
445 assert(ptr[1] == 2.0);446 assert(ptr[1] == 2.0);
446}447}
447448
448test "isInteger" {449test "@isInteger" {
449 comptime {450 comptime {
450 assert(@isInteger(i8));451 assert(@isInteger(i8));
451 assert(@isInteger(u8));452 assert(@isInteger(u8));
...@@ -458,7 +459,7 @@ test "isInteger" {...@@ -458,7 +459,7 @@ test "isInteger" {
458 }459 }
459}460}
460461
461test "isFloat" {462test "@isFloat" {
462 comptime {463 comptime {
463 assert(!@isFloat(i8));464 assert(!@isFloat(i8));
464 assert(!@isFloat(u8));465 assert(!@isFloat(u8));
...@@ -471,7 +472,7 @@ test "isFloat" {...@@ -471,7 +472,7 @@ test "isFloat" {
471 }472 }
472}473}
473474
474test "canImplicitCast" {475test "@canImplicitCast" {
475 comptime {476 comptime {
476 assert(@canImplicitCast(i64, i32(3)));477 assert(@canImplicitCast(i64, i32(3)));
477 assert(!@canImplicitCast(i32, f32(1.234)));478 assert(!@canImplicitCast(i32, f32(1.234)));
...@@ -479,14 +480,14 @@ test "canImplicitCast" {...@@ -479,14 +480,14 @@ test "canImplicitCast" {
479 }480 }
480}481}
481482
482test "typeName" {483test "@typeName" {
483 comptime {484 comptime {
484 assert(mem.eql(u8, @typeName(i64), "i64"));485 assert(mem.eql(u8, @typeName(i64), "i64"));
485 assert(mem.eql(u8, @typeName(&usize), "&usize"));486 assert(mem.eql(u8, @typeName(&usize), "&usize"));
486 }487 }
487}488}
488489
489test "volatileLoadAndStore" {490test "volatile load and store" {
490 var number: i32 = 1234;491 var number: i32 = 1234;
491 const ptr = &volatile number;492 const ptr = &volatile number;
492 *ptr += 1;493 *ptr += 1;
...@@ -500,3 +501,15 @@ test "slice string literal has type []const u8" {...@@ -500,3 +501,15 @@ test "slice string literal has type []const u8" {
500 assert(@typeOf(array[0...]) == []const i32);501 assert(@typeOf(array[0...]) == []const i32);
501 }502 }
502}503}
504
505test "global variable initialized to global variable array element" {
506 assert(global_ptr == &gdt[0]);
507}
508const GDTEntry = struct {
509 field: i32,
510};
511var gdt = []GDTEntry {
512 GDTEntry {.field = 1},
513 GDTEntry {.field = 2},
514};
515var global_ptr = &gdt[0];