| author | |
| committer | |
| log | fd6020c4e26c5a1e3652c2f88ab4e668f6fc1dbc |
| tree | b355a679245752973edda218201550def88aa58d |
| parent | cf2fe2536e65e7d0d8892f630282f3d264454cc3 |
| signature |
6 files changed, 50 insertions(+), 44 deletions(-)
lib/std/zig/parser_test.zig-6| ... | ... | @@ -1725,11 +1725,6 @@ test "zig fmt: multiline string" { |
| 1725 | 1725 | \\ \\two) |
| 1726 | 1726 | \\ \\three |
| 1727 | 1727 | \\ ; |
| 1728 | \\ const s2 = | |
| 1729 | \\ c\\one | |
| 1730 | \\ c\\two) | |
| 1731 | \\ c\\three | |
| 1732 | \\ ; | |
| 1733 | 1728 | \\ const s3 = // hi |
| 1734 | 1729 | \\ \\one |
| 1735 | 1730 | \\ \\two) |
| ... | ... | @@ -1746,7 +1741,6 @@ test "zig fmt: values" { |
| 1746 | 1741 | \\ 1; |
| 1747 | 1742 | \\ 1.0; |
| 1748 | 1743 | \\ "string"; |
| 1749 | \\ c"cstring"; | |
| 1750 | 1744 | \\ 'c'; |
| 1751 | 1745 | \\ true; |
| 1752 | 1746 | \\ false; |
lib/std/zig/tokenizer.zig+1-21| ... | ... | @@ -351,7 +351,6 @@ pub const Tokenizer = struct { |
| 351 | 351 | Start, |
| 352 | 352 | Identifier, |
| 353 | 353 | Builtin, |
| 354 | C, | |
| 355 | 354 | StringLiteral, |
| 356 | 355 | StringLiteralBackslash, |
| 357 | 356 | MultilineStringLiteralLine, |
| ... | ... | @@ -427,10 +426,6 @@ pub const Tokenizer = struct { |
| 427 | 426 | ' ', '\n', '\t', '\r' => { |
| 428 | 427 | result.start = self.index + 1; |
| 429 | 428 | }, |
| 430 | 'c' => { | |
| 431 | state = State.C; | |
| 432 | result.id = Token.Id.Identifier; | |
| 433 | }, | |
| 434 | 429 | '"' => { |
| 435 | 430 | state = State.StringLiteral; |
| 436 | 431 | result.id = Token.Id.StringLiteral; |
| ... | ... | @@ -438,7 +433,7 @@ pub const Tokenizer = struct { |
| 438 | 433 | '\'' => { |
| 439 | 434 | state = State.CharLiteral; |
| 440 | 435 | }, |
| 441 | 'a'...'b', 'd'...'z', 'A'...'Z', '_' => { | |
| 436 | 'a'...'z', 'A'...'Z', '_' => { | |
| 442 | 437 | state = State.Identifier; |
| 443 | 438 | result.id = Token.Id.Identifier; |
| 444 | 439 | }, |
| ... | ... | @@ -730,20 +725,6 @@ pub const Tokenizer = struct { |
| 730 | 725 | }, |
| 731 | 726 | else => break, |
| 732 | 727 | }, |
| 733 | State.C => switch (c) { | |
| 734 | '\\' => { | |
| 735 | state = State.Backslash; | |
| 736 | result.id = Token.Id.MultilineStringLiteralLine; | |
| 737 | }, | |
| 738 | '"' => { | |
| 739 | state = State.StringLiteral; | |
| 740 | result.id = Token.Id.StringLiteral; | |
| 741 | }, | |
| 742 | 'a'...'z', 'A'...'Z', '_', '0'...'9' => { | |
| 743 | state = State.Identifier; | |
| 744 | }, | |
| 745 | else => break, | |
| 746 | }, | |
| 747 | 728 | State.StringLiteral => switch (c) { |
| 748 | 729 | '\\' => { |
| 749 | 730 | state = State.StringLiteralBackslash; |
| ... | ... | @@ -1204,7 +1185,6 @@ pub const Tokenizer = struct { |
| 1204 | 1185 | } else if (self.index == self.buffer.len) { |
| 1205 | 1186 | switch (state) { |
| 1206 | 1187 | State.Start, |
| 1207 | State.C, | |
| 1208 | 1188 | State.IntegerLiteral, |
| 1209 | 1189 | State.IntegerLiteralWithRadix, |
| 1210 | 1190 | State.IntegerLiteralWithRadixHex, |
src-self-hosted/translate_c.zig+3-4| ... | ... | @@ -698,10 +698,9 @@ fn transStringLiteral( |
| 698 | 698 | len = 0; |
| 699 | 699 | for (str) |c| len += escapeChar(c, &char_buf).len; |
| 700 | 700 | |
| 701 | const buf = try rp.c.a().alloc(u8, len + "c\"\"".len); | |
| 702 | buf[0] = 'c'; | |
| 703 | buf[1] = '"'; | |
| 704 | writeEscapedString(buf[2..], str); | |
| 701 | const buf = try rp.c.a().alloc(u8, len + "\"\"".len); | |
| 702 | buf[0] = '"'; | |
| 703 | writeEscapedString(buf[1..], str); | |
| 705 | 704 | buf[buf.len - 1] = '"'; |
| 706 | 705 | |
| 707 | 706 | const token = try appendToken(rp.c, .StringLiteral, buf); |
src/ir.cpp+35-3| ... | ... | @@ -69,6 +69,7 @@ enum ConstCastResultId { |
| 69 | 69 | ConstCastResultIdArrayChild, |
| 70 | 70 | ConstCastResultIdBadNullTermArrays, |
| 71 | 71 | ConstCastResultIdPtrLens, |
| 72 | ConstCastResultIdCV, | |
| 72 | 73 | }; |
| 73 | 74 | |
| 74 | 75 | struct ConstCastOnly; |
| ... | ... | @@ -94,6 +95,7 @@ struct ConstCastArrayMismatch; |
| 94 | 95 | struct ConstCastBadAllowsZero; |
| 95 | 96 | struct ConstCastBadNullTermArrays; |
| 96 | 97 | struct ConstCastBadPtrLens; |
| 98 | struct ConstCastBadCV; | |
| 97 | 99 | |
| 98 | 100 | struct ConstCastOnly { |
| 99 | 101 | ConstCastResultId id; |
| ... | ... | @@ -113,6 +115,7 @@ struct ConstCastOnly { |
| 113 | 115 | ConstCastBadAllowsZero *bad_allows_zero; |
| 114 | 116 | ConstCastBadNullTermArrays *bad_null_term_arrays; |
| 115 | 117 | ConstCastBadPtrLens *bad_ptr_lens; |
| 118 | ConstCastBadCV *bad_cv; | |
| 116 | 119 | } data; |
| 117 | 120 | }; |
| 118 | 121 | |
| ... | ... | @@ -177,6 +180,10 @@ struct ConstCastBadPtrLens { |
| 177 | 180 | ZigType *actual_type; |
| 178 | 181 | }; |
| 179 | 182 | |
| 183 | struct ConstCastBadCV { | |
| 184 | ZigType *wanted_type; | |
| 185 | ZigType *actual_type; | |
| 186 | }; | |
| 180 | 187 | |
| 181 | 188 | static IrInstruction *ir_gen_node(IrBuilder *irb, AstNode *node, Scope *scope); |
| 182 | 189 | static IrInstruction *ir_gen_node_extra(IrBuilder *irb, AstNode *node, Scope *scope, LVal lval, |
| ... | ... | @@ -9863,6 +9870,17 @@ static ConstCastOnly types_match_const_cast_only(IrAnalyze *ira, ZigType *wanted |
| 9863 | 9870 | return result; |
| 9864 | 9871 | } |
| 9865 | 9872 | |
| 9873 | bool ok_cv_qualifiers = | |
| 9874 | (!actual_ptr_type->data.pointer.is_const || wanted_ptr_type->data.pointer.is_const) && | |
| 9875 | (!actual_ptr_type->data.pointer.is_volatile || wanted_ptr_type->data.pointer.is_volatile); | |
| 9876 | if (!ok_cv_qualifiers) { | |
| 9877 | result.id = ConstCastResultIdCV; | |
| 9878 | result.data.bad_cv = allocate_nonzero<ConstCastBadCV>(1); | |
| 9879 | result.data.bad_cv->wanted_type = wanted_ptr_type; | |
| 9880 | result.data.bad_cv->actual_type = actual_ptr_type; | |
| 9881 | return result; | |
| 9882 | } | |
| 9883 | ||
| 9866 | 9884 | ConstCastOnly child = types_match_const_cast_only(ira, wanted_ptr_type->data.pointer.child_type, |
| 9867 | 9885 | actual_ptr_type->data.pointer.child_type, source_node, !wanted_ptr_type->data.pointer.is_const); |
| 9868 | 9886 | if (child.id == ConstCastResultIdInvalid) |
| ... | ... | @@ -9902,8 +9920,6 @@ static ConstCastOnly types_match_const_cast_only(IrAnalyze *ira, ZigType *wanted |
| 9902 | 9920 | return result; |
| 9903 | 9921 | } |
| 9904 | 9922 | if (type_has_bits(wanted_type) == type_has_bits(actual_type) && |
| 9905 | (!actual_ptr_type->data.pointer.is_const || wanted_ptr_type->data.pointer.is_const) && | |
| 9906 | (!actual_ptr_type->data.pointer.is_volatile || wanted_ptr_type->data.pointer.is_volatile) && | |
| 9907 | 9923 | actual_ptr_type->data.pointer.bit_offset_in_host == wanted_ptr_type->data.pointer.bit_offset_in_host && |
| 9908 | 9924 | actual_ptr_type->data.pointer.host_int_bytes == wanted_ptr_type->data.pointer.host_int_bytes && |
| 9909 | 9925 | get_ptr_align(ira->codegen, actual_ptr_type) >= get_ptr_align(ira->codegen, wanted_ptr_type)) |
| ... | ... | @@ -12595,6 +12611,20 @@ static void report_recursive_error(IrAnalyze *ira, AstNode *source_node, ConstCa |
| 12595 | 12611 | } |
| 12596 | 12612 | break; |
| 12597 | 12613 | } |
| 12614 | case ConstCastResultIdCV: { | |
| 12615 | ZigType *wanted_type = cast_result->data.bad_cv->wanted_type; | |
| 12616 | ZigType *actual_type = cast_result->data.bad_cv->actual_type; | |
| 12617 | bool ok_const = !actual_type->data.pointer.is_const || wanted_type->data.pointer.is_const; | |
| 12618 | bool ok_volatile = !actual_type->data.pointer.is_volatile || wanted_type->data.pointer.is_volatile; | |
| 12619 | if (!ok_const) { | |
| 12620 | add_error_note(ira->codegen, parent_msg, source_node, buf_sprintf("cast discards const qualifier")); | |
| 12621 | } else if (!ok_volatile) { | |
| 12622 | add_error_note(ira->codegen, parent_msg, source_node, buf_sprintf("cast discards volatile qualifier")); | |
| 12623 | } else { | |
| 12624 | zig_unreachable(); | |
| 12625 | } | |
| 12626 | break; | |
| 12627 | } | |
| 12598 | 12628 | case ConstCastResultIdFnIsGeneric: |
| 12599 | 12629 | add_error_note(ira->codegen, parent_msg, source_node, |
| 12600 | 12630 | buf_sprintf("only one of the functions is generic")); |
| ... | ... | @@ -12987,7 +13017,9 @@ static IrInstruction *ir_analyze_cast(IrAnalyze *ira, IrInstruction *source_inst |
| 12987 | 13017 | wanted_type->data.pointer.ptr_len == PtrLenNull) && |
| 12988 | 13018 | actual_type->id == ZigTypeIdPointer && |
| 12989 | 13019 | actual_type->data.pointer.ptr_len == PtrLenSingle && |
| 12990 | actual_type->data.pointer.child_type->id == ZigTypeIdArray) | |
| 13020 | actual_type->data.pointer.child_type->id == ZigTypeIdArray && | |
| 13021 | (!actual_type->data.pointer.is_const || wanted_type->data.pointer.is_const) && | |
| 13022 | (!actual_type->data.pointer.is_volatile || wanted_type->data.pointer.is_volatile)) | |
| 12991 | 13023 | { |
| 12992 | 13024 | if (wanted_type->data.pointer.ptr_len != PtrLenNull || |
| 12993 | 13025 | actual_type->data.pointer.child_type->data.array.is_null_terminated) |
test/compile_errors.zig+10-9| ... | ... | @@ -784,7 +784,8 @@ pub fn addCases(cases: *tests.CompileErrorContext) void { |
| 784 | 784 | \\ strValue = strValue orelse ""; |
| 785 | 785 | \\} |
| 786 | 786 | , |
| 787 | "tmp.zig:3:32: error: cast discards const qualifier", | |
| 787 | "tmp.zig:3:32: error: expected type '[*c]u8', found '*const [0]null u8'", | |
| 788 | "tmp.zig:3:32: note: cast discards const qualifier", | |
| 788 | 789 | ); |
| 789 | 790 | |
| 790 | 791 | cases.add( |
| ... | ... | @@ -1323,7 +1324,7 @@ pub fn addCases(cases: *tests.CompileErrorContext) void { |
| 1323 | 1324 | \\ ptr_opt_many_ptr = c_ptr; |
| 1324 | 1325 | \\} |
| 1325 | 1326 | \\export fn entry2() void { |
| 1326 | \\ var buf: [4]u8 = "aoeu"; | |
| 1327 | \\ var buf: [4]u8 = "aoeu".*; | |
| 1327 | 1328 | \\ var slice: []u8 = &buf; |
| 1328 | 1329 | \\ var opt_many_ptr: [*]u8 = slice.ptr; |
| 1329 | 1330 | \\ var ptr_opt_many_ptr = &opt_many_ptr; |
| ... | ... | @@ -1518,7 +1519,7 @@ pub fn addCases(cases: *tests.CompileErrorContext) void { |
| 1518 | 1519 | cases.add( |
| 1519 | 1520 | "reading past end of pointer casted array", |
| 1520 | 1521 | \\comptime { |
| 1521 | \\ const array = "aoeu"; | |
| 1522 | \\ const array: [4]u8 = "aoeu".*; | |
| 1522 | 1523 | \\ const slice = array[1..]; |
| 1523 | 1524 | \\ const int_ptr = @ptrCast(*const u24, slice.ptr); |
| 1524 | 1525 | \\ const deref = int_ptr.*; |
| ... | ... | @@ -3356,7 +3357,7 @@ pub fn addCases(cases: *tests.CompileErrorContext) void { |
| 3356 | 3357 | \\ return a; |
| 3357 | 3358 | \\} |
| 3358 | 3359 | , |
| 3359 | "tmp.zig:3:12: error: expected type 'i32', found '[*]const u8'", | |
| 3360 | "tmp.zig:3:12: error: expected type 'i32', found '*const [1]null u8'", | |
| 3360 | 3361 | ); |
| 3361 | 3362 | |
| 3362 | 3363 | cases.add( |
| ... | ... | @@ -3827,12 +3828,12 @@ pub fn addCases(cases: *tests.CompileErrorContext) void { |
| 3827 | 3828 | cases.add( |
| 3828 | 3829 | "array concatenation with wrong type", |
| 3829 | 3830 | \\const src = "aoeu"; |
| 3830 | \\const derp = @as(usize, 1234); | |
| 3831 | \\const derp: usize = 1234; | |
| 3831 | 3832 | \\const a = derp ++ "foo"; |
| 3832 | 3833 | \\ |
| 3833 | 3834 | \\export fn entry() usize { return @sizeOf(@typeOf(a)); } |
| 3834 | 3835 | , |
| 3835 | "tmp.zig:3:11: error: expected array or C string literal, found 'usize'", | |
| 3836 | "tmp.zig:3:11: error: expected array, found 'usize'", | |
| 3836 | 3837 | ); |
| 3837 | 3838 | |
| 3838 | 3839 | cases.add( |
| ... | ... | @@ -6207,11 +6208,11 @@ pub fn addCases(cases: *tests.CompileErrorContext) void { |
| 6207 | 6208 | cases.add( |
| 6208 | 6209 | "calling var args extern function, passing array instead of pointer", |
| 6209 | 6210 | \\export fn entry() void { |
| 6210 | \\ foo("hello",); | |
| 6211 | \\ foo("hello".*,); | |
| 6211 | 6212 | \\} |
| 6212 | 6213 | \\pub extern fn foo(format: *const u8, ...) void; |
| 6213 | 6214 | , |
| 6214 | "tmp.zig:2:9: error: expected type '*const u8', found '[5]u8'", | |
| 6215 | "tmp.zig:2:16: error: expected type '*const u8', found '[5]null u8'", | |
| 6215 | 6216 | ); |
| 6216 | 6217 | |
| 6217 | 6218 | cases.add( |
| ... | ... | @@ -6777,7 +6778,7 @@ pub fn addCases(cases: *tests.CompileErrorContext) void { |
| 6777 | 6778 | \\} |
| 6778 | 6779 | , |
| 6779 | 6780 | "tmp.zig:4:22: error: expected type '*[1]i32', found '*const i32'", |
| 6780 | "tmp.zig:4:22: note: pointer type child 'i32' cannot cast into pointer type child '[1]i32'", | |
| 6781 | "tmp.zig:4:22: note: cast discards const qualifier", | |
| 6781 | 6782 | ); |
| 6782 | 6783 | |
| 6783 | 6784 | cases.add( |
test/stage1/c_abi/main.zig+1-1| ... | ... | @@ -119,7 +119,7 @@ export fn zig_bool(x: bool) void { |
| 119 | 119 | extern fn c_array([10]u8) void; |
| 120 | 120 | |
| 121 | 121 | test "C ABI array" { |
| 122 | var array: [10]u8 = "1234567890"; | |
| 122 | var array: [10]u8 = "1234567890".*; | |
| 123 | 123 | c_array(array); |
| 124 | 124 | } |
| 125 | 125 |