mirror of
https://github.com/c3lang/c3c.git
synced 2026-02-27 12:01:16 +00:00
Prevent implicit array casts to pointers with higher alignment. #1237
This commit is contained in:
@@ -18,6 +18,7 @@
|
||||
- Max number of members in a struct is limited to 65535.
|
||||
- The maximum number of parameters in a call is now 255, up from 127.
|
||||
- Array comparison now uses built-in memcmp on LLVM to enable optimizations.
|
||||
- Prevent implicit array casts to pointers with higher alignment #1237.
|
||||
|
||||
### Fixes
|
||||
- Error with unsigned compare in `@ensure` when early returning 0 #1207.
|
||||
|
||||
@@ -2496,6 +2496,7 @@ typedef enum
|
||||
TYPE_MISMATCH = 0,
|
||||
TYPE_SAME = 1,
|
||||
TYPE_SAME_INT_SIZE = 2,
|
||||
TYPE_ALIGNMENT_INCREASE = 3,
|
||||
TYPE_ERROR = -1,
|
||||
} TypeCmpResult;
|
||||
|
||||
|
||||
@@ -682,6 +682,17 @@ static bool rule_ptr_to_ptr(CastContext *cc, bool is_explicit, bool is_silent)
|
||||
return true;
|
||||
case TYPE_ERROR:
|
||||
return false;
|
||||
case TYPE_ALIGNMENT_INCREASE:
|
||||
if (is_explicit) return false;
|
||||
assert(!is_explicit);
|
||||
RETURN_CAST_ERROR(cc->expr,
|
||||
"Implicitly casting %s (alignment %d) to %s (alignment %d) is not permitted, "
|
||||
"it would require an explicit cast. Before using an explicit cast, please make "
|
||||
"sure you understand the ramifications as the explicit cast might crash your program if used incorrectly.",
|
||||
type_quoted_error_string(type_no_optional(cc->expr->type)),
|
||||
type_abi_alignment(type_get_indexed_type(cc->expr->type)),
|
||||
type_quoted_error_string(cc->to),
|
||||
type_abi_alignment(type_get_indexed_type(cc->to)));
|
||||
case TYPE_MISMATCH:
|
||||
case TYPE_SAME_INT_SIZE:
|
||||
return sema_cast_error(cc, true, is_silent);
|
||||
|
||||
@@ -1661,6 +1661,8 @@ RETRY:
|
||||
|
||||
if (to_pointee->type_kind != from_pointee->type_kind)
|
||||
{
|
||||
TypeCmpResult res_current = TYPE_SAME;
|
||||
if (type_abi_alignment(to_pointee) > type_abi_alignment(from_pointee)) res_current = TYPE_ALIGNMENT_INCREASE;
|
||||
if (type_is_matching_int(to_pointee, from_pointee)) return TYPE_SAME_INT_SIZE;
|
||||
|
||||
if (type_is_any_arraylike(from_pointee))
|
||||
@@ -1669,10 +1671,11 @@ RETRY:
|
||||
if (type_is_any_arraylike(to_pointee))
|
||||
{
|
||||
TypeCmpResult res = type_array_is_equivalent(context, to_pointee, from_pointee, flatten_distinct);
|
||||
if (res != TYPE_MISMATCH) return res;
|
||||
if (res != TYPE_MISMATCH) return res == TYPE_SAME ? res_current : res;
|
||||
}
|
||||
// A possible int[4]* -> int* decay?
|
||||
return type_is_pointer_equivalent(context, type_get_ptr(from_pointee->array.base), to_pointer, flatten_distinct);
|
||||
TypeCmpResult res = type_is_pointer_equivalent(context, type_get_ptr(from_pointee->array.base), to_pointer, flatten_distinct);
|
||||
return res == TYPE_SAME ? res_current : res;
|
||||
}
|
||||
// Not arraylike and no array decay. Failure.
|
||||
return TYPE_MISMATCH;
|
||||
|
||||
17
test/test_suite/expressions/casts/cast_vector_fail.c3
Normal file
17
test/test_suite/expressions/casts/cast_vector_fail.c3
Normal file
@@ -0,0 +1,17 @@
|
||||
module foo;
|
||||
import std;
|
||||
fn void test(float[<4>]* x)
|
||||
{}
|
||||
fn void test2(float[4]* x)
|
||||
{}
|
||||
|
||||
fn int main(String[] args)
|
||||
{
|
||||
float[4] a;
|
||||
float[<4>] b;
|
||||
test(&a); // #error: Implicitly casting
|
||||
test(&b);
|
||||
test2(&a);
|
||||
test2(&b);
|
||||
return 1;
|
||||
}
|
||||
Reference in New Issue
Block a user