c3c icon indicating copy to clipboard operation
c3c copied to clipboard

compiler assert on `@naked` function with inline assembly and pointer

Open Book-reader opened this issue 10 months ago • 5 comments

fn void main()
{
	char[8] foo = {255, 0, 0, 0, 0, 0, 0, 0};
	io::printn(to_ulong(&foo));
}

fn ulong to_ulong(char[8]* buf) @naked @noinline
{
	asm
	{
		movq $rax, [buf];
		ret;
	}
	unreachable();
}
⚠️ The compiler encountered an unexpected error: "Violated assert: decl->var.kind == VARDECL_GLOBAL || decl->var.kind == VARDECL_CONST".

- Function: llvm_get_ref(...)
- Source file: ../src/compiler/llvm_codegen.c:1283

🙏 Please consider taking the time to file an issue on GitHub, so that we can get it fixed:

https://github.com/c3lang/c3c/issues/new so that we can get it fixed.

Book-reader avatar Feb 11 '25 05:02 Book-reader

Only asm("....") was intended to be available for these sections. If we should make more available or not is an open question, so I'm going to put this a little on hold.

lerno avatar Feb 12 '25 21:02 lerno

Only asm("....") was intended to be available for these sections

as in asm{} blocks weren't intended to be allowed in @naked functions?

Book-reader avatar Feb 12 '25 21:02 Book-reader

oh, do you mean that @naked functions were intended to only be used with asm blocks and not regular code (even the unreachable() would be disallowed)?

Book-reader avatar Feb 12 '25 22:02 Book-reader

Yes

lerno avatar Feb 12 '25 22:02 lerno

Even more, only asm("...") with strings would be allowed.

lerno avatar Feb 12 '25 22:02 lerno

I've extended what's allowed in naked functions. Only return is disallowed now.

lerno avatar Jul 29 '25 18:07 lerno

Please try it out.

lerno avatar Jul 29 '25 19:07 lerno

running the example I gave at -O1 and above now causes a compiler segfault

Book-reader avatar Jul 29 '25 21:07 Book-reader

Ok, it turns out that LLVM cannot properly support accessing those parameters, so I've completely disallowed it.

lerno avatar Jul 29 '25 23:07 lerno

You can try this:

module test;
import std;

fn void main()
{
	char[8] foo = {255, 0, 0, 0, 0, 0, 0, 0};
	io::printn(to_ulong(&foo));
}

fn ulong to_ulong(char[8]*) @naked @noinline
{
	asm
	{
		movq [$rsp - 8], $rdi;
    	movq $rax, [$rsp - 8];
    	movq $rax, [$rax];
		ret;
	}
	unreachable();
}

lerno avatar Jul 29 '25 23:07 lerno

it doesn't allow the unreachable() due to it using parameters under -O2, but other than that I can't get it to crash anymore, so I'll close this and #1959. Thank you!

Book-reader avatar Jul 30 '25 06:07 Book-reader