Commit 14f03fbd16

Veikka Tuominen <git@vexu.eu>
2023-01-16 14:13:06
AstGen: reset source cursor before generating pointer attributes
These attributes can appear in any order but AstGen expects the source cursor to be incremented in a monotonically increasing order. Closes #14332
1 parent 24646b8
Changed files (2)
src
test
behavior
src/AstGen.zig
@@ -3341,6 +3341,9 @@ fn ptrType(
         return gz.astgen.failTok(ptr_info.allowzero_token.?, "C pointers always allow address zero", .{});
     }
 
+    const source_offset = gz.astgen.source_offset;
+    const source_line = gz.astgen.source_line;
+    const source_column = gz.astgen.source_column;
     const elem_type = try typeExpr(gz, scope, ptr_info.ast.child_type);
 
     var sentinel_ref: Zir.Inst.Ref = .none;
@@ -3351,17 +3354,31 @@ fn ptrType(
     var trailing_count: u32 = 0;
 
     if (ptr_info.ast.sentinel != 0) {
+        // These attributes can appear in any order and they all come before the
+        // element type so we need to reset the source cursor before generating them.
+        gz.astgen.source_offset = source_offset;
+        gz.astgen.source_line = source_line;
+        gz.astgen.source_column = source_column;
+
         sentinel_ref = try comptimeExpr(gz, scope, .{ .rl = .{ .ty = elem_type } }, ptr_info.ast.sentinel);
         trailing_count += 1;
     }
-    if (ptr_info.ast.align_node != 0) {
-        align_ref = try expr(gz, scope, coerced_align_ri, ptr_info.ast.align_node);
-        trailing_count += 1;
-    }
     if (ptr_info.ast.addrspace_node != 0) {
+        gz.astgen.source_offset = source_offset;
+        gz.astgen.source_line = source_line;
+        gz.astgen.source_column = source_column;
+
         addrspace_ref = try expr(gz, scope, .{ .rl = .{ .ty = .address_space_type } }, ptr_info.ast.addrspace_node);
         trailing_count += 1;
     }
+    if (ptr_info.ast.align_node != 0) {
+        gz.astgen.source_offset = source_offset;
+        gz.astgen.source_line = source_line;
+        gz.astgen.source_column = source_column;
+
+        align_ref = try expr(gz, scope, coerced_align_ri, ptr_info.ast.align_node);
+        trailing_count += 1;
+    }
     if (ptr_info.ast.bit_range_start != 0) {
         assert(ptr_info.ast.bit_range_end != 0);
         bit_start_ref = try expr(gz, scope, .{ .rl = .{ .coerced_ty = .u16_type } }, ptr_info.ast.bit_range_start);
test/behavior/pointers.zig
@@ -522,3 +522,13 @@ test "ptrToInt on a generic function" {
     };
     try S.doTheTest(&S.generic);
 }
+
+test "pointer alignment and element type include call expression" {
+    const S = struct {
+        fn T() type {
+            return struct { _: i32 };
+        }
+        const P = *align(@alignOf(T())) [@sizeOf(T())]u8;
+    };
+    try expect(@alignOf(S.P) > 0);
+}