update tests, better error messages, update self-hosted tokenizer
This commit is contained in:
parent
cf2fe2536e
commit
fd6020c4e2
@ -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;
|
||||||
|
@ -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,
|
||||||
|
@ -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);
|
||||||
|
38
src/ir.cpp
38
src/ir.cpp
@ -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)
|
||||||
|
@ -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(
|
||||||
|
@ -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);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user