mirror of
https://github.com/c3lang/c3c.git
synced 2026-02-27 03:51:18 +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
|
||||
- Ignore const null check on deref in `$defined` and `$sizeof` #2633.
|
||||
- Subscripting of constant slices would sometimes be considered non-constant #2635.
|
||||
- Compiler crash when concatenating structs and arrays to an untyped list.
|
||||
|
||||
### Stdlib changes
|
||||
- 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
|
||||
case CONST_INIT_ARRAY_FULL:
|
||||
{
|
||||
Expr *el;
|
||||
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;
|
||||
}
|
||||
|
||||
@@ -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