diff --git a/lib/checkother.cpp b/lib/checkother.cpp index 3c3a874cf..b944a3df7 100644 --- a/lib/checkother.cpp +++ b/lib/checkother.cpp @@ -333,7 +333,7 @@ static std::string analyzeType(const Token* tok) } if (tok->str() == "float") return "float"; - if (Token::Match(tok, "unsigned| int|long|short|char|size_t")) + if (Token::Match(tok, "int|long|short|char|size_t")) return "integer"; return ""; } @@ -398,16 +398,19 @@ void CheckOther::invalidPointerCast() std::string fromType = analyzeType(fromTok); std::string toType = analyzeType(toTok); - if (fromType != toType && !fromType.empty() && !toType.empty() && (toType != "integer" || _settings->isEnabled("portability"))) - invalidPointerCastError(tok, fromType, toType); + if (fromType != toType && !fromType.empty() && !toType.empty() && (toType != "integer" || _settings->isEnabled("portability")) && (toTok->str() != "char" || _settings->inconclusive)) + invalidPointerCastError(tok, fromType, toType, toTok->str() == "char"); } } -void CheckOther::invalidPointerCastError(const Token* tok, const std::string& from, const std::string& to) +void CheckOther::invalidPointerCastError(const Token* tok, const std::string& from, const std::string& to, bool inconclusive) { - if (to == "integer") // 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 integer* is not portable due to different binary data representations on different platforms"); - else + 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"); + else + reportInconclusiveError(tok, Severity::portability, "invalidPointerCast", "Casting from " + from + "* to char* might be not portable due to different binary data representations on different platforms"); + } else reportError(tok, Severity::warning, "invalidPointerCast", "Casting between " + from + "* and " + to + "* which have an incompatible binary data representation"); } diff --git a/lib/checkother.h b/lib/checkother.h index f0377ecf3..74d709a22 100644 --- a/lib/checkother.h +++ b/lib/checkother.h @@ -268,7 +268,7 @@ private: void invalidPrintfArgTypeError_int(const Token* tok, unsigned int numFormat, char c); void invalidPrintfArgTypeError_float(const Token* tok, unsigned int numFormat, char c); void cstyleCastError(const Token *tok); - void invalidPointerCastError(const Token* tok, const std::string& from, const std::string& to); + void invalidPointerCastError(const Token* tok, const std::string& from, const std::string& to, bool inconclusive); void dangerousUsageStrtolError(const Token *tok); void sprintfOverlappingDataError(const Token *tok, const std::string &varname); void udivError(const Token *tok, bool inconclusive); @@ -331,7 +331,7 @@ private: c.sizeofForNumericParameterError(0); c.coutCerrMisusageError(0, "cout"); c.doubleFreeError(0, "varname"); - c.invalidPointerCastError(0, "float", "double"); + c.invalidPointerCastError(0, "float", "double", false); // style/warning c.cstyleCastError(0); diff --git a/test/testother.cpp b/test/testother.cpp index 490b9b27e..6fc8707bb 100644 --- a/test/testother.cpp +++ b/test/testother.cpp @@ -783,7 +783,7 @@ private: ASSERT_EQUALS("", errout.str()); } - void checkInvalidPointerCast(const char code[], bool portability = false) { + void checkInvalidPointerCast(const char code[], bool portability = false, bool inconclusive = false) { // Clear the error buffer.. errout.str(""); @@ -791,6 +791,7 @@ private: settings.addEnabled("style"); if (portability) settings.addEnabled("portability"); + settings.inconclusive = inconclusive; // Tokenize.. Tokenizer tokenizer(&settings, this); @@ -849,6 +850,16 @@ private: "}"); ASSERT_EQUALS("[test.cpp:2]: (warning) Casting between double* and float* which have an incompatible binary data representation\n", errout.str()); + checkInvalidPointerCast("void test(float* data) {\n" // #3639 + " f.write((char*)data,sizeof(float));\n" + "}", true, false); + ASSERT_EQUALS("", errout.str()); + + checkInvalidPointerCast("void test(float* data) {\n" + " f.write((char*)data,sizeof(float));\n" + "}", true, true); + ASSERT_EQUALS("[test.cpp:2]: (portability) Casting from float* to char* might be not portable due to different binary data representations on different platforms\n", errout.str()); + checkInvalidPointerCast("long long* test(float* f) {\n" " return (long long*)f;\n"