Skip to content

fix segfault on polymorphic arguments when no arguments are expected - #7140

Open
edizeqiri wants to merge 2 commits into
odin-lang:masterfrom
edizeqiri:fix/segfault-on-polymorphic-params
Open

fix segfault on polymorphic arguments when no arguments are expected#7140
edizeqiri wants to merge 2 commits into
odin-lang:masterfrom
edizeqiri:fix/segfault-on-polymorphic-params

Conversation

@edizeqiri

@edizeqiri edizeqiri commented Jul 26, 2026

Copy link
Copy Markdown

Hi, I've been learning Odin and trying to build an ECS with it and stumbled upon a segfault while compiling my code.

Bug

package main

ArchetypeRow :: struct($Components: typeid) {
}

Archetype :: struct {
  components: ArchetypeRow
}

Player :: struct {
}

spawn :: proc(entity: Entity) {
  archetype := Archetype(entity) 
}

ecs :: proc() {
  player := Player {}
  spawn(player)
}

output:

odin check -file bug.odin                                                                                                                                                                                                     [13:47:17]
[1]    31783 segmentation fault  odin check -file bug.odin

This happens with the latest release and main.

    Odin:    dev-2026-07:819fdc7a8
    OS:      macOS Tahoe 26.5.2 (build 25F84, kernel 25.5.0)
    CPU:     Apple M4 Pro
    RAM:     49152 MiB
    Backend: LLVM 22.1.8

Fix

Since I would like to contribute in the future, I tried to find and fix the error in the compiler.

From my understanding, the problem lies in the struct 'Archetype' which should have a generic input like 'ArcheTypeRow' and which the compiler expects, but the naive user (me) forgot it in the struct definition but not in the initialization of it.

This is the following error message the user now gets:

.../bug.odin(14:16) Error: No params are expected!
        archetype := Archetype(entity)
                     ^~~~~~~~~~~~~~~~^

@antisaling

antisaling commented Aug 10, 2026

Copy link
Copy Markdown
Contributor

can you confirm your patch also keeps the intended error message for a type assignment? e.g.

Error: Cannot assign a type 'int' to variable 'x'
        x := int
             ^~^

so your output should look like

.../bug.odin(14:16) Error: No params are expected!
        archetype := Archetype(entity)
                     ^~~~~~~~~~~~~~~~^
.../bug.odin(14:16) Error: Cannot assign a type 'Archetype(entity)' to variable 'archetype'
        archetype := Archetype(entity)
                     ^~~~~~~~~~~~~~~~^

Comment thread src/check_expr.cpp Outdated
@edizeqiri

Copy link
Copy Markdown
Author

can you confirm your patch also keeps the intended error message for a type assignment? e.g.

Error: Cannot assign a type 'int' to variable 'x'
        x := int
             ^~^

so your output should look like

.../bug.odin(14:16) Error: No params are expected!
        archetype := Archetype(entity)
                     ^~~~~~~~~~~~~~~~^
.../bug.odin(14:16) Error: Cannot assign a type 'Archetype(entity)' to variable 'archetype'
        archetype := Archetype(entity)
                     ^~~~~~~~~~~~~~~~^

The current output does not emit that error:

./odin run -file debug/test.odin                                                                                                                                                                                                                                                                                                                                                            
/Users/edi/Documents/GitHub/Odin/debug/test.odin(1:1) Error: Undefined entry point procedure 'main'
	package main
	^

/Users/edi/Documents/GitHub/Odin/debug/test.odin(7:3) Error: Invalid parameter type
	components: ArchetypeRow
	^~~~~~~~~~~~~~~~~~~~~~~^

/Users/edi/Documents/GitHub/Odin/debug/test.odin(7:15) Error: Invalid use of a non-specialized polymorphic type 'ArchetypeRow'
	components: ArchetypeRow
	            ^~~~~~~~~~~^

/Users/edi/Documents/GitHub/Odin/debug/test.odin(13:23) Error: Undeclared name: Entity
	spawn :: proc(entity: Entity) {
	                      ^~~~~^

/Users/edi/Documents/GitHub/Odin/debug/test.odin(14:16) Error: Type 'Archetype' does not expect any polymorphic parameters
	archetype := Archetype(entity)
	             ^~~~~~~~~~~~~~~~^

/Users/edi/Documents/GitHub/Odin/debug/test.odin(19:9) Error: Cannot assign value 'player' of type 'Player' to 'invalid type' in a procedure argument
	spawn(player)
	      ^~~~~^

While debugging I found out that the error you mentioned would be in check_decl.cpp:60. But when debugging it never went past the first if condition.

check_decl.cpp:47-68

	if (operand->mode == Addressing_Type) {
		if (e->type != nullptr && is_type_typeid(e->type) && !is_type_polymorphic(operand->type)) {
			add_type_info_type(ctx, operand->type);
			add_type_and_value(ctx, operand->expr, Addressing_Value, e->type, exact_value_typeid(operand->type));
			return e->type;
		} else {
			ERROR_BLOCK();

			gbString t = type_to_string(operand->type);
			defer (gb_string_free(t));
			if (is_type_polymorphic(operand->type)) {
				error(operand->expr, "Cannot assign a non-specialized polymorphic type '%s' to variable '%.*s'", t, LIT(e->token.string));
			} else {
				error(operand->expr, "Cannot assign a type '%s' to variable '%.*s'", t, LIT(e->token.string));
			}
			if (e->type == nullptr) {
				error_line("\tThe type of the variable '%.*s' cannot be inferred as a type and does not have a default type\n", LIT(e->token.string));
			}
			e->type = operand->type;
			return nullptr;
		}
	}

I do not think that my patch is causing this to not show the error, but I am not certain. What do you think?

@antisaling antisaling left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

So your patch causes check_call_expr_as_type_cast to poison the operand. I'm not completely sure on what's the clear path here to preserve the second error because check_call_expr_as_type_cast would need to be smarter about "recoverable" errors.

LGTM?

@edizeqiri

Copy link
Copy Markdown
Author

After this gets merged, I could open an issue for check_call_expr_as_type_cast and try to come up with a solution to preserve the other error.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants