Fix #9166 (print proper types in invalidCast message) (#2347)

* Fix #9166 (print proper types in invalidCast message)

* Use ValueType->str()

* astyle

* Set default sign to avoid issues on different platforms
This commit is contained in:
Rikard Falkeborn 2019-11-11 07:17:50 +01:00 committed by Daniel Marjamäki
parent af170c8e3f
commit 38dea4719b
3 changed files with 21 additions and 26 deletions

View File

@ -344,26 +344,20 @@ void CheckOther::invalidPointerCast()
if (fromType->type != toType->type && fromType->type >= ValueType::Type::BOOL && toType->type >= ValueType::Type::BOOL && (toType->type != ValueType::Type::CHAR || printInconclusive)) {
if (toType->isIntegral() && fromType->isIntegral())
continue;
std::string toStr = toType->isIntegral() ? "integer *" : toType->str();
toStr.erase(toStr.size()-2);
std::string fromStr = fromType->isIntegral() ? "integer *" : fromType->str();
fromStr.erase(fromStr.size() - 2);
invalidPointerCastError(tok, fromStr, toStr, toType->type == ValueType::Type::CHAR);
invalidPointerCastError(tok, fromType->str(), toType->str(), toType->type == ValueType::Type::CHAR, toType->isIntegral());
}
}
}
}
void CheckOther::invalidPointerCastError(const Token* tok, const std::string& from, const std::string& to, bool inconclusive)
void CheckOther::invalidPointerCastError(const Token* tok, const std::string& from, const std::string& to, bool inconclusive, bool toIsInt)
{
if (to == "integer") { // If we cast something to int*, this can be useful to play with its binary data representation
if (!inconclusive)
reportError(tok, Severity::portability, "invalidPointerCast", "Casting from " + from + "* to integer* is not portable due to different binary data representations on different platforms.", CWE704, false);
else
reportError(tok, Severity::portability, "invalidPointerCast", "Casting from " + from + "* to char* is not portable due to different binary data representations on different platforms.", CWE704, true);
if (toIsInt) { // If we cast something to int*, this can be useful to play with its binary data representation
reportError(tok, Severity::portability, "invalidPointerCast", "Casting from " + from + " to " + to + " is not portable due to different binary data representations on different platforms.", CWE704, inconclusive);
} else
reportError(tok, Severity::portability, "invalidPointerCast", "Casting between " + from + "* and " + to + "* which have an incompatible binary data representation.", CWE704, false);
reportError(tok, Severity::portability, "invalidPointerCast", "Casting between " + from + " and " + to + " which have an incompatible binary data representation.", CWE704, false);
}
//---------------------------------------------------------------------------

View File

@ -219,7 +219,7 @@ private:
void clarifyCalculationError(const Token *tok, const std::string &op);
void clarifyStatementError(const Token* tok);
void cstyleCastError(const Token *tok);
void invalidPointerCastError(const Token* tok, const std::string& from, const std::string& to, bool inconclusive);
void invalidPointerCastError(const Token* tok, const std::string& from, const std::string& to, bool inconclusive, bool toIsInt);
void passedByValueError(const Token *tok, const std::string &parname, bool inconclusive);
void constVariableError(const Variable *var);
void constStatementError(const Token *tok, const std::string &type, bool inconclusive);
@ -276,7 +276,7 @@ private:
// error
c.zerodivError(nullptr, nullptr);
c.misusedScopeObjectError(nullptr, "varname");
c.invalidPointerCastError(nullptr, "float", "double", false);
c.invalidPointerCastError(nullptr, "float *", "double *", false, false);
c.negativeBitwiseShiftError(nullptr, 1);
c.negativeBitwiseShiftError(nullptr, 2);
c.checkPipeParameterSizeError(nullptr, "varname", "dimension");

View File

@ -1375,6 +1375,7 @@ private:
settings.addEnabled("portability");
settings.inconclusive = inconclusive;
settings.defaultSign = 's';
// Tokenize..
Tokenizer tokenizer(&settings, this);
std::istringstream istr(code);
@ -1391,34 +1392,34 @@ private:
" delete [] (double*)f;\n"
" delete [] (long double const*)(new float[10]);\n"
"}");
ASSERT_EQUALS("[test.cpp:3]: (portability) Casting between float* and double* which have an incompatible binary data representation.\n"
"[test.cpp:4]: (portability) Casting between float* and const long double* which have an incompatible binary data representation.\n", errout.str());
ASSERT_EQUALS("[test.cpp:3]: (portability) Casting between float * and double * which have an incompatible binary data representation.\n"
"[test.cpp:4]: (portability) Casting between float * and const long double * which have an incompatible binary data representation.\n", errout.str());
checkInvalidPointerCast("void test(const float* f) {\n"
" double *d = (double*)f;\n"
"}");
ASSERT_EQUALS("[test.cpp:2]: (portability) Casting between const float* and double* which have an incompatible binary data representation.\n", errout.str());
ASSERT_EQUALS("[test.cpp:2]: (portability) Casting between const float * and double * which have an incompatible binary data representation.\n", errout.str());
checkInvalidPointerCast("void test(double* d1) {\n"
" long double *ld = (long double*)d1;\n"
" double *d2 = (double*)ld;\n"
"}");
ASSERT_EQUALS("[test.cpp:2]: (portability) Casting between double* and long double* which have an incompatible binary data representation.\n"
"[test.cpp:3]: (portability) Casting between long double* and double* which have an incompatible binary data representation.\n", errout.str());
ASSERT_EQUALS("[test.cpp:2]: (portability) Casting between double * and long double * which have an incompatible binary data representation.\n"
"[test.cpp:3]: (portability) Casting between long double * and double * which have an incompatible binary data representation.\n", errout.str());
checkInvalidPointerCast("char* test(int* i) {\n"
" long double *d = (long double*)(i);\n"
" double *d = (double*)(i);\n"
" float *f = reinterpret_cast<float*>(i);\n"
"}");
ASSERT_EQUALS("[test.cpp:2]: (portability) Casting between integer* and long double* which have an incompatible binary data representation.\n"
"[test.cpp:3]: (portability) Casting between integer* and double* which have an incompatible binary data representation.\n"
"[test.cpp:4]: (portability) Casting between integer* and float* which have an incompatible binary data representation.\n", errout.str());
ASSERT_EQUALS("[test.cpp:2]: (portability) Casting between signed int * and long double * which have an incompatible binary data representation.\n"
"[test.cpp:3]: (portability) Casting between signed int * and double * which have an incompatible binary data representation.\n"
"[test.cpp:4]: (portability) Casting between signed int * and float * which have an incompatible binary data representation.\n", errout.str());
checkInvalidPointerCast("float* test(unsigned int* i) {\n"
" return (float*)i;\n"
"}");
ASSERT_EQUALS("[test.cpp:2]: (portability) Casting between integer* and float* which have an incompatible binary data representation.\n", errout.str());
ASSERT_EQUALS("[test.cpp:2]: (portability) Casting between unsigned int * and float * which have an incompatible binary data representation.\n", errout.str());
checkInvalidPointerCast("float* test(unsigned int* i) {\n"
" return (float*)i[0];\n"
@ -1428,7 +1429,7 @@ private:
checkInvalidPointerCast("float* test(double& d) {\n"
" return (float*)&d;\n"
"}");
ASSERT_EQUALS("[test.cpp:2]: (portability) Casting between double* and float* which have an incompatible binary data representation.\n", errout.str());
ASSERT_EQUALS("[test.cpp:2]: (portability) Casting between double * and float * which have an incompatible binary data representation.\n", errout.str());
checkInvalidPointerCast("void test(float* data) {\n"
" f.write((char*)data,sizeof(float));\n"
@ -1438,7 +1439,7 @@ private:
checkInvalidPointerCast("void test(float* data) {\n"
" f.write((char*)data,sizeof(float));\n"
"}", true, true); // #3639
ASSERT_EQUALS("[test.cpp:2]: (portability, inconclusive) Casting from float* to char* is not portable due to different binary data representations on different platforms.\n", errout.str());
ASSERT_EQUALS("[test.cpp:2]: (portability, inconclusive) Casting from float * to signed char * is not portable due to different binary data representations on different platforms.\n", errout.str());
checkInvalidPointerCast("long long* test(float* f) {\n"
@ -1450,7 +1451,7 @@ private:
" foo((long long*)f);\n"
" return reinterpret_cast<long long*>(c);\n"
"}", true);
ASSERT_EQUALS("[test.cpp:2]: (portability) Casting from float* to integer* is not portable due to different binary data representations on different platforms.\n", errout.str());
ASSERT_EQUALS("[test.cpp:2]: (portability) Casting from float * to signed long long * is not portable due to different binary data representations on different platforms.\n", errout.str());
checkInvalidPointerCast("Q_DECLARE_METATYPE(int*)"); // #4135 - don't crash
}