I discovered this bug while calling GetMethodByDecl on a Template Object.
This seems to be the problem loop (as_builder.cpp: line 4371, asCBuilder::CreateDataTypeFromNode:
// If this is for a template type, then we must first determine if the
// identifier matches any of the template subtypes
if( currentType && (currentType->flags & asOBJ_TEMPLATE))
{
for( asUINT subtypeIndex = 0; subtypeIndex < currentType->templateSubTypes.GetLength(); subtypeIndex++)
{
if(str == currentType->templateSubTypes[subtypeIndex].GetObjectType()->name )
{
ot = currentType->templateSubTypes[subtypeIndex].GetObjectType();
break;
}
}
}
In that loop, currentType->templateSubTypes[0] looks like the following:
tokenType ttDouble (0x0000005a)
objectType 0x0000000000000000
funcDef 0x0000000000000000
isReference false
isReadOnly false
isObjectHandle false
isConstHandle false
dummy 0xfc 'ü'
So, obviously, the call to ->name on a NULL objectType results in an access violation.
This is the relevant part of my callstack:
- asCString::GetLength() Line 226
- asCString::Compare(const asCString & str) Line 296
- !operator==(const asCString & a, const asCString & b) Line 350
- AngelScript::asCBuilder::CreateDataTypeFromNode(AngelScript::asCScriptNode * node, AngelScript::asCScriptCode * file, AngelScript::asSNameSpace * implicitNamespace, bool acceptHandleForScope, AngelScript::asCObjectType * currentType) Line 4377
- AngelScript::asCBuilder::ParseFunctionDeclaration(AngelScript::asCObjectType * objType, const char * decl, AngelScript::asCScriptFunction * func, bool isSystemFunction, AngelScript::asCArray<bool> * paramAutoHandles, bool * returnAutoHandle, AngelScript::asSNameSpace * ns) Line 963
- AngelScript::asCScriptEngine::GetMethodIdByDecl(const AngelScript::asCObjectType * ot, const char * decl, AngelScript::asCModule * mod) Line 1221
- AngelScript::asCObjectType::GetMethodByDecl(const char * decl, bool getVirtual) Line 512
Changing the loop to the following seems to correct the problem in my situation, but I don't know if it would have other ramifications.
// If this is for a template type, then we must first determine if the
// identifier matches any of the template subtypes
if( currentType && (currentType->flags & asOBJ_TEMPLATE))
{
for( asUINT subtypeIndex = 0; subtypeIndex < currentType->templateSubTypes.GetLength(); subtypeIndex++)
{
ot = currentType->templateSubTypes[subtypeIndex].GetObjectType();
if( ot != nullptr && str == currentType->templateSubTypes[subtypeIndex].GetObjectType()->name )
break;
else
ot = nullptr;
}
}