Browse Source

Correct `or_return` logic for debug printing and expression is not used checking

gingerBill 4 years ago
parent
commit
4c306a6f99
2 changed files with 36 additions and 4 deletions
  1. 15 0
      src/check_expr.cpp
  2. 21 4
      src/check_stmt.cpp

+ 15 - 0
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) {
 		if (x.mode == Addressing_Invalid) {
 			o->mode = Addressing_Value;
 			o->mode = Addressing_Value;
 			o->type = t_invalid;
 			o->type = t_invalid;
+			o->expr = node;
 			return Expr_Expr;
 			return Expr_Expr;
 		}
 		}
 
 
@@ -6645,6 +6646,7 @@ ExprKind check_expr_base_internal(CheckerContext *c, Operand *o, Ast *node, Type
 		if (y.mode == Addressing_Invalid) {
 		if (y.mode == Addressing_Invalid) {
 			o->mode = Addressing_Value;
 			o->mode = Addressing_Value;
 			o->type = t_invalid;
 			o->type = t_invalid;
+			o->expr = node;
 			return Expr_Expr;
 			return Expr_Expr;
 		}
 		}
 
 
@@ -6664,6 +6666,7 @@ ExprKind check_expr_base_internal(CheckerContext *c, Operand *o, Ast *node, Type
 		}
 		}
 		o->mode = Addressing_Value;
 		o->mode = Addressing_Value;
 		o->type = left_type;
 		o->type = left_type;
+		o->expr = node;
 		return Expr_Expr;
 		return Expr_Expr;
 	case_end;
 	case_end;
 
 
@@ -6674,6 +6677,7 @@ ExprKind check_expr_base_internal(CheckerContext *c, Operand *o, Ast *node, Type
 		if (x.mode == Addressing_Invalid) {
 		if (x.mode == Addressing_Invalid) {
 			o->mode = Addressing_Value;
 			o->mode = Addressing_Value;
 			o->type = t_invalid;
 			o->type = t_invalid;
+			o->expr = node;
 			return Expr_Expr;
 			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;
 		o->type = left_type;
 		if (left_type != nullptr) {
 		if (left_type != nullptr) {
 			o->mode = Addressing_Value;
 			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);
 		str = write_expr_to_string(str, te->y, shorthand);
 	case_end;
 	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);
 	case_ast_node(pe, ParenExpr, node);
 		str = gb_string_append_rune(str, '(');
 		str = gb_string_append_rune(str, '(');

+ 21 - 4
src/check_stmt.cpp

@@ -1456,6 +1456,21 @@ bool all_operands_valid(Array<Operand> const &operands) {
 	return true;
 	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) {
 void check_stmt_internal(CheckerContext *ctx, Ast *node, u32 flags) {
 	u32 mod_flags = flags & (~Stmt_FallthroughAllowed);
 	u32 mod_flags = flags & (~Stmt_FallthroughAllowed);
 	switch (node->kind) {
 	switch (node->kind) {
@@ -1480,8 +1495,10 @@ void check_stmt_internal(CheckerContext *ctx, Ast *node, u32 flags) {
 			if (kind == Expr_Stmt) {
 			if (kind == Expr_Stmt) {
 				return;
 				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);
 				Type *t = type_of_expr(ce->proc);
 				if (is_type_proc(t)) {
 				if (is_type_proc(t)) {
 					if (t->Proc.require_results) {
 					if (t->Proc.require_results) {
@@ -1491,8 +1508,8 @@ void check_stmt_internal(CheckerContext *ctx, Ast *node, u32 flags) {
 					}
 					}
 				}
 				}
 				return;
 				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);
 				ast_node(ce, CallExpr, se->call);
 				Type *t = type_of_expr(ce->proc);
 				Type *t = type_of_expr(ce->proc);
 				if (is_type_proc(t)) {
 				if (is_type_proc(t)) {