Skip to content

Commit

Permalink
Bug when a continue is copied in a defer.
Browse files Browse the repository at this point in the history
  • Loading branch information
lerno committed Oct 8, 2024
1 parent 31f4882 commit 9f10996
Show file tree
Hide file tree
Showing 9 changed files with 68 additions and 4 deletions.
4 changes: 2 additions & 2 deletions lib/std/math/math_nolibc/sincos.c3
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ module std::math::nolibc @if(env::NO_LIBC);
* ====================================================
*/

fn void sincosf(float x, float *sin, float *cos) @extern("sincosf") @weak @nostrip
fn void sincosf(float x, float *sin, float *cos) @extern("__sincosf") @weak @nostrip
{

uint ix = bitcast(x, uint);
Expand Down Expand Up @@ -105,7 +105,7 @@ fn void sincosf(float x, float *sin, float *cos) @extern("sincosf") @weak @nostr

}

fn void sincos(double x, double *sin, double *cos) @extern("sincos") @weak @nostrip
fn void sincos(double x, double *sin, double *cos) @extern("__sincos") @weak @nostrip
{
// High word of x.
uint ix = (uint)(bitcast(x, ulong) >> 32);
Expand Down
1 change: 1 addition & 0 deletions releasenotes.md
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@
- Using no module with `-` would reject the program.
- Unintended deref of pointers with methods caused regression with hash function.
- Fix broken sincos function.
- Bug when a continue is copied in a defer.

### Stdlib changes
- Remove unintended print of `char[]` as String
Expand Down
1 change: 1 addition & 0 deletions src/compiler/llvm_codegen_stmt.c
Original file line number Diff line number Diff line change
Expand Up @@ -1071,6 +1071,7 @@ void llvm_emit_break(GenContext *c, Ast *ast)

void llvm_emit_continue(GenContext *c, Ast *ast)
{
assert(ast->contbreak_stmt.is_resolved);
llvm_emit_statement_chain(c, ast->contbreak_stmt.defers);
Ast *jump_target = astptr(ast->contbreak_stmt.ast);
LLVMBasicBlockRef jump;
Expand Down
1 change: 1 addition & 0 deletions src/compiler/sema_stmts.c
Original file line number Diff line number Diff line change
Expand Up @@ -247,6 +247,7 @@ static inline bool sema_analyse_continue_stmt(SemaContext *context, Ast *stateme

// Link the parent and add the defers.
statement->contbreak_stmt.ast = astid(parent);
statement->contbreak_stmt.is_resolved = true;
statement->contbreak_stmt.defers = context_get_defers(context, context->active_scope.defer_last, defer_id, true);
return true;
}
Expand Down
1 change: 1 addition & 0 deletions test/test_suite/statements/defer_break.c3t
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
// #target: macos-x64
module foo;

extern fn void printf(char* message, ...);
Expand Down
1 change: 1 addition & 0 deletions test/test_suite/statements/defer_break_switch.c3t
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
// #target: macos-x64

fn void test1()
{}
Expand Down
59 changes: 59 additions & 0 deletions test/test_suite/statements/defer_continue_bug.c3t
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
// #target: macos-aarch64
module test;

fn int main()
{
int[4] x = { 1, 4, 5, 7 };
defer
{
foreach (i : x)
{
if (i % 2 == 0) continue;
int a = 123;
}
}
return 0;
}

/* #expect: test.ll

entry:
%x = alloca [4 x i32], align 4
%.anon = alloca i64, align 8
%i = alloca i32, align 4
%a = alloca i32, align 4
call void @llvm.memcpy.p0.p0.i32(ptr align 4 %x, ptr align 4 @.__const, i32 16, i1 false)
store i64 0, ptr %.anon, align 8
br label %loop.cond

loop.cond: ; preds = %loop.inc, %entry
%0 = load i64, ptr %.anon, align 8
%gt = icmp ugt i64 4, %0
br i1 %gt, label %loop.body, label %loop.exit

loop.body: ; preds = %loop.cond
%1 = load i64, ptr %.anon, align 8
%ptroffset = getelementptr inbounds [4 x i8], ptr %x, i64 %1
%2 = load i32, ptr %ptroffset, align 4
store i32 %2, ptr %i, align 4
%3 = load i32, ptr %i, align 4
%smod = srem i32 %3, 2
%eq = icmp eq i32 %smod, 0
br i1 %eq, label %if.then, label %if.exit

if.then: ; preds = %loop.body
br label %loop.inc

if.exit: ; preds = %loop.body
store i32 123, ptr %a, align 4
br label %loop.inc

loop.inc: ; preds = %if.exit, %if.then
%4 = load i64, ptr %.anon, align 8
%addnuw = add nuw i64 %4, 1
store i64 %addnuw, ptr %.anon, align 8
br label %loop.cond

loop.exit: ; preds = %loop.cond
ret i32 0
}
2 changes: 1 addition & 1 deletion test/test_suite/statements/defer_in_defer.c3t
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@

// #target: macos-aarch64
fn void test1() {}
fn void test2() {}
fn void test3() {}
Expand Down
2 changes: 1 addition & 1 deletion test/test_suite/statements/defer_next_switch.c3t
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@

// #target: macos-aarch64
fn void test1()
{}

Expand Down

0 comments on commit 9f10996

Please sign in to comment.