Skip to content
Permalink
Browse files

Fix #384 leak of const alias (valgrind)

  • Loading branch information
klirichek committed Aug 14, 2018
1 parent 02dbdd6 commit c74d0b4035e4214510376845b22cb676a8da24a3
Showing with 27 additions and 34 deletions.
  1. +27 −34 src/sphinxexpr.cpp
@@ -4646,29 +4646,25 @@ ISphExpr * ExprParser_t::CreateTree ( int iNode )
}
}

ISphExpr * pLeft = bSkipLeft ? nullptr : CreateTree ( tNode.m_iLeft );
ISphExpr * pRight = bSkipRight ? nullptr : CreateTree ( tNode.m_iRight );
CSphRefcountedPtr<ISphExpr> pLeft ( bSkipLeft ? nullptr : CreateTree ( tNode.m_iLeft ) );
CSphRefcountedPtr<ISphExpr> pRight ( bSkipRight ? nullptr : CreateTree ( tNode.m_iRight ) );

if ( GetError() )
{
SafeRelease ( pLeft );
SafeRelease ( pRight );
return nullptr;
}

#define LOC_SPAWN_POLY(_classname) \
if ( tNode.m_eArgType==SPH_ATTR_INTEGER ) return new _classname##Int_c ( pLeft, pRight ); \
else if ( tNode.m_eArgType==SPH_ATTR_BIGINT ) return new _classname##Int64_c ( pLeft, pRight ); \
else return new _classname##Float_c ( pLeft, pRight );
if ( tNode.m_eArgType==SPH_ATTR_INTEGER ) return new _classname##Int_c ( pLeft.Leak(), pRight.Leak() ); \
else if ( tNode.m_eArgType==SPH_ATTR_BIGINT ) return new _classname##Int64_c ( pLeft.Leak(), pRight.Leak() ); \
else return new _classname##Float_c ( pLeft.Leak(), pRight.Leak() );

int iOp = tNode.m_iToken;
if ( iOp=='+' || iOp=='-' || iOp=='*' || iOp=='/' || iOp=='&' || iOp=='|' || iOp=='%' || iOp=='<' || iOp=='>'
|| iOp==TOK_LTE || iOp==TOK_GTE || iOp==TOK_EQ || iOp==TOK_NE || iOp==TOK_AND || iOp==TOK_OR || iOp==TOK_NOT )
{
if ( pLeft && m_dNodes[tNode.m_iLeft].m_eRetType==SPH_ATTR_JSON_FIELD && m_dNodes[tNode.m_iLeft].m_iToken==TOK_ATTR_JSON )
pLeft = new Expr_JsonFieldConv_c ( pLeft );
pLeft = new Expr_JsonFieldConv_c ( pLeft.Leak () );
if ( pRight && m_dNodes[tNode.m_iRight].m_eRetType==SPH_ATTR_JSON_FIELD && m_dNodes[tNode.m_iRight].m_iToken==TOK_ATTR_JSON )
pRight = new Expr_JsonFieldConv_c ( pRight );
pRight = new Expr_JsonFieldConv_c ( pRight.Leak () );
}

switch ( tNode.m_iToken )
@@ -4699,13 +4695,13 @@ ISphExpr * ExprParser_t::CreateTree ( int iNode )
case TOK_ID: return new Expr_GetId_c ();
case TOK_WEIGHT: return new Expr_GetWeight_c ();

case '+': return new Expr_Add_c ( pLeft, pRight ); break;
case '-': return new Expr_Sub_c ( pLeft, pRight ); break;
case '*': return new Expr_Mul_c ( pLeft, pRight ); break;
case '/': return new Expr_Div_c ( pLeft, pRight ); break;
case '&': return new Expr_BitAnd_c ( pLeft, pRight ); break;
case '|': return new Expr_BitOr_c ( pLeft, pRight ); break;
case '%': return new Expr_Mod_c ( pLeft, pRight ); break;
case '+': return new Expr_Add_c ( pLeft.Leak (), pRight.Leak () ); break;
case '-': return new Expr_Sub_c ( pLeft.Leak (), pRight.Leak () ); break;
case '*': return new Expr_Mul_c ( pLeft.Leak (), pRight.Leak () ); break;
case '/': return new Expr_Div_c ( pLeft.Leak (), pRight.Leak () ); break;
case '&': return new Expr_BitAnd_c ( pLeft.Leak (), pRight.Leak () ); break;
case '|': return new Expr_BitOr_c ( pLeft.Leak (), pRight.Leak () ); break;
case '%': return new Expr_Mod_c ( pLeft.Leak (), pRight.Leak () ); break;

