mirror of
https://github.com/c3lang/c3c.git
synced 2026-02-27 12:01:16 +00:00
- unsigned % signed and unsigned / signed is no longer allowed without explicit casts, except for const denominators. #2928
This commit is contained in:
@@ -272,7 +272,7 @@ macro fetch_mul(ptr, y, AtomicOrdering $ordering = SEQ_CONSISTENT)
|
|||||||
|
|
||||||
@require $defined(*ptr) : "Expected a pointer"
|
@require $defined(*ptr) : "Expected a pointer"
|
||||||
@require @is_native_atomic_value(*ptr) : "Only types that are native atomic may be used."
|
@require @is_native_atomic_value(*ptr) : "Only types that are native atomic may be used."
|
||||||
@require $defined(*ptr * y) : "/ must be defined between the values."
|
@require $defined(*ptr / y) : "/ must be defined between the values."
|
||||||
@require $ordering != NOT_ATOMIC && $ordering != UNORDERED : "Acquire ordering is not valid."
|
@require $ordering != NOT_ATOMIC && $ordering != UNORDERED : "Acquire ordering is not valid."
|
||||||
*>
|
*>
|
||||||
macro fetch_div(ptr, y, AtomicOrdering $ordering = SEQ_CONSISTENT)
|
macro fetch_div(ptr, y, AtomicOrdering $ordering = SEQ_CONSISTENT)
|
||||||
|
|||||||
@@ -158,7 +158,7 @@ macro double? decfloat(char[] chars, int $bits, int $emin, int sign)
|
|||||||
if (rp % 9)
|
if (rp % 9)
|
||||||
{
|
{
|
||||||
long rpm9 = rp >= 0 ? rp % 9 : rp % 9 + 9;
|
long rpm9 = rp >= 0 ? rp % 9 : rp % 9 + 9;
|
||||||
int p10 = P10S[8 - rpm9];
|
uint p10 = P10S[8 - rpm9];
|
||||||
uint carry = 0;
|
uint carry = 0;
|
||||||
for (k = a; k != z; k++)
|
for (k = a; k != z; k++)
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -377,13 +377,13 @@ fn usz? Formatter.floatformat(&self, FloatFormatting formatting, double y) @priv
|
|||||||
j %= 9;
|
j %= 9;
|
||||||
int i;
|
int i;
|
||||||
for (i = 10, j++; j < 9; i *= 10, j++);
|
for (i = 10, j++; j < 9; i *= 10, j++);
|
||||||
x = *d % i;
|
x = *d % (uint)i;
|
||||||
// Are there any significant digits past j?
|
// Are there any significant digits past j?
|
||||||
if (x || (d + 1) != z)
|
if (x || (d + 1) != z)
|
||||||
{
|
{
|
||||||
double round = 2 / math::DOUBLE_EPSILON;
|
double round = 2 / math::DOUBLE_EPSILON;
|
||||||
double small;
|
double small;
|
||||||
if (((*d / i) & 1) || (i == 1000000000 && d > a && (d[-1] & 1)))
|
if (((*d / (uint)i) & 1) || (i == 1000000000 && d > a && (d[-1] & 1)))
|
||||||
{
|
{
|
||||||
round += 2;
|
round += 2;
|
||||||
}
|
}
|
||||||
@@ -437,7 +437,7 @@ fn usz? Formatter.floatformat(&self, FloatFormatting formatting, double y) @priv
|
|||||||
// Count trailing zeros in last place
|
// Count trailing zeros in last place
|
||||||
if (z > a && z[-1])
|
if (z > a && z[-1])
|
||||||
{
|
{
|
||||||
for (int i = 10, j = 0; z[-1] % i == 0; i *= 10, j++);
|
for (int i = 10, j = 0; z[-1] % (uint)i == 0; i *= 10, j++);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -8,6 +8,7 @@
|
|||||||
- Improve support for Android with Termux.
|
- Improve support for Android with Termux.
|
||||||
- Integrated download of the MSVC SDK when compiling for Windows.
|
- Integrated download of the MSVC SDK when compiling for Windows.
|
||||||
- For `c3c init` with library templates, provide example exported functions. #2898
|
- For `c3c init` with library templates, provide example exported functions. #2898
|
||||||
|
- `unsigned % signed` and `unsigned / signed` is no longer allowed without explicit casts, except for const denominators. #2928
|
||||||
|
|
||||||
### Stdlib changes
|
### Stdlib changes
|
||||||
- Summarize sort macros as generic function wrappers to reduce the amount of generated code. #2831
|
- Summarize sort macros as generic function wrappers to reduce the amount of generated code. #2831
|
||||||
|
|||||||
@@ -1524,6 +1524,7 @@ static inline bool sema_binary_analyse_arithmetic_subexpr(SemaContext *context,
|
|||||||
if (flat_left->type_kind == TYPE_BITSTRUCT && left_type == right_type) return true;
|
if (flat_left->type_kind == TYPE_BITSTRUCT && left_type == right_type) return true;
|
||||||
if (flat_left == type_bool && left_type == right_type) return true;
|
if (flat_left == type_bool && left_type == right_type) return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
// 2. Perform promotion to a common type.
|
// 2. Perform promotion to a common type.
|
||||||
return sema_binary_arithmetic_promotion(context, left, right, left_type, right_type, expr, error,
|
return sema_binary_arithmetic_promotion(context, left, right, left_type, right_type, expr, error,
|
||||||
bool_and_bitstruct_is_allowed, operator_overload_ref, failed_ref);
|
bool_and_bitstruct_is_allowed, operator_overload_ref, failed_ref);
|
||||||
@@ -8157,6 +8158,16 @@ static bool sema_expr_analyse_mult(SemaContext *context, Expr *expr, Expr *left,
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static inline bool sema_convert_denominator_to_unsigned_if_needed(SemaContext *context, Expr *left, Expr *right)
|
||||||
|
{
|
||||||
|
if (!type_is_unsigned(left->type->canonical) || !type_is_signed(right->type->canonical)) return true;
|
||||||
|
if (sema_cast_const(right) && expr_is_const_int(right) && !int_is_neg(right->const_expr.ixx))
|
||||||
|
{
|
||||||
|
return cast_implicit(context, right, type_int_unsigned_by_bitsize(type_bit_size(right->type->canonical)), true);
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Analyse a / b
|
* Analyse a / b
|
||||||
* @return true if analysis completed ok.
|
* @return true if analysis completed ok.
|
||||||
@@ -8165,6 +8176,11 @@ static bool sema_expr_analyse_div(SemaContext *context, Expr *expr, Expr *left,
|
|||||||
{
|
{
|
||||||
// 1. Analyse sub expressions and promote to a common type
|
// 1. Analyse sub expressions and promote to a common type
|
||||||
OperatorOverload overload = OVERLOAD_DIVIDE;
|
OperatorOverload overload = OVERLOAD_DIVIDE;
|
||||||
|
if (!sema_convert_denominator_to_unsigned_if_needed(context, left, right))
|
||||||
|
{
|
||||||
|
if (failed_ref) return *failed_ref = true, false;
|
||||||
|
RETURN_SEMA_ERROR(expr, "Cannot implicitly divide an unsigned integer by an non-const signed integer, please use explicit casts.");
|
||||||
|
}
|
||||||
if (!sema_binary_analyse_arithmetic_subexpr(context, expr, "Cannot divide %s by %s.", false, &overload, failed_ref)) return false;
|
if (!sema_binary_analyse_arithmetic_subexpr(context, expr, "Cannot divide %s by %s.", false, &overload, failed_ref)) return false;
|
||||||
if (!overload) return true;
|
if (!overload) return true;
|
||||||
|
|
||||||
@@ -8221,6 +8237,12 @@ static bool sema_expr_analyse_mod(SemaContext *context, Expr *expr, Expr *left,
|
|||||||
{
|
{
|
||||||
// 1. Analyse both sides and promote to a common type
|
// 1. Analyse both sides and promote to a common type
|
||||||
OperatorOverload overload = OVERLOAD_REMINDER;
|
OperatorOverload overload = OVERLOAD_REMINDER;
|
||||||
|
if (!sema_convert_denominator_to_unsigned_if_needed(context, left, right))
|
||||||
|
{
|
||||||
|
if (failed_ref) return *failed_ref = true, false;
|
||||||
|
RETURN_SEMA_ERROR(expr, "Cannot implicitly convert the values in a remainder operation with an unsigned nominator and non-const or negative signed denominator, please use explicit casts.");
|
||||||
|
}
|
||||||
|
|
||||||
if (!sema_binary_analyse_arithmetic_subexpr(context, expr, "Cannot calculate the remainder %s %% %s",
|
if (!sema_binary_analyse_arithmetic_subexpr(context, expr, "Cannot calculate the remainder %s %% %s",
|
||||||
false, &overload, failed_ref)) return false;
|
false, &overload, failed_ref)) return false;
|
||||||
if (!overload) return true;
|
if (!overload) return true;
|
||||||
|
|||||||
@@ -87,7 +87,7 @@ fn void div() @test
|
|||||||
{
|
{
|
||||||
t.create(fn int(void* arg) {
|
t.create(fn int(void* arg) {
|
||||||
thread::sleep_ms(5);
|
thread::sleep_ms(5);
|
||||||
atomic::fetch_div(&a, 8);
|
atomic::fetch_div(&a, 8U);
|
||||||
return 0;
|
return 0;
|
||||||
}, null)!!;
|
}, null)!!;
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user