Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -572,7 +572,7 @@ $(libcppdir)/checkstl.o: lib/checkstl.cpp lib/addoninfo.h lib/astutils.h lib/che
$(libcppdir)/checkstring.o: lib/checkstring.cpp lib/addoninfo.h lib/astutils.h lib/check.h lib/checkstring.h lib/config.h lib/errortypes.h lib/library.h lib/mathlib.h lib/platform.h lib/settings.h lib/smallvector.h lib/sourcelocation.h lib/standards.h lib/suppressions.h lib/symboldatabase.h lib/templatesimplifier.h lib/token.h lib/tokenize.h lib/tokenlist.h lib/utils.h lib/vfvalue.h
$(CXX) ${INCLUDE_FOR_LIB} $(CPPFLAGS) $(CXXFLAGS) -c -o $@ $(libcppdir)/checkstring.cpp

$(libcppdir)/checktype.o: lib/checktype.cpp lib/addoninfo.h lib/check.h lib/checktype.h lib/config.h lib/errortypes.h lib/library.h lib/mathlib.h lib/platform.h lib/settings.h lib/sourcelocation.h lib/standards.h lib/suppressions.h lib/symboldatabase.h lib/templatesimplifier.h lib/token.h lib/tokenize.h lib/tokenlist.h lib/utils.h lib/valueflow.h lib/vfvalue.h
$(libcppdir)/checktype.o: lib/checktype.cpp lib/addoninfo.h lib/astutils.h lib/check.h lib/checktype.h lib/config.h lib/errortypes.h lib/library.h lib/mathlib.h lib/platform.h lib/settings.h lib/smallvector.h lib/sourcelocation.h lib/standards.h lib/suppressions.h lib/symboldatabase.h lib/templatesimplifier.h lib/token.h lib/tokenize.h lib/tokenlist.h lib/utils.h lib/valueflow.h lib/vfvalue.h
$(CXX) ${INCLUDE_FOR_LIB} $(CPPFLAGS) $(CXXFLAGS) -c -o $@ $(libcppdir)/checktype.cpp

$(libcppdir)/checkuninitvar.o: lib/checkuninitvar.cpp lib/addoninfo.h lib/astutils.h lib/check.h lib/checknullpointer.h lib/checkuninitvar.h lib/color.h lib/config.h lib/ctu.h lib/errorlogger.h lib/errortypes.h lib/library.h lib/mathlib.h lib/platform.h lib/settings.h lib/smallvector.h lib/sourcelocation.h lib/standards.h lib/suppressions.h lib/symboldatabase.h lib/templatesimplifier.h lib/token.h lib/tokenize.h lib/tokenlist.h lib/utils.h lib/vfvalue.h
Expand Down
36 changes: 36 additions & 0 deletions lib/astutils.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -3725,3 +3725,39 @@ bool isExhaustiveSwitch(const Token *startbrace)

return false;
}

bool isUnreachableOperand(const Token *tok)
{
for (;;)
{
const Token *parent = tok->astParent();
if (!parent)
break;

if (parent->isBinaryOp()) {
const bool left = tok == parent->astOperand1();
const Token *sibling = left ? parent->astOperand2() : parent->astOperand1();

// logical and
if (Token::simpleMatch(parent, "&&") && !left && sibling->hasKnownIntValue()
&& !sibling->getKnownIntValue())
return true;

// logical or
if (Token::simpleMatch(parent, "||") && !left && sibling->hasKnownIntValue()
&& sibling->getKnownIntValue())
return true;

// ternary
if (Token::simpleMatch(parent, ":") && Token::simpleMatch(parent->astParent(), "?")) {
const Token *condTok = parent->astParent()->astOperand1();
if (condTok->hasKnownIntValue() && static_cast<bool>(condTok->getKnownIntValue()) != left)
return true;
}
}

tok = parent;
}

return false;
}
2 changes: 2 additions & 0 deletions lib/astutils.h
Original file line number Diff line number Diff line change
Expand Up @@ -448,4 +448,6 @@ bool isUnevaluated(const Token *tok);

bool isExhaustiveSwitch(const Token *startbrace);

bool isUnreachableOperand(const Token *tok);

#endif // astutilsH
7 changes: 7 additions & 0 deletions lib/checktype.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@
//---------------------------------------------------------------------------
#include "checktype.h"

#include "astutils.h"
#include "errortypes.h"
#include "mathlib.h"
#include "platform.h"
Expand Down Expand Up @@ -437,19 +438,25 @@ void CheckType::checkFloatToIntegerOverflow()

// Explicit cast
if (Token::Match(tok, "( %name%") && tok->astOperand1() && !tok->astOperand2()) {
if (isUnreachableOperand(tok))
continue;
vtint = tok->valueType();
vtfloat = tok->astOperand1()->valueType();
checkFloatToIntegerOverflow(tok, vtint, vtfloat, tok->astOperand1()->values());
}

// Assignment
else if (tok->str() == "=" && tok->astOperand1() && tok->astOperand2()) {
if (isUnreachableOperand(tok))
continue;
vtint = tok->astOperand1()->valueType();
vtfloat = tok->astOperand2()->valueType();
checkFloatToIntegerOverflow(tok, vtint, vtfloat, tok->astOperand2()->values());
}

