aboutsummaryrefslogtreecommitdiff
path: root/src/checker.cpp
diff options
context:
space:
mode:
authorgingerBill <bill@gingerbill.org>2022-05-11 12:15:37 +0100
committergingerBill <bill@gingerbill.org>2022-05-11 12:15:37 +0100
commitb4df272eb5ca8b43a47ad0f70dff19dc98563642 (patch)
treeae5141754762f1cdf3658d289bd33dfb07c03104 /src/checker.cpp
parentdca2fbccffd22b47cdb89e56170f3dae9a6257ad (diff)
Improve -vet shadowing to allow `x := x if cond else y` etc
Diffstat (limited to 'src/checker.cpp')
-rw-r--r--src/checker.cpp37
1 files changed, 28 insertions, 9 deletions
diff --git a/src/checker.cpp b/src/checker.cpp
index fdd75126f..d186163e4 100644
--- a/src/checker.cpp
+++ b/src/checker.cpp
@@ -544,6 +544,28 @@ GB_COMPARE_PROC(vetted_entity_variable_pos_cmp) {
return token_pos_cmp(x->token.pos, y->token.pos);
}
+bool check_vet_shadowing_assignment(Checker *c, Entity *shadowed, Ast *expr) {
+ Ast *init = unparen_expr(expr);
+ if (init == nullptr) {
+ return false;
+ }
+ if (init->kind == Ast_Ident) {
+ // TODO(bill): Which logic is better? Same name or same entity
+ // bool ignore = init->Ident.token.string == name;
+ bool ignore = init->Ident.entity == shadowed;
+ if (ignore) {
+ return true;
+ }
+ } else if (init->kind == Ast_TernaryIfExpr) {
+ bool x = check_vet_shadowing_assignment(c, shadowed, init->TernaryIfExpr.x);
+ bool y = check_vet_shadowing_assignment(c, shadowed, init->TernaryIfExpr.y);
+ if (x || y) {
+ return true;
+ }
+ }
+
+ return false;
+}
bool check_vet_shadowing(Checker *c, Entity *e, VettedEntity *ve) {
@@ -594,17 +616,14 @@ bool check_vet_shadowing(Checker *c, Entity *e, VettedEntity *ve) {
}
// NOTE(bill): Ignore intentional redeclaration
- // x := x;
+ // x := x
// Suggested in issue #637 (2020-05-11)
+ // Also allow the following
+ // x := x if cond else y
+ // x := z if cond else x
if ((e->flags & EntityFlag_Using) == 0 && e->kind == Entity_Variable) {
- Ast *init = unparen_expr(e->Variable.init_expr);
- if (init != nullptr && init->kind == Ast_Ident) {
- // TODO(bill): Which logic is better? Same name or same entity
- // bool ignore = init->Ident.token.string == name;
- bool ignore = init->Ident.entity == shadowed;
- if (ignore) {
- return false;
- }
+ if (check_vet_shadowing_assignment(c, shadowed, e->Variable.init_expr)) {
+ return false;
}
}