Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Accessing a #soa pointer in a struct field under using doesn't work correctly, and leads to compiler panic #3582

Closed
wrapperup opened this issue May 13, 2024 · 1 comment

Comments

@wrapperup
Copy link
Contributor

Context

Odin:    dev-2024-05:3994dcb7b
OS:      Windows 10 Professional (version: 22H2), build 19045.4291
CPU:     Intel(R) Core(TM) i7-8700K CPU @ 3.70GHz
RAM:     32641 MiB
Backend: LLVM 17.0.1

Expected Behavior

Accessing/Writing to a #soa pointer that is included with using should work the same way as accessing it from a non using field.

Current Behavior

Writing to a #soa pointer behind using writes to the wrong memory offset. The compiler also panics if the types don't match (even if it's a valid expression).

Failure Information (for bugs)

A minimal reproduction of the issue.

package main

import "core:fmt"

Entity :: struct {
	translation: [3]f32,
	velocity:    [3]f32, // Successfully compiles
	// velocity:    [1]f32, // This will cause the compiler to panic
}

entities: #soa[dynamic]Entity

Player :: struct {
	using entity: #soa^#soa[dynamic]Entity,
	foo:          i32,
}

new_entity :: proc($T: typeid) -> T {
	entity := T{}
	append_soa(&entities, Entity{})
	entity.entity = &entities[len(entities) - 1]

	return entity
}

main :: proc() {
	player := new_entity(Player)

	player.velocity = 2 // This doesn't work, it writes to the wrong offset (writes over translation)
	// player.entity.velocity = 2 // This works

	for _ in 0 ..= 10 {
		fmt.println("Player translation:", player.translation)

		for &entity in entities {
			entity.translation += entity.velocity.x
		}
	}
}

The disassembly for player.velocity = 2 and player.entity.velocity = 2, while expected to be the same, shows that the using version doesn't write to the correct offset.

image

Additionally, changing the type of velocity will cause the compiler to panic.

main.main
lb_emit_conv: src -> dst
Not Identical [1]f32 != f32
Not Identical [1]f32 != f32
Not Identical 1b539496320 != 7ff756600178
Not Identical 1b539496320 != 7ff756600178
C:\Repos\odin\Odin\src\llvm_backend_expr.cpp(2324): Panic: Invalid type conversion: '[1]f32' to 'f32' for procedure 'main.main'

Steps to Reproduce

  1. Build and run the reproduction code to get the incorrect behavior
  2. Switch the type of velocity to a different type (in this example, [1]f32) to get the compiler panic
@gingerBill
Copy link
Member

I am just going to disallow this.

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

No branches or pull requests

2 participants