diff --git a/lib/std/atomic.c3 b/lib/std/atomic.c3 index 0a3a7cc82..f47d8ea4e 100644 --- a/lib/std/atomic.c3 +++ b/lib/std/atomic.c3 @@ -129,13 +129,15 @@ macro @atomic_exec(#func, data, value, ordering) @local } module std::atomic; +import std::math; /** * @param [&in] ptr "the variable or dereferenced pointer to the data." * @param [in] y "the value to be added to ptr." * @param $ordering "atomic ordering of the load, defaults to SEQ_CONSISTENT" * @return "returns the old value of ptr" - * + * + * @require !$alignment || math::is_power_of_2($alignment) "Alignment must be a power of two." * @require types::is_int($typeof(*ptr)) || types::is_float($typeof(*ptr)) "Only integer/float pointers may be used." * @require $ordering != AtomicOrdering.NOT_ATOMIC && $ordering != AtomicOrdering.UNORDERED "Acquire ordering is not valid." **/ @@ -153,6 +155,7 @@ macro fetch_add(ptr, y, AtomicOrdering $ordering = SEQ_CONSISTENT, bool $volatil * @param $ordering "atomic ordering of the load, defaults to SEQ_CONSISTENT" * @return "returns the old value of ptr" * + * @require !$alignment || math::is_power_of_2($alignment) "Alignment must be a power of two." * @require types::is_int($typeof(*ptr)) || types::is_float($typeof(*ptr)) "Only integer/float pointers may be used." * @require $ordering != AtomicOrdering.NOT_ATOMIC && $ordering != AtomicOrdering.UNORDERED "Acquire ordering is not valid." **/ @@ -170,8 +173,8 @@ macro fetch_sub(ptr, y, AtomicOrdering $ordering = SEQ_CONSISTENT, bool $volatil * @param $ordering "atomic ordering of the load, defaults to SEQ_CONSISTENT" * @return "returns the old value of ptr" * -* @require types::is_int($typeof(*ptr)) || types::is_float($typeof(*ptr)) "Only integer/float pointers may be used." -* @require $ordering != AtomicOrdering.NOT_ATOMIC && $ordering != AtomicOrdering.UNORDERED "Acquire ordering is not valid." + * @require types::is_int($typeof(*ptr)) || types::is_float($typeof(*ptr)) "Only integer/float pointers may be used." + * @require $ordering != AtomicOrdering.NOT_ATOMIC && $ordering != AtomicOrdering.UNORDERED "Acquire ordering is not valid." **/ macro fetch_mul(ptr, y, AtomicOrdering $ordering = SEQ_CONSISTENT) { @@ -243,6 +246,7 @@ macro fetch_div(ptr, y, AtomicOrdering $ordering = SEQ_CONSISTENT) * @param $ordering "atomic ordering of the load, defaults to SEQ_CONSISTENT" * @return "returns the old value of ptr" * + * @require !$alignment || math::is_power_of_2($alignment) "Alignment must be a power of two." * @require types::is_int($typeof(*ptr)) "Only intege pointers may be used." * @require types::is_int($typeof(y)) "The value for or must be an int" * @require $ordering != AtomicOrdering.NOT_ATOMIC && $ordering != AtomicOrdering.UNORDERED "Acquire ordering is not valid." @@ -285,6 +289,7 @@ macro fetch_or(ptr, y, AtomicOrdering $ordering = SEQ_CONSISTENT, bool $volatile * @param $ordering "atomic ordering of the load, defaults to SEQ_CONSISTENT" * @return "returns the old value of ptr" * + * @require !$alignment || math::is_power_of_2($alignment) "Alignment must be a power of two." * @require types::is_int($typeof(*ptr)) "Only integer pointers may be used." * @require types::is_int($typeof(y)) "The value for or must be an int" * @require $ordering != AtomicOrdering.NOT_ATOMIC && $ordering != AtomicOrdering.UNORDERED "Acquire ordering is not valid." @@ -327,6 +332,7 @@ macro fetch_xor(ptr, y, AtomicOrdering $ordering = SEQ_CONSISTENT, bool $volatil * @param $ordering "atomic ordering of the load, defaults to SEQ_CONSISTENT" * @return "returns the old value of ptr" * + * @require !$alignment || math::is_power_of_2($alignment) "Alignment must be a power of two." * @require types::is_int($typeof(*ptr)) "Only integer pointers may be used." * @require types::is_int($typeof(y)) "The value for or must be an int" * @require $ordering != AtomicOrdering.NOT_ATOMIC && $ordering != AtomicOrdering.UNORDERED "Acquire ordering is not valid." diff --git a/src/compiler/llvm_codegen_builtins.c b/src/compiler/llvm_codegen_builtins.c index 5c1e94889..3539f0873 100644 --- a/src/compiler/llvm_codegen_builtins.c +++ b/src/compiler/llvm_codegen_builtins.c @@ -112,6 +112,7 @@ INLINE void llvm_emit_compare_exchange(GenContext *c, BEValue *result_value, Exp ordering_to_llvm(success_ordering), ordering_to_llvm(failure_ordering), false); if (alignment && alignment >= type_abi_alignment(type)) { + assert(is_power_of_two(alignment)); LLVMSetAlignment(result, alignment); } if (is_volatile) @@ -232,9 +233,10 @@ INLINE void llvm_emit_atomic_fetch(GenContext *c, BuiltinFunction func, BEValue llvm_atomic_ordering(expr->call_expr.arguments[3]->const_expr.ixx.i.low), false); if (expr->call_expr.arguments[2]->const_expr.b) LLVMSetVolatile(res, true); - uint64_t alignment = expr->call_expr.arguments[3]->const_expr.ixx.i.low; + uint64_t alignment = expr->call_expr.arguments[4]->const_expr.ixx.i.low; if (alignment) { + assert(is_power_of_two(alignment)); LLVMSetAlignment(res, alignment); } llvm_value_set(result_value, res, result_value->type); diff --git a/src/version.h b/src/version.h index 196268cc2..19bb80370 100644 --- a/src/version.h +++ b/src/version.h @@ -1 +1 @@ -#define COMPILER_VERSION "0.4.650" \ No newline at end of file +#define COMPILER_VERSION "0.4.651" \ No newline at end of file