authorgravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2017-04-19 04:12:22-04:00
committergravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2017-04-19 04:12:22-04:00
logd0a17b6937cd0128f4a4fc37ec0f2bd99266034e
tree1fbdea60aae446a602674a630b9d9aabf21a51ab
parent10525b869d1a50eef65d8ec2717dda61c937e154

convert std lib tests to zig build system


4 files changed, 1889 insertions(+), 1874 deletions(-)

build.zig+17-1
......@@ -11,6 +11,7 @@ pub fn build(b: &Builder) {
1111 run_tests_cmd.step.dependOn(&run_tests_exe.step);
1212
1313 const self_hosted_tests = b.step("test-self-hosted", "Run the self-hosted tests");
14 test_step.dependOn(self_hosted_tests);
1415 for ([]bool{false, true}) |release| {
1516 for ([]bool{false, true}) |link_libc| {
1617 const these_tests = b.addTest("test/self_hosted.zig");
......@@ -24,9 +25,24 @@ pub fn build(b: &Builder) {
2425 }
2526 }
2627
27 test_step.dependOn(self_hosted_tests);
28 const std_lib_tests = b.step("test-std", "Run the standard library tests");
29 test_step.dependOn(std_lib_tests);
30 for ([]bool{false, true}) |release| {
31 for ([]bool{false, true}) |link_libc| {
32 const these_tests = b.addTest("std/index.zig");
33 // TODO add prefix to test names
34 // TODO pass test_filter to these_tests
35 these_tests.setRelease(release);
36 if (link_libc) {
37 these_tests.linkLibrary("c");
38 }
39 std_lib_tests.dependOn(&these_tests.step);
40 }
41 }
42
2843 //test_step.dependOn(&run_tests_cmd.step);
2944
3045 test_step.dependOn(tests.addCompareOutputTests(b, test_filter));
3146 test_step.dependOn(tests.addBuildExampleTests(b, test_filter));
47 test_step.dependOn(tests.addCompileErrorTests(b, test_filter));
3248}
test/compile_errors.zig created+1812
......@@ -0,0 +1,1812 @@
1const std = @import("std");
2const debug = std.debug;
3const build = std.build;
4const os = std.os;
5const StdIo = os.ChildProcess.StdIo;
6const Term = os.ChildProcess.Term;
7const Buffer0 = std.cstr.Buffer0;
8const io = std.io;
9const mem = std.mem;
10const fmt = std.fmt;
11const List = std.list.List;
12
13error TestFailed;
14
15pub fn addCompileErrorTests(b: &build.Builder, test_filter: ?[]const u8) -> &build.Step {
16 const cases = %%b.allocator.create(CompileErrorContext);
17 *cases = CompileErrorContext {
18 .b = b,
19 .step = b.step("test-compile-errors", "Run the compile error tests"),
20 .test_index = 0,
21 .test_filter = test_filter,
22 };
23
24 cases.add("implicit semicolon - block statement",
25 \\export fn entry() {
26 \\ {}
27 \\ var good = {};
28 \\ ({})
29 \\ var bad = {};
30 \\}
31 , ".tmp_source.zig:5:5: error: invalid token: 'var'");
32
33 cases.add("implicit semicolon - block expr",
34 \\export fn entry() {
35 \\ _ = {};
36 \\ var good = {};
37 \\ _ = {}
38 \\ var bad = {};
39 \\}
40 , ".tmp_source.zig:5:5: error: invalid token: 'var'");
41
42 cases.add("implicit semicolon - comptime statement",
43 \\export fn entry() {
44 \\ comptime {}
45 \\ var good = {};
46 \\ comptime ({})
47 \\ var bad = {};
48 \\}
49 , ".tmp_source.zig:5:5: error: invalid token: 'var'");
50
51 cases.add("implicit semicolon - comptime expression",
52 \\export fn entry() {
53 \\ _ = comptime {};
54 \\ var good = {};
55 \\ _ = comptime {}
56 \\ var bad = {};
57 \\}
58 , ".tmp_source.zig:5:5: error: invalid token: 'var'");
59
60 cases.add("implicit semicolon - defer",
61 \\export fn entry() {
62 \\ defer {}
63 \\ var good = {};
64 \\ defer ({})
65 \\ var bad = {};
66 \\}
67 , ".tmp_source.zig:5:5: error: expected token ';', found 'var'");
68
69 cases.add("implicit semicolon - if statement",
70 \\export fn entry() {
71 \\ if(true) {}
72 \\ var good = {};
73 \\ if(true) ({})
74 \\ var bad = {};
75 \\}
76 , ".tmp_source.zig:5:5: error: invalid token: 'var'");
77
78 cases.add("implicit semicolon - if expression",
79 \\export fn entry() {
80 \\ _ = if(true) {};
81 \\ var good = {};
82 \\ _ = if(true) {}
83 \\ var bad = {};
84 \\}
85 , ".tmp_source.zig:5:5: error: invalid token: 'var'");
86
87 cases.add("implicit semicolon - if-else statement",
88 \\export fn entry() {
89 \\ if(true) {} else {}
90 \\ var good = {};
91 \\ if(true) ({}) else ({})
92 \\ var bad = {};
93 \\}
94 , ".tmp_source.zig:5:5: error: invalid token: 'var'");
95
96 cases.add("implicit semicolon - if-else expression",
97 \\export fn entry() {
98 \\ _ = if(true) {} else {};
99 \\ var good = {};
100 \\ _ = if(true) {} else {}
101 \\ var bad = {};
102 \\}
103 , ".tmp_source.zig:5:5: error: invalid token: 'var'");
104
105 cases.add("implicit semicolon - if-else-if statement",
106 \\export fn entry() {
107 \\ if(true) {} else if(true) {}
108 \\ var good = {};
109 \\ if(true) ({}) else if(true) ({})
110 \\ var bad = {};
111 \\}
112 , ".tmp_source.zig:5:5: error: invalid token: 'var'");
113
114 cases.add("implicit semicolon - if-else-if expression",
115 \\export fn entry() {
116 \\ _ = if(true) {} else if(true) {};
117 \\ var good = {};
118 \\ _ = if(true) {} else if(true) {}
119 \\ var bad = {};
120 \\}
121 , ".tmp_source.zig:5:5: error: invalid token: 'var'");
122
123 cases.add("implicit semicolon - if-else-if-else statement",
124 \\export fn entry() {
125 \\ if(true) {} else if(true) {} else {}
126 \\ var good = {};
127 \\ if(true) ({}) else if(true) ({}) else ({})
128 \\ var bad = {};
129 \\}
130 , ".tmp_source.zig:5:5: error: invalid token: 'var'");
131
132 cases.add("implicit semicolon - if-else-if-else expression",
133 \\export fn entry() {
134 \\ _ = if(true) {} else if(true) {} else {};
135 \\ var good = {};
136 \\ _ = if(true) {} else if(true) {} else {}
137 \\ var bad = {};
138 \\}
139 , ".tmp_source.zig:5:5: error: invalid token: 'var'");
140
141 cases.add("implicit semicolon - if(var) statement",
142 \\export fn entry() {
143 \\ if(_=foo()) {}
144 \\ var good = {};
145 \\ if(_=foo()) ({})
146 \\ var bad = {};
147 \\}
148 , ".tmp_source.zig:5:5: error: invalid token: 'var'");
149
150 cases.add("implicit semicolon - if(var) expression",
151 \\export fn entry() {
152 \\ _ = if(_=foo()) {};
153 \\ var good = {};
154 \\ _ = if(_=foo()) {}
155 \\ var bad = {};
156 \\}
157 , ".tmp_source.zig:5:5: error: invalid token: 'var'");
158
159 cases.add("implicit semicolon - if(var)-else statement",
160 \\export fn entry() {
161 \\ if(_=foo()) {} else {}
162 \\ var good = {};
163 \\ if(_=foo()) ({}) else ({})
164 \\ var bad = {};
165 \\}
166 , ".tmp_source.zig:5:5: error: invalid token: 'var'");
167
168 cases.add("implicit semicolon - if(var)-else expression",
169 \\export fn entry() {
170 \\ _ = if(_=foo()) {} else {};
171 \\ var good = {};
172 \\ _ = if(_=foo()) {} else {}
173 \\ var bad = {};
174 \\}
175 , ".tmp_source.zig:5:5: error: invalid token: 'var'");
176
177 cases.add("implicit semicolon - if(var)-else-if(var) statement",
178 \\export fn entry() {
179 \\ if(_=foo()) {} else if(_=foo()) {}
180 \\ var good = {};
181 \\ if(_=foo()) ({}) else if(_=foo()) ({})
182 \\ var bad = {};
183 \\}
184 , ".tmp_source.zig:5:5: error: invalid token: 'var'");
185
186 cases.add("implicit semicolon - if(var)-else-if(var) expression",
187 \\export fn entry() {
188 \\ _ = if(_=foo()) {} else if(_=foo()) {};
189 \\ var good = {};
190 \\ _ = if(_=foo()) {} else if(_=foo()) {}
191 \\ var bad = {};
192 \\}
193 , ".tmp_source.zig:5:5: error: invalid token: 'var'");
194
195 cases.add("implicit semicolon - if(var)-else-if(var)-else statement",
196 \\export fn entry() {
197 \\ if(_=foo()) {} else if(_=foo()) {} else {}
198 \\ var good = {};
199 \\ if(_=foo()) ({}) else if(_=foo()) ({}) else ({})
200 \\ var bad = {};
201 \\}
202 , ".tmp_source.zig:5:5: error: invalid token: 'var'");
203
204 cases.add("implicit semicolon - if(var)-else-if(var)-else expression",
205 \\export fn entry() {
206 \\ _ = if(_=foo()) {} else if(_=foo()) {} else {};
207 \\ var good = {};
208 \\ _ = if(_=foo()) {} else if(_=foo()) {} else {}
209 \\ var bad = {};
210 \\}
211 , ".tmp_source.zig:5:5: error: invalid token: 'var'");
212
213 cases.add("implicit semicolon - try statement",
214 \\export fn entry() {
215 \\ try (_ = foo()) {}
216 \\ var good = {};
217 \\ try (_ = foo()) ({})
218 \\ var bad = {};
219 \\}
220 , ".tmp_source.zig:5:5: error: invalid token: 'var'");
221
222 cases.add("implicit semicolon - try expression",
223 \\export fn entry() {
224 \\ _ = try (_ = foo()) {};
225 \\ var good = {};
226 \\ _ = try (_ = foo()) {}
227 \\ var bad = {};
228 \\}
229 , ".tmp_source.zig:5:5: error: invalid token: 'var'");
230
231 cases.add("implicit semicolon - while statement",
232 \\export fn entry() {
233 \\ while(true) {}
234 \\ var good = {};
235 \\ while(true) ({})
236 \\ var bad = {};
237 \\}
238 , ".tmp_source.zig:5:5: error: invalid token: 'var'");
239
240 cases.add("implicit semicolon - while expression",
241 \\export fn entry() {
242 \\ _ = while(true) {};
243 \\ var good = {};
244 \\ _ = while(true) {}
245 \\ var bad = {};
246 \\}
247 , ".tmp_source.zig:5:5: error: invalid token: 'var'");
248
249 cases.add("implicit semicolon - while-continue statement",
250 \\export fn entry() {
251 \\ while(true;{}) {}
252 \\ var good = {};
253 \\ while(true;{}) ({})
254 \\ var bad = {};
255 \\}
256 , ".tmp_source.zig:5:5: error: invalid token: 'var'");
257
258 cases.add("implicit semicolon - while-continue expression",
259 \\export fn entry() {
260 \\ _ = while(true;{}) {};
261 \\ var good = {};
262 \\ _ = while(true;{}) {}
263 \\ var bad = {};
264 \\}
265 , ".tmp_source.zig:5:5: error: invalid token: 'var'");
266
267 cases.add("implicit semicolon - for statement",
268 \\export fn entry() {
269 \\ for(foo()) {}
270 \\ var good = {};
271 \\ for(foo()) ({})
272 \\ var bad = {};
273 \\}
274 , ".tmp_source.zig:5:5: error: invalid token: 'var'");
275
276 cases.add("implicit semicolon - for expression",
277 \\export fn entry() {
278 \\ _ = for(foo()) {};
279 \\ var good = {};
280 \\ _ = for(foo()) {}
281 \\ var bad = {};
282 \\}
283 , ".tmp_source.zig:5:5: error: invalid token: 'var'");
284
285 cases.add("multiple function definitions",
286 \\fn a() {}
287 \\fn a() {}
288 \\export fn entry() { a(); }
289 , ".tmp_source.zig:2:1: error: redefinition of 'a'");
290
291 cases.add("unreachable with return",
292 \\fn a() -> noreturn {return;}
293 \\export fn entry() { a(); }
294 , ".tmp_source.zig:1:21: error: expected type 'noreturn', found 'void'");
295
296 cases.add("control reaches end of non-void function",
297 \\fn a() -> i32 {}
298 \\export fn entry() { _ = a(); }
299 , ".tmp_source.zig:1:15: error: expected type 'i32', found 'void'");
300
301 cases.add("undefined function call",
302 \\export fn a() {
303 \\ b();
304 \\}
305 , ".tmp_source.zig:2:5: error: use of undeclared identifier 'b'");
306
307 cases.add("wrong number of arguments",
308 \\export fn a() {
309 \\ b(1);
310 \\}
311 \\fn b(a: i32, b: i32, c: i32) { }
312 , ".tmp_source.zig:2:6: error: expected 3 arguments, found 1");
313
314 cases.add("invalid type",
315 \\fn a() -> bogus {}
316 \\export fn entry() { _ = a(); }
317 , ".tmp_source.zig:1:11: error: use of undeclared identifier 'bogus'");
318
319 cases.add("pointer to unreachable",
320 \\fn a() -> &noreturn {}
321 \\export fn entry() { _ = a(); }
322 , ".tmp_source.zig:1:12: error: pointer to unreachable not allowed");
323
324 cases.add("unreachable code",
325 \\export fn a() {
326 \\ return;
327 \\ b();
328 \\}
329 \\
330 \\fn b() {}
331 , ".tmp_source.zig:3:6: error: unreachable code");
332
333 cases.add("bad import",
334 \\const bogus = @import("bogus-does-not-exist.zig");
335 \\export fn entry() { bogus.bogo(); }
336 , ".tmp_source.zig:1:15: error: unable to find 'bogus-does-not-exist.zig'");
337
338 cases.add("undeclared identifier",
339 \\export fn a() {
340 \\ b +
341 \\ c
342 \\}
343 ,
344 ".tmp_source.zig:2:5: error: use of undeclared identifier 'b'",
345 ".tmp_source.zig:3:5: error: use of undeclared identifier 'c'");
346
347 cases.add("parameter redeclaration",
348 \\fn f(a : i32, a : i32) {
349 \\}
350 \\export fn entry() { f(1, 2); }
351 , ".tmp_source.zig:1:15: error: redeclaration of variable 'a'");
352
353 cases.add("local variable redeclaration",
354 \\export fn f() {
355 \\ const a : i32 = 0;
356 \\ const a = 0;
357 \\}
358 , ".tmp_source.zig:3:5: error: redeclaration of variable 'a'");
359
360 cases.add("local variable redeclares parameter",
361 \\fn f(a : i32) {
362 \\ const a = 0;
363 \\}
364 \\export fn entry() { f(1); }
365 , ".tmp_source.zig:2:5: error: redeclaration of variable 'a'");
366
367 cases.add("variable has wrong type",
368 \\export fn f() -> i32 {
369 \\ const a = c"a";
370 \\ a
371 \\}
372 , ".tmp_source.zig:3:5: error: expected type 'i32', found '&const u8'");
373
374 cases.add("if condition is bool, not int",
375 \\export fn f() {
376 \\ if (0) {}
377 \\}
378 , ".tmp_source.zig:2:9: error: integer value 0 cannot be implicitly casted to type 'bool'");
379
380 cases.add("assign unreachable",
381 \\export fn f() {
382 \\ const a = return;
383 \\}
384 , ".tmp_source.zig:2:5: error: unreachable code");
385
386 cases.add("unreachable variable",
387 \\export fn f() {
388 \\ const a: noreturn = {};
389 \\}
390 , ".tmp_source.zig:2:14: error: variable of type 'noreturn' not allowed");
391
392 cases.add("unreachable parameter",
393 \\fn f(a: noreturn) {}
394 \\export fn entry() { f(); }
395 , ".tmp_source.zig:1:9: error: parameter of type 'noreturn' not allowed");
396
397 cases.add("bad assignment target",
398 \\export fn f() {
399 \\ 3 = 3;
400 \\}
401 , ".tmp_source.zig:2:7: error: cannot assign to constant");
402
403 cases.add("assign to constant variable",
404 \\export fn f() {
405 \\ const a = 3;
406 \\ a = 4;
407 \\}
408 , ".tmp_source.zig:3:7: error: cannot assign to constant");
409
410 cases.add("use of undeclared identifier",
411 \\export fn f() {
412 \\ b = 3;
413 \\}
414 , ".tmp_source.zig:2:5: error: use of undeclared identifier 'b'");
415
416 cases.add("const is a statement, not an expression",
417 \\export fn f() {
418 \\ (const a = 0);
419 \\}
420 , ".tmp_source.zig:2:6: error: invalid token: 'const'");
421
422 cases.add("array access of undeclared identifier",
423 \\export fn f() {
424 \\ i[i] = i[i];
425 \\}
426 , ".tmp_source.zig:2:5: error: use of undeclared identifier 'i'",
427 ".tmp_source.zig:2:12: error: use of undeclared identifier 'i'");
428
429 cases.add("array access of non array",
430 \\export fn f() {
431 \\ var bad : bool = undefined;
432 \\ bad[bad] = bad[bad];
433 \\}
434 , ".tmp_source.zig:3:8: error: array access of non-array type 'bool'",
435 ".tmp_source.zig:3:19: error: array access of non-array type 'bool'");
436
437 cases.add("array access with non integer index",
438 \\export fn f() {
439 \\ var array = "aoeu";
440 \\ var bad = false;
441 \\ array[bad] = array[bad];
442 \\}
443 , ".tmp_source.zig:4:11: error: expected type 'usize', found 'bool'",
444 ".tmp_source.zig:4:24: error: expected type 'usize', found 'bool'");
445
446 cases.add("write to const global variable",
447 \\const x : i32 = 99;
448 \\fn f() {
449 \\ x = 1;
450 \\}
451 \\export fn entry() { f(); }
452 , ".tmp_source.zig:3:7: error: cannot assign to constant");
453
454
455 cases.add("missing else clause",
456 \\fn f(b: bool) {
457 \\ const x : i32 = if (b) { 1 };
458 \\ const y = if (b) { i32(1) };
459 \\}
460 \\export fn entry() { f(true); }
461 , ".tmp_source.zig:2:30: error: integer value 1 cannot be implicitly casted to type 'void'",
462 ".tmp_source.zig:3:15: error: incompatible types: 'i32' and 'void'");
463
464 cases.add("direct struct loop",
465 \\const A = struct { a : A, };
466 \\export fn entry() -> usize { @sizeOf(A) }
467 , ".tmp_source.zig:1:11: error: struct 'A' contains itself");
468
469 cases.add("indirect struct loop",
470 \\const A = struct { b : B, };
471 \\const B = struct { c : C, };
472 \\const C = struct { a : A, };
473 \\export fn entry() -> usize { @sizeOf(A) }
474 , ".tmp_source.zig:1:11: error: struct 'A' contains itself");
475
476 cases.add("invalid struct field",
477 \\const A = struct { x : i32, };
478 \\export fn f() {
479 \\ var a : A = undefined;
480 \\ a.foo = 1;
481 \\ const y = a.bar;
482 \\}
483 ,
484 ".tmp_source.zig:4:6: error: no member named 'foo' in 'A'",
485 ".tmp_source.zig:5:16: error: no member named 'bar' in 'A'");
486
487 cases.add("redefinition of struct",
488 \\const A = struct { x : i32, };
489 \\const A = struct { y : i32, };
490 , ".tmp_source.zig:2:1: error: redefinition of 'A'");
491
492 cases.add("redefinition of enums",
493 \\const A = enum {};
494 \\const A = enum {};
495 , ".tmp_source.zig:2:1: error: redefinition of 'A'");
496
497 cases.add("redefinition of global variables",
498 \\var a : i32 = 1;
499 \\var a : i32 = 2;
500 ,
501 ".tmp_source.zig:2:1: error: redefinition of 'a'",
502 ".tmp_source.zig:1:1: note: previous definition is here");
503
504 cases.add("byvalue struct parameter in exported function",
505 \\const A = struct { x : i32, };
506 \\export fn f(a : A) {}
507 , ".tmp_source.zig:2:13: error: byvalue types not yet supported on extern function parameters");
508
509 cases.add("byvalue struct return value in exported function",
510 \\const A = struct { x: i32, };
511 \\export fn f() -> A {
512 \\ A {.x = 1234 }
513 \\}
514 , ".tmp_source.zig:2:18: error: byvalue types not yet supported on extern function return values");
515
516 cases.add("duplicate field in struct value expression",
517 \\const A = struct {
518 \\ x : i32,
519 \\ y : i32,
520 \\ z : i32,
521 \\};
522 \\export fn f() {
523 \\ const a = A {
524 \\ .z = 1,
525 \\ .y = 2,
526 \\ .x = 3,
527 \\ .z = 4,
528 \\ };
529 \\}
530 , ".tmp_source.zig:11:9: error: duplicate field");
531
532 cases.add("missing field in struct value expression",
533 \\const A = struct {
534 \\ x : i32,
535 \\ y : i32,
536 \\ z : i32,
537 \\};
538 \\export fn f() {
539 \\ // we want the error on the '{' not the 'A' because
540 \\ // the A could be a complicated expression
541 \\ const a = A {
542 \\ .z = 4,
543 \\ .y = 2,
544 \\ };
545 \\}
546 , ".tmp_source.zig:9:17: error: missing field: 'x'");
547
548 cases.add("invalid field in struct value expression",
549 \\const A = struct {
550 \\ x : i32,
551 \\ y : i32,
552 \\ z : i32,
553 \\};
554 \\export fn f() {
555 \\ const a = A {
556 \\ .z = 4,
557 \\ .y = 2,
558 \\ .foo = 42,
559 \\ };
560 \\}
561 , ".tmp_source.zig:10:9: error: no member named 'foo' in 'A'");
562
563 cases.add("invalid break expression",
564 \\export fn f() {
565 \\ break;
566 \\}
567 , ".tmp_source.zig:2:5: error: 'break' expression outside loop");
568
569 cases.add("invalid continue expression",
570 \\export fn f() {
571 \\ continue;
572 \\}
573 , ".tmp_source.zig:2:5: error: 'continue' expression outside loop");
574
575 cases.add("invalid maybe type",
576 \\export fn f() {
577 \\ if (const x ?= true) { }
578 \\}
579 , ".tmp_source.zig:2:20: error: expected nullable type, found 'bool'");
580
581 cases.add("cast unreachable",
582 \\fn f() -> i32 {
583 \\ i32(return 1)
584 \\}
585 \\export fn entry() { _ = f(); }
586 , ".tmp_source.zig:2:8: error: unreachable code");
587
588 cases.add("invalid builtin fn",
589 \\fn f() -> @bogus(foo) {
590 \\}
591 \\export fn entry() { _ = f(); }
592 , ".tmp_source.zig:1:11: error: invalid builtin function: 'bogus'");
593
594 cases.add("top level decl dependency loop",
595 \\const a : @typeOf(b) = 0;
596 \\const b : @typeOf(a) = 0;
597 \\export fn entry() {
598 \\ const c = a + b;
599 \\}
600 , ".tmp_source.zig:1:1: error: 'a' depends on itself");
601
602 cases.add("noalias on non pointer param",
603 \\fn f(noalias x: i32) {}
604 \\export fn entry() { f(1234); }
605 , ".tmp_source.zig:1:6: error: noalias on non-pointer parameter");
606
607 cases.add("struct init syntax for array",
608 \\const foo = []u16{.x = 1024,};
609 \\export fn entry() -> usize { @sizeOf(@typeOf(foo)) }
610 , ".tmp_source.zig:1:18: error: type '[]u16' does not support struct initialization syntax");
611
612 cases.add("type variables must be constant",
613 \\var foo = u8;
614 \\export fn entry() -> foo {
615 \\ return 1;
616 \\}
617 , ".tmp_source.zig:1:1: error: variable of type 'type' must be constant");
618
619
620 cases.add("variables shadowing types",
621 \\const Foo = struct {};
622 \\const Bar = struct {};
623 \\
624 \\fn f(Foo: i32) {
625 \\ var Bar : i32 = undefined;
626 \\}
627 \\
628 \\export fn entry() {
629 \\ f(1234);
630 \\}
631 ,
632 ".tmp_source.zig:4:6: error: redefinition of 'Foo'",
633 ".tmp_source.zig:1:1: note: previous definition is here",
634 ".tmp_source.zig:5:5: error: redefinition of 'Bar'",
635 ".tmp_source.zig:2:1: note: previous definition is here");
636
637 cases.add("multiple else prongs in a switch",
638 \\fn f(x: u32) {
639 \\ const value: bool = switch (x) {
640 \\ 1234 => false,
641 \\ else => true,
642 \\ else => true,
643 \\ };
644 \\}
645 \\export fn entry() {
646 \\ f(1234);
647 \\}
648 , ".tmp_source.zig:5:9: error: multiple else prongs in switch expression");
649
650 cases.add("global variable initializer must be constant expression",
651 \\extern fn foo() -> i32;
652 \\const x = foo();
653 \\export fn entry() -> i32 { x }
654 , ".tmp_source.zig:2:11: error: unable to evaluate constant expression");
655
656 cases.add("array concatenation with wrong type",
657 \\const src = "aoeu";
658 \\const derp = usize(1234);
659 \\const a = derp ++ "foo";
660 \\
661 \\export fn entry() -> usize { @sizeOf(@typeOf(a)) }
662 , ".tmp_source.zig:3:11: error: expected array or C string literal, found 'usize'");
663
664 cases.add("non compile time array concatenation",
665 \\fn f() -> []u8 {
666 \\ s ++ "foo"
667 \\}
668 \\var s: [10]u8 = undefined;
669 \\export fn entry() -> usize { @sizeOf(@typeOf(f)) }
670 , ".tmp_source.zig:2:5: error: unable to evaluate constant expression");
671
672 cases.add("@cImport with bogus include",
673 \\const c = @cImport(@cInclude("bogus.h"));
674 \\export fn entry() -> usize { @sizeOf(@typeOf(c.bogo)) }
675 , ".tmp_source.zig:1:11: error: C import failed",
676 ".h:1:10: note: 'bogus.h' file not found");
677
678 cases.add("address of number literal",
679 \\const x = 3;
680 \\const y = &x;
681 \\fn foo() -> &const i32 { y }
682 \\export fn entry() -> usize { @sizeOf(@typeOf(foo)) }
683 , ".tmp_source.zig:3:26: error: expected type '&const i32', found '&const (integer literal)'");
684
685 cases.add("integer overflow error",
686 \\const x : u8 = 300;
687 \\export fn entry() -> usize { @sizeOf(@typeOf(x)) }
688 , ".tmp_source.zig:1:16: error: integer value 300 cannot be implicitly casted to type 'u8'");
689
690 cases.add("incompatible number literals",
691 \\const x = 2 == 2.0;
692 \\export fn entry() -> usize { @sizeOf(@typeOf(x)) }
693 , ".tmp_source.zig:1:11: error: integer value 2 cannot be implicitly casted to type '(float literal)'");
694
695 cases.add("missing function call param",
696 \\const Foo = struct {
697 \\ a: i32,
698 \\ b: i32,
699 \\
700 \\ fn member_a(foo: &const Foo) -> i32 {
701 \\ return foo.a;
702 \\ }
703 \\ fn member_b(foo: &const Foo) -> i32 {
704 \\ return foo.b;
705 \\ }
706 \\};
707 \\
708 \\const member_fn_type = @typeOf(Foo.member_a);
709 \\const members = []member_fn_type {
710 \\ Foo.member_a,
711 \\ Foo.member_b,
712 \\};
713 \\
714 \\fn f(foo: &const Foo, index: usize) {
715 \\ const result = members[index]();
716 \\}
717 \\
718 \\export fn entry() -> usize { @sizeOf(@typeOf(f)) }
719 , ".tmp_source.zig:20:34: error: expected 1 arguments, found 0");
720
721 cases.add("missing function name and param name",
722 \\fn () {}
723 \\fn f(i32) {}
724 \\export fn entry() -> usize { @sizeOf(@typeOf(f)) }
725 ,
726 ".tmp_source.zig:1:1: error: missing function name",
727 ".tmp_source.zig:2:6: error: missing parameter name");
728
729 cases.add("wrong function type",
730 \\const fns = []fn(){ a, b, c };
731 \\fn a() -> i32 {0}
732 \\fn b() -> i32 {1}
733 \\fn c() -> i32 {2}
734 \\export fn entry() -> usize { @sizeOf(@typeOf(fns)) }
735 , ".tmp_source.zig:1:21: error: expected type 'fn()', found 'fn() -> i32'");
736
737 cases.add("extern function pointer mismatch",
738 \\const fns = [](fn(i32)->i32){ a, b, c };
739 \\pub fn a(x: i32) -> i32 {x + 0}
740 \\pub fn b(x: i32) -> i32 {x + 1}
741 \\export fn c(x: i32) -> i32 {x + 2}
742 \\
743 \\export fn entry() -> usize { @sizeOf(@typeOf(fns)) }
744 , ".tmp_source.zig:1:37: error: expected type 'fn(i32) -> i32', found 'extern fn(i32) -> i32'");
745
746
747 cases.add("implicit cast from f64 to f32",
748 \\const x : f64 = 1.0;
749 \\const y : f32 = x;
750 \\
751 \\export fn entry() -> usize { @sizeOf(@typeOf(y)) }
752 , ".tmp_source.zig:2:17: error: expected type 'f32', found 'f64'");
753
754
755 cases.add("colliding invalid top level functions",
756 \\fn func() -> bogus {}
757 \\fn func() -> bogus {}
758 \\export fn entry() -> usize { @sizeOf(@typeOf(func)) }
759 ,
760 ".tmp_source.zig:2:1: error: redefinition of 'func'",
761 ".tmp_source.zig:1:14: error: use of undeclared identifier 'bogus'");
762
763
764 cases.add("bogus compile var",
765 \\const x = @compileVar("bogus");
766 \\export fn entry() -> usize { @sizeOf(@typeOf(x)) }
767 , ".tmp_source.zig:1:23: error: unrecognized compile variable: 'bogus'");
768
769
770 cases.add("non constant expression in array size outside function",
771 \\const Foo = struct {
772 \\ y: [get()]u8,
773 \\};
774 \\var global_var: usize = 1;
775 \\fn get() -> usize { global_var }
776 \\
777 \\export fn entry() -> usize { @sizeOf(@typeOf(Foo)) }
778 ,
779 ".tmp_source.zig:5:21: error: unable to evaluate constant expression",
780 ".tmp_source.zig:2:12: note: called from here",
781 ".tmp_source.zig:2:8: note: called from here");
782
783
784 cases.add("addition with non numbers",
785 \\const Foo = struct {
786 \\ field: i32,
787 \\};
788 \\const x = Foo {.field = 1} + Foo {.field = 2};
789 \\
790 \\export fn entry() -> usize { @sizeOf(@typeOf(x)) }
791 , ".tmp_source.zig:4:28: error: invalid operands to binary expression: 'Foo' and 'Foo'");
792
793
794 cases.add("division by zero",
795 \\const lit_int_x = 1 / 0;
796 \\const lit_float_x = 1.0 / 0.0;
797 \\const int_x = i32(1) / i32(0);
798 \\const float_x = f32(1.0) / f32(0.0);
799 \\
800 \\export fn entry1() -> usize { @sizeOf(@typeOf(lit_int_x)) }
801 \\export fn entry2() -> usize { @sizeOf(@typeOf(lit_float_x)) }
802 \\export fn entry3() -> usize { @sizeOf(@typeOf(int_x)) }
803 \\export fn entry4() -> usize { @sizeOf(@typeOf(float_x)) }
804 ,
805 ".tmp_source.zig:1:21: error: division by zero is undefined",
806 ".tmp_source.zig:2:25: error: division by zero is undefined",
807 ".tmp_source.zig:3:22: error: division by zero is undefined",
808 ".tmp_source.zig:4:26: error: division by zero is undefined");
809
810
811 cases.add("missing switch prong",
812 \\const Number = enum {
813 \\ One,
814 \\ Two,
815 \\ Three,
816 \\ Four,
817 \\};
818 \\fn f(n: Number) -> i32 {
819 \\ switch (n) {
820 \\ Number.One => 1,
821 \\ Number.Two => 2,
822 \\ Number.Three => i32(3),
823 \\ }
824 \\}
825 \\
826 \\export fn entry() -> usize { @sizeOf(@typeOf(f)) }
827 , ".tmp_source.zig:8:5: error: enumeration value 'Number.Four' not handled in switch");
828
829 cases.add("normal string with newline",
830 \\const foo = "a
831 \\b";
832 \\
833 \\export fn entry() -> usize { @sizeOf(@typeOf(foo)) }
834 , ".tmp_source.zig:1:13: error: newline not allowed in string literal");
835
836 cases.add("invalid comparison for function pointers",
837 \\fn foo() {}
838 \\const invalid = foo > foo;
839 \\
840 \\export fn entry() -> usize { @sizeOf(@typeOf(invalid)) }
841 , ".tmp_source.zig:2:21: error: operator not allowed for type 'fn()'");
842
843 cases.add("generic function instance with non-constant expression",
844 \\fn foo(comptime x: i32, y: i32) -> i32 { return x + y; }
845 \\fn test1(a: i32, b: i32) -> i32 {
846 \\ return foo(a, b);
847 \\}
848 \\
849 \\export fn entry() -> usize { @sizeOf(@typeOf(test1)) }
850 , ".tmp_source.zig:3:16: error: unable to evaluate constant expression");
851
852 cases.add("goto jumping into block",
853 \\export fn f() {
854 \\ {
855 \\a_label:
856 \\ }
857 \\ goto a_label;
858 \\}
859 , ".tmp_source.zig:5:5: error: no label in scope named 'a_label'");
860
861 cases.add("goto jumping past a defer",
862 \\fn f(b: bool) {
863 \\ if (b) goto label;
864 \\ defer derp();
865 \\label:
866 \\}
867 \\fn derp(){}
868 \\
869 \\export fn entry() -> usize { @sizeOf(@typeOf(f)) }
870 , ".tmp_source.zig:2:12: error: no label in scope named 'label'");
871
872 cases.add("assign null to non-nullable pointer",
873 \\const a: &u8 = null;
874 \\
875 \\export fn entry() -> usize { @sizeOf(@typeOf(a)) }
876 , ".tmp_source.zig:1:16: error: expected type '&u8', found '(null)'");
877
878 cases.add("indexing an array of size zero",
879 \\const array = []u8{};
880 \\export fn foo() {
881 \\ const pointer = &array[0];
882 \\}
883 , ".tmp_source.zig:3:27: error: index 0 outside array of size 0");
884
885 cases.add("compile time division by zero",
886 \\const y = foo(0);
887 \\fn foo(x: i32) -> i32 {
888 \\ 1 / x
889 \\}
890 \\
891 \\export fn entry() -> usize { @sizeOf(@typeOf(y)) }
892 ,
893 ".tmp_source.zig:3:7: error: division by zero is undefined",
894 ".tmp_source.zig:1:14: note: called from here");
895
896 cases.add("branch on undefined value",
897 \\const x = if (undefined) true else false;
898 \\
899 \\export fn entry() -> usize { @sizeOf(@typeOf(x)) }
900 , ".tmp_source.zig:1:15: error: use of undefined value");
901
902
903 cases.add("endless loop in function evaluation",
904 \\const seventh_fib_number = fibbonaci(7);
905 \\fn fibbonaci(x: i32) -> i32 {
906 \\ return fibbonaci(x - 1) + fibbonaci(x - 2);
907 \\}
908 \\
909 \\export fn entry() -> usize { @sizeOf(@typeOf(seventh_fib_number)) }
910 ,
911 ".tmp_source.zig:3:21: error: evaluation exceeded 1000 backwards branches",
912 ".tmp_source.zig:3:21: note: called from here");
913
914 cases.add("@embedFile with bogus file",
915 \\const resource = @embedFile("bogus.txt");
916 \\
917 \\export fn entry() -> usize { @sizeOf(@typeOf(resource)) }
918 , ".tmp_source.zig:1:29: error: unable to find '", "/bogus.txt'");
919
920 cases.add("non-const expression in struct literal outside function",
921 \\const Foo = struct {
922 \\ x: i32,
923 \\};
924 \\const a = Foo {.x = get_it()};
925 \\extern fn get_it() -> i32;
926 \\
927 \\export fn entry() -> usize { @sizeOf(@typeOf(a)) }
928 , ".tmp_source.zig:4:21: error: unable to evaluate constant expression");
929
930 cases.add("non-const expression function call with struct return value outside function",
931 \\const Foo = struct {
932 \\ x: i32,
933 \\};
934 \\const a = get_it();
935 \\fn get_it() -> Foo {
936 \\ global_side_effect = true;
937 \\ Foo {.x = 13}
938 \\}
939 \\var global_side_effect = false;
940 \\
941 \\export fn entry() -> usize { @sizeOf(@typeOf(a)) }
942 ,
943 ".tmp_source.zig:6:24: error: unable to evaluate constant expression",
944 ".tmp_source.zig:4:17: note: called from here");
945
946 cases.add("undeclared identifier error should mark fn as impure",
947 \\export fn foo() {
948 \\ test_a_thing();
949 \\}
950 \\fn test_a_thing() {
951 \\ bad_fn_call();
952 \\}
953 , ".tmp_source.zig:5:5: error: use of undeclared identifier 'bad_fn_call'");
954
955 cases.add("illegal comparison of types",
956 \\fn bad_eql_1(a: []u8, b: []u8) -> bool {
957 \\ a == b
958 \\}
959 \\const EnumWithData = enum {
960 \\ One,
961 \\ Two: i32,
962 \\};
963 \\fn bad_eql_2(a: &const EnumWithData, b: &const EnumWithData) -> bool {
964 \\ *a == *b
965 \\}
966 \\
967 \\export fn entry1() -> usize { @sizeOf(@typeOf(bad_eql_1)) }
968 \\export fn entry2() -> usize { @sizeOf(@typeOf(bad_eql_2)) }
969 ,
970 ".tmp_source.zig:2:7: error: operator not allowed for type '[]u8'",
971 ".tmp_source.zig:9:8: error: operator not allowed for type 'EnumWithData'");
972
973 cases.add("non-const switch number literal",
974 \\export fn foo() {
975 \\ const x = switch (bar()) {
976 \\ 1, 2 => 1,
977 \\ 3, 4 => 2,
978 \\ else => 3,
979 \\ };
980 \\}
981 \\fn bar() -> i32 {
982 \\ 2
983 \\}
984 , ".tmp_source.zig:2:15: error: unable to infer expression type");
985
986 cases.add("atomic orderings of cmpxchg - failure stricter than success",
987 \\export fn f() {
988 \\ var x: i32 = 1234;
989 \\ while (!@cmpxchg(&x, 1234, 5678, AtomicOrder.Monotonic, AtomicOrder.SeqCst)) {}
990 \\}
991 , ".tmp_source.zig:3:72: error: failure atomic ordering must be no stricter than success");
992
993 cases.add("atomic orderings of cmpxchg - success Monotonic or stricter",
994 \\export fn f() {
995 \\ var x: i32 = 1234;
996 \\ while (!@cmpxchg(&x, 1234, 5678, AtomicOrder.Unordered, AtomicOrder.Unordered)) {}
997 \\}
998 , ".tmp_source.zig:3:49: error: success atomic ordering must be Monotonic or stricter");
999
1000 cases.add("negation overflow in function evaluation",
1001 \\const y = neg(-128);
1002 \\fn neg(x: i8) -> i8 {
1003 \\ -x
1004 \\}
1005 \\
1006 \\export fn entry() -> usize { @sizeOf(@typeOf(y)) }
1007 ,
1008 ".tmp_source.zig:3:5: error: negation caused overflow",
1009 ".tmp_source.zig:1:14: note: called from here");
1010
1011 cases.add("add overflow in function evaluation",
1012 \\const y = add(65530, 10);
1013 \\fn add(a: u16, b: u16) -> u16 {
1014 \\ a + b
1015 \\}
1016 \\
1017 \\export fn entry() -> usize { @sizeOf(@typeOf(y)) }
1018 ,
1019 ".tmp_source.zig:3:7: error: operation caused overflow",
1020 ".tmp_source.zig:1:14: note: called from here");
1021
1022
1023 cases.add("sub overflow in function evaluation",
1024 \\const y = sub(10, 20);
1025 \\fn sub(a: u16, b: u16) -> u16 {
1026 \\ a - b
1027 \\}
1028 \\
1029 \\export fn entry() -> usize { @sizeOf(@typeOf(y)) }
1030 ,
1031 ".tmp_source.zig:3:7: error: operation caused overflow",
1032 ".tmp_source.zig:1:14: note: called from here");
1033
1034 cases.add("mul overflow in function evaluation",
1035 \\const y = mul(300, 6000);
1036 \\fn mul(a: u16, b: u16) -> u16 {
1037 \\ a * b
1038 \\}
1039 \\
1040 \\export fn entry() -> usize { @sizeOf(@typeOf(y)) }
1041 ,
1042 ".tmp_source.zig:3:7: error: operation caused overflow",
1043 ".tmp_source.zig:1:14: note: called from here");
1044
1045 cases.add("truncate sign mismatch",
1046 \\fn f() -> i8 {
1047 \\ const x: u32 = 10;
1048 \\ @truncate(i8, x)
1049 \\}
1050 \\
1051 \\export fn entry() -> usize { @sizeOf(@typeOf(f)) }
1052 , ".tmp_source.zig:3:19: error: expected signed integer type, found 'u32'");
1053
1054 cases.add("%return in function with non error return type",
1055 \\export fn f() {
1056 \\ %return something();
1057 \\}
1058 \\fn something() -> %void { }
1059 ,
1060 ".tmp_source.zig:2:5: error: expected type 'void', found 'error'");
1061
1062 cases.add("wrong return type for main",
1063 \\pub fn main() { }
1064 , ".tmp_source.zig:1:15: error: expected return type of main to be '%void', instead is 'void'");
1065
1066 cases.add("double ?? on main return value",
1067 \\pub fn main() -> ??void {
1068 \\}
1069 , ".tmp_source.zig:1:18: error: expected return type of main to be '%void', instead is '??void'");
1070
1071 cases.add("invalid pointer for var type",
1072 \\extern fn ext() -> usize;
1073 \\var bytes: [ext()]u8 = undefined;
1074 \\export fn f() {
1075 \\ for (bytes) |*b, i| {
1076 \\ *b = u8(i);
1077 \\ }
1078 \\}
1079 , ".tmp_source.zig:2:13: error: unable to evaluate constant expression");
1080
1081 cases.add("export function with comptime parameter",
1082 \\export fn foo(comptime x: i32, y: i32) -> i32{
1083 \\ x + y
1084 \\}
1085 , ".tmp_source.zig:1:15: error: comptime parameter not allowed in extern function");
1086
1087 cases.add("extern function with comptime parameter",
1088 \\extern fn foo(comptime x: i32, y: i32) -> i32;
1089 \\fn f() -> i32 {
1090 \\ foo(1, 2)
1091 \\}
1092 \\export fn entry() -> usize { @sizeOf(@typeOf(f)) }
1093 , ".tmp_source.zig:1:15: error: comptime parameter not allowed in extern function");
1094
1095 cases.add("convert fixed size array to slice with invalid size",
1096 \\export fn f() {
1097 \\ var array: [5]u8 = undefined;
1098 \\ var foo = ([]const u32)(array)[0];
1099 \\}
1100 , ".tmp_source.zig:3:28: error: unable to convert [5]u8 to []const u32: size mismatch");
1101
1102 cases.add("non-pure function returns type",
1103 \\var a: u32 = 0;
1104 \\pub fn List(comptime T: type) -> type {
1105 \\ a += 1;
1106 \\ SmallList(T, 8)
1107 \\}
1108 \\
1109 \\pub fn SmallList(comptime T: type, comptime STATIC_SIZE: usize) -> type {
1110 \\ struct {
1111 \\ items: []T,
1112 \\ length: usize,
1113 \\ prealloc_items: [STATIC_SIZE]T,
1114 \\ }
1115 \\}
1116 \\
1117 \\export fn function_with_return_type_type() {
1118 \\ var list: List(i32) = undefined;
1119 \\ list.length = 10;
1120 \\}
1121 , ".tmp_source.zig:3:7: error: unable to evaluate constant expression",
1122 ".tmp_source.zig:16:19: note: called from here");
1123
1124 cases.add("bogus method call on slice",
1125 \\var self = "aoeu";
1126 \\fn f(m: []const u8) {
1127 \\ m.copy(u8, self[0...], m);
1128 \\}
1129 \\export fn entry() -> usize { @sizeOf(@typeOf(f)) }
1130 , ".tmp_source.zig:3:6: error: no member named 'copy' in '[]const u8'");
1131
1132 cases.add("wrong number of arguments for method fn call",
1133 \\const Foo = struct {
1134 \\ fn method(self: &const Foo, a: i32) {}
1135 \\};
1136 \\fn f(foo: &const Foo) {
1137 \\
1138 \\ foo.method(1, 2);
1139 \\}
1140 \\export fn entry() -> usize { @sizeOf(@typeOf(f)) }
1141 , ".tmp_source.zig:6:15: error: expected 2 arguments, found 3");
1142
1143 cases.add("assign through constant pointer",
1144 \\export fn f() {
1145 \\ var cstr = c"Hat";
1146 \\ cstr[0] = 'W';
1147 \\}
1148 , ".tmp_source.zig:3:11: error: cannot assign to constant");
1149
1150 cases.add("assign through constant slice",
1151 \\export fn f() {
1152 \\ var cstr: []const u8 = "Hat";
1153 \\ cstr[0] = 'W';
1154 \\}
1155 , ".tmp_source.zig:3:11: error: cannot assign to constant");
1156
1157 cases.add("main function with bogus args type",
1158 \\pub fn main(args: [][]bogus) -> %void {}
1159 , ".tmp_source.zig:1:23: error: use of undeclared identifier 'bogus'");
1160
1161 cases.add("for loop missing element param",
1162 \\fn foo(blah: []u8) {
1163 \\ for (blah) { }
1164 \\}
1165 \\export fn entry() -> usize { @sizeOf(@typeOf(foo)) }
1166 , ".tmp_source.zig:2:5: error: for loop expression missing element parameter");
1167
1168 cases.add("misspelled type with pointer only reference",
1169 \\const JasonHM = u8;
1170 \\const JasonList = &JsonNode;
1171 \\
1172 \\const JsonOA = enum {
1173 \\ JSONArray: JsonList,
1174 \\ JSONObject: JasonHM,
1175 \\};
1176 \\
1177 \\const JsonType = enum {
1178 \\ JSONNull: void,
1179 \\ JSONInteger: isize,
1180 \\ JSONDouble: f64,
1181 \\ JSONBool: bool,
1182 \\ JSONString: []u8,
1183 \\ JSONArray,
1184 \\ JSONObject,
1185 \\};
1186 \\
1187 \\pub const JsonNode = struct {
1188 \\ kind: JsonType,
1189 \\ jobject: ?JsonOA,
1190 \\};
1191 \\
1192 \\fn foo() {
1193 \\ var jll: JasonList = undefined;
1194 \\ jll.init(1234);
1195 \\ var jd = JsonNode {.kind = JsonType.JSONArray , .jobject = JsonOA.JSONArray {jll} };
1196 \\}
1197 \\
1198 \\export fn entry() -> usize { @sizeOf(@typeOf(foo)) }
1199 , ".tmp_source.zig:5:16: error: use of undeclared identifier 'JsonList'");
1200
1201 cases.add("method call with first arg type primitive",
1202 \\const Foo = struct {
1203 \\ x: i32,
1204 \\
1205 \\ fn init(x: i32) -> Foo {
1206 \\ Foo {
1207 \\ .x = x,
1208 \\ }
1209 \\ }
1210 \\};
1211 \\
1212 \\export fn f() {
1213 \\ const derp = Foo.init(3);
1214 \\
1215 \\ derp.init();
1216 \\}
1217 , ".tmp_source.zig:14:5: error: expected type 'i32', found '&const Foo'");
1218
1219 cases.add("method call with first arg type wrong container",
1220 \\pub const List = struct {
1221 \\ len: usize,
1222 \\ allocator: &Allocator,
1223 \\
1224 \\ pub fn init(allocator: &Allocator) -> List {
1225 \\ List {
1226 \\ .len = 0,
1227 \\ .allocator = allocator,
1228 \\ }
1229 \\ }
1230 \\};
1231 \\
1232 \\pub var global_allocator = Allocator {
1233 \\ .field = 1234,
1234 \\};
1235 \\
1236 \\pub const Allocator = struct {
1237 \\ field: i32,
1238 \\};
1239 \\
1240 \\export fn foo() {
1241 \\ var x = List.init(&global_allocator);
1242 \\ x.init();
1243 \\}
1244 , ".tmp_source.zig:23:5: error: expected type '&Allocator', found '&List'");
1245
1246 cases.add("binary not on number literal",
1247 \\const TINY_QUANTUM_SHIFT = 4;
1248 \\const TINY_QUANTUM_SIZE = 1 << TINY_QUANTUM_SHIFT;
1249 \\var block_aligned_stuff: usize = (4 + TINY_QUANTUM_SIZE) & ~(TINY_QUANTUM_SIZE - 1);
1250 \\
1251 \\export fn entry() -> usize { @sizeOf(@typeOf(block_aligned_stuff)) }
1252 , ".tmp_source.zig:3:60: error: unable to perform binary not operation on type '(integer literal)'");
1253
1254 cases.addCase({
1255 const tc = cases.create("multiple files with private function error",
1256 \\const foo = @import("foo.zig");
1257 \\
1258 \\export fn callPrivFunction() {
1259 \\ foo.privateFunction();
1260 \\}
1261 ,
1262 ".tmp_source.zig:4:8: error: 'privateFunction' is private",
1263 "foo.zig:1:1: note: declared here");
1264
1265 tc.addSourceFile("foo.zig",
1266 \\fn privateFunction() { }
1267 );
1268
1269 tc
1270 });
1271
1272 cases.add("container init with non-type",
1273 \\const zero: i32 = 0;
1274 \\const a = zero{1};
1275 \\
1276 \\export fn entry() -> usize { @sizeOf(@typeOf(a)) }
1277 , ".tmp_source.zig:2:11: error: expected type, found 'i32'");
1278
1279 cases.add("assign to constant field",
1280 \\const Foo = struct {
1281 \\ field: i32,
1282 \\};
1283 \\export fn derp() {
1284 \\ const f = Foo {.field = 1234,};
1285 \\ f.field = 0;
1286 \\}
1287 , ".tmp_source.zig:6:13: error: cannot assign to constant");
1288
1289 cases.add("return from defer expression",
1290 \\pub fn testTrickyDefer() -> %void {
1291 \\ defer canFail() %% {};
1292 \\
1293 \\ defer %return canFail();
1294 \\
1295 \\ const a = maybeInt() ?? return;
1296 \\}
1297 \\
1298 \\fn canFail() -> %void { }
1299 \\
1300 \\pub fn maybeInt() -> ?i32 {
1301 \\ return 0;
1302 \\}
1303 \\
1304 \\export fn entry() -> usize { @sizeOf(@typeOf(testTrickyDefer)) }
1305 , ".tmp_source.zig:4:11: error: cannot return from defer expression");
1306
1307 cases.add("attempt to access var args out of bounds",
1308 \\fn add(args: ...) -> i32 {
1309 \\ args[0] + args[1]
1310 \\}
1311 \\
1312 \\fn foo() -> i32 {
1313 \\ add(i32(1234))
1314 \\}
1315 \\
1316 \\export fn entry() -> usize { @sizeOf(@typeOf(foo)) }
1317 ,
1318 ".tmp_source.zig:2:19: error: index 1 outside argument list of size 1",
1319 ".tmp_source.zig:6:8: note: called from here");
1320
1321 cases.add("pass integer literal to var args",
1322 \\fn add(args: ...) -> i32 {
1323 \\ var sum = i32(0);
1324 \\ {comptime var i: usize = 0; inline while (i < args.len; i += 1) {
1325 \\ sum += args[i];
1326 \\ }}
1327 \\ return sum;
1328 \\}
1329 \\
1330 \\fn bar() -> i32 {
1331 \\ add(1, 2, 3, 4)
1332 \\}
1333 \\
1334 \\export fn entry() -> usize { @sizeOf(@typeOf(bar)) }
1335 , ".tmp_source.zig:10:9: error: parameter of type '(integer literal)' requires comptime");
1336
1337 cases.add("assign too big number to u16",
1338 \\export fn foo() {
1339 \\ var vga_mem: u16 = 0xB8000;
1340 \\}
1341 , ".tmp_source.zig:2:24: error: integer value 753664 cannot be implicitly casted to type 'u16'");
1342
1343 cases.add("set global variable alignment to non power of 2",
1344 \\const some_data: [100]u8 = {
1345 \\ @setGlobalAlign(some_data, 3);
1346 \\ undefined
1347 \\};
1348 \\export fn entry() -> usize { @sizeOf(@typeOf(some_data)) }
1349 , ".tmp_source.zig:2:32: error: alignment value must be power of 2");
1350
1351 cases.add("compile log",
1352 \\export fn foo() {
1353 \\ comptime bar(12, "hi");
1354 \\}
1355 \\fn bar(a: i32, b: []const u8) {
1356 \\ @compileLog("begin");
1357 \\ @compileLog("a", a, "b", b);
1358 \\ @compileLog("end");
1359 \\}
1360 ,
1361 ".tmp_source.zig:5:5: error: found compile log statement",
1362 ".tmp_source.zig:2:17: note: called from here",
1363 ".tmp_source.zig:6:5: error: found compile log statement",
1364 ".tmp_source.zig:2:17: note: called from here",
1365 ".tmp_source.zig:7:5: error: found compile log statement",
1366 ".tmp_source.zig:2:17: note: called from here");
1367
1368 cases.add("casting bit offset pointer to regular pointer",
1369 \\const u2 = @IntType(false, 2);
1370 \\const u3 = @IntType(false, 3);
1371 \\
1372 \\const BitField = packed struct {
1373 \\ a: u3,
1374 \\ b: u3,
1375 \\ c: u2,
1376 \\};
1377 \\
1378 \\fn foo(bit_field: &const BitField) -> u3 {
1379 \\ return bar(&bit_field.b);
1380 \\}
1381 \\
1382 \\fn bar(x: &const u3) -> u3 {
1383 \\ return *x;
1384 \\}
1385 \\
1386 \\export fn entry() -> usize { @sizeOf(@typeOf(foo)) }
1387 , ".tmp_source.zig:11:26: error: expected type '&const u3', found '&:3:6 const u3'");
1388
1389 cases.add("referring to a struct that is invalid",
1390 \\const UsbDeviceRequest = struct {
1391 \\ Type: u8,
1392 \\};
1393 \\
1394 \\export fn foo() {
1395 \\ comptime assert(@sizeOf(UsbDeviceRequest) == 0x8);
1396 \\}
1397 \\
1398 \\fn assert(ok: bool) {
1399 \\ if (!ok) unreachable;
1400 \\}
1401 ,
1402 ".tmp_source.zig:10:14: error: unable to evaluate constant expression",
1403 ".tmp_source.zig:6:20: note: called from here");
1404
1405 cases.add("control flow uses comptime var at runtime",
1406 \\export fn foo() {
1407 \\ comptime var i = 0;
1408 \\ while (i < 5; i += 1) {
1409 \\ bar();
1410 \\ }
1411 \\}
1412 \\
1413 \\fn bar() { }
1414 ,
1415 ".tmp_source.zig:3:5: error: control flow attempts to use compile-time variable at runtime",
1416 ".tmp_source.zig:3:21: note: compile-time variable assigned here");
1417
1418 cases.add("ignored return value",
1419 \\export fn foo() {
1420 \\ bar();
1421 \\}
1422 \\fn bar() -> i32 { 0 }
1423 , ".tmp_source.zig:2:8: error: return value ignored");
1424
1425 cases.add("integer literal on a non-comptime var",
1426 \\export fn foo() {
1427 \\ var i = 0;
1428 \\ while (i < 10; i += 1) { }
1429 \\}
1430 , ".tmp_source.zig:2:5: error: unable to infer variable type");
1431
1432 cases.add("undefined literal on a non-comptime var",
1433 \\export fn foo() {
1434 \\ var i = undefined;
1435 \\ i = i32(1);
1436 \\}
1437 , ".tmp_source.zig:2:5: error: unable to infer variable type");
1438
1439 cases.add("dereference an array",
1440 \\var s_buffer: [10]u8 = undefined;
1441 \\pub fn pass(in: []u8) -> []u8 {
1442 \\ var out = &s_buffer;
1443 \\ *out[0] = in[0];
1444 \\ return (*out)[0...1];
1445 \\}
1446 \\
1447 \\export fn entry() -> usize { @sizeOf(@typeOf(pass)) }
1448 , ".tmp_source.zig:4:5: error: attempt to dereference non pointer type '[10]u8'");
1449
1450 cases.add("pass const ptr to mutable ptr fn",
1451 \\fn foo() -> bool {
1452 \\ const a = ([]const u8)("a");
1453 \\ const b = &a;
1454 \\ return ptrEql(b, b);
1455 \\}
1456 \\fn ptrEql(a: &[]const u8, b: &[]const u8) -> bool {
1457 \\ return true;
1458 \\}
1459 \\
1460 \\export fn entry() -> usize { @sizeOf(@typeOf(foo)) }
1461 , ".tmp_source.zig:4:19: error: expected type '&[]const u8', found '&const []const u8'");
1462
1463 cases.addCase({
1464 const tc = cases.create("export collision",
1465 \\const foo = @import("foo.zig");
1466 \\
1467 \\export fn bar() -> usize {
1468 \\ return foo.baz;
1469 \\}
1470 ,
1471 "foo.zig:1:8: error: exported symbol collision: 'bar'",
1472 ".tmp_source.zig:3:8: note: other symbol is here");
1473
1474 tc.addSourceFile("foo.zig",
1475 \\export fn bar() {}
1476 \\pub const baz = 1234;
1477 );
1478
1479 tc
1480 });
1481
1482 cases.add("pass non-copyable type by value to function",
1483 \\const Point = struct { x: i32, y: i32, };
1484 \\fn foo(p: Point) { }
1485 \\export fn entry() -> usize { @sizeOf(@typeOf(foo)) }
1486 , ".tmp_source.zig:2:11: error: type 'Point' is not copyable; cannot pass by value");
1487
1488 cases.add("implicit cast from array to mutable slice",
1489 \\var global_array: [10]i32 = undefined;
1490 \\fn foo(param: []i32) {}
1491 \\export fn entry() {
1492 \\ foo(global_array);
1493 \\}
1494 , ".tmp_source.zig:4:9: error: expected type '[]i32', found '[10]i32'");
1495
1496 cases.add("ptrcast to non-pointer",
1497 \\export fn entry(a: &i32) -> usize {
1498 \\ return @ptrcast(usize, a);
1499 \\}
1500 , ".tmp_source.zig:2:21: error: expected pointer, found 'usize'");
1501
1502 cases.add("too many error values to cast to small integer",
1503 \\error A; error B; error C; error D; error E; error F; error G; error H;
1504 \\const u2 = @IntType(false, 2);
1505 \\fn foo(e: error) -> u2 {
1506 \\ return u2(e);
1507 \\}
1508 \\export fn entry() -> usize { @sizeOf(@typeOf(foo)) }
1509 , ".tmp_source.zig:4:14: error: too many error values to fit in 'u2'");
1510
1511 cases.add("asm at compile time",
1512 \\comptime {
1513 \\ doSomeAsm();
1514 \\}
1515 \\
1516 \\fn doSomeAsm() {
1517 \\ asm volatile (
1518 \\ \\.globl aoeu;
1519 \\ \\.type aoeu, @function;
1520 \\ \\.set aoeu, derp;
1521 \\ );
1522 \\}
1523 , ".tmp_source.zig:6:5: error: unable to evaluate constant expression");
1524
1525 cases.add("invalid member of builtin enum",
1526 \\export fn entry() {
1527 \\ const foo = Arch.x86;
1528 \\}
1529 , ".tmp_source.zig:2:21: error: container 'Arch' has no member called 'x86'");
1530
1531 cases.add("int to ptr of 0 bits",
1532 \\export fn foo() {
1533 \\ var x: usize = 0x1000;
1534 \\ var y: &void = @intToPtr(&void, x);
1535 \\}
1536 , ".tmp_source.zig:3:31: error: type '&void' has 0 bits and cannot store information");
1537
1538 cases.add("@fieldParentPtr - non struct",
1539 \\const Foo = i32;
1540 \\export fn foo(a: &i32) -> &Foo {
1541 \\ return @fieldParentPtr(Foo, "a", a);
1542 \\}
1543 , ".tmp_source.zig:3:28: error: expected struct type, found 'i32'");
1544
1545 cases.add("@fieldParentPtr - bad field name",
1546 \\const Foo = struct {
1547 \\ derp: i32,
1548 \\};
1549 \\export fn foo(a: &i32) -> &Foo {
1550 \\ return @fieldParentPtr(Foo, "a", a);
1551 \\}
1552 , ".tmp_source.zig:5:33: error: struct 'Foo' has no field 'a'");
1553
1554 cases.add("@fieldParentPtr - field pointer is not pointer",
1555 \\const Foo = struct {
1556 \\ a: i32,
1557 \\};
1558 \\export fn foo(a: i32) -> &Foo {
1559 \\ return @fieldParentPtr(Foo, "a", a);
1560 \\}
1561 , ".tmp_source.zig:5:38: error: expected pointer, found 'i32'");
1562
1563 cases.add("@fieldParentPtr - comptime field ptr not based on struct",
1564 \\const Foo = struct {
1565 \\ a: i32,
1566 \\ b: i32,
1567 \\};
1568 \\const foo = Foo { .a = 1, .b = 2, };
1569 \\
1570 \\comptime {
1571 \\ const field_ptr = @intToPtr(&i32, 0x1234);
1572 \\ const another_foo_ptr = @fieldParentPtr(Foo, "b", field_ptr);
1573 \\}
1574 , ".tmp_source.zig:9:55: error: pointer value not based on parent struct");
1575
1576 cases.add("@fieldParentPtr - comptime wrong field index",
1577 \\const Foo = struct {
1578 \\ a: i32,
1579 \\ b: i32,
1580 \\};
1581 \\const foo = Foo { .a = 1, .b = 2, };
1582 \\
1583 \\comptime {
1584 \\ const another_foo_ptr = @fieldParentPtr(Foo, "b", &foo.a);
1585 \\}
1586 , ".tmp_source.zig:8:29: error: field 'b' has index 1 but pointer value is index 0 of struct 'Foo'");
1587
1588 cases.addExe("missing main fn in executable",
1589 \\
1590 , "error: no member named 'main' in '");
1591
1592 cases.addExe("private main fn",
1593 \\fn main() {}
1594 ,
1595 "error: 'main' is private",
1596 ".tmp_source.zig:1:1: note: declared here");
1597
1598
1599
1600
1601 return cases.step;
1602}
1603
1604const CompileErrorContext = struct {
1605 b: &build.Builder,
1606 step: &build.Step,
1607 test_index: usize,
1608 test_filter: ?[]const u8,
1609
1610 const TestCase = struct {
1611 name: []const u8,
1612 sources: List(SourceFile),
1613 expected_errors: List([]const u8),
1614 link_libc: bool,
1615 is_exe: bool,
1616
1617 const SourceFile = struct {
1618 filename: []const u8,
1619 source: []const u8,
1620 };
1621
1622 pub fn addSourceFile(self: &TestCase, filename: []const u8, source: []const u8) {
1623 %%self.sources.append(SourceFile {
1624 .filename = filename,
1625 .source = source,
1626 });
1627 }
1628
1629 pub fn addExpectedError(self: &TestCase, text: []const u8) {
1630 %%self.expected_errors.append(text);
1631 }
1632 };
1633
1634 const CompileCmpOutputStep = struct {
1635 step: build.Step,
1636 context: &CompileErrorContext,
1637 name: []const u8,
1638 test_index: usize,
1639 case: &const TestCase,
1640 release: bool,
1641
1642 pub fn create(context: &CompileErrorContext, name: []const u8,
1643 case: &const TestCase, release: bool) -> &CompileCmpOutputStep
1644 {
1645 const allocator = context.b.allocator;
1646 const ptr = %%allocator.create(CompileCmpOutputStep);
1647 *ptr = CompileCmpOutputStep {
1648 .step = build.Step.init("CompileCmpOutput", allocator, make),
1649 .context = context,
1650 .name = name,
1651 .test_index = context.test_index,
1652 .case = case,
1653 .release = release,
1654 };
1655 context.test_index += 1;
1656 return ptr;
1657 }
1658
1659 fn make(step: &build.Step) -> %void {
1660 const self = @fieldParentPtr(CompileCmpOutputStep, "step", step);
1661 const b = self.context.b;
1662
1663 const root_src = %%os.path.join(b.allocator, "test_artifacts", self.case.sources.items[0].filename);
1664 const obj_path = %%os.path.join(b.allocator, "test_artifacts", "test.o");
1665
1666 var zig_args = List([]const u8).init(b.allocator);
1667 %%zig_args.append(if (self.case.is_exe) "build_exe" else "build_obj");
1668 %%zig_args.append(b.pathFromRoot(root_src));
1669
1670 %%zig_args.append("--name");
1671 %%zig_args.append("test");
1672
1673 %%zig_args.append("--output");
1674 %%zig_args.append(b.pathFromRoot(obj_path));
1675
1676 if (self.release) {
1677 %%zig_args.append("--release");
1678 }
1679
1680 %%io.stderr.printf("Test {}/{} {}...", self.test_index+1, self.context.test_index, self.name);
1681
1682 if (b.verbose) {
1683 printInvocation(b.zig_exe, zig_args.toSliceConst());
1684 }
1685
1686 var child = os.ChildProcess.spawn(b.zig_exe, zig_args.toSliceConst(), &b.env_map,
1687 StdIo.Ignore, StdIo.Pipe, StdIo.Pipe, b.allocator) %% |err|
1688 {
1689 debug.panic("Unable to spawn {}: {}\n", b.zig_exe, @errorName(err));
1690 };
1691
1692 const term = child.wait() %% |err| {
1693 debug.panic("Unable to spawn {}: {}\n", b.zig_exe, @errorName(err));
1694 };
1695 switch (term) {
1696 Term.Clean => |code| {
1697 if (code == 0) {
1698 %%io.stderr.printf("Compilation incorrectly succeeded\n");
1699 return error.TestFailed;
1700 }
1701 },
1702 else => {
1703 %%io.stderr.printf("Process {} terminated unexpectedly\n", b.zig_exe);
1704 return error.TestFailed;
1705 },
1706 };
1707
1708 var stdout_buf = %%Buffer0.initEmpty(b.allocator);
1709 var stderr_buf = %%Buffer0.initEmpty(b.allocator);
1710
1711 %%(??child.stdout).readAll(&stdout_buf);
1712 %%(??child.stderr).readAll(&stderr_buf);
1713
1714 const stdout = stdout_buf.toSliceConst();
1715 const stderr = stderr_buf.toSliceConst();
1716
1717 if (stdout.len != 0) {
1718 %%io.stderr.printf(
1719 \\
1720 \\Expected empty stdout, instead found:
1721 \\================================================
1722 \\{}
1723 \\================================================
1724 \\
1725 , stdout);
1726 return error.TestFailed;
1727 }
1728
1729 for (self.case.expected_errors.toSliceConst()) |expected_error| {
1730 if (mem.indexOf(u8, stderr, expected_error) == null) {
1731 %%io.stderr.printf(
1732 \\
1733 \\========= Expected this compile error: =========
1734 \\{}
1735 \\================================================
1736 \\{}
1737 \\
1738 , expected_error, stderr);
1739 return error.TestFailed;
1740 }
1741 }
1742 %%io.stderr.printf("OK\n");
1743 }
1744 };
1745
1746 fn printInvocation(exe_path: []const u8, args: []const []const u8) {
1747 %%io.stderr.printf("{}", exe_path);
1748 for (args) |arg| {
1749 %%io.stderr.printf(" {}", arg);
1750 }
1751 %%io.stderr.printf("\n");
1752 }
1753
1754 pub fn create(self: &CompileErrorContext, name: []const u8, source: []const u8,
1755 expected_lines: ...) -> &TestCase
1756 {
1757 const tc = %%self.b.allocator.create(TestCase);
1758 *tc = TestCase {
1759 .name = name,
1760 .sources = List(TestCase.SourceFile).init(self.b.allocator),
1761 .expected_errors = List([]const u8).init(self.b.allocator),
1762 .link_libc = false,
1763 .is_exe = false,
1764 };
1765 tc.addSourceFile(".tmp_source.zig", source);
1766 comptime var arg_i = 0;
1767 inline while (arg_i < expected_lines.len; arg_i += 1) {
1768 // TODO mem.dupe is because of issue #336
1769 tc.addExpectedError(%%mem.dupe(self.b.allocator, u8, expected_lines[arg_i]));
1770 }
1771 return tc;
1772 }
1773
1774 pub fn addC(self: &CompileErrorContext, name: []const u8, source: []const u8, expected_lines: ...) {
1775 var tc = self.create(name, source, expected_lines);
1776 tc.link_libc = true;
1777 self.addCase(tc);
1778 }
1779
1780 pub fn addExe(self: &CompileErrorContext, name: []const u8, source: []const u8, expected_lines: ...) {
1781 var tc = self.create(name, source, expected_lines);
1782 tc.is_exe = true;
1783 self.addCase(tc);
1784 }
1785
1786 pub fn add(self: &CompileErrorContext, name: []const u8, source: []const u8, expected_lines: ...) {
1787 const tc = self.create(name, source, expected_lines);
1788 self.addCase(tc);
1789 }
1790
1791 pub fn addCase(self: &CompileErrorContext, case: &const TestCase) {
1792 const b = self.b;
1793
1794 for ([]bool{false, true}) |release| {
1795 const annotated_case_name = %%fmt.allocPrint(self.b.allocator, "{} ({})",
1796 case.name, if (release) "release" else "debug");
1797 if (const filter ?= self.test_filter) {
1798 if (mem.indexOf(u8, annotated_case_name, filter) == null)
1799 continue;
1800 }
1801
1802 const compile_and_cmp_errors = CompileCmpOutputStep.create(self, annotated_case_name, case, release);
1803 self.step.dependOn(&compile_and_cmp_errors.step);
1804
1805 for (case.sources.toSliceConst()) |src_file| {
1806 const expanded_src_path = %%os.path.join(b.allocator, "test_artifacts", src_file.filename);
1807 const write_src = b.addWriteFile(expanded_src_path, src_file.source);
1808 compile_and_cmp_errors.step.dependOn(&write_src.step);
1809 }
1810 }
1811 }
1812};
test/run_tests.cpp+59-1873
......@@ -16,8 +16,6 @@
1616
1717enum TestSpecial {
1818 TestSpecialNone,
19 TestSpecialSelfHosted,
20 TestSpecialStd,
2119 TestSpecialLinkStep,
2220};
2321
......@@ -60,1799 +58,86 @@ static const char *zig_exe = "./zig";
6058#define NL "\n"
6159#endif
6260
63static void add_source_file(TestCase *test_case, const char *path, const char *source) {
64 test_case->source_files.add_one();
65 test_case->source_files.last().relative_path = path;
66 test_case->source_files.last().source_code = source;
67}
68
69static TestCase *add_simple_case(const char *case_name, const char *source, const char *output) {
70 TestCase *test_case = allocate<TestCase>(1);
71 test_case->case_name = case_name;
72 test_case->output = output;
73
74 test_case->source_files.resize(1);
75 test_case->source_files.at(0).relative_path = tmp_source_path;
76 test_case->source_files.at(0).source_code = source;
77
78 test_case->compiler_args.append("build_exe");
79 test_case->compiler_args.append(tmp_source_path);
80 test_case->compiler_args.append("--name");
81 test_case->compiler_args.append("test");
82 test_case->compiler_args.append("--output");
83 test_case->compiler_args.append(tmp_exe_path);
84 test_case->compiler_args.append("--release");
85 test_case->compiler_args.append("--strip");
86 test_case->compiler_args.append("--color");
87 test_case->compiler_args.append("on");
88
89 test_cases.append(test_case);
90
91 return test_case;
92}
93
94static TestCase *add_asm_case(const char *case_name, const char *source, const char *output) {
95 TestCase *test_case = allocate<TestCase>(1);
96 test_case->case_name = case_name;
97 test_case->output = output;
98 test_case->special = TestSpecialLinkStep;
99
100 test_case->source_files.resize(1);
101 test_case->source_files.at(0).relative_path = ".tmp_source.s";
102 test_case->source_files.at(0).source_code = source;
103
104 test_case->compiler_args.append("asm");
105 test_case->compiler_args.append(".tmp_source.s");
106 test_case->compiler_args.append("--name");
107 test_case->compiler_args.append("test");
108 test_case->compiler_args.append("--color");
109 test_case->compiler_args.append("on");
110
111 test_case->linker_args.append("link_exe");
112 test_case->linker_args.append("test.o");
113 test_case->linker_args.append("--name");
114 test_case->linker_args.append("test");
115 test_case->linker_args.append("--output");
116 test_case->linker_args.append(tmp_exe_path);
117 test_case->linker_args.append("--color");
118 test_case->linker_args.append("on");
119
120 test_cases.append(test_case);
121
122 return test_case;
123}
124
125static TestCase *add_simple_case_libc(const char *case_name, const char *source, const char *output) {
126 TestCase *tc = add_simple_case(case_name, source, output);
127 tc->compiler_args.append("--library");
128 tc->compiler_args.append("c");
129 return tc;
130}
131
132static TestCase *add_compile_fail_case(const char *case_name, const char *source, size_t count, ...) {
133 va_list ap;
134 va_start(ap, count);
135
136 TestCase *test_case = allocate<TestCase>(1);
137 test_case->case_name = case_name;
138 test_case->source_files.resize(1);
139 test_case->source_files.at(0).relative_path = tmp_source_path;
140 test_case->source_files.at(0).source_code = source;
141
142 for (size_t i = 0; i < count; i += 1) {
143 const char *arg = va_arg(ap, const char *);
144 test_case->compile_errors.append(arg);
145 }
146
147 test_case->compiler_args.append("build_obj");
148 test_case->compiler_args.append(tmp_source_path);
149
150 test_case->compiler_args.append("--name");
151 test_case->compiler_args.append("test");
152
153 test_case->compiler_args.append("--output");
154 test_case->compiler_args.append(tmp_exe_path);
155
156 test_case->compiler_args.append("--release");
157 test_case->compiler_args.append("--strip");
158
159 test_cases.append(test_case);
160
161 return test_case;
162}
163
164static TestCase *add_compile_fail_case_exe(const char *case_name, const char *source, size_t count, ...) {
165 va_list ap;
166 va_start(ap, count);
167
168 TestCase *test_case = allocate<TestCase>(1);
169 test_case->case_name = case_name;
170 test_case->source_files.resize(1);
171 test_case->source_files.at(0).relative_path = tmp_source_path;
172 test_case->source_files.at(0).source_code = source;
173
174 for (size_t i = 0; i < count; i += 1) {
175 const char *arg = va_arg(ap, const char *);
176 test_case->compile_errors.append(arg);
177 }
178
179 test_case->compiler_args.append("build_exe");
180 test_case->compiler_args.append(tmp_source_path);
181
182 test_case->compiler_args.append("--name");
183 test_case->compiler_args.append("test");
184
185 test_case->compiler_args.append("--output");
186 test_case->compiler_args.append(tmp_exe_path);
187
188 test_case->compiler_args.append("--release");
189 test_case->compiler_args.append("--strip");
190
191 test_cases.append(test_case);
192
193 return test_case;
194}
195
196static void add_debug_safety_case(const char *case_name, const char *source) {
197 TestCase *test_case = allocate<TestCase>(1);
198 test_case->is_debug_safety = true;
199 test_case->case_name = buf_ptr(buf_sprintf("%s", case_name));
200 test_case->source_files.resize(1);
201 test_case->source_files.at(0).relative_path = tmp_source_path;
202 test_case->source_files.at(0).source_code = source;
203
204 test_case->compiler_args.append("build_exe");
205 test_case->compiler_args.append(tmp_source_path);
206
207 test_case->compiler_args.append("--name");
208 test_case->compiler_args.append("test");
209
210 test_case->compiler_args.append("--output");
211 test_case->compiler_args.append(tmp_exe_path);
212
213 test_cases.append(test_case);
214}
215
216static TestCase *add_parseh_case(const char *case_name, AllowWarnings allow_warnings,
217 const char *source, size_t count, ...)
218{
219 va_list ap;
220 va_start(ap, count);
221
222 TestCase *test_case = allocate<TestCase>(1);
223 test_case->case_name = case_name;
224 test_case->is_parseh = true;
225 test_case->allow_warnings = allow_warnings;
226
227 test_case->source_files.resize(1);
228 test_case->source_files.at(0).relative_path = tmp_h_path;
229 test_case->source_files.at(0).source_code = source;
230
231 for (size_t i = 0; i < count; i += 1) {
232 const char *arg = va_arg(ap, const char *);
233 test_case->compile_errors.append(arg);
234 }
235
236 test_case->compiler_args.append("parseh");
237 test_case->compiler_args.append(tmp_h_path);
238 //test_case->compiler_args.append("--verbose");
239
240 test_cases.append(test_case);
241
242 va_end(ap);
243 return test_case;
244}
245
246static TestCase *add_example_compile_extra(const char *root_source_file, bool libc) {
247 TestCase *test_case = allocate<TestCase>(1);
248 test_case->case_name = buf_ptr(buf_sprintf("build example %s", root_source_file));
249 test_case->output = nullptr;
250 test_case->special = TestSpecialNone;
251
252 test_case->compiler_args.append("build_exe");
253 test_case->compiler_args.append(buf_ptr(buf_sprintf("../%s", root_source_file)));
254
255 if (libc) {
256 test_case->compiler_args.append("--library");
257 test_case->compiler_args.append("c");
258 }
259
260 test_cases.append(test_case);
261
262 return test_case;
263}
264
265static TestCase *add_example_compile(const char *root_source_file) {
266 return add_example_compile_extra(root_source_file, false);
267}
268
269static TestCase *add_example_compile_libc(const char *root_source_file) {
270 return add_example_compile_extra(root_source_file, true);
271}
272
273////////////////////////////////////////////////////////////////////////////////////
274
275
276////////////////////////////////////////////////////////////////////////////////////
277
278static void add_compile_failure_test_cases(void) {
279 add_compile_fail_case("multiple function definitions", R"SOURCE(
280fn a() {}
281fn a() {}
282export fn entry() { a(); }
283 )SOURCE", 1, ".tmp_source.zig:3:1: error: redefinition of 'a'");
284
285 add_compile_fail_case("unreachable with return", R"SOURCE(
286fn a() -> noreturn {return;}
287export fn entry() { a(); }
288 )SOURCE", 1, ".tmp_source.zig:2:21: error: expected type 'noreturn', found 'void'");
289
290 add_compile_fail_case("control reaches end of non-void function", R"SOURCE(
291fn a() -> i32 {}
292export fn entry() { _ = a(); }
293 )SOURCE", 1, ".tmp_source.zig:2:15: error: expected type 'i32', found 'void'");
294
295 add_compile_fail_case("undefined function call", R"SOURCE(
296export fn a() {
297 b();
298}
299 )SOURCE", 1, ".tmp_source.zig:3:5: error: use of undeclared identifier 'b'");
300
301 add_compile_fail_case("wrong number of arguments", R"SOURCE(
302export fn a() {
303 b(1);
304}
305fn b(a: i32, b: i32, c: i32) { }
306 )SOURCE", 1, ".tmp_source.zig:3:6: error: expected 3 arguments, found 1");
307
308 add_compile_fail_case("invalid type", R"SOURCE(
309fn a() -> bogus {}
310export fn entry() { _ = a(); }
311 )SOURCE", 1, ".tmp_source.zig:2:11: error: use of undeclared identifier 'bogus'");
312
313 add_compile_fail_case("pointer to unreachable", R"SOURCE(
314fn a() -> &noreturn {}
315export fn entry() { _ = a(); }
316 )SOURCE", 1, ".tmp_source.zig:2:12: error: pointer to unreachable not allowed");
317
318 add_compile_fail_case("unreachable code", R"SOURCE(
319export fn a() {
320 return;
321 b();
322}
323
324fn b() {}
325 )SOURCE", 1, ".tmp_source.zig:4:6: error: unreachable code");
326
327 add_compile_fail_case("bad import", R"SOURCE(
328const bogus = @import("bogus-does-not-exist.zig");
329export fn entry() { bogus.bogo(); }
330 )SOURCE", 1, ".tmp_source.zig:2:15: error: unable to find 'bogus-does-not-exist.zig'");
331
332 add_compile_fail_case("undeclared identifier", R"SOURCE(
333export fn a() {
334 b +
335 c
336}
337 )SOURCE", 2,
338 ".tmp_source.zig:3:5: error: use of undeclared identifier 'b'",
339 ".tmp_source.zig:4:5: error: use of undeclared identifier 'c'");
340
341 add_compile_fail_case("parameter redeclaration", R"SOURCE(
342fn f(a : i32, a : i32) {
343}
344export fn entry() { f(1, 2); }
345 )SOURCE", 1, ".tmp_source.zig:2:15: error: redeclaration of variable 'a'");
346
347 add_compile_fail_case("local variable redeclaration", R"SOURCE(
348export fn f() {
349 const a : i32 = 0;
350 const a = 0;
351}
352 )SOURCE", 1, ".tmp_source.zig:4:5: error: redeclaration of variable 'a'");
353
354 add_compile_fail_case("local variable redeclares parameter", R"SOURCE(
355fn f(a : i32) {
356 const a = 0;
357}
358export fn entry() { f(1); }
359 )SOURCE", 1, ".tmp_source.zig:3:5: error: redeclaration of variable 'a'");
360
361 add_compile_fail_case("variable has wrong type", R"SOURCE(
362export fn f() -> i32 {
363 const a = c"a";
364 a
365}
366 )SOURCE", 1, ".tmp_source.zig:4:5: error: expected type 'i32', found '&const u8'");
367
368 add_compile_fail_case("if condition is bool, not int", R"SOURCE(
369export fn f() {
370 if (0) {}
371}
372 )SOURCE", 1, ".tmp_source.zig:3:9: error: integer value 0 cannot be implicitly casted to type 'bool'");
373
374 add_compile_fail_case("assign unreachable", R"SOURCE(
375export fn f() {
376 const a = return;
377}
378 )SOURCE", 1, ".tmp_source.zig:3:5: error: unreachable code");
379
380 add_compile_fail_case("unreachable variable", R"SOURCE(
381export fn f() {
382 const a: noreturn = {};
383}
384 )SOURCE", 1, ".tmp_source.zig:3:14: error: variable of type 'noreturn' not allowed");
385
386 add_compile_fail_case("unreachable parameter", R"SOURCE(
387fn f(a: noreturn) {}
388export fn entry() { f(); }
389 )SOURCE", 1, ".tmp_source.zig:2:9: error: parameter of type 'noreturn' not allowed");
390
391 add_compile_fail_case("bad assignment target", R"SOURCE(
392export fn f() {
393 3 = 3;
394}
395 )SOURCE", 1, ".tmp_source.zig:3:7: error: cannot assign to constant");
396
397 add_compile_fail_case("assign to constant variable", R"SOURCE(
398export fn f() {
399 const a = 3;
400 a = 4;
401}
402 )SOURCE", 1, ".tmp_source.zig:4:7: error: cannot assign to constant");
403
404 add_compile_fail_case("use of undeclared identifier", R"SOURCE(
405export fn f() {
406 b = 3;
407}
408 )SOURCE", 1, ".tmp_source.zig:3:5: error: use of undeclared identifier 'b'");
409
410 add_compile_fail_case("const is a statement, not an expression", R"SOURCE(
411export fn f() {
412 (const a = 0);
413}
414 )SOURCE", 1, ".tmp_source.zig:3:6: error: invalid token: 'const'");
415
416 add_compile_fail_case("array access of undeclared identifier", R"SOURCE(
417export fn f() {
418 i[i] = i[i];
419}
420 )SOURCE", 2, ".tmp_source.zig:3:5: error: use of undeclared identifier 'i'",
421 ".tmp_source.zig:3:12: error: use of undeclared identifier 'i'");
422
423 add_compile_fail_case("array access of non array", R"SOURCE(
424export fn f() {
425 var bad : bool = undefined;
426 bad[bad] = bad[bad];
427}
428 )SOURCE", 2, ".tmp_source.zig:4:8: error: array access of non-array type 'bool'",
429 ".tmp_source.zig:4:19: error: array access of non-array type 'bool'");
430
431 add_compile_fail_case("array access with non integer index", R"SOURCE(
432export fn f() {
433 var array = "aoeu";
434 var bad = false;
435 array[bad] = array[bad];
436}
437 )SOURCE", 2, ".tmp_source.zig:5:11: error: expected type 'usize', found 'bool'",
438 ".tmp_source.zig:5:24: error: expected type 'usize', found 'bool'");
439
440 add_compile_fail_case("write to const global variable", R"SOURCE(
441const x : i32 = 99;
442fn f() {
443 x = 1;
444}
445export fn entry() { f(); }
446 )SOURCE", 1, ".tmp_source.zig:4:7: error: cannot assign to constant");
447
448
449 add_compile_fail_case("missing else clause", R"SOURCE(
450fn f(b: bool) {
451 const x : i32 = if (b) { 1 };
452 const y = if (b) { i32(1) };
453}
454export fn entry() { f(true); }
455 )SOURCE", 2, ".tmp_source.zig:3:30: error: integer value 1 cannot be implicitly casted to type 'void'",
456 ".tmp_source.zig:4:15: error: incompatible types: 'i32' and 'void'");
457
458 add_compile_fail_case("direct struct loop", R"SOURCE(
459const A = struct { a : A, };
460export fn entry() -> usize { @sizeOf(A) }
461 )SOURCE", 1, ".tmp_source.zig:2:11: error: struct 'A' contains itself");
462
463 add_compile_fail_case("indirect struct loop", R"SOURCE(
464const A = struct { b : B, };
465const B = struct { c : C, };
466const C = struct { a : A, };
467export fn entry() -> usize { @sizeOf(A) }
468 )SOURCE", 1, ".tmp_source.zig:2:11: error: struct 'A' contains itself");
469
470 add_compile_fail_case("invalid struct field", R"SOURCE(
471const A = struct { x : i32, };
472export fn f() {
473 var a : A = undefined;
474 a.foo = 1;
475 const y = a.bar;
476}
477 )SOURCE", 2,
478 ".tmp_source.zig:5:6: error: no member named 'foo' in 'A'",
479 ".tmp_source.zig:6:16: error: no member named 'bar' in 'A'");
480
481 add_compile_fail_case("redefinition of struct", R"SOURCE(
482const A = struct { x : i32, };
483const A = struct { y : i32, };
484 )SOURCE", 1, ".tmp_source.zig:3:1: error: redefinition of 'A'");
485
486 add_compile_fail_case("redefinition of enums", R"SOURCE(
487const A = enum {};
488const A = enum {};
489 )SOURCE", 1, ".tmp_source.zig:3:1: error: redefinition of 'A'");
490
491 add_compile_fail_case("redefinition of global variables", R"SOURCE(
492var a : i32 = 1;
493var a : i32 = 2;
494 )SOURCE", 2,
495 ".tmp_source.zig:3:1: error: redefinition of 'a'",
496 ".tmp_source.zig:2:1: note: previous definition is here");
497
498 add_compile_fail_case("byvalue struct parameter in exported function", R"SOURCE(
499const A = struct { x : i32, };
500export fn f(a : A) {}
501 )SOURCE", 1, ".tmp_source.zig:3:13: error: byvalue types not yet supported on extern function parameters");
502
503 add_compile_fail_case("byvalue struct return value in exported function", R"SOURCE(
504const A = struct { x: i32, };
505export fn f() -> A {
506 A {.x = 1234 }
507}
508 )SOURCE", 1, ".tmp_source.zig:3:18: error: byvalue types not yet supported on extern function return values");
509
510 add_compile_fail_case("duplicate field in struct value expression", R"SOURCE(
511const A = struct {
512 x : i32,
513 y : i32,
514 z : i32,
515};
516export fn f() {
517 const a = A {
518 .z = 1,
519 .y = 2,
520 .x = 3,
521 .z = 4,
522 };
523}
524 )SOURCE", 1, ".tmp_source.zig:12:9: error: duplicate field");
525
526 add_compile_fail_case("missing field in struct value expression", R"SOURCE(
527const A = struct {
528 x : i32,
529 y : i32,
530 z : i32,
531};
532export fn f() {
533 // we want the error on the '{' not the 'A' because
534 // the A could be a complicated expression
535 const a = A {
536 .z = 4,
537 .y = 2,
538 };
539}
540 )SOURCE", 1, ".tmp_source.zig:10:17: error: missing field: 'x'");
541
542 add_compile_fail_case("invalid field in struct value expression", R"SOURCE(
543const A = struct {
544 x : i32,
545 y : i32,
546 z : i32,
547};
548export fn f() {
549 const a = A {
550 .z = 4,
551 .y = 2,
552 .foo = 42,
553 };
554}
555 )SOURCE", 1, ".tmp_source.zig:11:9: error: no member named 'foo' in 'A'");
556
557 add_compile_fail_case("invalid break expression", R"SOURCE(
558export fn f() {
559 break;
560}
561 )SOURCE", 1, ".tmp_source.zig:3:5: error: 'break' expression outside loop");
562
563 add_compile_fail_case("invalid continue expression", R"SOURCE(
564export fn f() {
565 continue;
566}
567 )SOURCE", 1, ".tmp_source.zig:3:5: error: 'continue' expression outside loop");
568
569 add_compile_fail_case("invalid maybe type", R"SOURCE(
570export fn f() {
571 if (const x ?= true) { }
572}
573 )SOURCE", 1, ".tmp_source.zig:3:20: error: expected nullable type, found 'bool'");
574
575 add_compile_fail_case("cast unreachable", R"SOURCE(
576fn f() -> i32 {
577 i32(return 1)
578}
579export fn entry() { _ = f(); }
580 )SOURCE", 1, ".tmp_source.zig:3:8: error: unreachable code");
581
582 add_compile_fail_case("invalid builtin fn", R"SOURCE(
583fn f() -> @bogus(foo) {
584}
585export fn entry() { _ = f(); }
586 )SOURCE", 1, ".tmp_source.zig:2:11: error: invalid builtin function: 'bogus'");
587
588 add_compile_fail_case("top level decl dependency loop", R"SOURCE(
589const a : @typeOf(b) = 0;
590const b : @typeOf(a) = 0;
591export fn entry() {
592 const c = a + b;
593}
594 )SOURCE", 1, ".tmp_source.zig:2:1: error: 'a' depends on itself");
595
596 add_compile_fail_case("noalias on non pointer param", R"SOURCE(
597fn f(noalias x: i32) {}
598export fn entry() { f(1234); }
599 )SOURCE", 1, ".tmp_source.zig:2:6: error: noalias on non-pointer parameter");
600
601 add_compile_fail_case("struct init syntax for array", R"SOURCE(
602const foo = []u16{.x = 1024,};
603export fn entry() -> usize { @sizeOf(@typeOf(foo)) }
604 )SOURCE", 1, ".tmp_source.zig:2:18: error: type '[]u16' does not support struct initialization syntax");
605
606 add_compile_fail_case("type variables must be constant", R"SOURCE(
607var foo = u8;
608export fn entry() -> foo {
609 return 1;
610}
611 )SOURCE", 1, ".tmp_source.zig:2:1: error: variable of type 'type' must be constant");
612
613
614 add_compile_fail_case("variables shadowing types", R"SOURCE(
615const Foo = struct {};
616const Bar = struct {};
617
618fn f(Foo: i32) {
619 var Bar : i32 = undefined;
620}
621
622export fn entry() {
623 f(1234);
624}
625 )SOURCE", 4,
626 ".tmp_source.zig:5:6: error: redefinition of 'Foo'",
627 ".tmp_source.zig:2:1: note: previous definition is here",
628 ".tmp_source.zig:6:5: error: redefinition of 'Bar'",
629 ".tmp_source.zig:3:1: note: previous definition is here");
630
631 add_compile_fail_case("multiple else prongs in a switch", R"SOURCE(
632fn f(x: u32) {
633 const value: bool = switch (x) {
634 1234 => false,
635 else => true,
636 else => true,
637 };
638}
639export fn entry() {
640 f(1234);
641}
642 )SOURCE", 1, ".tmp_source.zig:6:9: error: multiple else prongs in switch expression");
643
644 add_compile_fail_case("global variable initializer must be constant expression", R"SOURCE(
645extern fn foo() -> i32;
646const x = foo();
647export fn entry() -> i32 { x }
648 )SOURCE", 1, ".tmp_source.zig:3:11: error: unable to evaluate constant expression");
649
650 add_compile_fail_case("array concatenation with wrong type", R"SOURCE(
651const src = "aoeu";
652const derp = usize(1234);
653const a = derp ++ "foo";
654
655export fn entry() -> usize { @sizeOf(@typeOf(a)) }
656 )SOURCE", 1, ".tmp_source.zig:4:11: error: expected array or C string literal, found 'usize'");
657
658 add_compile_fail_case("non compile time array concatenation", R"SOURCE(
659fn f() -> []u8 {
660 s ++ "foo"
661}
662var s: [10]u8 = undefined;
663export fn entry() -> usize { @sizeOf(@typeOf(f)) }
664 )SOURCE", 1, ".tmp_source.zig:3:5: error: unable to evaluate constant expression");
665
666 add_compile_fail_case("@cImport with bogus include", R"SOURCE(
667const c = @cImport(@cInclude("bogus.h"));
668export fn entry() -> usize { @sizeOf(@typeOf(c.bogo)) }
669 )SOURCE", 2, ".tmp_source.zig:2:11: error: C import failed",
670 ".h:1:10: note: 'bogus.h' file not found");
671
672 add_compile_fail_case("address of number literal", R"SOURCE(
673const x = 3;
674const y = &x;
675fn foo() -> &const i32 { y }
676export fn entry() -> usize { @sizeOf(@typeOf(foo)) }
677 )SOURCE", 1, ".tmp_source.zig:4:26: error: expected type '&const i32', found '&const (integer literal)'");
678
679 add_compile_fail_case("integer overflow error", R"SOURCE(
680const x : u8 = 300;
681export fn entry() -> usize { @sizeOf(@typeOf(x)) }
682 )SOURCE", 1, ".tmp_source.zig:2:16: error: integer value 300 cannot be implicitly casted to type 'u8'");
683
684 add_compile_fail_case("incompatible number literals", R"SOURCE(
685const x = 2 == 2.0;
686export fn entry() -> usize { @sizeOf(@typeOf(x)) }
687 )SOURCE", 1, ".tmp_source.zig:2:11: error: integer value 2 cannot be implicitly casted to type '(float literal)'");
688
689 add_compile_fail_case("missing function call param", R"SOURCE(
690const Foo = struct {
691 a: i32,
692 b: i32,
693
694 fn member_a(foo: &const Foo) -> i32 {
695 return foo.a;
696 }
697 fn member_b(foo: &const Foo) -> i32 {
698 return foo.b;
699 }
700};
701
702const member_fn_type = @typeOf(Foo.member_a);
703const members = []member_fn_type {
704 Foo.member_a,
705 Foo.member_b,
706};
707
708fn f(foo: &const Foo, index: usize) {
709 const result = members[index]();
710}
711
712export fn entry() -> usize { @sizeOf(@typeOf(f)) }
713 )SOURCE", 1, ".tmp_source.zig:21:34: error: expected 1 arguments, found 0");
714
715 add_compile_fail_case("missing function name and param name", R"SOURCE(
716fn () {}
717fn f(i32) {}
718export fn entry() -> usize { @sizeOf(@typeOf(f)) }
719 )SOURCE", 2,
720 ".tmp_source.zig:2:1: error: missing function name",
721 ".tmp_source.zig:3:6: error: missing parameter name");
722
723 add_compile_fail_case("wrong function type", R"SOURCE(
724const fns = []fn(){ a, b, c };
725fn a() -> i32 {0}
726fn b() -> i32 {1}
727fn c() -> i32 {2}
728export fn entry() -> usize { @sizeOf(@typeOf(fns)) }
729 )SOURCE", 1, ".tmp_source.zig:2:21: error: expected type 'fn()', found 'fn() -> i32'");
730
731 add_compile_fail_case("extern function pointer mismatch", R"SOURCE(
732const fns = [](fn(i32)->i32){ a, b, c };
733pub fn a(x: i32) -> i32 {x + 0}
734pub fn b(x: i32) -> i32 {x + 1}
735export fn c(x: i32) -> i32 {x + 2}
736
737export fn entry() -> usize { @sizeOf(@typeOf(fns)) }
738 )SOURCE", 1, ".tmp_source.zig:2:37: error: expected type 'fn(i32) -> i32', found 'extern fn(i32) -> i32'");
739
740
741 add_compile_fail_case("implicit cast from f64 to f32", R"SOURCE(
742const x : f64 = 1.0;
743const y : f32 = x;
744
745export fn entry() -> usize { @sizeOf(@typeOf(y)) }
746 )SOURCE", 1, ".tmp_source.zig:3:17: error: expected type 'f32', found 'f64'");
747
748
749 add_compile_fail_case("colliding invalid top level functions", R"SOURCE(
750fn func() -> bogus {}
751fn func() -> bogus {}
752export fn entry() -> usize { @sizeOf(@typeOf(func)) }
753 )SOURCE", 2,
754 ".tmp_source.zig:3:1: error: redefinition of 'func'",
755 ".tmp_source.zig:2:14: error: use of undeclared identifier 'bogus'");
756
757
758 add_compile_fail_case("bogus compile var", R"SOURCE(
759const x = @compileVar("bogus");
760export fn entry() -> usize { @sizeOf(@typeOf(x)) }
761 )SOURCE", 1, ".tmp_source.zig:2:23: error: unrecognized compile variable: 'bogus'");
762
763
764 add_compile_fail_case("non constant expression in array size outside function", R"SOURCE(
765const Foo = struct {
766 y: [get()]u8,
767};
768var global_var: usize = 1;
769fn get() -> usize { global_var }
770
771export fn entry() -> usize { @sizeOf(@typeOf(Foo)) }
772 )SOURCE", 3,
773 ".tmp_source.zig:6:21: error: unable to evaluate constant expression",
774 ".tmp_source.zig:3:12: note: called from here",
775 ".tmp_source.zig:3:8: note: called from here");
776
777
778 add_compile_fail_case("addition with non numbers", R"SOURCE(
779const Foo = struct {
780 field: i32,
781};
782const x = Foo {.field = 1} + Foo {.field = 2};
783
784export fn entry() -> usize { @sizeOf(@typeOf(x)) }
785 )SOURCE", 1, ".tmp_source.zig:5:28: error: invalid operands to binary expression: 'Foo' and 'Foo'");
786
787
788 add_compile_fail_case("division by zero", R"SOURCE(
789const lit_int_x = 1 / 0;
790const lit_float_x = 1.0 / 0.0;
791const int_x = i32(1) / i32(0);
792const float_x = f32(1.0) / f32(0.0);
793
794export fn entry1() -> usize { @sizeOf(@typeOf(lit_int_x)) }
795export fn entry2() -> usize { @sizeOf(@typeOf(lit_float_x)) }
796export fn entry3() -> usize { @sizeOf(@typeOf(int_x)) }
797export fn entry4() -> usize { @sizeOf(@typeOf(float_x)) }
798 )SOURCE", 4,
799 ".tmp_source.zig:2:21: error: division by zero is undefined",
800 ".tmp_source.zig:3:25: error: division by zero is undefined",
801 ".tmp_source.zig:4:22: error: division by zero is undefined",
802 ".tmp_source.zig:5:26: error: division by zero is undefined");
803
804
805 add_compile_fail_case("missing switch prong", R"SOURCE(
806const Number = enum {
807 One,
808 Two,
809 Three,
810 Four,
811};
812fn f(n: Number) -> i32 {
813 switch (n) {
814 Number.One => 1,
815 Number.Two => 2,
816 Number.Three => i32(3),
817 }
818}
819
820export fn entry() -> usize { @sizeOf(@typeOf(f)) }
821 )SOURCE", 1, ".tmp_source.zig:9:5: error: enumeration value 'Number.Four' not handled in switch");
822
823 add_compile_fail_case("normal string with newline", R"SOURCE(
824const foo = "a
825b";
826
827export fn entry() -> usize { @sizeOf(@typeOf(foo)) }
828 )SOURCE", 1, ".tmp_source.zig:2:13: error: newline not allowed in string literal");
829
830 add_compile_fail_case("invalid comparison for function pointers", R"SOURCE(
831fn foo() {}
832const invalid = foo > foo;
833
834export fn entry() -> usize { @sizeOf(@typeOf(invalid)) }
835 )SOURCE", 1, ".tmp_source.zig:3:21: error: operator not allowed for type 'fn()'");
836
837 add_compile_fail_case("generic function instance with non-constant expression", R"SOURCE(
838fn foo(comptime x: i32, y: i32) -> i32 { return x + y; }
839fn test1(a: i32, b: i32) -> i32 {
840 return foo(a, b);
841}
842
843export fn entry() -> usize { @sizeOf(@typeOf(test1)) }
844 )SOURCE", 1, ".tmp_source.zig:4:16: error: unable to evaluate constant expression");
845
846 add_compile_fail_case("goto jumping into block", R"SOURCE(
847export fn f() {
848 {
849a_label:
850 }
851 goto a_label;
852}
853 )SOURCE", 1, ".tmp_source.zig:6:5: error: no label in scope named 'a_label'");
854
855 add_compile_fail_case("goto jumping past a defer", R"SOURCE(
856fn f(b: bool) {
857 if (b) goto label;
858 defer derp();
859label:
860}
861fn derp(){}
862
863export fn entry() -> usize { @sizeOf(@typeOf(f)) }
864 )SOURCE", 1, ".tmp_source.zig:3:12: error: no label in scope named 'label'");
865
866 add_compile_fail_case("assign null to non-nullable pointer", R"SOURCE(
867const a: &u8 = null;
868
869export fn entry() -> usize { @sizeOf(@typeOf(a)) }
870 )SOURCE", 1, ".tmp_source.zig:2:16: error: expected type '&u8', found '(null)'");
871
872 add_compile_fail_case("indexing an array of size zero", R"SOURCE(
873const array = []u8{};
874export fn foo() {
875 const pointer = &array[0];
876}
877 )SOURCE", 1, ".tmp_source.zig:4:27: error: index 0 outside array of size 0");
878
879 add_compile_fail_case("compile time division by zero", R"SOURCE(
880const y = foo(0);
881fn foo(x: i32) -> i32 {
882 1 / x
883}
884
885export fn entry() -> usize { @sizeOf(@typeOf(y)) }
886 )SOURCE", 2,
887 ".tmp_source.zig:4:7: error: division by zero is undefined",
888 ".tmp_source.zig:2:14: note: called from here");
889
890 add_compile_fail_case("branch on undefined value", R"SOURCE(
891const x = if (undefined) true else false;
892
893export fn entry() -> usize { @sizeOf(@typeOf(x)) }
894 )SOURCE", 1, ".tmp_source.zig:2:15: error: use of undefined value");
895
896
897 add_compile_fail_case("endless loop in function evaluation", R"SOURCE(
898const seventh_fib_number = fibbonaci(7);
899fn fibbonaci(x: i32) -> i32 {
900 return fibbonaci(x - 1) + fibbonaci(x - 2);
901}
902
903export fn entry() -> usize { @sizeOf(@typeOf(seventh_fib_number)) }
904 )SOURCE", 2,
905 ".tmp_source.zig:4:21: error: evaluation exceeded 1000 backwards branches",
906 ".tmp_source.zig:4:21: note: called from here");
907
908 add_compile_fail_case("@embedFile with bogus file", R"SOURCE(
909const resource = @embedFile("bogus.txt");
910
911export fn entry() -> usize { @sizeOf(@typeOf(resource)) }
912 )SOURCE", 2, ".tmp_source.zig:2:29: error: unable to find '", "/bogus.txt'");
913
914 add_compile_fail_case("non-const expression in struct literal outside function", R"SOURCE(
915const Foo = struct {
916 x: i32,
917};
918const a = Foo {.x = get_it()};
919extern fn get_it() -> i32;
920
921export fn entry() -> usize { @sizeOf(@typeOf(a)) }
922 )SOURCE", 1, ".tmp_source.zig:5:21: error: unable to evaluate constant expression");
923
924 add_compile_fail_case("non-const expression function call with struct return value outside function", R"SOURCE(
925const Foo = struct {
926 x: i32,
927};
928const a = get_it();
929fn get_it() -> Foo {
930 global_side_effect = true;
931 Foo {.x = 13}
932}
933var global_side_effect = false;
934
935export fn entry() -> usize { @sizeOf(@typeOf(a)) }
936 )SOURCE", 2,
937 ".tmp_source.zig:7:24: error: unable to evaluate constant expression",
938 ".tmp_source.zig:5:17: note: called from here");
939
940 add_compile_fail_case("undeclared identifier error should mark fn as impure", R"SOURCE(
941export fn foo() {
942 test_a_thing();
943}
944fn test_a_thing() {
945 bad_fn_call();
946}
947 )SOURCE", 1, ".tmp_source.zig:6:5: error: use of undeclared identifier 'bad_fn_call'");
948
949 add_compile_fail_case("illegal comparison of types", R"SOURCE(
950fn bad_eql_1(a: []u8, b: []u8) -> bool {
951 a == b
952}
953const EnumWithData = enum {
954 One,
955 Two: i32,
956};
957fn bad_eql_2(a: &const EnumWithData, b: &const EnumWithData) -> bool {
958 *a == *b
959}
960
961export fn entry1() -> usize { @sizeOf(@typeOf(bad_eql_1)) }
962export fn entry2() -> usize { @sizeOf(@typeOf(bad_eql_2)) }
963 )SOURCE", 2,
964 ".tmp_source.zig:3:7: error: operator not allowed for type '[]u8'",
965 ".tmp_source.zig:10:8: error: operator not allowed for type 'EnumWithData'");
966
967 add_compile_fail_case("non-const switch number literal", R"SOURCE(
968export fn foo() {
969 const x = switch (bar()) {
970 1, 2 => 1,
971 3, 4 => 2,
972 else => 3,
973 };
974}
975fn bar() -> i32 {
976 2
977}
978 )SOURCE", 1, ".tmp_source.zig:3:15: error: unable to infer expression type");
979
980 add_compile_fail_case("atomic orderings of cmpxchg - failure stricter than success", R"SOURCE(
981export fn f() {
982 var x: i32 = 1234;
983 while (!@cmpxchg(&x, 1234, 5678, AtomicOrder.Monotonic, AtomicOrder.SeqCst)) {}
984}
985 )SOURCE", 1, ".tmp_source.zig:4:72: error: failure atomic ordering must be no stricter than success");
986
987 add_compile_fail_case("atomic orderings of cmpxchg - success Monotonic or stricter", R"SOURCE(
988export fn f() {
989 var x: i32 = 1234;
990 while (!@cmpxchg(&x, 1234, 5678, AtomicOrder.Unordered, AtomicOrder.Unordered)) {}
991}
992 )SOURCE", 1, ".tmp_source.zig:4:49: error: success atomic ordering must be Monotonic or stricter");
993
994 add_compile_fail_case("negation overflow in function evaluation", R"SOURCE(
995const y = neg(-128);
996fn neg(x: i8) -> i8 {
997 -x
998}
999
1000export fn entry() -> usize { @sizeOf(@typeOf(y)) }
1001 )SOURCE", 2,
1002 ".tmp_source.zig:4:5: error: negation caused overflow",
1003 ".tmp_source.zig:2:14: note: called from here");
1004
1005 add_compile_fail_case("add overflow in function evaluation", R"SOURCE(
1006const y = add(65530, 10);
1007fn add(a: u16, b: u16) -> u16 {
1008 a + b
1009}
1010
1011export fn entry() -> usize { @sizeOf(@typeOf(y)) }
1012 )SOURCE", 2,
1013 ".tmp_source.zig:4:7: error: operation caused overflow",
1014 ".tmp_source.zig:2:14: note: called from here");
1015
1016
1017 add_compile_fail_case("sub overflow in function evaluation", R"SOURCE(
1018const y = sub(10, 20);
1019fn sub(a: u16, b: u16) -> u16 {
1020 a - b
1021}
1022
1023export fn entry() -> usize { @sizeOf(@typeOf(y)) }
1024 )SOURCE", 2,
1025 ".tmp_source.zig:4:7: error: operation caused overflow",
1026 ".tmp_source.zig:2:14: note: called from here");
1027
1028 add_compile_fail_case("mul overflow in function evaluation", R"SOURCE(
1029const y = mul(300, 6000);
1030fn mul(a: u16, b: u16) -> u16 {
1031 a * b
1032}
1033
1034export fn entry() -> usize { @sizeOf(@typeOf(y)) }
1035 )SOURCE", 2,
1036 ".tmp_source.zig:4:7: error: operation caused overflow",
1037 ".tmp_source.zig:2:14: note: called from here");
1038
1039 add_compile_fail_case("truncate sign mismatch", R"SOURCE(
1040fn f() -> i8 {
1041 const x: u32 = 10;
1042 @truncate(i8, x)
1043}
1044
1045export fn entry() -> usize { @sizeOf(@typeOf(f)) }
1046 )SOURCE", 1, ".tmp_source.zig:4:19: error: expected signed integer type, found 'u32'");
1047
1048 add_compile_fail_case("%return in function with non error return type", R"SOURCE(
1049export fn f() {
1050 %return something();
1051}
1052fn something() -> %void { }
1053 )SOURCE", 1,
1054 ".tmp_source.zig:3:5: error: expected type 'void', found 'error'");
1055
1056 add_compile_fail_case("wrong return type for main", R"SOURCE(
1057pub fn main() { }
1058 )SOURCE", 1, ".tmp_source.zig:2:15: error: expected return type of main to be '%void', instead is 'void'");
1059
1060 add_compile_fail_case("double ?? on main return value", R"SOURCE(
1061pub fn main() -> ??void {
1062}
1063 )SOURCE", 1, ".tmp_source.zig:2:18: error: expected return type of main to be '%void', instead is '??void'");
1064
1065 add_compile_fail_case("invalid pointer for var type", R"SOURCE(
1066extern fn ext() -> usize;
1067var bytes: [ext()]u8 = undefined;
1068export fn f() {
1069 for (bytes) |*b, i| {
1070 *b = u8(i);
1071 }
1072}
1073 )SOURCE", 1, ".tmp_source.zig:3:13: error: unable to evaluate constant expression");
1074
1075 add_compile_fail_case("export function with comptime parameter", R"SOURCE(
1076export fn foo(comptime x: i32, y: i32) -> i32{
1077 x + y
1078}
1079 )SOURCE", 1, ".tmp_source.zig:2:15: error: comptime parameter not allowed in extern function");
1080
1081 add_compile_fail_case("extern function with comptime parameter", R"SOURCE(
1082extern fn foo(comptime x: i32, y: i32) -> i32;
1083fn f() -> i32 {
1084 foo(1, 2)
1085}
1086export fn entry() -> usize { @sizeOf(@typeOf(f)) }
1087 )SOURCE", 1, ".tmp_source.zig:2:15: error: comptime parameter not allowed in extern function");
1088
1089 add_compile_fail_case("convert fixed size array to slice with invalid size", R"SOURCE(
1090export fn f() {
1091 var array: [5]u8 = undefined;
1092 var foo = ([]const u32)(array)[0];
1093}
1094 )SOURCE", 1, ".tmp_source.zig:4:28: error: unable to convert [5]u8 to []const u32: size mismatch");
1095
1096 add_compile_fail_case("non-pure function returns type", R"SOURCE(
1097var a: u32 = 0;
1098pub fn List(comptime T: type) -> type {
1099 a += 1;
1100 SmallList(T, 8)
1101}
1102
1103pub fn SmallList(comptime T: type, comptime STATIC_SIZE: usize) -> type {
1104 struct {
1105 items: []T,
1106 length: usize,
1107 prealloc_items: [STATIC_SIZE]T,
1108 }
1109}
1110
1111export fn function_with_return_type_type() {
1112 var list: List(i32) = undefined;
1113 list.length = 10;
1114}
1115
1116 )SOURCE", 2,
1117 ".tmp_source.zig:4:7: error: unable to evaluate constant expression",
1118 ".tmp_source.zig:17:19: note: called from here");
1119
1120 add_compile_fail_case("bogus method call on slice", R"SOURCE(
1121var self = "aoeu";
1122fn f(m: []const u8) {
1123 m.copy(u8, self[0...], m);
1124}
1125export fn entry() -> usize { @sizeOf(@typeOf(f)) }
1126 )SOURCE", 1, ".tmp_source.zig:4:6: error: no member named 'copy' in '[]const u8'");
1127
1128 add_compile_fail_case("wrong number of arguments for method fn call", R"SOURCE(
1129const Foo = struct {
1130 fn method(self: &const Foo, a: i32) {}
1131};
1132fn f(foo: &const Foo) {
1133
1134 foo.method(1, 2);
1135}
1136export fn entry() -> usize { @sizeOf(@typeOf(f)) }
1137 )SOURCE", 1, ".tmp_source.zig:7:15: error: expected 2 arguments, found 3");
1138
1139 add_compile_fail_case("assign through constant pointer", R"SOURCE(
1140export fn f() {
1141 var cstr = c"Hat";
1142 cstr[0] = 'W';
1143}
1144 )SOURCE", 1, ".tmp_source.zig:4:11: error: cannot assign to constant");
1145
1146 add_compile_fail_case("assign through constant slice", R"SOURCE(
1147export fn f() {
1148 var cstr: []const u8 = "Hat";
1149 cstr[0] = 'W';
1150}
1151 )SOURCE", 1, ".tmp_source.zig:4:11: error: cannot assign to constant");
1152
1153 add_compile_fail_case("main function with bogus args type", R"SOURCE(
1154pub fn main(args: [][]bogus) -> %void {}
1155 )SOURCE", 1, ".tmp_source.zig:2:23: error: use of undeclared identifier 'bogus'");
1156
1157 add_compile_fail_case("for loop missing element param", R"SOURCE(
1158fn foo(blah: []u8) {
1159 for (blah) { }
1160}
1161export fn entry() -> usize { @sizeOf(@typeOf(foo)) }
1162 )SOURCE", 1, ".tmp_source.zig:3:5: error: for loop expression missing element parameter");
1163
1164 add_compile_fail_case("misspelled type with pointer only reference", R"SOURCE(
1165const JasonHM = u8;
1166const JasonList = &JsonNode;
1167
1168const JsonOA = enum {
1169 JSONArray: JsonList,
1170 JSONObject: JasonHM,
1171};
1172
1173const JsonType = enum {
1174 JSONNull: void,
1175 JSONInteger: isize,
1176 JSONDouble: f64,
1177 JSONBool: bool,
1178 JSONString: []u8,
1179 JSONArray,
1180 JSONObject,
1181};
1182
1183pub const JsonNode = struct {
1184 kind: JsonType,
1185 jobject: ?JsonOA,
1186};
1187
1188fn foo() {
1189 var jll: JasonList = undefined;
1190 jll.init(1234);
1191 var jd = JsonNode {.kind = JsonType.JSONArray , .jobject = JsonOA.JSONArray {jll} };
1192}
1193
1194export fn entry() -> usize { @sizeOf(@typeOf(foo)) }
1195 )SOURCE", 1, ".tmp_source.zig:6:16: error: use of undeclared identifier 'JsonList'");
1196
1197 add_compile_fail_case("method call with first arg type primitive", R"SOURCE(
1198const Foo = struct {
1199 x: i32,
1200
1201 fn init(x: i32) -> Foo {
1202 Foo {
1203 .x = x,
1204 }
1205 }
1206};
1207
1208export fn f() {
1209 const derp = Foo.init(3);
1210
1211 derp.init();
1212}
1213 )SOURCE", 1, ".tmp_source.zig:15:5: error: expected type 'i32', found '&const Foo'");
1214
1215 add_compile_fail_case("method call with first arg type wrong container", R"SOURCE(
1216pub const List = struct {
1217 len: usize,
1218 allocator: &Allocator,
1219
1220 pub fn init(allocator: &Allocator) -> List {
1221 List {
1222 .len = 0,
1223 .allocator = allocator,
1224 }
1225 }
1226};
1227
1228pub var global_allocator = Allocator {
1229 .field = 1234,
1230};
1231
1232pub const Allocator = struct {
1233 field: i32,
1234};
1235
1236export fn foo() {
1237 var x = List.init(&global_allocator);
1238 x.init();
1239}
1240 )SOURCE", 1, ".tmp_source.zig:24:5: error: expected type '&Allocator', found '&List'");
1241
1242 add_compile_fail_case("binary not on number literal", R"SOURCE(
1243const TINY_QUANTUM_SHIFT = 4;
1244const TINY_QUANTUM_SIZE = 1 << TINY_QUANTUM_SHIFT;
1245var block_aligned_stuff: usize = (4 + TINY_QUANTUM_SIZE) & ~(TINY_QUANTUM_SIZE - 1);
1246
1247export fn entry() -> usize { @sizeOf(@typeOf(block_aligned_stuff)) }
1248 )SOURCE", 1, ".tmp_source.zig:4:60: error: unable to perform binary not operation on type '(integer literal)'");
1249
1250 {
1251 TestCase *tc = add_compile_fail_case("multiple files with private function error", R"SOURCE(
1252const foo = @import("foo.zig");
1253
1254export fn callPrivFunction() {
1255 foo.privateFunction();
1256}
1257 )SOURCE", 2,
1258 ".tmp_source.zig:5:8: error: 'privateFunction' is private",
1259 "foo.zig:2:1: note: declared here");
1260
1261 add_source_file(tc, "foo.zig", R"SOURCE(
1262fn privateFunction() { }
1263 )SOURCE");
1264 }
1265
1266 add_compile_fail_case("container init with non-type", R"SOURCE(
1267const zero: i32 = 0;
1268const a = zero{1};
1269
1270export fn entry() -> usize { @sizeOf(@typeOf(a)) }
1271 )SOURCE", 1, ".tmp_source.zig:3:11: error: expected type, found 'i32'");
1272
1273 add_compile_fail_case("assign to constant field", R"SOURCE(
1274const Foo = struct {
1275 field: i32,
1276};
1277export fn derp() {
1278 const f = Foo {.field = 1234,};
1279 f.field = 0;
1280}
1281 )SOURCE", 1, ".tmp_source.zig:7:13: error: cannot assign to constant");
1282
1283 add_compile_fail_case("return from defer expression", R"SOURCE(
1284pub fn testTrickyDefer() -> %void {
1285 defer canFail() %% {};
1286
1287 defer %return canFail();
1288
1289 const a = maybeInt() ?? return;
1290}
1291
1292fn canFail() -> %void { }
1293
1294pub fn maybeInt() -> ?i32 {
1295 return 0;
1296}
1297
1298export fn entry() -> usize { @sizeOf(@typeOf(testTrickyDefer)) }
1299 )SOURCE", 1, ".tmp_source.zig:5:11: error: cannot return from defer expression");
1300
1301 add_compile_fail_case("attempt to access var args out of bounds", R"SOURCE(
1302fn add(args: ...) -> i32 {
1303 args[0] + args[1]
1304}
1305
1306fn foo() -> i32 {
1307 add(i32(1234))
1308}
1309
1310export fn entry() -> usize { @sizeOf(@typeOf(foo)) }
1311 )SOURCE", 2,
1312 ".tmp_source.zig:3:19: error: index 1 outside argument list of size 1",
1313 ".tmp_source.zig:7:8: note: called from here");
1314
1315 add_compile_fail_case("pass integer literal to var args", R"SOURCE(
1316fn add(args: ...) -> i32 {
1317 var sum = i32(0);
1318 {comptime var i: usize = 0; inline while (i < args.len; i += 1) {
1319 sum += args[i];
1320 }}
1321 return sum;
1322}
1323
1324fn bar() -> i32 {
1325 add(1, 2, 3, 4)
1326}
1327
1328export fn entry() -> usize { @sizeOf(@typeOf(bar)) }
1329 )SOURCE", 1, ".tmp_source.zig:11:9: error: parameter of type '(integer literal)' requires comptime");
1330
1331 add_compile_fail_case("assign too big number to u16", R"SOURCE(
1332export fn foo() {
1333 var vga_mem: u16 = 0xB8000;
1334}
1335 )SOURCE", 1, ".tmp_source.zig:3:24: error: integer value 753664 cannot be implicitly casted to type 'u16'");
1336
1337 add_compile_fail_case("set global variable alignment to non power of 2", R"SOURCE(
1338const some_data: [100]u8 = {
1339 @setGlobalAlign(some_data, 3);
1340 undefined
1341};
1342export fn entry() -> usize { @sizeOf(@typeOf(some_data)) }
1343 )SOURCE", 1, ".tmp_source.zig:3:32: error: alignment value must be power of 2");
1344
1345 add_compile_fail_case("compile log", R"SOURCE(
1346export fn foo() {
1347 comptime bar(12, "hi");
1348}
1349fn bar(a: i32, b: []const u8) {
1350 @compileLog("begin");
1351 @compileLog("a", a, "b", b);
1352 @compileLog("end");
1353}
1354 )SOURCE", 6,
1355 ".tmp_source.zig:6:5: error: found compile log statement",
1356 ".tmp_source.zig:3:17: note: called from here",
1357 ".tmp_source.zig:7:5: error: found compile log statement",
1358 ".tmp_source.zig:3:17: note: called from here",
1359 ".tmp_source.zig:8:5: error: found compile log statement",
1360 ".tmp_source.zig:3:17: note: called from here");
1361
1362 add_compile_fail_case("casting bit offset pointer to regular pointer", R"SOURCE(
1363const u2 = @IntType(false, 2);
1364const u3 = @IntType(false, 3);
1365
1366const BitField = packed struct {
1367 a: u3,
1368 b: u3,
1369 c: u2,
1370};
61static TestCase *add_asm_case(const char *case_name, const char *source, const char *output) {
62 TestCase *test_case = allocate<TestCase>(1);
63 test_case->case_name = case_name;
64 test_case->output = output;
65 test_case->special = TestSpecialLinkStep;
137166
1372fn foo(bit_field: &const BitField) -> u3 {
1373 return bar(&bit_field.b);
1374}
67 test_case->source_files.resize(1);
68 test_case->source_files.at(0).relative_path = ".tmp_source.s";
69 test_case->source_files.at(0).source_code = source;
137570
1376fn bar(x: &const u3) -> u3 {
1377 return *x;
1378}
71 test_case->compiler_args.append("asm");
72 test_case->compiler_args.append(".tmp_source.s");
73 test_case->compiler_args.append("--name");
74 test_case->compiler_args.append("test");
75 test_case->compiler_args.append("--color");
76 test_case->compiler_args.append("on");
137977
1380export fn entry() -> usize { @sizeOf(@typeOf(foo)) }
1381 )SOURCE", 1, ".tmp_source.zig:12:26: error: expected type '&const u3', found '&:3:6 const u3'");
78 test_case->linker_args.append("link_exe");
79 test_case->linker_args.append("test.o");
80 test_case->linker_args.append("--name");
81 test_case->linker_args.append("test");
82 test_case->linker_args.append("--output");
83 test_case->linker_args.append(tmp_exe_path);
84 test_case->linker_args.append("--color");
85 test_case->linker_args.append("on");
138286
1383 add_compile_fail_case("referring to a struct that is invalid", R"SOURCE(
1384const UsbDeviceRequest = struct {
1385 Type: u8,
1386};
87 test_cases.append(test_case);
138788
1388export fn foo() {
1389 comptime assert(@sizeOf(UsbDeviceRequest) == 0x8);
89 return test_case;
139090}
139191
1392fn assert(ok: bool) {
1393 if (!ok) unreachable;
1394}
1395 )SOURCE", 2,
1396 ".tmp_source.zig:11:14: error: unable to evaluate constant expression",
1397 ".tmp_source.zig:7:20: note: called from here");
1398
1399 add_compile_fail_case("control flow uses comptime var at runtime", R"SOURCE(
1400export fn foo() {
1401 comptime var i = 0;
1402 while (i < 5; i += 1) {
1403 bar();
1404 }
1405}
92static void add_debug_safety_case(const char *case_name, const char *source) {
93 TestCase *test_case = allocate<TestCase>(1);
94 test_case->is_debug_safety = true;
95 test_case->case_name = buf_ptr(buf_sprintf("%s", case_name));
96 test_case->source_files.resize(1);
97 test_case->source_files.at(0).relative_path = tmp_source_path;
98 test_case->source_files.at(0).source_code = source;
140699
1407fn bar() { }
1408 )SOURCE", 2,
1409 ".tmp_source.zig:4:5: error: control flow attempts to use compile-time variable at runtime",
1410 ".tmp_source.zig:4:21: note: compile-time variable assigned here");
100 test_case->compiler_args.append("build_exe");
101 test_case->compiler_args.append(tmp_source_path);
1411102
1412 add_compile_fail_case("ignored return value", R"SOURCE(
1413export fn foo() {
1414 bar();
1415}
1416fn bar() -> i32 { 0 }
1417 )SOURCE", 1, ".tmp_source.zig:3:8: error: return value ignored");
103 test_case->compiler_args.append("--name");
104 test_case->compiler_args.append("test");
1418105
1419 add_compile_fail_case("integer literal on a non-comptime var", R"SOURCE(
1420export fn foo() {
1421 var i = 0;
1422 while (i < 10; i += 1) { }
1423}
1424 )SOURCE", 1, ".tmp_source.zig:3:5: error: unable to infer variable type");
106 test_case->compiler_args.append("--output");
107 test_case->compiler_args.append(tmp_exe_path);
1425108
1426 add_compile_fail_case("undefined literal on a non-comptime var", R"SOURCE(
1427export fn foo() {
1428 var i = undefined;
1429 i = i32(1);
1430}
1431 )SOURCE", 1, ".tmp_source.zig:3:5: error: unable to infer variable type");
1432
1433 add_compile_fail_case("dereference an array", R"SOURCE(
1434var s_buffer: [10]u8 = undefined;
1435pub fn pass(in: []u8) -> []u8 {
1436 var out = &s_buffer;
1437 *out[0] = in[0];
1438 return (*out)[0...1];
109 test_cases.append(test_case);
1439110}
1440111
1441export fn entry() -> usize { @sizeOf(@typeOf(pass)) }
1442 )SOURCE", 1, ".tmp_source.zig:5:5: error: attempt to dereference non pointer type '[10]u8'");
1443
1444 add_compile_fail_case("pass const ptr to mutable ptr fn", R"SOURCE(
1445fn foo() -> bool {
1446 const a = ([]const u8)("a");
1447 const b = &a;
1448 return ptrEql(b, b);
1449}
1450fn ptrEql(a: &[]const u8, b: &[]const u8) -> bool {
1451 return true;
1452}
112static TestCase *add_parseh_case(const char *case_name, AllowWarnings allow_warnings,
113 const char *source, size_t count, ...)
114{
115 va_list ap;
116 va_start(ap, count);
1453117
1454export fn entry() -> usize { @sizeOf(@typeOf(foo)) }
1455 )SOURCE", 1, ".tmp_source.zig:5:19: error: expected type '&[]const u8', found '&const []const u8'");
118 TestCase *test_case = allocate<TestCase>(1);
119 test_case->case_name = case_name;
120 test_case->is_parseh = true;
121 test_case->allow_warnings = allow_warnings;
1456122
1457 {
1458 TestCase *tc = add_compile_fail_case("export collision", R"SOURCE(
1459const foo = @import("foo.zig");
123 test_case->source_files.resize(1);
124 test_case->source_files.at(0).relative_path = tmp_h_path;
125 test_case->source_files.at(0).source_code = source;
1460126
1461export fn bar() -> usize {
1462 return foo.baz;
1463}
1464 )SOURCE", 2,
1465 "foo.zig:2:8: error: exported symbol collision: 'bar'",
1466 ".tmp_source.zig:4:8: note: other symbol is here");
1467
1468 add_source_file(tc, "foo.zig", R"SOURCE(
1469export fn bar() {}
1470pub const baz = 1234;
1471 )SOURCE");
127 for (size_t i = 0; i < count; i += 1) {
128 const char *arg = va_arg(ap, const char *);
129 test_case->compile_errors.append(arg);
1472130 }
1473131
1474 add_compile_fail_case("pass non-copyable type by value to function", R"SOURCE(
1475const Point = struct { x: i32, y: i32, };
1476fn foo(p: Point) { }
1477export fn entry() -> usize { @sizeOf(@typeOf(foo)) }
1478 )SOURCE", 1, ".tmp_source.zig:3:11: error: type 'Point' is not copyable; cannot pass by value");
1479
1480 add_compile_fail_case("implicit cast from array to mutable slice", R"SOURCE(
1481var global_array: [10]i32 = undefined;
1482fn foo(param: []i32) {}
1483export fn entry() {
1484 foo(global_array);
1485}
1486 )SOURCE", 1, ".tmp_source.zig:5:9: error: expected type '[]i32', found '[10]i32'");
1487
1488 add_compile_fail_case("ptrcast to non-pointer", R"SOURCE(
1489export fn entry(a: &i32) -> usize {
1490 return @ptrcast(usize, a);
1491}
1492 )SOURCE", 1, ".tmp_source.zig:3:21: error: expected pointer, found 'usize'");
1493
1494 add_compile_fail_case("too many error values to cast to small integer", R"SOURCE(
1495error A; error B; error C; error D; error E; error F; error G; error H;
1496const u2 = @IntType(false, 2);
1497fn foo(e: error) -> u2 {
1498 return u2(e);
1499}
1500export fn entry() -> usize { @sizeOf(@typeOf(foo)) }
1501 )SOURCE", 1, ".tmp_source.zig:5:14: error: too many error values to fit in 'u2'");
1502
1503 add_compile_fail_case("asm at compile time", R"SOURCE(
1504comptime {
1505 doSomeAsm();
1506}
1507
1508fn doSomeAsm() {
1509 asm volatile (
1510 \\.globl aoeu;
1511 \\.type aoeu, @function;
1512 \\.set aoeu, derp;
1513 );
1514}
1515 )SOURCE", 1, ".tmp_source.zig:7:5: error: unable to evaluate constant expression");
1516
1517 add_compile_fail_case("invalid member of builtin enum", R"SOURCE(
1518export fn entry() {
1519 const foo = Arch.x86;
1520}
1521 )SOURCE", 1, ".tmp_source.zig:3:21: error: container 'Arch' has no member called 'x86'");
1522
1523 add_compile_fail_case("int to ptr of 0 bits", R"SOURCE(
1524export fn foo() {
1525 var x: usize = 0x1000;
1526 var y: &void = @intToPtr(&void, x);
1527}
1528 )SOURCE", 1, ".tmp_source.zig:4:31: error: type '&void' has 0 bits and cannot store information");
1529
1530 add_compile_fail_case("@fieldParentPtr - non struct", R"SOURCE(
1531const Foo = i32;
1532export fn foo(a: &i32) -> &Foo {
1533 return @fieldParentPtr(Foo, "a", a);
1534}
1535 )SOURCE", 1, ".tmp_source.zig:4:28: error: expected struct type, found 'i32'");
1536
1537 add_compile_fail_case("@fieldParentPtr - bad field name", R"SOURCE(
1538const Foo = struct {
1539 derp: i32,
1540};
1541export fn foo(a: &i32) -> &Foo {
1542 return @fieldParentPtr(Foo, "a", a);
1543}
1544 )SOURCE", 1, ".tmp_source.zig:6:33: error: struct 'Foo' has no field 'a'");
1545
1546 add_compile_fail_case("@fieldParentPtr - field pointer is not pointer", R"SOURCE(
1547const Foo = struct {
1548 a: i32,
1549};
1550export fn foo(a: i32) -> &Foo {
1551 return @fieldParentPtr(Foo, "a", a);
1552}
1553 )SOURCE", 1, ".tmp_source.zig:6:38: error: expected pointer, found 'i32'");
1554
1555 add_compile_fail_case("@fieldParentPtr - comptime field ptr not based on struct", R"SOURCE(
1556const Foo = struct {
1557 a: i32,
1558 b: i32,
1559};
1560const foo = Foo { .a = 1, .b = 2, };
1561
1562comptime {
1563 const field_ptr = @intToPtr(&i32, 0x1234);
1564 const another_foo_ptr = @fieldParentPtr(Foo, "b", field_ptr);
1565}
1566 )SOURCE", 1, ".tmp_source.zig:10:55: error: pointer value not based on parent struct");
1567
1568 add_compile_fail_case("@fieldParentPtr - comptime wrong field index", R"SOURCE(
1569const Foo = struct {
1570 a: i32,
1571 b: i32,
1572};
1573const foo = Foo { .a = 1, .b = 2, };
1574
1575comptime {
1576 const another_foo_ptr = @fieldParentPtr(Foo, "b", &foo.a);
1577}
1578 )SOURCE", 1, ".tmp_source.zig:9:29: error: field 'b' has index 1 but pointer value is index 0 of struct 'Foo'");
1579
1580 add_compile_fail_case_exe("missing main fn in executable", R"SOURCE(
1581 )SOURCE", 1, "error: no member named 'main' in '");
1582
1583 add_compile_fail_case_exe("private main fn", R"SOURCE(
1584fn main() {}
1585 )SOURCE", 2,
1586 "error: 'main' is private",
1587 ".tmp_source.zig:2:1: note: declared here");
1588
1589}
132 test_case->compiler_args.append("parseh");
133 test_case->compiler_args.append(tmp_h_path);
134 //test_case->compiler_args.append("--verbose");
1590135
1591//////////////////////////////////////////////////////////////////////////////
136 test_cases.append(test_case);
1592137
1593static void add_parse_error_tests(void) {
1594 add_compile_fail_case("implicit semicolon - block statement", R"SOURCE(
1595export fn entry() {
1596 {}
1597 var good = {};
1598 ({})
1599 var bad = {};
1600}
1601 )SOURCE", 1, ".tmp_source.zig:6:5: error: invalid token: 'var'");
1602
1603 add_compile_fail_case("implicit semicolon - block expr", R"SOURCE(
1604export fn entry() {
1605 _ = {};
1606 var good = {};
1607 _ = {}
1608 var bad = {};
1609}
1610 )SOURCE", 1, ".tmp_source.zig:6:5: error: invalid token: 'var'");
1611
1612 add_compile_fail_case("implicit semicolon - comptime statement", R"SOURCE(
1613export fn entry() {
1614 comptime {}
1615 var good = {};
1616 comptime ({})
1617 var bad = {};
1618}
1619 )SOURCE", 1, ".tmp_source.zig:6:5: error: invalid token: 'var'");
1620
1621 add_compile_fail_case("implicit semicolon - comptime expression", R"SOURCE(
1622export fn entry() {
1623 _ = comptime {};
1624 var good = {};
1625 _ = comptime {}
1626 var bad = {};
1627}
1628 )SOURCE", 1, ".tmp_source.zig:6:5: error: invalid token: 'var'");
1629
1630 add_compile_fail_case("implicit semicolon - defer", R"SOURCE(
1631export fn entry() {
1632 defer {}
1633 var good = {};
1634 defer ({})
1635 var bad = {};
1636}
1637 )SOURCE", 1, ".tmp_source.zig:6:5: error: expected token ';', found 'var'");
1638
1639 add_compile_fail_case("implicit semicolon - if statement", R"SOURCE(
1640export fn entry() {
1641 if(true) {}
1642 var good = {};
1643 if(true) ({})
1644 var bad = {};
1645}
1646 )SOURCE", 1, ".tmp_source.zig:6:5: error: invalid token: 'var'");
1647
1648 add_compile_fail_case("implicit semicolon - if expression", R"SOURCE(
1649export fn entry() {
1650 _ = if(true) {};
1651 var good = {};
1652 _ = if(true) {}
1653 var bad = {};
1654}
1655 )SOURCE", 1, ".tmp_source.zig:6:5: error: invalid token: 'var'");
1656
1657 add_compile_fail_case("implicit semicolon - if-else statement", R"SOURCE(
1658export fn entry() {
1659 if(true) {} else {}
1660 var good = {};
1661 if(true) ({}) else ({})
1662 var bad = {};
1663}
1664 )SOURCE", 1, ".tmp_source.zig:6:5: error: invalid token: 'var'");
1665
1666 add_compile_fail_case("implicit semicolon - if-else expression", R"SOURCE(
1667export fn entry() {
1668 _ = if(true) {} else {};
1669 var good = {};
1670 _ = if(true) {} else {}
1671 var bad = {};
1672}
1673 )SOURCE", 1, ".tmp_source.zig:6:5: error: invalid token: 'var'");
1674
1675 add_compile_fail_case("implicit semicolon - if-else-if statement", R"SOURCE(
1676export fn entry() {
1677 if(true) {} else if(true) {}
1678 var good = {};
1679 if(true) ({}) else if(true) ({})
1680 var bad = {};
1681}
1682 )SOURCE", 1, ".tmp_source.zig:6:5: error: invalid token: 'var'");
1683
1684 add_compile_fail_case("implicit semicolon - if-else-if expression", R"SOURCE(
1685export fn entry() {
1686 _ = if(true) {} else if(true) {};
1687 var good = {};
1688 _ = if(true) {} else if(true) {}
1689 var bad = {};
1690}
1691 )SOURCE", 1, ".tmp_source.zig:6:5: error: invalid token: 'var'");
1692
1693 add_compile_fail_case("implicit semicolon - if-else-if-else statement", R"SOURCE(
1694export fn entry() {
1695 if(true) {} else if(true) {} else {}
1696 var good = {};
1697 if(true) ({}) else if(true) ({}) else ({})
1698 var bad = {};
1699}
1700 )SOURCE", 1, ".tmp_source.zig:6:5: error: invalid token: 'var'");
1701
1702 add_compile_fail_case("implicit semicolon - if-else-if-else expression", R"SOURCE(
1703export fn entry() {
1704 _ = if(true) {} else if(true) {} else {};
1705 var good = {};
1706 _ = if(true) {} else if(true) {} else {}
1707 var bad = {};
1708}
1709 )SOURCE", 1, ".tmp_source.zig:6:5: error: invalid token: 'var'");
1710
1711 add_compile_fail_case("implicit semicolon - if(var) statement", R"SOURCE(
1712export fn entry() {
1713 if(_=foo()) {}
1714 var good = {};
1715 if(_=foo()) ({})
1716 var bad = {};
1717}
1718 )SOURCE", 1, ".tmp_source.zig:6:5: error: invalid token: 'var'");
1719
1720 add_compile_fail_case("implicit semicolon - if(var) expression", R"SOURCE(
1721export fn entry() {
1722 _ = if(_=foo()) {};
1723 var good = {};
1724 _ = if(_=foo()) {}
1725 var bad = {};
1726}
1727 )SOURCE", 1, ".tmp_source.zig:6:5: error: invalid token: 'var'");
1728
1729 add_compile_fail_case("implicit semicolon - if(var)-else statement", R"SOURCE(
1730export fn entry() {
1731 if(_=foo()) {} else {}
1732 var good = {};
1733 if(_=foo()) ({}) else ({})
1734 var bad = {};
1735}
1736 )SOURCE", 1, ".tmp_source.zig:6:5: error: invalid token: 'var'");
1737
1738 add_compile_fail_case("implicit semicolon - if(var)-else expression", R"SOURCE(
1739export fn entry() {
1740 _ = if(_=foo()) {} else {};
1741 var good = {};
1742 _ = if(_=foo()) {} else {}
1743 var bad = {};
1744}
1745 )SOURCE", 1, ".tmp_source.zig:6:5: error: invalid token: 'var'");
1746
1747 add_compile_fail_case("implicit semicolon - if(var)-else-if(var) statement", R"SOURCE(
1748export fn entry() {
1749 if(_=foo()) {} else if(_=foo()) {}
1750 var good = {};
1751 if(_=foo()) ({}) else if(_=foo()) ({})
1752 var bad = {};
1753}
1754 )SOURCE", 1, ".tmp_source.zig:6:5: error: invalid token: 'var'");
1755
1756 add_compile_fail_case("implicit semicolon - if(var)-else-if(var) expression", R"SOURCE(
1757export fn entry() {
1758 _ = if(_=foo()) {} else if(_=foo()) {};
1759 var good = {};
1760 _ = if(_=foo()) {} else if(_=foo()) {}
1761 var bad = {};
1762}
1763 )SOURCE", 1, ".tmp_source.zig:6:5: error: invalid token: 'var'");
1764
1765 add_compile_fail_case("implicit semicolon - if(var)-else-if(var)-else statement", R"SOURCE(
1766export fn entry() {
1767 if(_=foo()) {} else if(_=foo()) {} else {}
1768 var good = {};
1769 if(_=foo()) ({}) else if(_=foo()) ({}) else ({})
1770 var bad = {};
1771}
1772 )SOURCE", 1, ".tmp_source.zig:6:5: error: invalid token: 'var'");
1773
1774 add_compile_fail_case("implicit semicolon - if(var)-else-if(var)-else expression", R"SOURCE(
1775export fn entry() {
1776 _ = if(_=foo()) {} else if(_=foo()) {} else {};
1777 var good = {};
1778 _ = if(_=foo()) {} else if(_=foo()) {} else {}
1779 var bad = {};
1780}
1781 )SOURCE", 1, ".tmp_source.zig:6:5: error: invalid token: 'var'");
1782
1783 add_compile_fail_case("implicit semicolon - try statement", R"SOURCE(
1784export fn entry() {
1785 try (_ = foo()) {}
1786 var good = {};
1787 try (_ = foo()) ({})
1788 var bad = {};
1789}
1790 )SOURCE", 1, ".tmp_source.zig:6:5: error: invalid token: 'var'");
1791
1792 add_compile_fail_case("implicit semicolon - try expression", R"SOURCE(
1793export fn entry() {
1794 _ = try (_ = foo()) {};
1795 var good = {};
1796 _ = try (_ = foo()) {}
1797 var bad = {};
1798}
1799 )SOURCE", 1, ".tmp_source.zig:6:5: error: invalid token: 'var'");
1800
1801 add_compile_fail_case("implicit semicolon - while statement", R"SOURCE(
1802export fn entry() {
1803 while(true) {}
1804 var good = {};
1805 while(true) ({})
1806 var bad = {};
1807}
1808 )SOURCE", 1, ".tmp_source.zig:6:5: error: invalid token: 'var'");
1809
1810 add_compile_fail_case("implicit semicolon - while expression", R"SOURCE(
1811export fn entry() {
1812 _ = while(true) {};
1813 var good = {};
1814 _ = while(true) {}
1815 var bad = {};
1816}
1817 )SOURCE", 1, ".tmp_source.zig:6:5: error: invalid token: 'var'");
1818
1819 add_compile_fail_case("implicit semicolon - while-continue statement", R"SOURCE(
1820export fn entry() {
1821 while(true;{}) {}
1822 var good = {};
1823 while(true;{}) ({})
1824 var bad = {};
1825}
1826 )SOURCE", 1, ".tmp_source.zig:6:5: error: invalid token: 'var'");
1827
1828 add_compile_fail_case("implicit semicolon - while-continue expression", R"SOURCE(
1829export fn entry() {
1830 _ = while(true;{}) {};
1831 var good = {};
1832 _ = while(true;{}) {}
1833 var bad = {};
1834}
1835 )SOURCE", 1, ".tmp_source.zig:6:5: error: invalid token: 'var'");
1836
1837 add_compile_fail_case("implicit semicolon - for statement", R"SOURCE(
1838export fn entry() {
1839 for(foo()) {}
1840 var good = {};
1841 for(foo()) ({})
1842 var bad = {};
1843}
1844 )SOURCE", 1, ".tmp_source.zig:6:5: error: invalid token: 'var'");
1845
1846 add_compile_fail_case("implicit semicolon - for expression", R"SOURCE(
1847export fn entry() {
1848 _ = for(foo()) {};
1849 var good = {};
1850 _ = for(foo()) {}
1851 var bad = {};
1852}
1853 )SOURCE", 1, ".tmp_source.zig:6:5: error: invalid token: 'var'");
138 va_end(ap);
139 return test_case;
1854140}
1855
1856141//////////////////////////////////////////////////////////////////////////////
1857142
1858143static void add_debug_safety_test_cases(void) {
......@@ -2281,95 +566,6 @@ struct comptime {
2281566 R"(pub const FOO_CHAR = 63;)");
2282567}
2283568
2284static void run_self_hosted_test(bool is_release_mode) {
2285 Buf self_hosted_tests_file = BUF_INIT;
2286 os_path_join(buf_create_from_str(ZIG_TEST_DIR),
2287 buf_create_from_str("self_hosted.zig"), &self_hosted_tests_file);
2288
2289 Buf zig_stderr = BUF_INIT;
2290 Buf zig_stdout = BUF_INIT;
2291 ZigList<const char *> args = {0};
2292 args.append("test");
2293 args.append(buf_ptr(&self_hosted_tests_file));
2294 if (is_release_mode) {
2295 args.append("--release");
2296 }
2297 Termination term;
2298 os_exec_process(zig_exe, args, &term, &zig_stderr, &zig_stdout);
2299
2300 if (term.how != TerminationIdClean || term.code != 0) {
2301 printf("\nSelf-hosted tests failed:\n");
2302 printf("./zig");
2303 for (size_t i = 0; i < args.length; i += 1) {
2304 printf(" %s", args.at(i));
2305 }
2306 printf("\n%s\n", buf_ptr(&zig_stderr));
2307 exit(1);
2308 }
2309}
2310
2311static void run_std_lib_test(bool is_release_mode) {
2312 Buf std_index_file = BUF_INIT;
2313 os_path_join(buf_create_from_str(ZIG_STD_DIR),
2314 buf_create_from_str("index.zig"), &std_index_file);
2315
2316 Buf zig_stderr = BUF_INIT;
2317 Buf zig_stdout = BUF_INIT;
2318 ZigList<const char *> args = {0};
2319 args.append("test");
2320 args.append(buf_ptr(&std_index_file));
2321 if (is_release_mode) {
2322 args.append("--release");
2323 }
2324 Termination term;
2325 os_exec_process(zig_exe, args, &term, &zig_stderr, &zig_stdout);
2326
2327 if (term.how != TerminationIdClean || term.code != 0) {
2328 printf("\nstd lib tests failed:\n");
2329 printf("./zig");
2330 for (size_t i = 0; i < args.length; i += 1) {
2331 printf(" %s", args.at(i));
2332 }
2333 printf("\n%s\n", buf_ptr(&zig_stderr));
2334 exit(1);
2335 }
2336}
2337
2338
2339static void add_self_hosted_tests(void) {
2340 {
2341 TestCase *test_case = allocate<TestCase>(1);
2342 test_case->case_name = "self hosted tests (debug)";
2343 test_case->special = TestSpecialSelfHosted;
2344 test_case->is_release_mode = false;
2345 test_cases.append(test_case);
2346 }
2347 {
2348 TestCase *test_case = allocate<TestCase>(1);
2349 test_case->case_name = "self hosted tests (release)";
2350 test_case->special = TestSpecialSelfHosted;
2351 test_case->is_release_mode = true;
2352 test_cases.append(test_case);
2353 }
2354}
2355
2356static void add_std_lib_tests(void) {
2357 {
2358 TestCase *test_case = allocate<TestCase>(1);
2359 test_case->case_name = "std (debug)";
2360 test_case->special = TestSpecialStd;
2361 test_case->is_release_mode = false;
2362 test_cases.append(test_case);
2363 }
2364 {
2365 TestCase *test_case = allocate<TestCase>(1);
2366 test_case->case_name = "std (release)";
2367 test_case->special = TestSpecialStd;
2368 test_case->is_release_mode = true;
2369 test_cases.append(test_case);
2370 }
2371}
2372
2373569static void add_asm_tests(void) {
2374570#if defined(ZIG_OS_LINUX) && defined(ZIG_ARCH_X86_64)
2375571 add_asm_case("assemble and link hello world linux x86_64", R"SOURCE(
......@@ -2423,12 +619,6 @@ static void print_exe_invocation(TestCase *test_case) {
2423619}
2424620
2425621static void run_test(TestCase *test_case) {
2426 if (test_case->special == TestSpecialSelfHosted) {
2427 return run_self_hosted_test(test_case->is_release_mode);
2428 } else if (test_case->special == TestSpecialStd) {
2429 return run_std_lib_test(test_case->is_release_mode);
2430 }
2431
2432622 for (size_t i = 0; i < test_case->source_files.length; i += 1) {
2433623 TestSourceFile *test_source = &test_case->source_files.at(i);
2434624 os_write_file(
......@@ -2609,11 +799,7 @@ int main(int argc, char **argv) {
2609799 }
2610800 }
2611801 add_debug_safety_test_cases();
2612 add_compile_failure_test_cases();
2613 add_parse_error_tests();
2614802 add_parseh_test_cases();
2615 add_self_hosted_tests();
2616 add_std_lib_tests();
2617803 add_asm_tests();
2618804 run_all_tests(grep_text);
2619805 cleanup();
test/tests.zig+1
......@@ -1,2 +1,3 @@
11pub const addCompareOutputTests = @import("compare_output.zig").addCompareOutputTests;
22pub const addBuildExampleTests = @import("build_examples.zig").addBuildExampleTests;
3pub const addCompileErrorTests = @import("compile_errors.zig").addCompileErrorTests;