From 4c306a6f9958a01302cf09fdff8f7d4ff143c605 Mon Sep 17 00:00:00 2001 From: gingerBill Date: Mon, 16 Aug 2021 11:08:37 +0100 Subject: [PATCH] Correct `or_return` logic for debug printing and expression is not used checking --- src/check_expr.cpp | 15 +++++++++++++++ src/check_stmt.cpp | 25 +++++++++++++++++++++---- 2 files changed, 36 insertions(+), 4 deletions(-) diff --git a/src/check_expr.cpp b/src/check_expr.cpp index c4715f67e..30f44a59f 100644 --- a/src/check_expr.cpp +++ b/src/check_expr.cpp @@ -6637,6 +6637,7 @@ ExprKind check_expr_base_internal(CheckerContext *c, Operand *o, Ast *node, Type if (x.mode == Addressing_Invalid) { o->mode = Addressing_Value; o->type = t_invalid; + o->expr = node; return Expr_Expr; } @@ -6645,6 +6646,7 @@ ExprKind check_expr_base_internal(CheckerContext *c, Operand *o, Ast *node, Type if (y.mode == Addressing_Invalid) { o->mode = Addressing_Value; o->type = t_invalid; + o->expr = node; return Expr_Expr; } @@ -6664,6 +6666,7 @@ ExprKind check_expr_base_internal(CheckerContext *c, Operand *o, Ast *node, Type } o->mode = Addressing_Value; o->type = left_type; + o->expr = node; return Expr_Expr; case_end; @@ -6674,6 +6677,7 @@ ExprKind check_expr_base_internal(CheckerContext *c, Operand *o, Ast *node, Type if (x.mode == Addressing_Invalid) { o->mode = Addressing_Value; o->type = t_invalid; + o->expr = node; return Expr_Expr; } @@ -6724,6 +6728,7 @@ ExprKind check_expr_base_internal(CheckerContext *c, Operand *o, Ast *node, Type } } + o->expr = node; o->type = left_type; if (left_type != nullptr) { o->mode = Addressing_Value; @@ -8701,6 +8706,16 @@ gbString write_expr_to_string(gbString str, Ast *node, bool shorthand) { str = write_expr_to_string(str, te->y, shorthand); case_end; + case_ast_node(oe, OrElseExpr, node); + str = write_expr_to_string(str, oe->x, shorthand); + str = gb_string_appendc(str, " or_else "); + str = write_expr_to_string(str, oe->y, shorthand); + case_end; + + case_ast_node(oe, OrReturnExpr, node); + str = write_expr_to_string(str, oe->expr, shorthand); + str = gb_string_appendc(str, " or_return"); + case_end; case_ast_node(pe, ParenExpr, node); str = gb_string_append_rune(str, '('); diff --git a/src/check_stmt.cpp b/src/check_stmt.cpp index 236b5a9f5..6c5da5197 100644 --- a/src/check_stmt.cpp +++ b/src/check_stmt.cpp @@ -1456,6 +1456,21 @@ bool all_operands_valid(Array const &operands) { return true; } +Ast *strip_or_return_expr(Ast *node) { + for (;;) { + if (node == nullptr) { + return node; + } + if (node->kind == Ast_OrReturnExpr) { + node = node->OrReturnExpr.expr; + } else if (node->kind == Ast_ParenExpr) { + node = node->ParenExpr.expr; + } else { + return node; + } + } +} + void check_stmt_internal(CheckerContext *ctx, Ast *node, u32 flags) { u32 mod_flags = flags & (~Stmt_FallthroughAllowed); switch (node->kind) { @@ -1480,8 +1495,10 @@ void check_stmt_internal(CheckerContext *ctx, Ast *node, u32 flags) { if (kind == Expr_Stmt) { return; } - if (operand.expr->kind == Ast_CallExpr) { - AstCallExpr *ce = &operand.expr->CallExpr; + Ast *expr = strip_or_return_expr(operand.expr); + + if (expr->kind == Ast_CallExpr) { + AstCallExpr *ce = &expr->CallExpr; Type *t = type_of_expr(ce->proc); if (is_type_proc(t)) { if (t->Proc.require_results) { @@ -1491,8 +1508,8 @@ void check_stmt_internal(CheckerContext *ctx, Ast *node, u32 flags) { } } return; - } else if (operand.expr->kind == Ast_SelectorCallExpr) { - AstSelectorCallExpr *se = &operand.expr->SelectorCallExpr; + } else if (expr->kind == Ast_SelectorCallExpr) { + AstSelectorCallExpr *se = &expr->SelectorCallExpr; ast_node(ce, CallExpr, se->call); Type *t = type_of_expr(ce->proc); if (is_type_proc(t)) {