parser: disallow ptr modifiers on array types

This commit is contained in:
Isaac Freund
2021-03-07 19:20:41 +01:00
parent 482424e2b1
commit a5cb4ab95e
3 changed files with 34 additions and 21 deletions

View File

@@ -275,8 +275,10 @@ pub const Tree = struct {
.extra_volatile_qualifier => {
return stream.writeAll("extra volatile qualifier");
},
.invalid_align => {
return stream.writeAll("alignment not allowed on arrays");
.ptr_mod_on_array_child_type => {
return stream.print("pointer modifier '{s}' not allowed on array child type", .{
token_tags[parse_error.token].symbol(),
});
},
.invalid_and => {
return stream.writeAll("`&&` is invalid; note that `and` is boolean AND");
@@ -2388,7 +2390,7 @@ pub const Error = struct {
extra_allowzero_qualifier,
extra_const_qualifier,
extra_volatile_qualifier,
invalid_align,
ptr_mod_on_array_child_type,
invalid_and,
invalid_bit_range,
invalid_token,

View File

@@ -1612,13 +1612,15 @@ const Parser = struct {
/// PrefixTypeOp
/// <- QUESTIONMARK
/// / KEYWORD_anyframe MINUSRARROW
/// / ArrayTypeStart (ByteAlign / KEYWORD_const / KEYWORD_volatile / KEYWORD_allowzero)*
/// / SliceTypeStart (ByteAlign / KEYWORD_const / KEYWORD_volatile / KEYWORD_allowzero)*
/// / PtrTypeStart (KEYWORD_align LPAREN Expr (COLON INTEGER COLON INTEGER)? RPAREN / KEYWORD_const / KEYWORD_volatile / KEYWORD_allowzero)*
/// / ArrayTypeStart
/// SliceTypeStart <- LBRACKET (COLON Expr)? RBRACKET
/// PtrTypeStart
/// <- ASTERISK
/// / ASTERISK2
/// / LBRACKET ASTERISK (LETTERC / COLON Expr)? RBRACKET
/// ArrayTypeStart <- LBRACKET Expr? (COLON Expr)? RBRACKET
/// ArrayTypeStart <- LBRACKET Expr (COLON Expr)? RBRACKET
fn parseTypeExpr(p: *Parser) Error!Node.Index {
switch (p.token_tags[p.tok_i]) {
.question_mark => return p.addNode(.{
@@ -1785,15 +1787,15 @@ const Parser = struct {
else
0;
_ = try p.expectToken(.r_bracket);
const mods = try p.parsePtrModifiers();
const elem_type = try p.expectTypeExpr();
if (mods.bit_range_start != 0) {
try p.warnMsg(.{
.tag = .invalid_bit_range,
.token = p.nodes.items(.main_token)[mods.bit_range_start],
});
}
if (len_expr == 0) {
const mods = try p.parsePtrModifiers();
const elem_type = try p.expectTypeExpr();
if (mods.bit_range_start != 0) {
try p.warnMsg(.{
.tag = .invalid_bit_range,
.token = p.nodes.items(.main_token)[mods.bit_range_start],
});
}
if (sentinel == 0) {
return p.addNode(.{
.tag = .ptr_type_aligned,
@@ -1826,12 +1828,15 @@ const Parser = struct {
});
}
} else {
if (mods.align_node != 0) {
try p.warnMsg(.{
.tag = .invalid_align,
.token = p.nodes.items(.main_token)[mods.align_node],
});
switch (p.token_tags[p.tok_i]) {
.keyword_align,
.keyword_const,
.keyword_volatile,
.keyword_allowzero,
=> return p.fail(.ptr_mod_on_array_child_type),
else => {},
}
const elem_type = try p.expectTypeExpr();
if (sentinel == 0) {
return p.addNode(.{
.tag = .array_type,

View File

@@ -4350,11 +4350,17 @@ test "zig fmt: error for invalid bit range" {
});
}
test "zig fmt: error for invalid align" {
test "zig fmt: error for ptr mod on array child type" {
try testError(
\\var x: [10]align(10)u8 = bar;
\\var a: [10]align(10) u8 = e;
\\var b: [10]const u8 = f;
\\var c: [10]volatile u8 = g;
\\var d: [10]allowzero u8 = h;
, &[_]Error{
.invalid_align,
.ptr_mod_on_array_child_type,
.ptr_mod_on_array_child_type,
.ptr_mod_on_array_child_type,
.ptr_mod_on_array_child_type,
});
}