authorgravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2017-08-30 04:54:33-04:00
committergravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2017-08-30 04:54:33-04:00
log052b4ae9415596e0b6b6c32b9b4f2d3ff8c9e953
tree7a11abbcf1de240ec1dd2e9913183eca5e5ebb41
parent3f5dd08ca8010ef365b6cf203214aac353c36643

align syntax: align(4) instead of align 4

closes #37

10 files changed, 92 insertions(+), 85 deletions(-)

src/analyze.cpp+3-3
...@@ -359,10 +359,10 @@ TypeTableEntry *get_pointer_to_type_extra(CodeGen *g, TypeTableEntry *child_type...@@ -359,10 +359,10 @@ TypeTableEntry *get_pointer_to_type_extra(CodeGen *g, TypeTableEntry *child_type
359 if (unaligned_bit_count == 0 && byte_alignment == abi_alignment) {359 if (unaligned_bit_count == 0 && byte_alignment == abi_alignment) {
360 buf_appendf(&entry->name, "&%s%s%s", const_str, volatile_str, buf_ptr(&child_type->name));360 buf_appendf(&entry->name, "&%s%s%s", const_str, volatile_str, buf_ptr(&child_type->name));
361 } else if (unaligned_bit_count == 0) {361 } else if (unaligned_bit_count == 0) {
362 buf_appendf(&entry->name, "&align %" PRIu32 " %s%s%s", byte_alignment,362 buf_appendf(&entry->name, "&align(%" PRIu32 ") %s%s%s", byte_alignment,
363 const_str, volatile_str, buf_ptr(&child_type->name));363 const_str, volatile_str, buf_ptr(&child_type->name));
364 } else {364 } else {
365 buf_appendf(&entry->name, "&align %" PRIu32 ":%" PRIu32 ":%" PRIu32 " %s%s%s", byte_alignment,365 buf_appendf(&entry->name, "&align(%" PRIu32 ":%" PRIu32 ":%" PRIu32 ") %s%s%s", byte_alignment,
366 bit_offset, bit_offset + unaligned_bit_count, const_str, volatile_str, buf_ptr(&child_type->name));366 bit_offset, bit_offset + unaligned_bit_count, const_str, volatile_str, buf_ptr(&child_type->name));
367 }367 }
368368
...@@ -885,7 +885,7 @@ TypeTableEntry *get_fn_type(CodeGen *g, FnTypeId *fn_type_id) {...@@ -885,7 +885,7 @@ TypeTableEntry *get_fn_type(CodeGen *g, FnTypeId *fn_type_id) {
885 }885 }
886 buf_appendf(&fn_type->name, ")");886 buf_appendf(&fn_type->name, ")");
887 if (fn_type_id->alignment != 0) {887 if (fn_type_id->alignment != 0) {
888 buf_appendf(&fn_type->name, " align %" PRIu32, fn_type_id->alignment);888 buf_appendf(&fn_type->name, " align(%" PRIu32 ")", fn_type_id->alignment);
889 }889 }
890 if (fn_type_id->return_type->id != TypeTableEntryIdVoid) {890 if (fn_type_id->return_type->id != TypeTableEntryIdVoid) {
891 buf_appendf(&fn_type->name, " -> %s", buf_ptr(&fn_type_id->return_type->name));891 buf_appendf(&fn_type->name, " -> %s", buf_ptr(&fn_type_id->return_type->name));
src/ast_render.cpp+2-3
...@@ -585,7 +585,7 @@ static void render_node_extra(AstRender *ar, AstNode *node, bool grouped) {...@@ -585,7 +585,7 @@ static void render_node_extra(AstRender *ar, AstNode *node, bool grouped) {
585 {585 {
586 fprintf(ar->f, "&");586 fprintf(ar->f, "&");
587 if (node->data.addr_of_expr.align_expr != nullptr) {587 if (node->data.addr_of_expr.align_expr != nullptr) {
588 fprintf(ar->f, "align ");588 fprintf(ar->f, "align(");
589 render_node_grouped(ar, node->data.addr_of_expr.align_expr);589 render_node_grouped(ar, node->data.addr_of_expr.align_expr);
590 if (node->data.addr_of_expr.bit_offset_start != nullptr) {590 if (node->data.addr_of_expr.bit_offset_start != nullptr) {
591 assert(node->data.addr_of_expr.bit_offset_end != nullptr);591 assert(node->data.addr_of_expr.bit_offset_end != nullptr);
...@@ -599,9 +599,8 @@ static void render_node_extra(AstRender *ar, AstNode *node, bool grouped) {...@@ -599,9 +599,8 @@ static void render_node_extra(AstRender *ar, AstNode *node, bool grouped) {
599 bigint_append_buf(&offset_end_buf, node->data.addr_of_expr.bit_offset_end, 10);599 bigint_append_buf(&offset_end_buf, node->data.addr_of_expr.bit_offset_end, 10);
600600
601 fprintf(ar->f, ":%s:%s ", buf_ptr(&offset_start_buf), buf_ptr(&offset_end_buf));601 fprintf(ar->f, ":%s:%s ", buf_ptr(&offset_start_buf), buf_ptr(&offset_end_buf));
602 } else {
603 fprintf(ar->f, " ");
604 }602 }
603 fprintf(ar->f, ") ");
605 }604 }
606 if (node->data.addr_of_expr.is_const) {605 if (node->data.addr_of_expr.is_const) {
607 fprintf(ar->f, "const ");606 fprintf(ar->f, "const ");
src/parser.cpp+17-9
...@@ -385,7 +385,7 @@ static AstNode *ast_parse_grouped_expr(ParseContext *pc, size_t *token_index, bo...@@ -385,7 +385,7 @@ static AstNode *ast_parse_grouped_expr(ParseContext *pc, size_t *token_index, bo
385}385}
386386
387/*387/*
388ArrayType : "[" option(Expression) "]" option("align" PrimaryExpression)) option("const") option("volatile") PrefixOpExpression388ArrayType : "[" option(Expression) "]" option("align" "(" Expression option(":" Integer ":" Integer) ")")) option("const") option("volatile") TypeExpr
389*/389*/
390static AstNode *ast_parse_array_type_expr(ParseContext *pc, size_t *token_index, bool mandatory) {390static AstNode *ast_parse_array_type_expr(ParseContext *pc, size_t *token_index, bool mandatory) {
391 Token *l_bracket = &pc->tokens->at(*token_index);391 Token *l_bracket = &pc->tokens->at(*token_index);
...@@ -407,7 +407,9 @@ static AstNode *ast_parse_array_type_expr(ParseContext *pc, size_t *token_index,...@@ -407,7 +407,9 @@ static AstNode *ast_parse_array_type_expr(ParseContext *pc, size_t *token_index,
407 Token *token = &pc->tokens->at(*token_index);407 Token *token = &pc->tokens->at(*token_index);
408 if (token->id == TokenIdKeywordAlign) {408 if (token->id == TokenIdKeywordAlign) {
409 *token_index += 1;409 *token_index += 1;
410 node->data.array_type.align_expr = ast_parse_primary_expr(pc, token_index, true);410 ast_eat_token(pc, token_index, TokenIdLParen);
411 node->data.array_type.align_expr = ast_parse_expression(pc, token_index, true);
412 ast_eat_token(pc, token_index, TokenIdRParen);
411413
412 token = &pc->tokens->at(*token_index);414 token = &pc->tokens->at(*token_index);
413 }415 }
...@@ -984,7 +986,8 @@ static AstNode *ast_parse_addr_of(ParseContext *pc, size_t *token_index) {...@@ -984,7 +986,8 @@ static AstNode *ast_parse_addr_of(ParseContext *pc, size_t *token_index) {
984 Token *token = &pc->tokens->at(*token_index);986 Token *token = &pc->tokens->at(*token_index);
985 if (token->id == TokenIdKeywordAlign) {987 if (token->id == TokenIdKeywordAlign) {
986 *token_index += 1;988 *token_index += 1;
987 node->data.addr_of_expr.align_expr = ast_parse_primary_expr(pc, token_index, true);989 ast_eat_token(pc, token_index, TokenIdLParen);
990 node->data.addr_of_expr.align_expr = ast_parse_expression(pc, token_index, true);
988991
989 token = &pc->tokens->at(*token_index);992 token = &pc->tokens->at(*token_index);
990 if (token->id == TokenIdColon) {993 if (token->id == TokenIdColon) {
...@@ -992,11 +995,12 @@ static AstNode *ast_parse_addr_of(ParseContext *pc, size_t *token_index) {...@@ -992,11 +995,12 @@ static AstNode *ast_parse_addr_of(ParseContext *pc, size_t *token_index) {
992 Token *bit_offset_start_tok = ast_eat_token(pc, token_index, TokenIdIntLiteral);995 Token *bit_offset_start_tok = ast_eat_token(pc, token_index, TokenIdIntLiteral);
993 ast_eat_token(pc, token_index, TokenIdColon);996 ast_eat_token(pc, token_index, TokenIdColon);
994 Token *bit_offset_end_tok = ast_eat_token(pc, token_index, TokenIdIntLiteral);997 Token *bit_offset_end_tok = ast_eat_token(pc, token_index, TokenIdIntLiteral);
995 token = &pc->tokens->at(*token_index);
996998
997 node->data.addr_of_expr.bit_offset_start = token_bigint(bit_offset_start_tok);999 node->data.addr_of_expr.bit_offset_start = token_bigint(bit_offset_start_tok);
998 node->data.addr_of_expr.bit_offset_end = token_bigint(bit_offset_end_tok);1000 node->data.addr_of_expr.bit_offset_end = token_bigint(bit_offset_end_tok);
999 }1001 }
1002 ast_eat_token(pc, token_index, TokenIdRParen);
1003 token = &pc->tokens->at(*token_index);
1000 }1004 }
1001 if (token->id == TokenIdKeywordConst) {1005 if (token->id == TokenIdKeywordConst) {
1002 *token_index += 1;1006 *token_index += 1;
...@@ -1015,7 +1019,7 @@ static AstNode *ast_parse_addr_of(ParseContext *pc, size_t *token_index) {...@@ -1015,7 +1019,7 @@ static AstNode *ast_parse_addr_of(ParseContext *pc, size_t *token_index) {
10151019
1016/*1020/*
1017PrefixOpExpression : PrefixOp PrefixOpExpression | SuffixOpExpression1021PrefixOpExpression : PrefixOp PrefixOpExpression | SuffixOpExpression
1018PrefixOp = "!" | "-" | "~" | "*" | ("&" option("align" PrimaryExpression option(":" Integer ":" Integer)) option("const") option("volatile")) | "?" | "%" | "%%" | "??" | "-%"1022PrefixOp = "!" | "-" | "~" | "*" | ("&" option("align" "(" Expression option(":" Integer ":" Integer) ")" ) option("const") option("volatile")) | "?" | "%" | "%%" | "??" | "-%"
1019*/1023*/
1020static AstNode *ast_parse_prefix_op_expr(ParseContext *pc, size_t *token_index, bool mandatory) {1024static AstNode *ast_parse_prefix_op_expr(ParseContext *pc, size_t *token_index, bool mandatory) {
1021 Token *token = &pc->tokens->at(*token_index);1025 Token *token = &pc->tokens->at(*token_index);
...@@ -1534,7 +1538,7 @@ static AstNode *ast_parse_defer_expr(ParseContext *pc, size_t *token_index) {...@@ -1534,7 +1538,7 @@ static AstNode *ast_parse_defer_expr(ParseContext *pc, size_t *token_index) {
1534}1538}
15351539
1536/*1540/*
1537VariableDeclaration = option("comptime") ("var" | "const") Symbol option(":" TypeExpr) option("align" PrimaryExpression) "=" Expression1541VariableDeclaration = option("comptime") ("var" | "const") Symbol option(":" TypeExpr) option("align" "(" Expression ")") "=" Expression
1538*/1542*/
1539static AstNode *ast_parse_variable_declaration_expr(ParseContext *pc, size_t *token_index, bool mandatory,1543static AstNode *ast_parse_variable_declaration_expr(ParseContext *pc, size_t *token_index, bool mandatory,
1540 VisibMod visib_mod)1544 VisibMod visib_mod)
...@@ -1594,7 +1598,9 @@ static AstNode *ast_parse_variable_declaration_expr(ParseContext *pc, size_t *to...@@ -1594,7 +1598,9 @@ static AstNode *ast_parse_variable_declaration_expr(ParseContext *pc, size_t *to
15941598
1595 if (next_token->id == TokenIdKeywordAlign) {1599 if (next_token->id == TokenIdKeywordAlign) {
1596 *token_index += 1;1600 *token_index += 1;
1597 node->data.variable_declaration.align_expr = ast_parse_primary_expr(pc, token_index, true);1601 ast_eat_token(pc, token_index, TokenIdLParen);
1602 node->data.variable_declaration.align_expr = ast_parse_expression(pc, token_index, true);
1603 ast_eat_token(pc, token_index, TokenIdRParen);
1598 next_token = &pc->tokens->at(*token_index);1604 next_token = &pc->tokens->at(*token_index);
1599 }1605 }
16001606
...@@ -2203,7 +2209,7 @@ static AstNode *ast_parse_block(ParseContext *pc, size_t *token_index, bool mand...@@ -2203,7 +2209,7 @@ static AstNode *ast_parse_block(ParseContext *pc, size_t *token_index, bool mand
2203}2209}
22042210
2205/*2211/*
2206FnProto = option("coldcc" | "nakedcc" | "stdcallcc") "fn" option(Symbol) ParamDeclList option("align" PrimaryExpression) option("->" TypeExpr)2212FnProto = option("coldcc" | "nakedcc" | "stdcallcc") "fn" option(Symbol) ParamDeclList option("align" "(" Expression ")") option("->" TypeExpr)
2207*/2213*/
2208static AstNode *ast_parse_fn_proto(ParseContext *pc, size_t *token_index, bool mandatory, VisibMod visib_mod) {2214static AstNode *ast_parse_fn_proto(ParseContext *pc, size_t *token_index, bool mandatory, VisibMod visib_mod) {
2209 Token *first_token = &pc->tokens->at(*token_index);2215 Token *first_token = &pc->tokens->at(*token_index);
...@@ -2251,8 +2257,10 @@ static AstNode *ast_parse_fn_proto(ParseContext *pc, size_t *token_index, bool m...@@ -2251,8 +2257,10 @@ static AstNode *ast_parse_fn_proto(ParseContext *pc, size_t *token_index, bool m
2251 Token *next_token = &pc->tokens->at(*token_index);2257 Token *next_token = &pc->tokens->at(*token_index);
2252 if (next_token->id == TokenIdKeywordAlign) {2258 if (next_token->id == TokenIdKeywordAlign) {
2253 *token_index += 1;2259 *token_index += 1;
2260 ast_eat_token(pc, token_index, TokenIdLParen);
22542261
2255 node->data.fn_proto.align_expr = ast_parse_primary_expr(pc, token_index, true);2262 node->data.fn_proto.align_expr = ast_parse_expression(pc, token_index, true);
2263 ast_eat_token(pc, token_index, TokenIdRParen);
2256 next_token = &pc->tokens->at(*token_index);2264 next_token = &pc->tokens->at(*token_index);
2257 }2265 }
2258 if (next_token->id == TokenIdArrow) {2266 if (next_token->id == TokenIdArrow) {
std/special/compiler_rt/udivmod.zig+5-5
...@@ -54,7 +54,7 @@ pub fn udivmod(comptime DoubleInt: type, a: DoubleInt, b: DoubleInt, maybe_rem:...@@ -54,7 +54,7 @@ pub fn udivmod(comptime DoubleInt: type, a: DoubleInt, b: DoubleInt, maybe_rem:
54 if (maybe_rem) |rem| {54 if (maybe_rem) |rem| {
55 r[high] = n[high] % d[high];55 r[high] = n[high] % d[high];
56 r[low] = 0;56 r[low] = 0;
57 *rem = *@ptrCast(&align @alignOf(SingleInt) DoubleInt, &r[0]); // TODO issue #42157 *rem = *@ptrCast(&align(@alignOf(SingleInt)) DoubleInt, &r[0]); // TODO issue #421
58 }58 }
59 return n[high] / d[high];59 return n[high] / d[high];
60 }60 }
...@@ -66,7 +66,7 @@ pub fn udivmod(comptime DoubleInt: type, a: DoubleInt, b: DoubleInt, maybe_rem:...@@ -66,7 +66,7 @@ pub fn udivmod(comptime DoubleInt: type, a: DoubleInt, b: DoubleInt, maybe_rem:
66 if (maybe_rem) |rem| {66 if (maybe_rem) |rem| {
67 r[low] = n[low];67 r[low] = n[low];
68 r[high] = n[high] & (d[high] - 1);68 r[high] = n[high] & (d[high] - 1);
69 *rem = *@ptrCast(&align @alignOf(SingleInt) DoubleInt, &r[0]); // TODO issue #42169 *rem = *@ptrCast(&align(@alignOf(SingleInt)) DoubleInt, &r[0]); // TODO issue #421
70 }70 }
71 return n[high] >> Log2SingleInt(@ctz(d[high]));71 return n[high] >> Log2SingleInt(@ctz(d[high]));
72 }72 }
...@@ -106,7 +106,7 @@ pub fn udivmod(comptime DoubleInt: type, a: DoubleInt, b: DoubleInt, maybe_rem:...@@ -106,7 +106,7 @@ pub fn udivmod(comptime DoubleInt: type, a: DoubleInt, b: DoubleInt, maybe_rem:
106 sr = @ctz(d[low]);106 sr = @ctz(d[low]);
107 q[high] = n[high] >> Log2SingleInt(sr);107 q[high] = n[high] >> Log2SingleInt(sr);
108 q[low] = (n[high] << Log2SingleInt(SingleInt.bit_count - sr)) | (n[low] >> Log2SingleInt(sr));108 q[low] = (n[high] << Log2SingleInt(SingleInt.bit_count - sr)) | (n[low] >> Log2SingleInt(sr));
109 return *@ptrCast(&align @alignOf(SingleInt) DoubleInt, &q[0]); // TODO issue #421109 return *@ptrCast(&align(@alignOf(SingleInt)) DoubleInt, &q[0]); // TODO issue #421
110 }110 }
111 // K X111 // K X
112 // ---112 // ---
...@@ -180,13 +180,13 @@ pub fn udivmod(comptime DoubleInt: type, a: DoubleInt, b: DoubleInt, maybe_rem:...@@ -180,13 +180,13 @@ pub fn udivmod(comptime DoubleInt: type, a: DoubleInt, b: DoubleInt, maybe_rem:
180 // r.all -= b;180 // r.all -= b;
181 // carry = 1;181 // carry = 1;
182 // }182 // }
183 r_all = *@ptrCast(&align @alignOf(SingleInt) DoubleInt, &r[0]); // TODO issue #421183 r_all = *@ptrCast(&align(@alignOf(SingleInt)) DoubleInt, &r[0]); // TODO issue #421
184 const s: SignedDoubleInt = SignedDoubleInt(b -% r_all -% 1) >> (DoubleInt.bit_count - 1);184 const s: SignedDoubleInt = SignedDoubleInt(b -% r_all -% 1) >> (DoubleInt.bit_count - 1);
185 carry = u32(s & 1);185 carry = u32(s & 1);
186 r_all -= b & @bitCast(DoubleInt, s);186 r_all -= b & @bitCast(DoubleInt, s);
187 r = *@ptrCast(&[2]SingleInt, &r_all); // TODO issue #421187 r = *@ptrCast(&[2]SingleInt, &r_all); // TODO issue #421
188 }188 }
189 const q_all = ((*@ptrCast(&align @alignOf(SingleInt) DoubleInt, &q[0])) << 1) | carry; // TODO issue #421189 const q_all = ((*@ptrCast(&align(@alignOf(SingleInt)) DoubleInt, &q[0])) << 1) | carry; // TODO issue #421
190 if (maybe_rem) |rem| {190 if (maybe_rem) |rem| {
191 *rem = r_all;191 *rem = r_all;
192 }192 }
test/cases/align.zig+49-49
...@@ -1,22 +1,22 @@...@@ -1,22 +1,22 @@
1const assert = @import("std").debug.assert;1const assert = @import("std").debug.assert;
22
3var foo: u8 align 4 = 100;3var foo: u8 align(4) = 100;
44
5test "global variable alignment" {5test "global variable alignment" {
6 assert(@typeOf(&foo).alignment == 4);6 assert(@typeOf(&foo).alignment == 4);
7 assert(@typeOf(&foo) == &align 4 u8);7 assert(@typeOf(&foo) == &align(4) u8);
8 const slice = (&foo)[0..1];8 const slice = (&foo)[0..1];
9 assert(@typeOf(slice) == []align 4 u8);9 assert(@typeOf(slice) == []align(4) u8);
10}10}
1111
12fn derp() align (@sizeOf(usize) * 2) -> i32 { 1234 }12fn derp() align(@sizeOf(usize) * 2) -> i32 { 1234 }
13fn noop1() align 1 {}13fn noop1() align(1) {}
14fn noop4() align 4 {}14fn noop4() align(4) {}
1515
16test "function alignment" {16test "function alignment" {
17 assert(derp() == 1234);17 assert(derp() == 1234);
18 assert(@typeOf(noop1) == fn() align 1);18 assert(@typeOf(noop1) == fn() align(1));
19 assert(@typeOf(noop4) == fn() align 4);19 assert(@typeOf(noop4) == fn() align(4));
20 noop1();20 noop1();
21 noop4();21 noop4();
22}22}
...@@ -28,7 +28,7 @@ var baz: packed struct {...@@ -28,7 +28,7 @@ var baz: packed struct {
28} = undefined;28} = undefined;
2929
30test "packed struct alignment" {30test "packed struct alignment" {
31 assert(@typeOf(&baz.b) == &align 1 u32);31 assert(@typeOf(&baz.b) == &align(1) u32);
32}32}
3333
3434
...@@ -39,33 +39,33 @@ const blah: packed struct {...@@ -39,33 +39,33 @@ const blah: packed struct {
39} = undefined;39} = undefined;
4040
41test "bit field alignment" {41test "bit field alignment" {
42 assert(@typeOf(&blah.b) == &align 1:3:6 const u3);42 assert(@typeOf(&blah.b) == &align(1:3:6) const u3);
43}43}
4444
45test "default alignment allows unspecified in type syntax" {45test "default alignment allows unspecified in type syntax" {
46 assert(&u32 == &align @alignOf(u32) u32);46 assert(&u32 == &align(@alignOf(u32)) u32);
47}47}
4848
49test "implicitly decreasing pointer alignment" {49test "implicitly decreasing pointer alignment" {
50 const a: u32 align 4 = 3;50 const a: u32 align(4) = 3;
51 const b: u32 align 8 = 4;51 const b: u32 align(8) = 4;
52 assert(addUnaligned(&a, &b) == 7);52 assert(addUnaligned(&a, &b) == 7);
53}53}
5454
55fn addUnaligned(a: &align 1 const u32, b: &align 1 const u32) -> u32 { *a + *b }55fn addUnaligned(a: &align(1) const u32, b: &align(1) const u32) -> u32 { *a + *b }
5656
57test "implicitly decreasing slice alignment" {57test "implicitly decreasing slice alignment" {
58 const a: u32 align 4 = 3;58 const a: u32 align(4) = 3;
59 const b: u32 align 8 = 4;59 const b: u32 align(8) = 4;
60 assert(addUnalignedSlice((&a)[0..1], (&b)[0..1]) == 7);60 assert(addUnalignedSlice((&a)[0..1], (&b)[0..1]) == 7);
61}61}
62fn addUnalignedSlice(a: []align 1 const u32, b: []align 1 const u32) -> u32 { a[0] + b[0] }62fn addUnalignedSlice(a: []align(1) const u32, b: []align(1) const u32) -> u32 { a[0] + b[0] }
6363
64test "specifying alignment allows pointer cast" {64test "specifying alignment allows pointer cast" {
65 testBytesAlign(0x33);65 testBytesAlign(0x33);
66}66}
67fn testBytesAlign(b: u8) {67fn testBytesAlign(b: u8) {
68 var bytes align 4 = []u8{b, b, b, b};68 var bytes align(4) = []u8{b, b, b, b};
69 const ptr = @ptrCast(&u32, &bytes[0]);69 const ptr = @ptrCast(&u32, &bytes[0]);
70 assert(*ptr == 0x33333333);70 assert(*ptr == 0x33333333);
71}71}
...@@ -74,33 +74,33 @@ test "specifying alignment allows slice cast" {...@@ -74,33 +74,33 @@ test "specifying alignment allows slice cast" {
74 testBytesAlignSlice(0x33);74 testBytesAlignSlice(0x33);
75}75}
76fn testBytesAlignSlice(b: u8) {76fn testBytesAlignSlice(b: u8) {
77 var bytes align 4 = []u8{b, b, b, b};77 var bytes align(4) = []u8{b, b, b, b};
78 const slice = ([]u32)(bytes[0..]);78 const slice = ([]u32)(bytes[0..]);
79 assert(slice[0] == 0x33333333);79 assert(slice[0] == 0x33333333);
80}80}
8181
82test "@alignCast pointers" {82test "@alignCast pointers" {
83 var x: u32 align 4 = 1;83 var x: u32 align(4) = 1;
84 expectsOnly1(&x);84 expectsOnly1(&x);
85 assert(x == 2);85 assert(x == 2);
86}86}
87fn expectsOnly1(x: &align 1 u32) {87fn expectsOnly1(x: &align(1) u32) {
88 expects4(@alignCast(4, x));88 expects4(@alignCast(4, x));
89}89}
90fn expects4(x: &align 4 u32) {90fn expects4(x: &align(4) u32) {
91 *x += 1;91 *x += 1;
92}92}
9393
94test "@alignCast slices" {94test "@alignCast slices" {
95 var array align 4 = []u32{1, 1};95 var array align(4) = []u32{1, 1};
96 const slice = array[0..];96 const slice = array[0..];
97 sliceExpectsOnly1(slice);97 sliceExpectsOnly1(slice);
98 assert(slice[0] == 2);98 assert(slice[0] == 2);
99}99}
100fn sliceExpectsOnly1(slice: []align 1 u32) {100fn sliceExpectsOnly1(slice: []align(1) u32) {
101 sliceExpects4(@alignCast(4, slice));101 sliceExpects4(@alignCast(4, slice));
102}102}
103fn sliceExpects4(slice: []align 4 u32) {103fn sliceExpects4(slice: []align(4) u32) {
104 slice[0] += 1;104 slice[0] += 1;
105}105}
106106
...@@ -110,24 +110,24 @@ test "implicitly decreasing fn alignment" {...@@ -110,24 +110,24 @@ test "implicitly decreasing fn alignment" {
110 testImplicitlyDecreaseFnAlign(alignedBig, 5678);110 testImplicitlyDecreaseFnAlign(alignedBig, 5678);
111}111}
112112
113fn testImplicitlyDecreaseFnAlign(ptr: fn () align 1 -> i32, answer: i32) {113fn testImplicitlyDecreaseFnAlign(ptr: fn () align(1) -> i32, answer: i32) {
114 assert(ptr() == answer);114 assert(ptr() == answer);
115}115}
116116
117fn alignedSmall() align 8 -> i32 { 1234 }117fn alignedSmall() align(8) -> i32 { 1234 }
118fn alignedBig() align 16 -> i32 { 5678 }118fn alignedBig() align(16) -> i32 { 5678 }
119119
120120
121test "@alignCast functions" {121test "@alignCast functions" {
122 assert(fnExpectsOnly1(simple4) == 0x19);122 assert(fnExpectsOnly1(simple4) == 0x19);
123}123}
124fn fnExpectsOnly1(ptr: fn()align 1 -> i32) -> i32 {124fn fnExpectsOnly1(ptr: fn()align(1) -> i32) -> i32 {
125 fnExpects4(@alignCast(4, ptr))125 fnExpects4(@alignCast(4, ptr))
126}126}
127fn fnExpects4(ptr: fn()align 4 -> i32) -> i32 {127fn fnExpects4(ptr: fn()align(4) -> i32) -> i32 {
128 ptr()128 ptr()
129}129}
130fn simple4() align 4 -> i32 { 0x19 }130fn simple4() align(4) -> i32 { 0x19 }
131131
132132
133test "generic function with align param" {133test "generic function with align param" {
...@@ -136,37 +136,37 @@ test "generic function with align param" {...@@ -136,37 +136,37 @@ test "generic function with align param" {
136 assert(whyWouldYouEverDoThis(8) == 0x1);136 assert(whyWouldYouEverDoThis(8) == 0x1);
137}137}
138138
139fn whyWouldYouEverDoThis(comptime align_bytes: u8) align align_bytes -> u8 { 0x1 }139fn whyWouldYouEverDoThis(comptime align_bytes: u8) align(align_bytes) -> u8 { 0x1 }
140140
141141
142test "@ptrCast preserves alignment of bigger source" {142test "@ptrCast preserves alignment of bigger source" {
143 var x: u32 align 16 = 1234;143 var x: u32 align(16) = 1234;
144 const ptr = @ptrCast(&u8, &x);144 const ptr = @ptrCast(&u8, &x);
145 assert(@typeOf(ptr) == &align 16 u8);145 assert(@typeOf(ptr) == &align(16) u8);
146}146}
147147
148148
149test "compile-time known array index has best alignment possible" {149test "compile-time known array index has best alignment possible" {
150 // take full advantage of over-alignment150 // take full advantage of over-alignment
151 var array align 4 = []u8 {1, 2, 3, 4};151 var array align(4) = []u8 {1, 2, 3, 4};
152 assert(@typeOf(&array[0]) == &align 4 u8);152 assert(@typeOf(&array[0]) == &align(4) u8);
153 assert(@typeOf(&array[1]) == &u8);153 assert(@typeOf(&array[1]) == &u8);
154 assert(@typeOf(&array[2]) == &align 2 u8);154 assert(@typeOf(&array[2]) == &align(2) u8);
155 assert(@typeOf(&array[3]) == &u8);155 assert(@typeOf(&array[3]) == &u8);
156156
157 // because align is too small but we still figure out to use 2157 // because align is too small but we still figure out to use 2
158 var bigger align 2 = []u64{1, 2, 3, 4};158 var bigger align(2) = []u64{1, 2, 3, 4};
159 assert(@typeOf(&bigger[0]) == &align 2 u64);159 assert(@typeOf(&bigger[0]) == &align(2) u64);
160 assert(@typeOf(&bigger[1]) == &align 2 u64);160 assert(@typeOf(&bigger[1]) == &align(2) u64);
161 assert(@typeOf(&bigger[2]) == &align 2 u64);161 assert(@typeOf(&bigger[2]) == &align(2) u64);
162 assert(@typeOf(&bigger[3]) == &align 2 u64);162 assert(@typeOf(&bigger[3]) == &align(2) u64);
163163
164 // because pointer is align 2 and u32 align % 2 == 0 we can assume align 2164 // because pointer is align 2 and u32 align % 2 == 0 we can assume align 2
165 var smaller align 2 = []u32{1, 2, 3, 4};165 var smaller align(2) = []u32{1, 2, 3, 4};
166 testIndex(&smaller[0], 0, &align 2 u32);166 testIndex(&smaller[0], 0, &align(2) u32);
167 testIndex(&smaller[0], 1, &align 2 u32);167 testIndex(&smaller[0], 1, &align(2) u32);
168 testIndex(&smaller[0], 2, &align 2 u32);168 testIndex(&smaller[0], 2, &align(2) u32);
169 testIndex(&smaller[0], 3, &align 2 u32);169 testIndex(&smaller[0], 3, &align(2) u32);
170170
171 // has to use ABI alignment because index known at runtime only171 // has to use ABI alignment because index known at runtime only
172 testIndex2(&array[0], 0, &u8);172 testIndex2(&array[0], 0, &u8);
...@@ -174,9 +174,9 @@ test "compile-time known array index has best alignment possible" {...@@ -174,9 +174,9 @@ test "compile-time known array index has best alignment possible" {
174 testIndex2(&array[0], 2, &u8);174 testIndex2(&array[0], 2, &u8);
175 testIndex2(&array[0], 3, &u8);175 testIndex2(&array[0], 3, &u8);
176}176}
177fn testIndex(smaller: &align 2 u32, index: usize, comptime T: type) {177fn testIndex(smaller: &align(2) u32, index: usize, comptime T: type) {
178 assert(@typeOf(&smaller[index]) == T);178 assert(@typeOf(&smaller[index]) == T);
179}179}
180fn testIndex2(ptr: &align 4 u8, index: usize, comptime T: type) {180fn testIndex2(ptr: &align(4) u8, index: usize, comptime T: type) {
181 assert(@typeOf(&ptr[index]) == T);181 assert(@typeOf(&ptr[index]) == T);
182}182}
test/cases/cast.zig+1-1
...@@ -277,7 +277,7 @@ fn cast128Float(x: u128) -> f128 {...@@ -277,7 +277,7 @@ fn cast128Float(x: u128) -> f128 {
277}277}
278278
279test "const slice widen cast" {279test "const slice widen cast" {
280 const bytes align 4 = []u8{0x12, 0x12, 0x12, 0x12};280 const bytes align(4) = []u8{0x12, 0x12, 0x12, 0x12};
281281
282 const u32_value = ([]const u32)(bytes[0..])[0];282 const u32_value = ([]const u32)(bytes[0..])[0];
283 assert(u32_value == 0x12121212);283 assert(u32_value == 0x12121212);
test/cases/misc.zig+1-1
...@@ -404,7 +404,7 @@ test "cast slice to u8 slice" {...@@ -404,7 +404,7 @@ test "cast slice to u8 slice" {
404 bytes[6] = 0;404 bytes[6] = 0;
405 bytes[7] = 0;405 bytes[7] = 0;
406 assert(big_thing_slice[1] == 0);406 assert(big_thing_slice[1] == 0);
407 const big_thing_again = ([]align 1 i32)(bytes);407 const big_thing_again = ([]align(1) i32)(bytes);
408 assert(big_thing_again[2] == 3);408 assert(big_thing_again[2] == 3);
409 big_thing_again[2] = -1;409 big_thing_again[2] = -1;
410 assert(bytes[8] == @maxValue(u8));410 assert(bytes[8] == @maxValue(u8));
test/compare_output.zig+2-2
...@@ -262,8 +262,8 @@ pub fn addCases(cases: &tests.CompareOutputContext) {...@@ -262,8 +262,8 @@ pub fn addCases(cases: &tests.CompareOutputContext) {
262 \\const c = @cImport(@cInclude("stdlib.h"));262 \\const c = @cImport(@cInclude("stdlib.h"));
263 \\263 \\
264 \\export fn compare_fn(a: ?&const c_void, b: ?&const c_void) -> c_int {264 \\export fn compare_fn(a: ?&const c_void, b: ?&const c_void) -> c_int {
265 \\ const a_int = @ptrCast(&align 1 i32, a ?? unreachable);265 \\ const a_int = @ptrCast(&align(1) i32, a ?? unreachable);
266 \\ const b_int = @ptrCast(&align 1 i32, b ?? unreachable);266 \\ const b_int = @ptrCast(&align(1) i32, b ?? unreachable);
267 \\ if (*a_int < *b_int) {267 \\ if (*a_int < *b_int) {
268 \\ -1268 \\ -1
269 \\ } else if (*a_int > *b_int) {269 \\ } else if (*a_int > *b_int) {
test/compile_errors.zig+9-9
...@@ -1317,12 +1317,12 @@ pub fn addCases(cases: &tests.CompileErrorContext) {...@@ -1317,12 +1317,12 @@ pub fn addCases(cases: &tests.CompileErrorContext) {
1317 , ".tmp_source.zig:2:24: error: integer value 753664 cannot be implicitly casted to type 'u16'");1317 , ".tmp_source.zig:2:24: error: integer value 753664 cannot be implicitly casted to type 'u16'");
13181318
1319 cases.add("global variable alignment non power of 2",1319 cases.add("global variable alignment non power of 2",
1320 \\const some_data: [100]u8 align 3 = undefined;1320 \\const some_data: [100]u8 align(3) = undefined;
1321 \\export fn entry() -> usize { @sizeOf(@typeOf(some_data)) }1321 \\export fn entry() -> usize { @sizeOf(@typeOf(some_data)) }
1322 , ".tmp_source.zig:1:32: error: alignment value 3 is not a power of 2");1322 , ".tmp_source.zig:1:32: error: alignment value 3 is not a power of 2");
13231323
1324 cases.add("function alignment non power of 2",1324 cases.add("function alignment non power of 2",
1325 \\extern fn foo() align 3;1325 \\extern fn foo() align(3);
1326 \\export fn entry() { foo() }1326 \\export fn entry() { foo() }
1327 , ".tmp_source.zig:1:23: error: alignment value 3 is not a power of 2");1327 , ".tmp_source.zig:1:23: error: alignment value 3 is not a power of 2");
13281328
...@@ -1359,7 +1359,7 @@ pub fn addCases(cases: &tests.CompileErrorContext) {...@@ -1359,7 +1359,7 @@ pub fn addCases(cases: &tests.CompileErrorContext) {
1359 \\}1359 \\}
1360 \\1360 \\
1361 \\export fn entry() -> usize { @sizeOf(@typeOf(foo)) }1361 \\export fn entry() -> usize { @sizeOf(@typeOf(foo)) }
1362 , ".tmp_source.zig:8:26: error: expected type '&const u3', found '&align 1:3:6 const u3'");1362 , ".tmp_source.zig:8:26: error: expected type '&const u3', found '&align(1:3:6) const u3'");
13631363
1364 cases.add("referring to a struct that is invalid",1364 cases.add("referring to a struct that is invalid",
1365 \\const UsbDeviceRequest = struct {1365 \\const UsbDeviceRequest = struct {
...@@ -1992,7 +1992,7 @@ pub fn addCases(cases: &tests.CompileErrorContext) {...@@ -1992,7 +1992,7 @@ pub fn addCases(cases: &tests.CompileErrorContext) {
1992 \\ *x += 1;1992 \\ *x += 1;
1993 \\}1993 \\}
1994 ,1994 ,
1995 ".tmp_source.zig:8:13: error: expected type '&u32', found '&align 1 u32'");1995 ".tmp_source.zig:8:13: error: expected type '&u32', found '&align(1) u32'");
19961996
1997 cases.add("implicitly increasing slice alignment",1997 cases.add("implicitly increasing slice alignment",
1998 \\const Foo = packed struct {1998 \\const Foo = packed struct {
...@@ -2010,7 +2010,7 @@ pub fn addCases(cases: &tests.CompileErrorContext) {...@@ -2010,7 +2010,7 @@ pub fn addCases(cases: &tests.CompileErrorContext) {
2010 \\ x[0] += 1;2010 \\ x[0] += 1;
2011 \\}2011 \\}
2012 ,2012 ,
2013 ".tmp_source.zig:9:17: error: expected type '[]u32', found '[]align 1 u32'");2013 ".tmp_source.zig:9:17: error: expected type '[]u32', found '[]align(1) u32'");
20142014
2015 cases.add("increase pointer alignment in @ptrCast",2015 cases.add("increase pointer alignment in @ptrCast",
2016 \\export fn entry() -> u32 {2016 \\export fn entry() -> u32 {
...@@ -2044,17 +2044,17 @@ pub fn addCases(cases: &tests.CompileErrorContext) {...@@ -2044,17 +2044,17 @@ pub fn addCases(cases: &tests.CompileErrorContext) {
2044 \\export fn entry() {2044 \\export fn entry() {
2045 \\ testImplicitlyDecreaseFnAlign(alignedSmall, 1234);2045 \\ testImplicitlyDecreaseFnAlign(alignedSmall, 1234);
2046 \\}2046 \\}
2047 \\fn testImplicitlyDecreaseFnAlign(ptr: fn () align 8 -> i32, answer: i32) {2047 \\fn testImplicitlyDecreaseFnAlign(ptr: fn () align(8) -> i32, answer: i32) {
2048 \\ if (ptr() != answer) unreachable;2048 \\ if (ptr() != answer) unreachable;
2049 \\}2049 \\}
2050 \\fn alignedSmall() align 4 -> i32 { 1234 }2050 \\fn alignedSmall() align(4) -> i32 { 1234 }
2051 ,2051 ,
2052 ".tmp_source.zig:2:35: error: expected type 'fn() align 8 -> i32', found 'fn() align 4 -> i32'");2052 ".tmp_source.zig:2:35: error: expected type 'fn() align(8) -> i32', found 'fn() align(4) -> i32'");
20532053
2054 cases.add("passing a not-aligned-enough pointer to cmpxchg",2054 cases.add("passing a not-aligned-enough pointer to cmpxchg",
2055 \\const AtomicOrder = @import("builtin").AtomicOrder;2055 \\const AtomicOrder = @import("builtin").AtomicOrder;
2056 \\export fn entry() -> bool {2056 \\export fn entry() -> bool {
2057 \\ var x: i32 align 1 = 1234;2057 \\ var x: i32 align(1) = 1234;
2058 \\ while (!@cmpxchg(&x, 1234, 5678, AtomicOrder.SeqCst, AtomicOrder.SeqCst)) {}2058 \\ while (!@cmpxchg(&x, 1234, 5678, AtomicOrder.SeqCst, AtomicOrder.SeqCst)) {}
2059 \\ return x == 5678;2059 \\ return x == 5678;
2060 \\}2060 \\}
test/debug_safety.zig+3-3
...@@ -200,8 +200,8 @@ pub fn addCases(cases: &tests.CompareOutputContext) {...@@ -200,8 +200,8 @@ pub fn addCases(cases: &tests.CompareOutputContext) {
200 \\ const x = widenSlice([]u8{1, 2, 3, 4, 5});200 \\ const x = widenSlice([]u8{1, 2, 3, 4, 5});
201 \\ if (x.len == 0) return error.Whatever;201 \\ if (x.len == 0) return error.Whatever;
202 \\}202 \\}
203 \\fn widenSlice(slice: []align 1 const u8) -> []align 1 const i32 {203 \\fn widenSlice(slice: []align(1) const u8) -> []align(1) const i32 {
204 \\ ([]align 1 const i32)(slice)204 \\ ([]align(1) const i32)(slice)
205 \\}205 \\}
206 );206 );
207207
...@@ -269,7 +269,7 @@ pub fn addCases(cases: &tests.CompareOutputContext) {...@@ -269,7 +269,7 @@ pub fn addCases(cases: &tests.CompareOutputContext) {
269 \\}269 \\}
270 \\error Wrong;270 \\error Wrong;
271 \\pub fn main() -> %void {271 \\pub fn main() -> %void {
272 \\ var array align 4 = []u32{0x11111111, 0x11111111};272 \\ var array align(4) = []u32{0x11111111, 0x11111111};
273 \\ const bytes = ([]u8)(array[0..]);273 \\ const bytes = ([]u8)(array[0..]);
274 \\ if (foo(bytes) != 0x11111111) return error.Wrong;274 \\ if (foo(bytes) != 0x11111111) return error.Wrong;
275 \\}275 \\}