Commit e9280c86a1

Andrew Kelley <superjoe30@gmail.com>
2017-08-30 08:56:42
compile error for not-aligned-enough pointer to cmpxchg
See #37
1 parent 010b725
Changed files (2)
src/ir.cpp
@@ -13488,6 +13488,15 @@ static TypeTableEntry *ir_analyze_instruction_cmpxchg(IrAnalyze *ira, IrInstruct
 
     TypeTableEntry *child_type = ptr->value.type->data.pointer.child_type;
 
+    uint32_t align_bytes = ptr->value.type->data.pointer.alignment;
+    uint64_t size_bytes = type_size(ira->codegen, child_type);
+    if (align_bytes < size_bytes) {
+        ir_add_error(ira, instruction->ptr,
+            buf_sprintf("expected pointer alignment of at least %" ZIG_PRI_u64 ", found %" PRIu32,
+                size_bytes, align_bytes));
+        return ira->codegen->builtin_types.entry_invalid;
+    }
+
     IrInstruction *casted_cmp_value = ir_implicit_cast(ira, cmp_value, child_type);
     if (type_is_invalid(casted_cmp_value->value.type))
         return ira->codegen->builtin_types.entry_invalid;
test/compile_errors.zig
@@ -2051,4 +2051,14 @@ pub fn addCases(cases: &tests.CompileErrorContext) {
     ,
         ".tmp_source.zig:2:35: error: expected type 'fn() align 8 -> i32', found 'fn() align 4 -> i32'");
 
+    cases.add("passing a not-aligned-enough pointer to cmpxchg",
+        \\const AtomicOrder = @import("builtin").AtomicOrder;
+        \\export fn entry() -> bool {
+        \\    var x: i32 align 1 = 1234;
+        \\    while (!@cmpxchg(&x, 1234, 5678, AtomicOrder.SeqCst, AtomicOrder.SeqCst)) {}
+        \\    return x == 5678;
+        \\}
+    ,
+        ".tmp_source.zig:4:23: error: expected pointer alignment of at least 4, found 1");
+
 }