Fix some more cases of malformed syntax crashing the compiler.
Fixes https://gitlab.com/kicad/code/kicad/issues/6016
This commit is contained in:
parent
445b9df827
commit
ebd5dc81cc
|
@ -892,7 +892,7 @@ bool COMPILER::generateUCode( UCODE* aCode, CONTEXT* aPreflightContext )
|
||||||
{
|
{
|
||||||
// Preflight the function call
|
// Preflight the function call
|
||||||
|
|
||||||
for( auto pnode : params )
|
for( TREE_NODE* pnode : params )
|
||||||
{
|
{
|
||||||
VALUE* param = aPreflightContext->AllocValue();
|
VALUE* param = aPreflightContext->AllocValue();
|
||||||
param->Set( *pnode->value.str );
|
param->Set( *pnode->value.str );
|
||||||
|
@ -918,7 +918,7 @@ bool COMPILER::generateUCode( UCODE* aCode, CONTEXT* aPreflightContext )
|
||||||
|
|
||||||
node->leaf[0]->isVisited = true;
|
node->leaf[0]->isVisited = true;
|
||||||
node->leaf[1]->isVisited = true;
|
node->leaf[1]->isVisited = true;
|
||||||
node->leaf[1]->leaf[0]->isVisited = true;;
|
node->leaf[1]->leaf[0]->isVisited = true;
|
||||||
node->leaf[1]->leaf[1]->isVisited = true;
|
node->leaf[1]->leaf[1]->isVisited = true;
|
||||||
|
|
||||||
// Our non-terminal-node stacking algorithm can't handle doubly-nested
|
// Our non-terminal-node stacking algorithm can't handle doubly-nested
|
||||||
|
@ -926,16 +926,38 @@ bool COMPILER::generateUCode( UCODE* aCode, CONTEXT* aPreflightContext )
|
||||||
// a TR_OP_FUNC_CALL and its function parameter
|
// a TR_OP_FUNC_CALL and its function parameter
|
||||||
stack.pop_back();
|
stack.pop_back();
|
||||||
stack.push_back( node->leaf[1] );
|
stack.push_back( node->leaf[1] );
|
||||||
//stack.push_back( node->leaf[1]->leaf[1] );
|
|
||||||
for( auto pnode : params )
|
for( TREE_NODE* pnode : params )
|
||||||
{
|
|
||||||
stack.push_back( pnode );
|
stack.push_back( pnode );
|
||||||
}
|
|
||||||
|
|
||||||
node->leaf[1]->SetUop( TR_OP_METHOD_CALL, func, std::move( vref ) );
|
node->leaf[1]->SetUop( TR_OP_METHOD_CALL, func, std::move( vref ) );
|
||||||
node->isTerminal = false;
|
node->isTerminal = false;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
default:
|
||||||
|
// leaf[0]: object
|
||||||
|
// leaf[1]: malformed syntax
|
||||||
|
|
||||||
|
wxString itemName = *node->leaf[0]->value.str;
|
||||||
|
wxString propName = *node->leaf[1]->value.str;
|
||||||
|
std::unique_ptr<VAR_REF> vref = aCode->CreateVarRef( itemName, propName );
|
||||||
|
|
||||||
|
if( !vref )
|
||||||
|
{
|
||||||
|
msg.Printf( _( "Unrecognized item '%s'" ), itemName );
|
||||||
|
reportError( CST_CODEGEN, msg, node->leaf[0]->srcPos - (int) itemName.length() );
|
||||||
|
}
|
||||||
|
|
||||||
|
msg.Printf( _( "Unrecognized property '%s'" ), propName );
|
||||||
|
reportError( CST_CODEGEN, msg, node->leaf[0]->srcPos + 1 );
|
||||||
|
|
||||||
|
node->leaf[0]->isVisited = true;
|
||||||
|
node->leaf[1]->isVisited = true;
|
||||||
|
|
||||||
|
node->SetUop( TR_UOP_PUSH_VALUE, 0.0 );
|
||||||
|
node->isTerminal = true;
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
@ -1001,13 +1023,13 @@ bool COMPILER::generateUCode( UCODE* aCode, CONTEXT* aPreflightContext )
|
||||||
if( node->leaf[0] && !node->leaf[0]->isVisited )
|
if( node->leaf[0] && !node->leaf[0]->isVisited )
|
||||||
{
|
{
|
||||||
stack.push_back( node->leaf[0] );
|
stack.push_back( node->leaf[0] );
|
||||||
node->leaf[0]->isVisited = true;;
|
node->leaf[0]->isVisited = true;
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
else if( node->leaf[1] && !node->leaf[1]->isVisited )
|
else if( node->leaf[1] && !node->leaf[1]->isVisited )
|
||||||
{
|
{
|
||||||
stack.push_back( node->leaf[1] );
|
stack.push_back( node->leaf[1] );
|
||||||
node->leaf[1]->isVisited = true;;
|
node->leaf[1]->isVisited = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
continue;
|
continue;
|
||||||
|
@ -1149,15 +1171,21 @@ VALUE* UCODE::Run( CONTEXT* ctx )
|
||||||
return &g_false;
|
return &g_false;
|
||||||
}
|
}
|
||||||
|
|
||||||
assert( ctx->SP() == 1 );
|
if( ctx->SP() == 1 )
|
||||||
|
{
|
||||||
|
return ctx->Pop();
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// If stack is corrupted after execution it suggests a problem with the compiler, not
|
||||||
|
// the rule....
|
||||||
|
|
||||||
// non-well-formed rules should not be fired
|
// do not use "assert"; it crashes outright on OSX
|
||||||
// fixme: not sure it's a good idea, if stack is corrupted after execution it means
|
wxASSERT( ctx->SP() == 1 );
|
||||||
// a problem with the compiler, not the rule...
|
|
||||||
if( ctx->SP() != 1 )
|
// non-well-formed rules should not be fired on a release build
|
||||||
return &g_false;
|
return &g_false;
|
||||||
|
}
|
||||||
return ctx->Pop();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -438,7 +438,7 @@ void DRC_RULES_PARSER::parseValueWithUnits( const wxString& aExpr, int& aResult
|
||||||
{
|
{
|
||||||
wxString msg = wxString::Format( _( "ERROR: <a href='%d:%d'>%s</a>%s" ),
|
wxString msg = wxString::Format( _( "ERROR: <a href='%d:%d'>%s</a>%s" ),
|
||||||
CurLineNumber(),
|
CurLineNumber(),
|
||||||
CurOffset(),
|
CurOffset() + aOffset,
|
||||||
first,
|
first,
|
||||||
rest );
|
rest );
|
||||||
|
|
||||||
|
@ -450,7 +450,8 @@ void DRC_RULES_PARSER::parseValueWithUnits( const wxString& aExpr, int& aResult
|
||||||
first,
|
first,
|
||||||
rest );
|
rest );
|
||||||
|
|
||||||
THROW_PARSE_ERROR( msg, CurSource(), CurLine(), CurLineNumber(), CurOffset() );
|
THROW_PARSE_ERROR( msg, CurSource(), CurLine(), CurLineNumber(),
|
||||||
|
CurOffset() + aOffset );
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -578,7 +578,8 @@ bool PCB_EXPR_EVALUATOR::Evaluate( const wxString& aExpr )
|
||||||
PCB_EXPR_UCODE ucode;
|
PCB_EXPR_UCODE ucode;
|
||||||
PCB_EXPR_CONTEXT preflightContext( F_Cu );
|
PCB_EXPR_CONTEXT preflightContext( F_Cu );
|
||||||
|
|
||||||
m_compiler.Compile( aExpr.ToUTF8().data(), &ucode, &preflightContext );
|
if( !m_compiler.Compile( aExpr.ToUTF8().data(), &ucode, &preflightContext ) )
|
||||||
|
return false;
|
||||||
|
|
||||||
PCB_EXPR_CONTEXT evaluationContext( F_Cu );
|
PCB_EXPR_CONTEXT evaluationContext( F_Cu );
|
||||||
LIBEVAL::VALUE* result = ucode.Run( &evaluationContext );
|
LIBEVAL::VALUE* result = ucode.Run( &evaluationContext );
|
||||||
|
|
Loading…
Reference in New Issue