else if (tok->str() == "return" && tok->astOperand1() && tok->astOperand1()->valueType() && tok->astOperand1()->valueType()->isFloat()) {
if (isUnreachableOperand(tok))
continue;
const Scope *scope = tok->scope();
while (scope && scope->type != Scope::ScopeType::eLambda && scope->type != Scope::ScopeType::eFunction)
scope = scope->nestedIn;
Expand Down
2 changes: 1 addition & 1 deletion oss-fuzz/Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -259,7 +259,7 @@ $(libcppdir)/checkstl.o: ../lib/checkstl.cpp ../lib/addoninfo.h ../lib/astutils.
$(libcppdir)/checkstring.o: ../lib/checkstring.cpp ../lib/addoninfo.h ../lib/astutils.h ../lib/check.h ../lib/checkstring.h ../lib/config.h ../lib/errortypes.h ../lib/library.h ../lib/mathlib.h ../lib/platform.h ../lib/settings.h ../lib/smallvector.h ../lib/sourcelocation.h ../lib/standards.h ../lib/suppressions.h ../lib/symboldatabase.h ../lib/templatesimplifier.h ../lib/token.h ../lib/tokenize.h ../lib/tokenlist.h ../lib/utils.h ../lib/vfvalue.h
$(CXX) ${LIB_FUZZING_ENGINE} $(CPPFLAGS) $(CXXFLAGS) -c -o $@ $(libcppdir)/checkstring.cpp

$(libcppdir)/checktype.o: ../lib/checktype.cpp ../lib/addoninfo.h ../lib/check.h ../lib/checktype.h ../lib/config.h ../lib/errortypes.h ../lib/library.h ../lib/mathlib.h ../lib/platform.h ../lib/settings.h ../lib/sourcelocation.h ../lib/standards.h ../lib/suppressions.h ../lib/symboldatabase.h ../lib/templatesimplifier.h ../lib/token.h ../lib/tokenize.h ../lib/tokenlist.h ../lib/utils.h ../lib/valueflow.h ../lib/vfvalue.h
$(libcppdir)/checktype.o: ../lib/checktype.cpp ../lib/addoninfo.h ../lib/astutils.h ../lib/check.h ../lib/checktype.h ../lib/config.h ../lib/errortypes.h ../lib/library.h ../lib/mathlib.h ../lib/platform.h ../lib/settings.h ../lib/smallvector.h ../lib/sourcelocation.h ../lib/standards.h ../lib/suppressions.h ../lib/symboldatabase.h ../lib/templatesimplifier.h ../lib/token.h ../lib/tokenize.h ../lib/tokenlist.h ../lib/utils.h ../lib/valueflow.h ../lib/vfvalue.h
$(CXX) ${LIB_FUZZING_ENGINE} $(CPPFLAGS) $(CXXFLAGS) -c -o $@ $(libcppdir)/checktype.cpp

$(libcppdir)/checkuninitvar.o: ../lib/checkuninitvar.cpp ../lib/addoninfo.h ../lib/astutils.h ../lib/check.h ../lib/checknullpointer.h ../lib/checkuninitvar.h ../lib/color.h ../lib/config.h ../lib/ctu.h ../lib/errorlogger.h ../lib/errortypes.h ../lib/library.h ../lib/mathlib.h ../lib/platform.h ../lib/settings.h ../lib/smallvector.h ../lib/sourcelocation.h ../lib/standards.h ../lib/suppressions.h ../lib/symboldatabase.h ../lib/templatesimplifier.h ../lib/token.h ../lib/tokenize.h ../lib/tokenlist.h ../lib/utils.h ../lib/vfvalue.h
Expand Down
38 changes: 38 additions & 0 deletions test/testtype.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -495,6 +495,44 @@ class TestType : public TestFixture {
" return 1234.5;\n"
"}", settingsDefault);
ASSERT_EQUALS("[test.cpp:2]: (error) Undefined behaviour: float () to integer conversion overflow.\n", removeFloat(errout_str()));

checkP("#define TEST(b, f) b ? 5000 : (unsigned short)f\n" // #11685
"void f()\n"
"{\n"
" unsigned short u = TEST(true, 75000.0);\n"
"}\n", settingsDefault);
ASSERT_EQUALS("", errout_str());

checkP("#define TEST(b, f) b ? 5000 : (unsigned short)f\n"
"void f()\n"
"{\n"
" unsigned short u = TEST(false, 75000.0);\n"
"}\n", settingsDefault);
ASSERT_EQUALS("[test.cpp:4]: (error) Undefined behaviour: float () to integer conversion overflow.\n", removeFloat(errout_str()));

check( "bool f(unsigned short x);\n"
"bool g() {\n"
" return false && f((unsigned short)75000.0);\n"
"}\n", settingsDefault);
ASSERT_EQUALS("", errout_str());

check( "bool f(unsigned short x);\n"
"bool g() {\n"
" return true && f((unsigned short)75000.0);\n"
"}\n", settingsDefault);
ASSERT_EQUALS("[test.cpp:3]: (error) Undefined behaviour: float () to integer conversion overflow.\n", removeFloat(errout_str()));

check( "bool f(unsigned short x);\n"
"bool g() {\n"
" return true || f((unsigned short)75000.0);\n"
"}\n", settingsDefault);
ASSERT_EQUALS("", errout_str());

check( "bool f(unsigned short x);\n"
"bool g() {\n"
" return false || f((unsigned short)75000.0);\n"
"}\n", settingsDefault);
ASSERT_EQUALS("[test.cpp:3]: (error) Undefined behaviour: float () to integer conversion overflow.\n", removeFloat(errout_str()));
}

void integerOverflow() { // #11794
Expand Down
Loading