authorgravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2019-02-10 11:03:17-05:00
committergravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2019-02-10 11:03:17-05:00
logbcbcb2e9ffbfef63d3692ea45eea2e2babacc3a9
tree48f4df2e6ce5e12077743a84433c4c2537dd4fc2
parent1864acd32608ae917f8afc11b11f08a4bb362cef
parent2f9fedabf0805a47aba5c348e5369c1c28f6cf21
signaturelock-open Commit is signed but in an unrecognized format.

Merge remote-tracking branch 'origin/master' into llvm8


7 files changed, 68 insertions(+), 20 deletions(-)

doc/langref.html.in+10-6
...@@ -6381,14 +6381,14 @@ fn List(comptime T: type) type {...@@ -6381,14 +6381,14 @@ fn List(comptime T: type) type {
6381 {#header_close#}6381 {#header_close#}
63826382
6383 {#header_open|@truncate#}6383 {#header_open|@truncate#}
6384 <pre>{#syntax#}@truncate(comptime T: type, integer) T{#endsyntax#}</pre>6384 <pre>{#syntax#}@truncate(comptime T: type, integer: var) T{#endsyntax#}</pre>
6385 <p>6385 <p>
6386 This function truncates bits from an integer type, resulting in a smaller6386 This function truncates bits from an integer type, resulting in a smaller
6387 integer type.6387 integer type.
6388 </p>6388 </p>
6389 <p>6389 <p>
6390 The following produces a crash in debug mode and undefined behavior in6390 The following produces a crash in {#link|Debug#} mode and {#link|Undefined Behavior#} in
6391 release mode:6391 {#link|ReleaseFast#} mode:
6392 </p>6392 </p>
6393 <pre>{#syntax#}const a: u16 = 0xabcd;6393 <pre>{#syntax#}const a: u16 = 0xabcd;
6394const b: u8 = u8(a);{#endsyntax#}</pre>6394const b: u8 = u8(a);{#endsyntax#}</pre>
...@@ -6402,7 +6402,10 @@ const b: u8 = @truncate(u8, a);...@@ -6402,7 +6402,10 @@ const b: u8 = @truncate(u8, a);
6402 This function always truncates the significant bits of the integer, regardless6402 This function always truncates the significant bits of the integer, regardless
6403 of endianness on the target platform.6403 of endianness on the target platform.
6404 </p>6404 </p>
64056405 <p>
6406 If {#syntax#}T{#endsyntax#} is {#syntax#}comptime_int{#endsyntax#},
6407 then this is semantically equivalent to an {#link|implicit cast|Implicit Casts#}.
6408 </p>
6406 {#header_close#}6409 {#header_close#}
64076410
6408 {#header_open|@typeId#}6411 {#header_open|@typeId#}
...@@ -7870,7 +7873,7 @@ TopLevelComptime &lt;- KEYWORD_comptime BlockExpr...@@ -7870,7 +7873,7 @@ TopLevelComptime &lt;- KEYWORD_comptime BlockExpr
78707873
7871TopLevelDecl7874TopLevelDecl
7872 &lt;- (KEYWORD_export / KEYWORD_extern STRINGLITERAL? / KEYWORD_inline)? FnProto (SEMICOLON / Block)7875 &lt;- (KEYWORD_export / KEYWORD_extern STRINGLITERAL? / KEYWORD_inline)? FnProto (SEMICOLON / Block)
7873 / (KEYWORD_export / KEYWORD_extern STRINGLITERAL?)? VarDecl7876 / (KEYWORD_export / KEYWORD_extern STRINGLITERAL?)? KEYWORD_threadlocal? VarDecl
7874 / KEYWORD_use Expr SEMICOLON7877 / KEYWORD_use Expr SEMICOLON
78757878
7876FnProto &lt;- FnCC? KEYWORD_fn IDENTIFIER? LPAREN ParamDeclList RPAREN ByteAlign? LinkSection? EXCLAMATIONMARK? (KEYWORD_var / TypeExpr)7879FnProto &lt;- FnCC? KEYWORD_fn IDENTIFIER? LPAREN ParamDeclList RPAREN ByteAlign? LinkSection? EXCLAMATIONMARK? (KEYWORD_var / TypeExpr)
...@@ -8330,6 +8333,7 @@ KEYWORD_struct &lt;- 'struct' end_of_word...@@ -8330,6 +8333,7 @@ KEYWORD_struct &lt;- 'struct' end_of_word
8330KEYWORD_suspend &lt;- 'suspend' end_of_word8333KEYWORD_suspend &lt;- 'suspend' end_of_word
8331KEYWORD_switch &lt;- 'switch' end_of_word8334KEYWORD_switch &lt;- 'switch' end_of_word
8332KEYWORD_test &lt;- 'test' end_of_word8335KEYWORD_test &lt;- 'test' end_of_word
8336KEYWORD_threadlocal &lt;- 'threadlocal' end_of_word
8333KEYWORD_true &lt;- 'true' end_of_word8337KEYWORD_true &lt;- 'true' end_of_word
8334KEYWORD_try &lt;- 'try' end_of_word8338KEYWORD_try &lt;- 'try' end_of_word
8335KEYWORD_undefined &lt;- 'undefined' end_of_word8339KEYWORD_undefined &lt;- 'undefined' end_of_word
...@@ -8350,7 +8354,7 @@ keyword &lt;- KEYWORD_align / KEYWORD_and / KEYWORD_anyerror / KEYWORD_asm...@@ -8350,7 +8354,7 @@ keyword &lt;- KEYWORD_align / KEYWORD_and / KEYWORD_anyerror / KEYWORD_asm
8350 / KEYWORD_orelse / KEYWORD_packed / KEYWORD_promise / KEYWORD_pub8354 / KEYWORD_orelse / KEYWORD_packed / KEYWORD_promise / KEYWORD_pub
8351 / KEYWORD_resume / KEYWORD_return / KEYWORD_linksection8355 / KEYWORD_resume / KEYWORD_return / KEYWORD_linksection
8352 / KEYWORD_stdcallcc / KEYWORD_struct / KEYWORD_suspend8356 / KEYWORD_stdcallcc / KEYWORD_struct / KEYWORD_suspend
8353 / KEYWORD_switch / KEYWORD_test / KEYWORD_true / KEYWORD_try8357 / KEYWORD_switch / KEYWORD_test / KEYWORD_threadlocal / KEYWORD_true / KEYWORD_try
8354 / KEYWORD_undefined / KEYWORD_union / KEYWORD_unreachable8358 / KEYWORD_undefined / KEYWORD_union / KEYWORD_unreachable
8355 / KEYWORD_use / KEYWORD_var / KEYWORD_volatile / KEYWORD_while</code></pre>8359 / KEYWORD_use / KEYWORD_var / KEYWORD_volatile / KEYWORD_while</code></pre>
8356 {#header_close#}8360 {#header_close#}
src/analyze.cpp+3
...@@ -594,6 +594,9 @@ ZigType *get_optional_type(CodeGen *g, ZigType *child_type) {...@@ -594,6 +594,9 @@ ZigType *get_optional_type(CodeGen *g, ZigType *child_type) {
594 // function types are technically pointers594 // function types are technically pointers
595 entry->type_ref = child_type->type_ref;595 entry->type_ref = child_type->type_ref;
596 entry->di_type = child_type->di_type;596 entry->di_type = child_type->di_type;
597 if (entry->di_type == g->builtin_types.entry_global_error_set->di_type) {
598 g->error_di_types.append(&entry->di_type);
599 }
597 } else {600 } else {
598 assert(child_type->di_type);601 assert(child_type->di_type);
599 // create a struct with a boolean whether this is the null value602 // create a struct with a boolean whether this is the null value
src/ir.cpp+16-8
...@@ -18491,7 +18491,22 @@ static IrInstruction *ir_analyze_instruction_truncate(IrAnalyze *ira, IrInstruct...@@ -18491,7 +18491,22 @@ static IrInstruction *ir_analyze_instruction_truncate(IrAnalyze *ira, IrInstruct
18491 return ira->codegen->invalid_instruction;18491 return ira->codegen->invalid_instruction;
18492 }18492 }
1849318493
18494 if (src_type->data.integral.bit_count == 0) {18494 if (dest_type->id == ZigTypeIdComptimeInt) {
18495 return ir_implicit_cast(ira, target, dest_type);
18496 }
18497
18498 if (instr_is_comptime(target)) {
18499 ConstExprValue *val = ir_resolve_const(ira, target, UndefBad);
18500 if (val == nullptr)
18501 return ira->codegen->invalid_instruction;
18502
18503 IrInstruction *result = ir_const(ira, &instruction->base, dest_type);
18504 bigint_truncate(&result->value.data.x_bigint, &val->data.x_bigint,
18505 dest_type->data.integral.bit_count, dest_type->data.integral.is_signed);
18506 return result;
18507 }
18508
18509 if (src_type->data.integral.bit_count == 0 || dest_type->data.integral.bit_count == 0) {
18495 IrInstruction *result = ir_const(ira, &instruction->base, dest_type);18510 IrInstruction *result = ir_const(ira, &instruction->base, dest_type);
18496 bigint_init_unsigned(&result->value.data.x_bigint, 0);18511 bigint_init_unsigned(&result->value.data.x_bigint, 0);
18497 return result;18512 return result;
...@@ -18507,13 +18522,6 @@ static IrInstruction *ir_analyze_instruction_truncate(IrAnalyze *ira, IrInstruct...@@ -18507,13 +18522,6 @@ static IrInstruction *ir_analyze_instruction_truncate(IrAnalyze *ira, IrInstruct
18507 return ira->codegen->invalid_instruction;18522 return ira->codegen->invalid_instruction;
18508 }18523 }
1850918524
18510 if (target->value.special == ConstValSpecialStatic) {
18511 IrInstruction *result = ir_const(ira, &instruction->base, dest_type);
18512 bigint_truncate(&result->value.data.x_bigint, &target->value.data.x_bigint,
18513 dest_type->data.integral.bit_count, dest_type->data.integral.is_signed);
18514 return result;
18515 }
18516
18517 IrInstruction *new_instruction = ir_build_truncate(&ira->new_irb, instruction->base.scope,18525 IrInstruction *new_instruction = ir_build_truncate(&ira->new_irb, instruction->base.scope,
18518 instruction->base.source_node, dest_type_value, target);18526 instruction->base.source_node, dest_type_value, target);
18519 new_instruction->value.type = dest_type;18527 new_instruction->value.type = dest_type;
std/testing.zig+1-5
...@@ -24,11 +24,7 @@ pub fn expectError(expected_error: anyerror, actual_error_union: var) void {...@@ -24,11 +24,7 @@ pub fn expectError(expected_error: anyerror, actual_error_union: var) void {
24/// equal, prints diagnostics to stderr to show exactly how they are not equal,24/// equal, prints diagnostics to stderr to show exactly how they are not equal,
25/// then aborts.25/// then aborts.
26/// The types must match exactly.26/// The types must match exactly.
27pub fn expectEqual(expected: var, actual: var) void {27pub fn expectEqual(expected: var, actual: @typeOf(expected)) void {
28 if (@typeOf(actual) != @typeOf(expected)) {
29 @compileError("type mismatch. expected " ++ @typeName(@typeOf(expected)) ++ ", found " ++ @typeName(@typeOf(actual)));
30 }
31
32 switch (@typeInfo(@typeOf(actual))) {28 switch (@typeInfo(@typeOf(actual))) {
33 TypeId.NoReturn,29 TypeId.NoReturn,
34 TypeId.BoundFn,30 TypeId.BoundFn,
test/compile_errors.zig+10-1
...@@ -1,6 +1,15 @@...@@ -1,6 +1,15 @@
1const tests = @import("tests.zig");1const tests = @import("tests.zig");
22
3pub fn addCases(cases: *tests.CompileErrorContext) void {3pub fn addCases(cases: *tests.CompileErrorContext) void {
4 cases.addTest(
5 "@truncate undefined value",
6 \\export fn entry() void {
7 \\ var z = @truncate(u8, u16(undefined));
8 \\}
9 ,
10 ".tmp_source.zig:2:30: error: use of undefined value",
11 );
12
4 cases.addTest(13 cases.addTest(
5 "return invalid type from test",14 "return invalid type from test",
6 \\test "example" { return 1; }15 \\test "example" { return 1; }
...@@ -3335,7 +3344,7 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {...@@ -3335,7 +3344,7 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {
3335 cases.add(3344 cases.add(
3336 "truncate sign mismatch",3345 "truncate sign mismatch",
3337 \\fn f() i8 {3346 \\fn f() i8 {
3338 \\ const x: u32 = 10;3347 \\ var x: u32 = 10;
3339 \\ return @truncate(i8, x);3348 \\ return @truncate(i8, x);
3340 \\}3349 \\}
3341 \\3350 \\
test/stage1/behavior/error.zig+5
...@@ -330,3 +330,8 @@ test "optional error set is the same size as error set" {...@@ -330,3 +330,8 @@ test "optional error set is the same size as error set" {
330 expect(S.returnsOptErrSet() == null);330 expect(S.returnsOptErrSet() == null);
331 comptime expect(S.returnsOptErrSet() == null);331 comptime expect(S.returnsOptErrSet() == null);
332}332}
333
334test "debug info for optional error set" {
335 const SomeError = error{Hello};
336 var a_local_variable: ?SomeError = null;
337}
test/stage1/behavior/truncate.zig+23
...@@ -6,3 +6,26 @@ test "truncate u0 to larger integer allowed and has comptime known result" {...@@ -6,3 +6,26 @@ test "truncate u0 to larger integer allowed and has comptime known result" {
6 const y = @truncate(u8, x);6 const y = @truncate(u8, x);
7 comptime expect(y == 0);7 comptime expect(y == 0);
8}8}
9
10test "truncate.u0.literal" {
11 var z = @truncate(u0, 0);
12 expect(z == 0);
13}
14
15test "truncate.u0.const" {
16 const c0: usize = 0;
17 var z = @truncate(u0, c0);
18 expect(z == 0);
19}
20
21test "truncate.u0.var" {
22 var d: u8 = 2;
23 var z = @truncate(u0, d);
24 expect(z == 0);
25}
26
27test "truncate sign mismatch but comptime known so it works anyway" {
28 const x: u32 = 10;
29 var result = @truncate(i8, x);
30 expect(result == 10);
31}