diff --git a/lib/checktype.cpp b/lib/checktype.cpp index 822d961a6..3b87f51c1 100644 --- a/lib/checktype.cpp +++ b/lib/checktype.cpp @@ -248,10 +248,16 @@ void CheckType::checkSignConversion() continue; // Todo: properly handle casts, function calls, etc const Variable *var = tok1->variable(); if (var && tok1->getValueLE(-1,_settings)) { - bool signedvar = false; + bool signedvar = true; // assume that variable is signed since it can have a negative value for (const Token *type = var->typeStartToken();; type = type->next()) { - if (type->isSigned()) { - signedvar = true; + if (type->isUnsigned()) { + signedvar = false; + break; + } + if (type->isSigned()) + break; + if (type->isName() && !Token::Match(type, "char|short|int|long|const")) { + signedvar = false; break; } if (type == var->typeEndToken()) diff --git a/test/testtype.cpp b/test/testtype.cpp index d9e0dd66b..9378a14c7 100644 --- a/test/testtype.cpp +++ b/test/testtype.cpp @@ -105,11 +105,17 @@ private: } void signConversion() { - check("unsigned int f1(signed int x, unsigned int y) {" + check("unsigned int f1(signed int x, unsigned int y) {" // x is signed " return x * y;\n" "}\n" "void f2() { f1(-4,4); }"); ASSERT_EQUALS("[test.cpp:1]: (warning) Suspicious code: sign conversion of x in calculation, even though x can have a negative value\n", errout.str()); + + check("unsigned int f1(int x) {" // x has no signedness, but it can have the value -1 so assume it's signed + " return x * 5U;\n" + "}\n" + "void f2() { f1(-4); }"); + ASSERT_EQUALS("[test.cpp:1]: (warning) Suspicious code: sign conversion of x in calculation, even though x can have a negative value\n", errout.str()); } };