mirror of
https://github.com/odin-lang/Odin.git
synced 2026-05-24 20:59:52 +00:00
gh 6594
prevent compiler crash from self-referential global initialisation
This commit is contained in:
@@ -1771,6 +1771,12 @@ gb_internal void check_global_variable_decl(CheckerContext *ctx, Entity *e, Ast
|
||||
|
||||
Operand o = {};
|
||||
check_expr_with_type_hint(ctx, &o, init_expr, e->type);
|
||||
if (check_vet_shadowing_assignment(ctx->checker, e, init_expr)) {
|
||||
error(e->token, "Illegal declaration cycle of `%.*s`", LIT(e->token.string));
|
||||
o.mode = Addressing_Invalid;
|
||||
o.type = t_invalid;
|
||||
e->type = t_invalid;
|
||||
}
|
||||
check_init_variable(ctx, e, &o, str_lit("variable declaration"));
|
||||
if (e->Variable.is_rodata && o.mode != Addressing_Constant) {
|
||||
ERROR_BLOCK();
|
||||
@@ -1980,6 +1986,20 @@ gb_internal void check_entity_decl(CheckerContext *ctx, Entity *e, DeclInfo *d,
|
||||
|
||||
e->parent_proc_decl = c.curr_proc_decl;
|
||||
e->state = EntityState_InProgress;
|
||||
bool track_cycle_path = false;
|
||||
switch (e->kind) {
|
||||
case Entity_Variable:
|
||||
case Entity_Constant:
|
||||
case Entity_TypeName:
|
||||
track_cycle_path = true;
|
||||
break;
|
||||
}
|
||||
if (track_cycle_path) {
|
||||
check_type_path_push(&c, e);
|
||||
}
|
||||
defer (if (track_cycle_path) {
|
||||
check_type_path_pop(&c);
|
||||
});
|
||||
|
||||
switch (e->kind) {
|
||||
case Entity_Variable:
|
||||
|
||||
@@ -1919,6 +1919,16 @@ gb_internal Entity *check_ident(CheckerContext *c, Operand *o, Ast *n, Type *nam
|
||||
if (e->state == EntityState_Unresolved) {
|
||||
check_entity_decl(c, e, nullptr, named_type);
|
||||
}
|
||||
switch (e->kind) {
|
||||
case Entity_Constant:
|
||||
case Entity_Variable:
|
||||
case Entity_TypeName:
|
||||
if (check_cycle(c, e, true)) {
|
||||
o->type = t_invalid;
|
||||
return e;
|
||||
}
|
||||
break;
|
||||
}
|
||||
if (e->type == nullptr) {
|
||||
// TODO(bill): Which is correct? return or compiler_error?
|
||||
// compiler_error("How did this happen? type: %s; identifier: %.*s\n", type_to_string(e->type), LIT(name));
|
||||
|
||||
@@ -53,6 +53,12 @@ else
|
||||
echo "SUCCESSFUL 0/1"
|
||||
exit 1
|
||||
fi
|
||||
if [[ $($ODIN build ../test_issue_6594.odin $COMMON 2>&1 >/dev/null | grep -c "Error:") -eq 1 ]] ; then
|
||||
echo "SUCCESSFUL 1/1"
|
||||
else
|
||||
echo "SUCCESSFUL 0/1"
|
||||
exit 1
|
||||
fi
|
||||
$ODIN test ../test_pr_6470.odin $COMMON
|
||||
if [[ $($ODIN test ../test_pr_6470.odin -define:TEST_EXPECT_FAILURE=true $COMMON 2>&1 >/dev/null | grep -c "Error:") -eq 1 ]] ; then
|
||||
echo "SUCCESSFUL 1/1"
|
||||
|
||||
9
tests/issues/test_issue_6594.odin
Normal file
9
tests/issues/test_issue_6594.odin
Normal file
@@ -0,0 +1,9 @@
|
||||
// Test issue #6594 https://github.com/odin-lang/Odin/issues/6594
|
||||
package test_issues
|
||||
|
||||
a := a
|
||||
|
||||
main :: proc() {
|
||||
_ = a + 1
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user