I have a system where for example scene nodes' properties can be accessed generically through a Variant value type, which can return an unsafe reference to the actual data it's holding (for example a String, 3D vector, or another Variant)
After migrating from AngelScript 2.21.1 to 2.22.0 I'm seeing a crash with the following code: (note that the actual C++ implementation of the Variant class is "safe" in such manner that if you query a Variant for a String when it's actually holding something else, you get a reference to a pre-created dummy string)
Node@ node = Node("Test"); // Create a dummy scene node
String str = node.attributes[0].GetString(); // Get its first attribute as a string
The execution of the code will later crash in the String destructor. I'm not able to see which string object it's actually trying to destroy.
The workaround is to actually create a local variable for the Variant object, and then it doesn't crash:
Node@ node = Node("Test"); // Create a dummy scene node
Variant value = node.attributes[0]; // Get its first attribute
String str = value.GetString(); // Get the string value from the variant
Also, another workaround which makes the crash go away is to actually make Variant return a copy of the String in GetString(), instead of a reference. But for speed optimization and to not need wrapper code I'd rather keep the unsafe reference.
The relevant class registration code is:
engine->RegisterObjectType("String", sizeof(String), asOBJ_VALUE | asOBJ_APP_CLASS_CDA);
engine->RegisterStringFactory("String", asFUNCTION(StringFactory), asCALL_CDECL);
engine->RegisterObjectBehaviour("String", asBEHAVE_CONSTRUCT, "void f()", asFUNCTION(ConstructString), asCALL_CDECL_OBJLAST);
engine->RegisterObjectBehaviour("String", asBEHAVE_CONSTRUCT, "void f(const String&in)", asFUNCTION(ConstructStringCopy), asCALL_CDECL_OBJLAST);
engine->RegisterObjectBehaviour("String", asBEHAVE_DESTRUCT, "void f()", asFUNCTION(DestructString), asCALL_CDECL_OBJLAST);
engine->RegisterObjectType("Variant", sizeof(Variant), asOBJ_VALUE | asOBJ_APP_CLASS_CDA);
engine->RegisterObjectBehaviour("Variant", asBEHAVE_CONSTRUCT, "void f()", asFUNCTION(ConstructVariant), asCALL_CDECL_OBJLAST);
engine->RegisterObjectBehaviour("Variant", asBEHAVE_CONSTRUCT, "void f(const Variant&in)", asFUNCTION(ConstructVariantCopy), asCALL_CDECL_OBJLAST);
engine->RegisterObjectBehaviour("Variant", asBEHAVE_DESTRUCT, "void f()", asFUNCTION(DestructVariant), asCALL_CDECL_OBJLAST);
engine->RegisterObjectMethod("Variant", "const String& GetString() const", asMETHOD(Variant, GetString), asCALL_THISCALL);
engine->RegisterObjectType("Node", 0, asOBJ_REF);
engine->RegisterObjectMethod("Node", "Variant get_attributes(uint) const", asMETHODPR(Node, GetAttribute, (unsigned), Variant), asCALL_THISCALL);