update tests, better error messages, update self-hosted tokenizer

This commit is contained in:
Andrew Kelley 2019-11-20 16:08:01 -05:00
parent cf2fe2536e
commit fd6020c4e2
No known key found for this signature in database
GPG Key ID: 7C5F548F728501A9
6 changed files with 50 additions and 44 deletions

View File

@ -1725,11 +1725,6 @@ test "zig fmt: multiline string" {
\\ \\two) \\ \\two)
\\ \\three \\ \\three
\\ ; \\ ;
\\ const s2 =
\\ c\\one
\\ c\\two)
\\ c\\three
\\ ;
\\ const s3 = // hi \\ const s3 = // hi
\\ \\one \\ \\one
\\ \\two) \\ \\two)
@ -1746,7 +1741,6 @@ test "zig fmt: values" {
\\ 1; \\ 1;
\\ 1.0; \\ 1.0;
\\ "string"; \\ "string";
\\ c"cstring";
\\ 'c'; \\ 'c';
\\ true; \\ true;
\\ false; \\ false;

View File

@ -351,7 +351,6 @@ pub const Tokenizer = struct {
Start, Start,
Identifier, Identifier,
Builtin, Builtin,
C,
StringLiteral, StringLiteral,
StringLiteralBackslash, StringLiteralBackslash,
MultilineStringLiteralLine, MultilineStringLiteralLine,
@ -427,10 +426,6 @@ pub const Tokenizer = struct {
' ', '\n', '\t', '\r' => { ' ', '\n', '\t', '\r' => {
result.start = self.index + 1; result.start = self.index + 1;
}, },
'c' => {
state = State.C;
result.id = Token.Id.Identifier;
},
'"' => { '"' => {
state = State.StringLiteral; state = State.StringLiteral;
result.id = Token.Id.StringLiteral; result.id = Token.Id.StringLiteral;
@ -438,7 +433,7 @@ pub const Tokenizer = struct {
'\'' => { '\'' => {
state = State.CharLiteral; state = State.CharLiteral;
}, },
'a'...'b', 'd'...'z', 'A'...'Z', '_' => { 'a'...'z', 'A'...'Z', '_' => {
state = State.Identifier; state = State.Identifier;
result.id = Token.Id.Identifier; result.id = Token.Id.Identifier;
}, },
@ -730,20 +725,6 @@ pub const Tokenizer = struct {
}, },
else => break, else => break,
}, },
State.C => switch (c) {
'\\' => {
state = State.Backslash;
result.id = Token.Id.MultilineStringLiteralLine;
},
'"' => {
state = State.StringLiteral;
result.id = Token.Id.StringLiteral;
},
'a'...'z', 'A'...'Z', '_', '0'...'9' => {
state = State.Identifier;
},
else => break,
},
State.StringLiteral => switch (c) { State.StringLiteral => switch (c) {
'\\' => { '\\' => {
state = State.StringLiteralBackslash; state = State.StringLiteralBackslash;
@ -1204,7 +1185,6 @@ pub const Tokenizer = struct {
} else if (self.index == self.buffer.len) { } else if (self.index == self.buffer.len) {
switch (state) { switch (state) {
State.Start, State.Start,
State.C,
State.IntegerLiteral, State.IntegerLiteral,
State.IntegerLiteralWithRadix, State.IntegerLiteralWithRadix,
State.IntegerLiteralWithRadixHex, State.IntegerLiteralWithRadixHex,

View File

@ -698,10 +698,9 @@ fn transStringLiteral(
len = 0; len = 0;
for (str) |c| len += escapeChar(c, &char_buf).len; for (str) |c| len += escapeChar(c, &char_buf).len;
const buf = try rp.c.a().alloc(u8, len + "c\"\"".len); const buf = try rp.c.a().alloc(u8, len + "\"\"".len);
buf[0] = 'c'; buf[0] = '"';
buf[1] = '"'; writeEscapedString(buf[1..], str);
writeEscapedString(buf[2..], str);
buf[buf.len - 1] = '"'; buf[buf.len - 1] = '"';
const token = try appendToken(rp.c, .StringLiteral, buf); const token = try appendToken(rp.c, .StringLiteral, buf);

View File

@ -69,6 +69,7 @@ enum ConstCastResultId {
ConstCastResultIdArrayChild, ConstCastResultIdArrayChild,
ConstCastResultIdBadNullTermArrays, ConstCastResultIdBadNullTermArrays,
ConstCastResultIdPtrLens, ConstCastResultIdPtrLens,
ConstCastResultIdCV,
}; };
struct ConstCastOnly; struct ConstCastOnly;
@ -94,6 +95,7 @@ struct ConstCastArrayMismatch;
struct ConstCastBadAllowsZero; struct ConstCastBadAllowsZero;
struct ConstCastBadNullTermArrays; struct ConstCastBadNullTermArrays;
struct ConstCastBadPtrLens; struct ConstCastBadPtrLens;
struct ConstCastBadCV;
struct ConstCastOnly { struct ConstCastOnly {
ConstCastResultId id; ConstCastResultId id;
@ -113,6 +115,7 @@ struct ConstCastOnly {
ConstCastBadAllowsZero *bad_allows_zero; ConstCastBadAllowsZero *bad_allows_zero;
ConstCastBadNullTermArrays *bad_null_term_arrays; ConstCastBadNullTermArrays *bad_null_term_arrays;
ConstCastBadPtrLens *bad_ptr_lens; ConstCastBadPtrLens *bad_ptr_lens;
ConstCastBadCV *bad_cv;
} data; } data;
}; };
@ -177,6 +180,10 @@ struct ConstCastBadPtrLens {
ZigType *actual_type; ZigType *actual_type;
}; };
struct ConstCastBadCV {
ZigType *wanted_type;
ZigType *actual_type;
};
static IrInstruction *ir_gen_node(IrBuilder *irb, AstNode *node, Scope *scope); static IrInstruction *ir_gen_node(IrBuilder *irb, AstNode *node, Scope *scope);
static IrInstruction *ir_gen_node_extra(IrBuilder *irb, AstNode *node, Scope *scope, LVal lval, 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
return result; return result;
} }
bool ok_cv_qualifiers =
(!actual_ptr_type->data.pointer.is_const || wanted_ptr_type->data.pointer.is_const) &&
(!actual_ptr_type->data.pointer.is_volatile || wanted_ptr_type->data.pointer.is_volatile);
if (!ok_cv_qualifiers) {
result.id = ConstCastResultIdCV;
result.data.bad_cv = allocate_nonzero<ConstCastBadCV>(1);
result.data.bad_cv->wanted_type = wanted_ptr_type;
result.data.bad_cv->actual_type = actual_ptr_type;
return result;
}
ConstCastOnly child = types_match_const_cast_only(ira, wanted_ptr_type->data.pointer.child_type, ConstCastOnly child = types_match_const_cast_only(ira, wanted_ptr_type->data.pointer.child_type,
actual_ptr_type->data.pointer.child_type, source_node, !wanted_ptr_type->data.pointer.is_const); actual_ptr_type->data.pointer.child_type, source_node, !wanted_ptr_type->data.pointer.is_const);
if (child.id == ConstCastResultIdInvalid) if (child.id == ConstCastResultIdInvalid)
@ -9902,8 +9920,6 @@ static ConstCastOnly types_match_const_cast_only(IrAnalyze *ira, ZigType *wanted
return result; return result;
} }
if (type_has_bits(wanted_type) == type_has_bits(actual_type) && if (type_has_bits(wanted_type) == type_has_bits(actual_type) &&
(!actual_ptr_type->data.pointer.is_const || wanted_ptr_type->data.pointer.is_const) &&
(!actual_ptr_type->data.pointer.is_volatile || wanted_ptr_type->data.pointer.is_volatile) &&
actual_ptr_type->data.pointer.bit_offset_in_host == wanted_ptr_type->data.pointer.bit_offset_in_host && actual_ptr_type->data.pointer.bit_offset_in_host == wanted_ptr_type->data.pointer.bit_offset_in_host &&
actual_ptr_type->data.pointer.host_int_bytes == wanted_ptr_type->data.pointer.host_int_bytes && actual_ptr_type->data.pointer.host_int_bytes == wanted_ptr_type->data.pointer.host_int_bytes &&
get_ptr_align(ira->codegen, actual_ptr_type) >= get_ptr_align(ira->codegen, wanted_ptr_type)) 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
} }
break; break;
} }
case ConstCastResultIdCV: {
ZigType *wanted_type = cast_result->data.bad_cv->wanted_type;
ZigType *actual_type = cast_result->data.bad_cv->actual_type;
bool ok_const = !actual_type->data.pointer.is_const || wanted_type->data.pointer.is_const;
bool ok_volatile = !actual_type->data.pointer.is_volatile || wanted_type->data.pointer.is_volatile;
if (!ok_const) {
add_error_note(ira->codegen, parent_msg, source_node, buf_sprintf("cast discards const qualifier"));
} else if (!ok_volatile) {
add_error_note(ira->codegen, parent_msg, source_node, buf_sprintf("cast discards volatile qualifier"));
} else {
zig_unreachable();
}
break;
}
case ConstCastResultIdFnIsGeneric: case ConstCastResultIdFnIsGeneric:
add_error_note(ira->codegen, parent_msg, source_node, add_error_note(ira->codegen, parent_msg, source_node,
buf_sprintf("only one of the functions is generic")); buf_sprintf("only one of the functions is generic"));
@ -12987,7 +13017,9 @@ static IrInstruction *ir_analyze_cast(IrAnalyze *ira, IrInstruction *source_inst
wanted_type->data.pointer.ptr_len == PtrLenNull) && wanted_type->data.pointer.ptr_len == PtrLenNull) &&
actual_type->id == ZigTypeIdPointer && actual_type->id == ZigTypeIdPointer &&
actual_type->data.pointer.ptr_len == PtrLenSingle && actual_type->data.pointer.ptr_len == PtrLenSingle &&
actual_type->data.pointer.child_type->id == ZigTypeIdArray) actual_type->data.pointer.child_type->id == ZigTypeIdArray &&
(!actual_type->data.pointer.is_const || wanted_type->data.pointer.is_const) &&
(!actual_type->data.pointer.is_volatile || wanted_type->data.pointer.is_volatile))
{ {
if (wanted_type->data.pointer.ptr_len != PtrLenNull || if (wanted_type->data.pointer.ptr_len != PtrLenNull ||
actual_type->data.pointer.child_type->data.array.is_null_terminated) actual_type->data.pointer.child_type->data.array.is_null_terminated)

View File

@ -784,7 +784,8 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {
\\ strValue = strValue orelse ""; \\ strValue = strValue orelse "";
\\} \\}
, ,
"tmp.zig:3:32: error: cast discards const qualifier", "tmp.zig:3:32: error: expected type '[*c]u8', found '*const [0]null u8'",
"tmp.zig:3:32: note: cast discards const qualifier",
); );
cases.add( cases.add(
@ -1323,7 +1324,7 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {
\\ ptr_opt_many_ptr = c_ptr; \\ ptr_opt_many_ptr = c_ptr;
\\} \\}
\\export fn entry2() void { \\export fn entry2() void {
\\ var buf: [4]u8 = "aoeu"; \\ var buf: [4]u8 = "aoeu".*;
\\ var slice: []u8 = &buf; \\ var slice: []u8 = &buf;
\\ var opt_many_ptr: [*]u8 = slice.ptr; \\ var opt_many_ptr: [*]u8 = slice.ptr;
\\ var ptr_opt_many_ptr = &opt_many_ptr; \\ var ptr_opt_many_ptr = &opt_many_ptr;
@ -1518,7 +1519,7 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {
cases.add( cases.add(
"reading past end of pointer casted array", "reading past end of pointer casted array",
\\comptime { \\comptime {
\\ const array = "aoeu"; \\ const array: [4]u8 = "aoeu".*;
\\ const slice = array[1..]; \\ const slice = array[1..];
\\ const int_ptr = @ptrCast(*const u24, slice.ptr); \\ const int_ptr = @ptrCast(*const u24, slice.ptr);
\\ const deref = int_ptr.*; \\ const deref = int_ptr.*;
@ -3356,7 +3357,7 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {
\\ return a; \\ return a;
\\} \\}
, ,
"tmp.zig:3:12: error: expected type 'i32', found '[*]const u8'", "tmp.zig:3:12: error: expected type 'i32', found '*const [1]null u8'",
); );
cases.add( cases.add(
@ -3827,12 +3828,12 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {
cases.add( cases.add(
"array concatenation with wrong type", "array concatenation with wrong type",
\\const src = "aoeu"; \\const src = "aoeu";
\\const derp = @as(usize, 1234); \\const derp: usize = 1234;
\\const a = derp ++ "foo"; \\const a = derp ++ "foo";
\\ \\
\\export fn entry() usize { return @sizeOf(@typeOf(a)); } \\export fn entry() usize { return @sizeOf(@typeOf(a)); }
, ,
"tmp.zig:3:11: error: expected array or C string literal, found 'usize'", "tmp.zig:3:11: error: expected array, found 'usize'",
); );
cases.add( cases.add(
@ -6207,11 +6208,11 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {
cases.add( cases.add(
"calling var args extern function, passing array instead of pointer", "calling var args extern function, passing array instead of pointer",
\\export fn entry() void { \\export fn entry() void {
\\ foo("hello",); \\ foo("hello".*,);
\\} \\}
\\pub extern fn foo(format: *const u8, ...) void; \\pub extern fn foo(format: *const u8, ...) void;
, ,
"tmp.zig:2:9: error: expected type '*const u8', found '[5]u8'", "tmp.zig:2:16: error: expected type '*const u8', found '[5]null u8'",
); );
cases.add( cases.add(
@ -6777,7 +6778,7 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {
\\} \\}
, ,
"tmp.zig:4:22: error: expected type '*[1]i32', found '*const i32'", "tmp.zig:4:22: error: expected type '*[1]i32', found '*const i32'",
"tmp.zig:4:22: note: pointer type child 'i32' cannot cast into pointer type child '[1]i32'", "tmp.zig:4:22: note: cast discards const qualifier",
); );
cases.add( cases.add(

View File

@ -119,7 +119,7 @@ export fn zig_bool(x: bool) void {
extern fn c_array([10]u8) void; extern fn c_array([10]u8) void;
test "C ABI array" { test "C ABI array" {
var array: [10]u8 = "1234567890"; var array: [10]u8 = "1234567890".*;
c_array(array); c_array(array);
} }