case '<': LOC_SPAWN_POLY ( Expr_Lt ); break;
case '>': LOC_SPAWN_POLY ( Expr_Gt ); break;
@@ -4715,27 +4711,26 @@ ISphExpr * ExprParser_t::CreateTree ( int iNode )
m_dNodes[tNode.m_iLeft].m_eRetType==SPH_ATTR_STRINGPTR ) &&
( m_dNodes[tNode.m_iRight].m_eRetType==SPH_ATTR_STRING ||
m_dNodes[tNode.m_iRight].m_eRetType==SPH_ATTR_STRINGPTR ) )
return new Expr_StrEq_c ( pLeft, pRight, m_eCollation );
return new Expr_StrEq_c ( pLeft.Leak (), pRight.Leak (), m_eCollation );
else if ( ( m_dNodes[tNode.m_iLeft].m_eRetType==SPH_ATTR_JSON_FIELD ) &&
( m_dNodes[tNode.m_iRight].m_eRetType==SPH_ATTR_STRING ||
m_dNodes[tNode.m_iRight].m_eRetType==SPH_ATTR_STRINGPTR ) )
return new Expr_StrEq_c ( pLeft, pRight, m_eCollation );
return new Expr_StrEq_c ( pLeft.Leak (), pRight.Leak (), m_eCollation );
LOC_SPAWN_POLY ( Expr_Eq ); break;
case TOK_NE: LOC_SPAWN_POLY ( Expr_Ne ); break;
case TOK_AND: LOC_SPAWN_POLY ( Expr_And ); break;
case TOK_OR: LOC_SPAWN_POLY ( Expr_Or ); break;
case TOK_NOT:
SafeDelete ( pRight );
return ( tNode.m_eArgType==SPH_ATTR_BIGINT )
? (ISphExpr * ) new Expr_NotInt64_c ( pLeft )
: (ISphExpr * ) new Expr_NotInt_c ( pLeft );
? (ISphExpr * ) new Expr_NotInt64_c ( pLeft.Leak () )
: (ISphExpr * ) new Expr_NotInt_c ( pLeft.Leak () );

case ',':
if ( pLeft && pRight )
return new Expr_Arglist_c ( pLeft, pRight );
return new Expr_Arglist_c ( pLeft.Leak (), pRight.Leak () );
break;

case TOK_NEG: assert ( pRight==nullptr ); return new Expr_Neg_c ( pLeft ); break;
case TOK_NEG: assert ( !pRight ); return new Expr_Neg_c ( pLeft.Leak () ); break;
case TOK_FUNC:
{
// fold arglist to array
@@ -4744,7 +4739,7 @@ ISphExpr * ExprParser_t::CreateTree ( int iNode )

CSphVector<ISphExpr *> dArgs;
if ( !bSkipLeft )
FoldArglist ( pLeft, dArgs );
FoldArglist ( pLeft.Leak (), dArgs );

// spawn proper function
assert ( tNode.m_iFunc>=0 && tNode.m_iFunc<int(sizeof(g_dFuncs)/sizeof(g_dFuncs[0])) );
@@ -4883,9 +4878,9 @@ ISphExpr * ExprParser_t::CreateTree ( int iNode )
break;
}

case TOK_UDF: return CreateUdfNode ( tNode.m_iFunc, pLeft ); break;
case TOK_UDF: return CreateUdfNode ( tNode.m_iFunc, pLeft.Leak () ); break;
case TOK_HOOK_IDENT: return m_pHook->CreateNode ( tNode.m_iFunc, NULL, NULL, m_sCreateError ); break;
case TOK_HOOK_FUNC: return m_pHook->CreateNode ( tNode.m_iFunc, pLeft, &m_eEvalStage, m_sCreateError ); break;
case TOK_HOOK_FUNC: return m_pHook->CreateNode ( tNode.m_iFunc, pLeft.Leak (), &m_eEvalStage, m_sCreateError ); break;
case TOK_MAP_ARG:
// tricky bit
// data gets moved (!) from node to ISphExpr at this point
@@ -4895,15 +4890,15 @@ ISphExpr * ExprParser_t::CreateTree ( int iNode )
if ( pLeft && m_dNodes[tNode.m_iLeft].m_iToken==TOK_SUBKEY && !tNode.m_tLocator.m_bDynamic )
{
// json key is a single static subkey, switch to fastpath
return new Expr_JsonFastKey_c ( tNode.m_tLocator, tNode.m_iLocator, pLeft );
return new Expr_JsonFastKey_c ( tNode.m_tLocator, tNode.m_iLocator, pLeft.Leak () );
} else
{
// json key is a generic expression, use generic catch-all JsonField
CSphVector<ISphExpr *> dArgs;
CSphVector<ESphAttr> dTypes;
if ( pLeft ) // may be NULL (top level array)
{
FoldArglist ( pLeft, dArgs );
FoldArglist ( pLeft.Leak (), dArgs );
GatherArgRetTypes ( tNode.m_iLeft, dTypes );
}
return new Expr_JsonField_c ( tNode.m_tLocator, tNode.m_iLocator, dArgs, dTypes );
@@ -4916,7 +4911,7 @@ ISphExpr * ExprParser_t::CreateTree ( int iNode )
CSphVector<ESphAttr> dTypes;
if ( pLeft )
{
FoldArglist ( pLeft, dArgs );
FoldArglist ( pLeft.Leak (), dArgs );
GatherArgRetTypes ( tNode.m_iLeft, dTypes );
}
return new Expr_JsonFieldConv_c ( new Expr_Iterator_c ( tNode.m_tLocator, tNode.m_iLocator, dArgs, dTypes, tNode.m_pAttr ) );
@@ -4926,7 +4921,7 @@ ISphExpr * ExprParser_t::CreateTree ( int iNode )
case TOK_IS_NULL:
case TOK_IS_NOT_NULL:
if ( m_dNodes[tNode.m_iLeft].m_eRetType==SPH_ATTR_JSON_FIELD )
return new Expr_JsonFieldIsNull_c ( pLeft, tNode.m_iToken==TOK_IS_NULL );
return new Expr_JsonFieldIsNull_c ( pLeft.Leak (), tNode.m_iToken==TOK_IS_NULL );
else
return new Expr_GetIntConst_c ( tNode.m_iToken!=TOK_IS_NULL );

@@ -4936,8 +4931,6 @@ ISphExpr * ExprParser_t::CreateTree ( int iNode )
#undef LOC_SPAWN_POLY

// fire exit
SafeRelease ( pLeft );
SafeRelease ( pRight );
return nullptr;
}

0 comments on commit c74d0b4

Please sign in to comment.
You can’t perform that action at this time.