library: Improved argument <valid>-interface to defined values that are explicitly excluded. (#4111)
* library: Improved <valid>-interface to defined values that are explicitly excluded. * std.cfg: Improved configuration of remainder[fl](). * Fixed failing self check * Fixed failing self check * std.cfg: Added support for std::remquo().
This commit is contained in:
parent
fffb03a242
commit
4f410ffb79
|
@ -273,7 +273,7 @@
|
|||
<optional>
|
||||
<element name="valid">
|
||||
<data type="string"> <!-- regex test: https://regex101.com/r/LoRGVj/2/ -->
|
||||
<param name="pattern">(-?[0-9]*(\.[0-9]+)?([eE][-+]?[0-9]+)?[,:])*([-]?[0-9]+(\.[0-9]+)?([eE][-+]?[0-9]+)?)?</param>
|
||||
<param name="pattern">([-!]?[0-9]*(\.[0-9]+)?([eE][-+]?[0-9]+)?[,:])*([-!]?[0-9]+(\.[0-9]+)?([eE][-+]?[0-9]+)?)?</param>
|
||||
</data>
|
||||
</element>
|
||||
</optional>
|
||||
|
|
58
cfg/std.cfg
58
cfg/std.cfg
|
@ -4156,6 +4156,61 @@ The obsolete function 'gets' is called. With 'gets' you'll get a buffer overrun
|
|||
<not-uninit/>
|
||||
</arg>
|
||||
</function>
|
||||
<!-- float remquo (float x , float y , int *quo); -->
|
||||
<!-- double remquo (double x, double y, int *quo); -->
|
||||
<!-- long double remquo (long double x, long double y, int *quo); -->
|
||||
<function name="remquo,std::remquo">
|
||||
<use-retval/>
|
||||
<pure/>
|
||||
<noreturn>false</noreturn>
|
||||
<leak-ignore/>
|
||||
<arg nr="1" direction="in">
|
||||
<not-uninit/>
|
||||
</arg>
|
||||
<arg nr="2" direction="in">
|
||||
<not-uninit/>
|
||||
<valid>!0.0</valid>
|
||||
</arg>
|
||||
<arg nr="3" direction="out">
|
||||
<not-null/>
|
||||
</arg>
|
||||
</function>
|
||||
<!-- float remquof (float x , float y , int *quo); -->
|
||||
<function name="remquof,std::remquof">
|
||||
<use-retval/>
|
||||
<pure/>
|
||||
<returnValue type="float"/>
|
||||
<noreturn>false</noreturn>
|
||||
<leak-ignore/>
|
||||
<arg nr="1" direction="in">
|
||||
<not-uninit/>
|
||||
</arg>
|
||||
<arg nr="2" direction="in">
|
||||
<not-uninit/>
|
||||
<valid>!0.0</valid>
|
||||
</arg>
|
||||
<arg nr="3" direction="out">
|
||||
<not-null/>
|
||||
</arg>
|
||||
</function>
|
||||
<!-- long double remquol (long double x , long double y , int *quo); -->
|
||||
<function name="remquol,std::remquol">
|
||||
<use-retval/>
|
||||
<pure/>
|
||||
<returnValue type="long double"/>
|
||||
<noreturn>false</noreturn>
|
||||
<leak-ignore/>
|
||||
<arg nr="1" direction="in">
|
||||
<not-uninit/>
|
||||
</arg>
|
||||
<arg nr="2" direction="in">
|
||||
<not-uninit/>
|
||||
<valid>!0.0</valid>
|
||||
</arg>
|
||||
<arg nr="3" direction="out">
|
||||
<not-null/>
|
||||
</arg>
|
||||
</function>
|
||||
<!-- double remainder(double x, double y); -->
|
||||
<function name="remainder,std::remainder">
|
||||
<use-retval/>
|
||||
|
@ -4168,6 +4223,7 @@ The obsolete function 'gets' is called. With 'gets' you'll get a buffer overrun
|
|||
</arg>
|
||||
<arg nr="2" direction="in">
|
||||
<not-uninit/>
|
||||
<valid>!0.0</valid>
|
||||
</arg>
|
||||
</function>
|
||||
<!-- float remainderf(float x, float y); -->
|
||||
|
@ -4182,6 +4238,7 @@ The obsolete function 'gets' is called. With 'gets' you'll get a buffer overrun
|
|||
</arg>
|
||||
<arg nr="2" direction="in">
|
||||
<not-uninit/>
|
||||
<valid>!0.0</valid>
|
||||
</arg>
|
||||
</function>
|
||||
<!-- long double remainderl(long double x, long double y); -->
|
||||
|
@ -4196,6 +4253,7 @@ The obsolete function 'gets' is called. With 'gets' you'll get a buffer overrun
|
|||
</arg>
|
||||
<arg nr="2" direction="in">
|
||||
<not-uninit/>
|
||||
<valid>!0.0</valid>
|
||||
</arg>
|
||||
</function>
|
||||
<!-- double remquo(double, x, double y, int *quo); -->
|
||||
|
|
|
@ -748,7 +748,8 @@ Library::Error Library::loadFunction(const tinyxml2::XMLElement * const node, co
|
|||
return Error(ErrorCode::BAD_ATTRIBUTE_VALUE, (!p ? "\"\"" : argnode->GetText()));
|
||||
// Set validation expression
|
||||
ac.valid = argnode->GetText();
|
||||
} else if (argnodename == "minsize") {
|
||||
}
|
||||
else if (argnodename == "minsize") {
|
||||
const char *typeattr = argnode->Attribute("type");
|
||||
if (!typeattr)
|
||||
return Error(ErrorCode::MISSING_ATTRIBUTE, "type");
|
||||
|
@ -929,6 +930,10 @@ bool Library::isFloatArgValid(const Token *ftok, int argnr, double argvalue) con
|
|||
return true;
|
||||
if ((!tok->previous() || tok->previous()->str() == ",") && Token::Match(tok,": %num%") && argvalue <= MathLib::toDoubleNumber(tok->strAt(1)))
|
||||
return true;
|
||||
if (Token::Match(tok, "%num%") && MathLib::isFloat(tok->str()) && MathLib::isEqual(tok->str(), MathLib::toString(argvalue)))
|
||||
return true;
|
||||
if (Token::Match(tok, "! %num%") && MathLib::isFloat(tok->next()->str()))
|
||||
return MathLib::isNotEqual(tok->next()->str(), MathLib::toString(argvalue));
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
@ -1227,7 +1232,7 @@ const Library::WarnInfo* Library::getWarnInfo(const Token* ftok) const
|
|||
|
||||
bool Library::isCompliantValidationExpression(const char* p)
|
||||
{
|
||||
if (!p)
|
||||
if (!p || !*p)
|
||||
return false;
|
||||
|
||||
bool error = false;
|
||||
|
@ -1237,15 +1242,18 @@ bool Library::isCompliantValidationExpression(const char* p)
|
|||
|
||||
error = *p == '.';
|
||||
for (; *p; p++) {
|
||||
if (std::isdigit(*p))
|
||||
if (std::isdigit(*p)) {
|
||||
error |= (*(p + 1) == '-');
|
||||
}
|
||||
else if (*p == ':') {
|
||||
error |= range | (*(p + 1) == '.');
|
||||
range = true;
|
||||
has_dot = false;
|
||||
has_E = false;
|
||||
} else if ((*p == '-') || (*p == '+'))
|
||||
}
|
||||
else if ((*p == '-') || (*p == '+')) {
|
||||
error |= (!std::isdigit(*(p + 1)));
|
||||
}
|
||||
else if (*p == ',') {
|
||||
range = false;
|
||||
error |= *(p + 1) == '.';
|
||||
|
@ -1257,6 +1265,8 @@ bool Library::isCompliantValidationExpression(const char* p)
|
|||
} else if (*p == 'E' || *p == 'e') {
|
||||
error |= has_E;
|
||||
has_E = true;
|
||||
} else if (*p == '!') {
|
||||
error |= !((*(p+1) == '-') || (*(p+1) == '+') || (std::isdigit(*(p + 1))));
|
||||
} else
|
||||
return false;
|
||||
}
|
||||
|
|
|
@ -30,6 +30,60 @@
|
|||
#include <float.h>
|
||||
|
||||
|
||||
float invalidFunctionArg_float_remquo (float x, float y, int* quo )
|
||||
{
|
||||
// cppcheck-suppress invalidFunctionArg
|
||||
(void) remquo(x,0.0f,quo);
|
||||
// cppcheck-suppress invalidFunctionArg
|
||||
(void) remquof(x,0.0f,quo);
|
||||
return remquo(x,y,quo);
|
||||
}
|
||||
|
||||
double invalidFunctionArg_double_remquo (double x, double y, int* quo )
|
||||
{
|
||||
// cppcheck-suppress invalidFunctionArg
|
||||
(void) remquo(x,0.0,quo);
|
||||
// cppcheck-suppress invalidFunctionArg
|
||||
(void) remquo(x,0.0f,quo);
|
||||
// cppcheck-suppress invalidFunctionArg
|
||||
(void) remquo(x,0.0L,quo);
|
||||
return remquo(x,y,quo);
|
||||
}
|
||||
|
||||
double invalidFunctionArg_long_double_remquo (long double x, long double y, int* quo )
|
||||
{
|
||||
// cppcheck-suppress invalidFunctionArg
|
||||
(void) remquo(x,0.0L,quo);
|
||||
// cppcheck-suppress invalidFunctionArg
|
||||
(void) remquol(x,0.0L,quo);
|
||||
return remquo(x,y,quo);
|
||||
}
|
||||
|
||||
void invalidFunctionArg_remainderl(long double f1, long double f2)
|
||||
{
|
||||
// cppcheck-suppress invalidFunctionArg
|
||||
(void)remainderl(f1,0.0);
|
||||
// cppcheck-suppress invalidFunctionArg
|
||||
(void)remainderl(f1,0.0L);
|
||||
(void)remainderl(f1,f2);
|
||||
}
|
||||
|
||||
void invalidFunctionArg_remainder(double f1, double f2)
|
||||
{
|
||||
// cppcheck-suppress invalidFunctionArg
|
||||
(void)remainder(f1,0.0);
|
||||
(void)remainder(f1,f2);
|
||||
}
|
||||
|
||||
void invalidFunctionArg_remainderf(float f1, float f2)
|
||||
{
|
||||
// cppcheck-suppress invalidFunctionArg
|
||||
(void)remainderf(f1,0.0);
|
||||
// cppcheck-suppress invalidFunctionArg
|
||||
(void)remainderf(f1,0.0f);
|
||||
(void)remainderf(f1,f2);
|
||||
}
|
||||
|
||||
int qsort_cmpfunc (const void * a, const void * b) {
|
||||
return (*(int*)a - *(int*)b);
|
||||
}
|
||||
|
|
|
@ -36,6 +36,60 @@
|
|||
#include <iterator>
|
||||
#include <vector>
|
||||
|
||||
float invalidFunctionArg_remquo (float x, float y, int* quo )
|
||||
{
|
||||
// cppcheck-suppress invalidFunctionArg
|
||||
(void) std::remquo(x,0.0f,quo);
|
||||
// cppcheck-suppress invalidFunctionArg
|
||||
(void) std::remquof(x,0.0f,quo);
|
||||
return std::remquo(x,y,quo);
|
||||
}
|
||||
|
||||
double invalidFunctionArg_remquo (double x, double y, int* quo )
|
||||
{
|
||||
// cppcheck-suppress invalidFunctionArg
|
||||
(void) std::remquo(x,0.0,quo);
|
||||
// cppcheck-suppress invalidFunctionArg
|
||||
(void) std::remquo(x,0.0f,quo);
|
||||
// cppcheck-suppress invalidFunctionArg
|
||||
(void) std::remquo(x,0.0L,quo);
|
||||
return std::remquo(x,y,quo);
|
||||
}
|
||||
|
||||
double invalidFunctionArg_remquo (long double x, long double y, int* quo )
|
||||
{
|
||||
// cppcheck-suppress invalidFunctionArg
|
||||
(void) std::remquo(x,0.0L,quo);
|
||||
// cppcheck-suppress invalidFunctionArg
|
||||
(void) std::remquol(x,0.0L,quo);
|
||||
return std::remquo(x,y,quo);
|
||||
}
|
||||
|
||||
void invalidFunctionArg_remainderl(long double f1, long double f2)
|
||||
{
|
||||
// cppcheck-suppress invalidFunctionArg
|
||||
(void)std::remainderl(f1,0.0);
|
||||
// cppcheck-suppress invalidFunctionArg
|
||||
(void)std::remainderl(f1,0.0L);
|
||||
(void)std::remainderl(f1,f2);
|
||||
}
|
||||
|
||||
void invalidFunctionArg_remainder(double f1, double f2)
|
||||
{
|
||||
// cppcheck-suppress invalidFunctionArg
|
||||
(void)std::remainder(f1,0.0);
|
||||
(void)std::remainder(f1,f2);
|
||||
}
|
||||
|
||||
void invalidFunctionArg_remainderf(float f1, float f2)
|
||||
{
|
||||
// cppcheck-suppress invalidFunctionArg
|
||||
(void)std::remainderf(f1,0.0);
|
||||
// cppcheck-suppress invalidFunctionArg
|
||||
(void)std::remainderf(f1,0.0f);
|
||||
(void)std::remainderf(f1,f2);
|
||||
}
|
||||
|
||||
void uninitvar_std_fstream_open(std::fstream &fs, const std::string &strFileName, const char* filename, std::ios_base::openmode mode)
|
||||
{
|
||||
std::string s;
|
||||
|
|
|
@ -89,10 +89,13 @@ private:
|
|||
ASSERT_EQUALS(true, Library::isCompliantValidationExpression("1.175494e-38:"));
|
||||
ASSERT_EQUALS(true, Library::isCompliantValidationExpression(":1.175494e-38"));
|
||||
ASSERT_EQUALS(true, Library::isCompliantValidationExpression(":42.0"));
|
||||
ASSERT_EQUALS(true, Library::isCompliantValidationExpression("!42.0"));
|
||||
|
||||
// Robustness tests
|
||||
ASSERT_EQUALS(false, Library::isCompliantValidationExpression(nullptr));
|
||||
ASSERT_EQUALS(false, Library::isCompliantValidationExpression("x"));
|
||||
ASSERT_EQUALS(false, Library::isCompliantValidationExpression("!"));
|
||||
ASSERT_EQUALS(false, Library::isCompliantValidationExpression(""));
|
||||
}
|
||||
|
||||
void empty() const {
|
||||
|
@ -336,6 +339,7 @@ private:
|
|||
" <arg nr=\"8\"><valid>0.0:</valid></arg>\n"
|
||||
" <arg nr=\"9\"><valid>:2.0</valid></arg>\n"
|
||||
" <arg nr=\"10\"><valid>0.0</valid></arg>\n"
|
||||
" <arg nr=\"11\"><valid>!0.0</valid></arg>\n"
|
||||
" </function>\n"
|
||||
"</def>";
|
||||
|
||||
|
@ -343,7 +347,7 @@ private:
|
|||
ASSERT_EQUALS(true, Library::ErrorCode::OK == (readLibrary(library, xmldata)).errorcode);
|
||||
|
||||
TokenList tokenList(nullptr);
|
||||
std::istringstream istr("foo(a,b,c,d,e,f,g,h,i,j);");
|
||||
std::istringstream istr("foo(a,b,c,d,e,f,g,h,i,j,k);");
|
||||
tokenList.createTokens(istr);
|
||||
tokenList.front()->next()->astOperand1(tokenList.front());
|
||||
|
||||
|
@ -460,8 +464,13 @@ private:
|
|||
ASSERT_EQUALS(false, library.isFloatArgValid(tokenList.front(), 9, 200.0));
|
||||
|
||||
// 0.0
|
||||
ASSERT_EQUALS(false, library.isIntArgValid(tokenList.front(), 10, 0));
|
||||
ASSERT_EQUALS(false, library.isFloatArgValid(tokenList.front(), 10, 0.0));
|
||||
ASSERT_EQUALS(true, library.isIntArgValid(tokenList.front(), 10, 0));
|
||||
ASSERT_EQUALS(true, library.isFloatArgValid(tokenList.front(), 10, 0.0));
|
||||
|
||||
// ! 0.0
|
||||
ASSERT_EQUALS(true, library.isFloatArgValid(tokenList.front(), 11, -0.42));
|
||||
ASSERT_EQUALS(false, library.isFloatArgValid(tokenList.front(), 11, 0.0));
|
||||
ASSERT_EQUALS(true, library.isFloatArgValid(tokenList.front(), 11, 0.42));
|
||||
}
|
||||
|
||||
void function_arg_minsize() const {
|
||||
|
|
Loading…
Reference in New Issue