diff --git a/src/check_decl.cpp b/src/check_decl.cpp index 4f224affa..afa819dd9 100644 --- a/src/check_decl.cpp +++ b/src/check_decl.cpp @@ -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: diff --git a/src/check_expr.cpp b/src/check_expr.cpp index 1c44bca09..9524893b3 100644 --- a/src/check_expr.cpp +++ b/src/check_expr.cpp @@ -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)); diff --git a/tests/issues/run.sh b/tests/issues/run.sh index 6eb2e09d3..2787235cb 100755 --- a/tests/issues/run.sh +++ b/tests/issues/run.sh @@ -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" diff --git a/tests/issues/test_issue_6594.odin b/tests/issues/test_issue_6594.odin new file mode 100644 index 000000000..d332c72da --- /dev/null +++ b/tests/issues/test_issue_6594.odin @@ -0,0 +1,9 @@ +// Test issue #6594 https://github.com/odin-lang/Odin/issues/6594 +package test_issues + +a := a + +main :: proc() { + _ = a + 1 +} +