diff options
| author | Andrew Kelley <superjoe30@gmail.com> | 2017-08-29 15:19:15 -0400 |
|---|---|---|
| committer | Andrew Kelley <superjoe30@gmail.com> | 2017-08-29 15:19:15 -0400 |
| commit | be94299666e57486be6bdb8fee2b79dbf3623c5d (patch) | |
| tree | e0a04a80df130e5aee55b6cfa5d309821fbd8e97 | |
| parent | 8f682efbc5abf4d631f60310f95b998c6fe44669 (diff) | |
| download | zig-be94299666e57486be6bdb8fee2b79dbf3623c5d.tar.gz zig-be94299666e57486be6bdb8fee2b79dbf3623c5d.zip | |
prevent implicitly increasing pointer alignment
See #37
| -rw-r--r-- | src/analyze.cpp | 25 | ||||
| -rw-r--r-- | test/cases/align.zig | 15 | ||||
| -rw-r--r-- | test/compile_errors.zig | 35 |
3 files changed, 65 insertions, 10 deletions
diff --git a/src/analyze.cpp b/src/analyze.cpp index c6e0c28b90..69a50253d2 100644 --- a/src/analyze.cpp +++ b/src/analyze.cpp @@ -2615,25 +2615,30 @@ bool types_match_const_cast_only(TypeTableEntry *expected_type, TypeTableEntry * (!actual_type->data.pointer.is_const || expected_type->data.pointer.is_const) && (!actual_type->data.pointer.is_volatile || expected_type->data.pointer.is_volatile) && actual_type->data.pointer.bit_offset == expected_type->data.pointer.bit_offset && - actual_type->data.pointer.unaligned_bit_count == expected_type->data.pointer.unaligned_bit_count) + actual_type->data.pointer.unaligned_bit_count == expected_type->data.pointer.unaligned_bit_count && + actual_type->data.pointer.alignment >= expected_type->data.pointer.alignment) { return types_match_const_cast_only(expected_type->data.pointer.child_type, actual_type->data.pointer.child_type); } - // unknown size array const + // slice const if (expected_type->id == TypeTableEntryIdStruct && actual_type->id == TypeTableEntryIdStruct && expected_type->data.structure.is_slice && - actual_type->data.structure.is_slice && - (!actual_type->data.structure.fields[slice_ptr_index].type_entry->data.pointer.is_const || - expected_type->data.structure.fields[slice_ptr_index].type_entry->data.pointer.is_const) && - (!actual_type->data.structure.fields[slice_ptr_index].type_entry->data.pointer.is_volatile || - expected_type->data.structure.fields[slice_ptr_index].type_entry->data.pointer.is_volatile)) + actual_type->data.structure.is_slice) { - return types_match_const_cast_only( - expected_type->data.structure.fields[slice_ptr_index].type_entry->data.pointer.child_type, - actual_type->data.structure.fields[slice_ptr_index].type_entry->data.pointer.child_type); + TypeTableEntry *actual_ptr_type = actual_type->data.structure.fields[slice_ptr_index].type_entry; + TypeTableEntry *expected_ptr_type = expected_type->data.structure.fields[slice_ptr_index].type_entry; + if ((!actual_ptr_type->data.pointer.is_const || expected_ptr_type->data.pointer.is_const) && + (!actual_ptr_type->data.pointer.is_volatile || expected_ptr_type->data.pointer.is_volatile) && + actual_ptr_type->data.pointer.bit_offset == expected_ptr_type->data.pointer.bit_offset && + actual_ptr_type->data.pointer.unaligned_bit_count == expected_ptr_type->data.pointer.unaligned_bit_count && + actual_ptr_type->data.pointer.alignment >= expected_ptr_type->data.pointer.alignment) + { + return types_match_const_cast_only(expected_ptr_type->data.pointer.child_type, + actual_ptr_type->data.pointer.child_type); + } } // maybe diff --git a/test/cases/align.zig b/test/cases/align.zig index 1de14b084a..383d0389b5 100644 --- a/test/cases/align.zig +++ b/test/cases/align.zig @@ -38,3 +38,18 @@ test "bit field alignment" { test "default alignment allows unspecified in type syntax" { assert(&u32 == &align @alignOf(u32) u32); } + +test "implicitly decreasing pointer alignment" { + const a: u32 align 4 = 3; + const b: u32 align 8 = 4; + assert(addUnaligned(&a, &b) == 7); +} + +fn addUnaligned(a: &align 1 const u32, b: &align 1 const u32) -> u32 { *a + *b } + +test "implicitly decreasing slice alignment" { + const a: u32 align 4 = 3; + const b: u32 align 8 = 4; + assert(addUnalignedSlice((&a)[0..1], (&b)[0..1]) == 7); +} +fn addUnalignedSlice(a: []align 1 const u32, b: []align 1 const u32) -> u32 { a[0] + b[0] } diff --git a/test/compile_errors.zig b/test/compile_errors.zig index ac5e06d9f3..03110f98e7 100644 --- a/test/compile_errors.zig +++ b/test/compile_errors.zig @@ -1976,4 +1976,39 @@ pub fn addCases(cases: &tests.CompileErrorContext) { \\} , ".tmp_source.zig:1:1: error: declaration shadows type 'u16'"); + + cases.add("implicitly increasing pointer alignment", + \\const Foo = packed struct { + \\ a: u8, + \\ b: u32, + \\}; + \\ + \\export fn entry() { + \\ var foo = Foo { .a = 1, .b = 10 }; + \\ bar(&foo.b); + \\} + \\ + \\fn bar(x: &u32) { + \\ *x += 1; + \\} + , + ".tmp_source.zig:8:13: error: expected type '&u32', found '&align 1 u32'"); + + cases.add("implicitly increasing slice alignment", + \\const Foo = packed struct { + \\ a: u8, + \\ b: u32, + \\}; + \\ + \\export fn entry() { + \\ var foo = Foo { .a = 1, .b = 10 }; + \\ foo.b += 1; + \\ bar((&foo.b)[0..1]); + \\} + \\ + \\fn bar(x: []u32) { + \\ x[0] += 1; + \\} + , + ".tmp_source.zig:9:17: error: expected type '[]u32', found '[]align 1 u32'"); } |
