mirror of
https://github.com/c3lang/c3c.git
synced 2026-02-27 12:01:16 +00:00
- Compiler crash when concatenating structs and arrays to an untyped list.
This commit is contained in:
@@ -14,6 +14,7 @@
|
|||||||
- Hex escapes like `"\x80"` would be incorrectly lowered. #2623
|
- Hex escapes like `"\x80"` would be incorrectly lowered. #2623
|
||||||
- Ignore const null check on deref in `$defined` and `$sizeof` #2633.
|
- Ignore const null check on deref in `$defined` and `$sizeof` #2633.
|
||||||
- Subscripting of constant slices would sometimes be considered non-constant #2635.
|
- Subscripting of constant slices would sometimes be considered non-constant #2635.
|
||||||
|
- Compiler crash when concatenating structs and arrays to an untyped list.
|
||||||
|
|
||||||
### Stdlib changes
|
### Stdlib changes
|
||||||
- Add `ThreadPool` join function to wait for all threads to finish in the pool without destroying the threads.
|
- Add `ThreadPool` join function to wait for all threads to finish in the pool without destroying the threads.
|
||||||
|
|||||||
@@ -425,9 +425,20 @@ bool sema_expr_analyse_ct_concat(SemaContext *context, Expr *concat_expr, Expr *
|
|||||||
UNREACHABLE
|
UNREACHABLE
|
||||||
case CONST_INIT_ARRAY_FULL:
|
case CONST_INIT_ARRAY_FULL:
|
||||||
{
|
{
|
||||||
|
Expr *el;
|
||||||
FOREACH(ConstInitializer *, val, init->init_array_full)
|
FOREACH(ConstInitializer *, val, init->init_array_full)
|
||||||
{
|
{
|
||||||
vec_add(untyped_exprs, val->init_value);
|
switch (val->kind)
|
||||||
|
{
|
||||||
|
case CONST_INIT_VALUE:
|
||||||
|
vec_add(untyped_exprs, val->init_value);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
el = expr_new_expr(EXPR_CONST, single_expr);
|
||||||
|
expr_rewrite_const_initializer(el, val->type, val);
|
||||||
|
vec_add(untyped_exprs, el);
|
||||||
|
break;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -0,0 +1,69 @@
|
|||||||
|
module assert_repro;
|
||||||
|
import assert_repro::macros;
|
||||||
|
|
||||||
|
struct ArrayEntry
|
||||||
|
{
|
||||||
|
int x;
|
||||||
|
}
|
||||||
|
|
||||||
|
macro cause_assert()
|
||||||
|
{
|
||||||
|
ArrayEntry[] $slice = {{1}, {2}, {3}};
|
||||||
|
$slice = macros::replace {ArrayEntry} ($slice, 0, {4});
|
||||||
|
}
|
||||||
|
|
||||||
|
fn int main()
|
||||||
|
{
|
||||||
|
cause_assert();
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
<*
|
||||||
|
This contains macros for working with arrays at compile time
|
||||||
|
*>
|
||||||
|
module assert_repro::macros { ValueT };
|
||||||
|
alias SliceT = ValueT[];
|
||||||
|
|
||||||
|
macro SliceT slice(SliceT $from, usz $start, usz $end = usz.max)
|
||||||
|
{
|
||||||
|
$if $start >= $from.len:
|
||||||
|
return (SliceT){};
|
||||||
|
$else
|
||||||
|
$if $end >= $from.len:
|
||||||
|
return $from[$start..];
|
||||||
|
$else
|
||||||
|
return $from[$start..$end-1];
|
||||||
|
$endif
|
||||||
|
$endif
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
macro SliceT insert(SliceT $array, usz $position, ValueT $value)
|
||||||
|
{
|
||||||
|
$if $position == $array.len:
|
||||||
|
return $array +++ {$value};
|
||||||
|
$else
|
||||||
|
$if $position == 0:
|
||||||
|
return {$value} +++ $array;
|
||||||
|
$else
|
||||||
|
return slice($array, 0, $position) +++ {$value} +++ slice($array, $position);
|
||||||
|
$endif
|
||||||
|
$endif
|
||||||
|
}
|
||||||
|
|
||||||
|
macro SliceT remove(SliceT $array, usz $position)
|
||||||
|
{
|
||||||
|
$if $position == $array.len - 1:
|
||||||
|
return slice($array, 0, $array.len - 1);
|
||||||
|
$else
|
||||||
|
$if $position == 0:
|
||||||
|
return slice($array, 1);
|
||||||
|
$else
|
||||||
|
return slice($array, 0, $position) +++ slice($array, $position + 1);
|
||||||
|
$endif
|
||||||
|
$endif
|
||||||
|
}
|
||||||
|
|
||||||
|
macro SliceT replace(SliceT $array, usz $position, ValueT $value)
|
||||||
|
{
|
||||||
|
return insert(remove($array,$position),$position,$value);
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user