ast: fix memleaks detected by ASAN during testing 48/21148/4
Clément DAVID [Wed, 4 Dec 2019 13:55:22 +0000 (14:55 +0100)]
Change-Id: Ib2d1c31769777209ddcd0abc75e534060f12c389

scilab/modules/ast/includes/analysis/call/Call.hxx
scilab/modules/ast/src/cpp/ast/run_CallExp.hpp
scilab/modules/ast/src/cpp/ast/run_OpExp.hpp
scilab/modules/ast/src/cpp/ast/visitor_common.cpp
scilab/modules/ast/src/cpp/operations/types_power.cpp
scilab/modules/ast/src/cpp/types/types_tools.cpp
scilab/modules/ast/tests/nonreg_tests/bug_15642.dia.ref
scilab/modules/elementary_functions/sci_gateway/cpp/sci_linspace.cpp

index ae96081..710306e 100644 (file)
@@ -38,6 +38,7 @@ public:
     Call(const std::wstring & _name, const TIType & _arg) : name(_name), args(1, _arg) { }
     Call(const std::wstring & _name) : name(_name) { }
     Call(Call && call) : name(call.name), args(call.args) { }
+    virtual ~Call() = default;
 
     inline const std::wstring & getName() const
     {
index 9a99381..4d92219 100644 (file)
@@ -65,8 +65,23 @@ void RunVisitorT<T>::visitprivate(const CallExp &e)
     types::typed_list in;
     types::optional_list opt;
 
+    int iInvokeNbOut = 0;
+    try
+    {
+        // getInvokeNbOut will parse the file in case of macrofile
+        // this could throw an exception
+        iInvokeNbOut = pIT->getInvokeNbOut();
+    }
+    catch (const InternalError& ie)
+    {
+        clearResult();
+        cleanIn(inTmp, outTmp);
+        CoverageInstance::stopChrono((void*)&e);
+        throw ie;
+    }
+
     // manage case [a,b]=foo() where foo is defined as a=foo()
-    if (pIT->getInvokeNbOut() != -1 && pIT->getInvokeNbOut() < iRetCount)
+    if (iInvokeNbOut != -1 && iInvokeNbOut < iRetCount)
     {
         clearResult();
         cleanIn(inTmp, outTmp);
index 2c048d0..84502e2 100644 (file)
@@ -395,6 +395,10 @@ void RunVisitorT<T>::visitprivate(const LogicalOpExp &e)
         {
             // We did not have any algorithm matching, so we try to call OverLoad
             e.getRight().accept(*this);
+            if (pITR)
+            {
+                pITR->killMe();
+            }
             pITR = getResult();
             if (isSingleResult() == false)
             {
index 6ba5e0c..b873906 100644 (file)
@@ -616,7 +616,7 @@ types::InternalType* callOverload(const ast::Exp& e, const std::wstring& _strTyp
 
     types::InternalType* pFunc = symbol::Context::getInstance()->get(symbol::Symbol(function_name));
     if (pFunc == NULL &&
-            (_source->getShortTypeStr().size() > 8 || _dest && _dest->getShortTypeStr().size() > 8))
+            (_source->getShortTypeStr().size() > 8 || (_dest && _dest->getShortTypeStr().size() > 8)))
     {
         if (_source->getShortTypeStr().size() > 8)
         {
@@ -2109,9 +2109,8 @@ types::InternalType* insertionCall(const ast::Exp& e, types::typed_list* _pArgs,
                                 pStructRet->addField(pStrInsertFieldsName->get(i));
                             }
                         }
-
-                        pStrInsertFieldsName->killMe();
                     }
+                    pStrInsertFieldsName->killMe();
                 }
                 else if (_pInsert->isStruct())
                 {
index 7c4190c..7e9c020 100644 (file)
@@ -540,6 +540,12 @@ int DotPowerSpaseByDouble(Sparse* _pSp, Double* _pDouble, InternalType** _pOut)
             std::complex<double> cplx(ppDblGet->get(0), ppDblGet->getImg(0));
             pSpTemp->set(iPositVal[i], cplx, false);
         }
+
+        if (ppDblGet)
+        {
+            ppDblGet->killMe();
+            ppDblGet = NULL;
+        }
     }
 
     delete[] Col;
index c98fb9e..d50cf5a 100644 (file)
@@ -816,6 +816,12 @@ int checkIndexesArguments(InternalType* _pRef, typed_list* _pArgsIn, typed_list*
                 {
                     wchar_t szError[bsiz];
                     os_swprintf(szError, bsiz, _W("variable size exceeded : less than %d expected.\n").c_str(), INT_MAX);
+
+                    if(_pRef)
+                    {
+                        _pRef->killMe(); // clean temporary clone if needed
+                    }
+
                     throw ast::InternalError(szError);
                 }
 
@@ -841,10 +847,15 @@ int checkIndexesArguments(InternalType* _pRef, typed_list* _pArgsIn, typed_list*
             delete[] _piCountDim;
             cleanIndexesArguments(_pArgsIn, _pArgsOut);
 
+            if(_pRef)
+            {
+                _pRef->killMe(); // clean temporary clone if needed
+            }
+
             throw ast::InternalError(szError);
         }
-        _pArgsOut->push_back(pCurrentArg);
 
+        _pArgsOut->push_back(pCurrentArg);
     }
 
 
index 88179a2..a567934 100644 (file)
@@ -17,6 +17,6 @@
 A=sparse([1 1; 2 2; 3 3],[%t %f %t],[3 3]);
 A(:)
  ans  =
-(  9,  1) sparse matrix
+(  9,  1) sparse boolean matrix
 (  1,  1)      T
 (  9,  1)      T
index 3234fe0..ffa874e 100644 (file)
@@ -45,7 +45,7 @@ types::Function::ReturnValue sci_linspace(types::typed_list &in, int _iRetCount,
 
     if (in.size() != 2 & in.size() != 3)
     {
-        Scierror(77, _("%s: Wrong number of input argument(s): %d to %d expected.\n"), "linspace", 2,3);
+        Scierror(77, _("%s: Wrong number of input argument(s): %d to %d expected.\n"), "linspace", 2, 3);
         return types::Function::Error;
     }
 
@@ -56,7 +56,7 @@ types::Function::ReturnValue sci_linspace(types::typed_list &in, int _iRetCount,
     }
 
     types::Double* pDbl[2];
-    for (int i=0; i<2; i++)
+    for (int i = 0; i < 2; i++)
     {
         if (in[i]->isDouble())
         {
@@ -77,14 +77,14 @@ types::Function::ReturnValue sci_linspace(types::typed_list &in, int _iRetCount,
     int* piDims1 = pDbl[1]->getDimsArray();
     if (iDims0 != iDims1)
     {
-        Scierror(999, _("%s: Arguments %d and %d must have same dimensions.\n"), "linspace",1,2);
+        Scierror(999, _("%s: Arguments %d and %d must have same dimensions.\n"), "linspace", 1, 2);
         return types::Function::Error;
     }
     for (int i = 0; i < iDims0; i++)
     {
         if (piDims0[i] != piDims1[i])
         {
-            Scierror(999, _("%s: Arguments %d and %d must have same dimensions.\n"), "linspace",1,2);
+            Scierror(999, _("%s: Arguments %d and %d must have same dimensions.\n"), "linspace", 1, 2);
             return types::Function::Error;
         }
     }
@@ -107,7 +107,7 @@ types::Function::ReturnValue sci_linspace(types::typed_list &in, int _iRetCount,
         }
         else
         {
-            Scierror(999, _("%s: Argument #%d: An integer value expected.\n"), "linspace",3);
+            Scierror(999, _("%s: Argument #%d: An integer value expected.\n"), "linspace", 3);
             return types::Function::Error;
         }
     }
@@ -128,7 +128,7 @@ types::Function::ReturnValue sci_linspace(types::typed_list &in, int _iRetCount,
     // generation is done by considering array as a column vector
     int iRows =  pDbl[0]->getSize();
     // pDblOut is resized later
-    pDblOut = new types::Double(iRows,iCols);
+    pDblOut = new types::Double(iRows, iCols);
 
     if (!fillRange(pDblOut->get(), pDbl[0]->get(), pDbl[1]->get(), iRows, iCols))
     {
@@ -140,7 +140,8 @@ types::Function::ReturnValue sci_linspace(types::typed_list &in, int _iRetCount,
     if (pDbl[0]->isComplex() || pDbl[1]->isComplex())
     {
         int iReal;
-        for (iReal = 0; iReal < 2; iReal++) {
+        for (iReal = 0; iReal < 2; iReal++)
+        {
             if (!pDbl[iReal]->isComplex())
             {
                 pDbl[iReal] = pDbl[iReal]->clone();
@@ -153,7 +154,7 @@ types::Function::ReturnValue sci_linspace(types::typed_list &in, int _iRetCount,
         bool status = fillRange(pDblOut->getImg(), pDbl[0]->getImg(), pDbl[1]->getImg(), iRows, iCols);
         if (iReal < 2)
         {
-              pDbl[iReal]->killMe();
+            pDbl[iReal]->killMe();
         }
         if (status != true) // if Infs or NaNs
         {
@@ -162,14 +163,14 @@ types::Function::ReturnValue sci_linspace(types::typed_list &in, int _iRetCount,
         }
     }
 
-    int *piNewDims = new int[iDims0+1];
+    int *piNewDims = new int[iDims0 + 1];
     // keep the first dimension unchanged
     piNewDims[0] = piDims0[0];
     int iDim = 1;
-    for (int i=1; i<iDims0; i++)
+    for (int i = 1; i < iDims0; i++)
     {
         // squeeze subsequent single dimensions
-        if (piDims0[i]>1)
+        if (piDims0[i] > 1)
         {
             piNewDims[iDim++] = piDims0[i];
         }
@@ -180,33 +181,34 @@ types::Function::ReturnValue sci_linspace(types::typed_list &in, int _iRetCount,
     pDblOut->reshape(piNewDims, iDim);
     out.push_back(pDblOut);
 
+    delete[] piNewDims;
     return types::Function::OK;
 }
 
 bool fillRange(double* pdblOut, double* pdblMin, double* pdblMax, int iRows, int iCols)
 {
     double* step = new double[iRows];
-    for (int j = 0, k = (iCols-1)*iRows; j < iRows; j++)
+    for (int j = 0, k = (iCols - 1) * iRows; j < iRows; j++)
     {
-        step[j] = (pdblMax[j]-pdblMin[j])/(iCols-1);
+        step[j] = (pdblMax[j] - pdblMin[j]) / (iCols - 1);
         // checking Infs and NaNs
         int indInfOrNan = std::isinf(pdblMin[j]) || std::isnan(pdblMin[j]) ? 1 : 0;
         indInfOrNan = indInfOrNan == 0 ? (std::isinf(pdblMax[j]) || std::isnan(pdblMax[j]) ? 2 : 0) : indInfOrNan;
         if (indInfOrNan > 0)
         {
             delete[] step;
-            Scierror(999, _("%s: Argument #%d: %%nan and %%inf values are forbidden.\n"), "linspace",indInfOrNan);
+            Scierror(999, _("%s: Argument #%d: %%nan and %%inf values are forbidden.\n"), "linspace", indInfOrNan);
             return false;
         }
         // last column is enforced (http://bugzilla.scilab.org/10966)
         pdblOut[k++] = pdblMax[j];
     }
     // doing the linear range generation
-    for (int i = 0; i<iCols-1; i++)
+    for (int i = 0; i < iCols - 1; i++)
     {
         for (int j = 0; j < iRows; j++)
         {
-              *(pdblOut++) = pdblMin[j]+i*step[j];
+            *(pdblOut++) = pdblMin[j] + i * step[j];
         }
     }
     delete[] step;