Browse Source

Check for `#assert` condition to be a constant bool

Fixes #4170
Jeroen van Rijn 11 months ago
parent
commit
a4ac50a5b4
1 changed files with 11 additions and 1 deletions
  1. 11 1
      src/check_builtin.cpp

+ 11 - 1
src/check_builtin.cpp

@@ -1792,7 +1792,17 @@ gb_internal bool check_builtin_procedure_directive(CheckerContext *c, Operand *o
 			error(call, "'#assert' expects either 1 or 2 arguments, got %td", ce->args.count);
 			error(call, "'#assert' expects either 1 or 2 arguments, got %td", ce->args.count);
 			return false;
 			return false;
 		}
 		}
-		if (!is_type_boolean(operand->type) || operand->mode != Addressing_Constant) {
+
+		// operand->type can be nil if the condition is a procedure, for example: #assert(assert())
+		// So let's check it before we use it, so we get the same error as if we wrote `#exists(assert())
+		Ast *arg = ce->args[0];
+		Entity *e = nullptr;
+		Operand o = {};
+		if (arg->kind == Ast_Ident) {
+			e = check_ident(c, &o, arg, nullptr, nullptr, true);
+		}
+
+		if (operand->type == nullptr || !is_type_boolean(operand->type) || operand->mode != Addressing_Constant) {
 			gbString str = expr_to_string(ce->args[0]);
 			gbString str = expr_to_string(ce->args[0]);
 			error(call, "'%s' is not a constant boolean", str);
 			error(call, "'%s' is not a constant boolean", str);
 			gb_string_free(str);
 			gb_string_free(str);