- Assert on optional-returning-function in a comma expression. #2722

This commit is contained in:
Christoffer Lerno
2026-01-07 15:53:54 +01:00
parent 197f82d829
commit 0fc1871ddf
7 changed files with 26 additions and 4 deletions

View File

@@ -52,6 +52,7 @@
- `io::read_fully` now handles unbounded streams properly. - `io::read_fully` now handles unbounded streams properly.
- Crash when doing a type property lookup for const inline enums in some cases #2717. - Crash when doing a type property lookup for const inline enums in some cases #2717.
- Incorrect alignment on typedef and local variable debug info. - Incorrect alignment on typedef and local variable debug info.
- Assert on optional-returning-function in a comma expression. #2722
### Stdlib changes ### Stdlib changes
- Add `ThreadPool` join function to wait for all threads to finish in the pool without destroying the threads. - Add `ThreadPool` join function to wait for all threads to finish in the pool without destroying the threads.

View File

@@ -197,8 +197,7 @@ static void llvm_emit_cond(GenContext *c, BEValue *be_value, Expr *expr, bool bo
ByteSize last_index = size - 1; ByteSize last_index = size - 1;
for (ByteSize i = 0; i < last_index; i++) for (ByteSize i = 0; i < last_index; i++)
{ {
BEValue value; llvm_emit_ignored_expr(c, expr->cond_expr[i]);
llvm_emit_expr(c, &value, expr->cond_expr[i]);
} }
// Emit the last element. // Emit the last element.

View File

@@ -129,6 +129,10 @@ void llvm_value_rvalue(GenContext *c, BEValue *value)
void llvm_emit_jump_to_optional_exit(GenContext *c, LLVMValueRef opt_value) void llvm_emit_jump_to_optional_exit(GenContext *c, LLVMValueRef opt_value)
{ {
if (!c->catch.block)
{
puts("foekf");
}
ASSERT_AT(c->last_emitted_loc, c->catch.block && "unexpected emit"); ASSERT_AT(c->last_emitted_loc, c->catch.block && "unexpected emit");
bool is_constant_opt = llvm_is_const(opt_value); bool is_constant_opt = llvm_is_const(opt_value);

View File

@@ -1121,7 +1121,9 @@ static inline bool sema_analyse_cond_list(SemaContext *context, Expr *expr, Cond
// 2. Walk through each of our declarations / expressions as if they were regular expressions. // 2. Walk through each of our declarations / expressions as if they were regular expressions.
for (unsigned i = 0; i < entries - 1; i++) for (unsigned i = 0; i < entries - 1; i++)
{ {
if (!sema_analyse_expr_rvalue(context, dexprs[i])) return false; Expr *dexpr = dexprs[i];
if (!sema_analyse_expr_rvalue(context, dexpr)) return false;
if (!sema_expr_check_discard(context, dexpr)) return false;
} }
if (!sema_analyse_last_cond(context, dexprs[entries - 1], cond_type, result)) return false; if (!sema_analyse_last_cond(context, dexprs[entries - 1], cond_type, result)) return false;

View File

@@ -0,0 +1,8 @@
module main;
fn int? may_fault() @maydiscard => 2;
fn void main()
{
if (may_fault(), true);
}

View File

@@ -0,0 +1,8 @@
module main;
fn int? may_fault() => 2;
fn void main()
{
if (may_fault(), true); // #error: You can either assign it to a variable
}

View File

@@ -59,7 +59,7 @@ fn void test8()
{ {
int? a; int? a;
int e; int e;
if (e == 0, try c = a && try d = a && e > 0) {} if (e = 3, try c = a && try d = a && e > 0) {}
if (try b = a && try c = a && e > 0) {} if (try b = a && try c = a && e > 0) {}
if (try c = a && try d = a) { c++; } if (try c = a && try d = a) { c++; }
} }