aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAndrew Kelley <superjoe30@gmail.com>2017-08-29 15:19:15 -0400
committerAndrew Kelley <superjoe30@gmail.com>2017-08-29 15:19:15 -0400
commitbe94299666e57486be6bdb8fee2b79dbf3623c5d (patch)
treee0a04a80df130e5aee55b6cfa5d309821fbd8e97
parent8f682efbc5abf4d631f60310f95b998c6fe44669 (diff)
downloadzig-be94299666e57486be6bdb8fee2b79dbf3623c5d.tar.gz
zig-be94299666e57486be6bdb8fee2b79dbf3623c5d.zip
prevent implicitly increasing pointer alignment
See #37
-rw-r--r--src/analyze.cpp25
-rw-r--r--test/cases/align.zig15
-rw-r--r--test/compile_errors.zig35
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'");
}