Assigning a Variant with value freed object to non-Variant causes error

Open
#1,365 0 comments 0 reactions 0 assignees View on GitHub

Maintainers usually reply within 1 day

Nobody has claimed this yet.

Assessment

Difficulty
4/5
Estimated time
3-5 days
Newbie friendliness
35/100
Issue type
Bug
Clarity
Mostly clear
Activity status
Quiet
Tech stack
cpp
Domain
backend

Research direction

The report provides GDScript reproductions but names no source files or tests. Start by reading the related Redot pull request #1311 and tracing how Variant-to-object assignment handles previously freed instances; the issue also links Godot issue #85947 and PR #87296 for context. Done means the reported assignment cases handle freed objects consistently without the described error.

Written by the indexing model from the issue text.

Description

bug topic:gdscript
Tested versions

26.3.alpha 1

System information

Redot v26.3.alpha.1 (957fda4c3) - CachyOS Linux

Issue description

I saw https://github.com/Redot-Engine/redot-engine/pull/1311 addressed the freed object issue with containers that has been reported in https://github.com/Redot-Engine/redot-engine/issues/1310 and https://github.com/godotengine/godot/issues/110511. So I was wondering if we plan to address a similar issue in https://github.com/godotengine/godot/issues/85947 when assigning a Variant with value freed object to non-Variant. There is a PR https://github.com/godotengine/godot/pull/87296 to address it but it is not merged.

I am not familiar with the Godot or Redot codebase (nor I have written a line of CPP before) but I saw this proposal completed a few days ago: https://github.com/godotengine/godot-proposals/issues/12323#issuecomment-5451503253

var node2d: Node2D = Node2D.new()
node2d.free()

var node: Node = node2d # OK

var variant: Variant = node2d # OK
node = variant # Trying to assign invalid previously freed instance.
var node := Node.new()
var dict := { "node": node }
node.free()

node = dict["node"] # Trying to assign invalid previously freed instance.

The following cases are not the same but they have a similar issue.

var node := Node.new()
node.free()

typed(node)  # Invalid type in function 'typed' in base 'Node2D (main.gd)'. The Object-derived class of argument 1 (previously freed) is not a subclass of the expected argument class.

func typed(node: Node) -> void:
	pass
var obj := Object.new()
print(obj is Object)
obj.free()
print(obj is Object) # Left operand of 'is' is a previously freed instance.

This case doesn't halt execution but it does emit an error.

var node := Node.new()
var lambda = func(): print(node)
node.free()
lambda.call() # Prints `<null>` but has error "Lambda capture at index 0 was freed. Passed "null" instead."

I think this one is just similar to typed function case.

var node := Node.new()
var lambda = func(node: Node): print(node)
node.free()
lambda.call(node) # Invalid type in function '<anonymous lambda>(lambda) (Callable)'. The Object-derived class of argument 1 (previously freed) is not a subclass of the expected argument class.
lambda.bind(node).call() # Invalid type in function '<anonymous lambda>(lambda) (Callable)'. The Object-derived class of argument 1 (previously freed) is not a subclass of the expected argument class.
Steps to reproduce

Same as provided codeblock

Minimal reproduction project (MRP)

Same as provided codeblock

Dominant language
C++
Stars
6.1k
Forks
337
Avg merge
4d 5h
Merged PRs (30d)
52

Getting set up

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

More from Redot-Engine/redot-engine

All issues in Redot-Engine/redot-engine

Similar issues

More C++ issues

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.