diff --git a/Makefile b/Makefile index 71dfc132c..ce7edc279 100644 --- a/Makefile +++ b/Makefile @@ -115,7 +115,8 @@ MAN_SOURCE=man/cppcheck.1.xml ###### Object Files -LIBOBJ = $(SRCDIR)/check.o \ +LIBOBJ = $(SRCDIR)/astutils.o \ + $(SRCDIR)/check.o \ $(SRCDIR)/check64bit.o \ $(SRCDIR)/checkassert.o \ $(SRCDIR)/checkautovariables.o \ @@ -282,6 +283,9 @@ endif ###### Build +$(SRCDIR)/astutils.o: lib/astutils.cpp lib/cxx11emu.h lib/astutils.h lib/token.h lib/config.h lib/valueflow.h lib/mathlib.h + $(CXX) ${INCLUDE_FOR_LIB} $(CPPFLAGS) $(CFG) $(CXXFLAGS) $(UNDEF_STRICT_ANSI) -std=c++0x -c -o $(SRCDIR)/astutils.o $(SRCDIR)/astutils.cpp + $(SRCDIR)/check.o: lib/check.cpp lib/cxx11emu.h lib/check.h lib/config.h lib/token.h lib/valueflow.h lib/mathlib.h lib/tokenize.h lib/errorlogger.h lib/suppressions.h lib/tokenlist.h lib/settings.h lib/library.h lib/standards.h lib/timer.h $(CXX) ${INCLUDE_FOR_LIB} $(CPPFLAGS) $(CFG) $(CXXFLAGS) $(UNDEF_STRICT_ANSI) -std=c++0x -c -o $(SRCDIR)/check.o $(SRCDIR)/check.cpp @@ -333,7 +337,7 @@ $(SRCDIR)/checknullpointer.o: lib/checknullpointer.cpp lib/cxx11emu.h lib/checkn $(SRCDIR)/checkobsolescentfunctions.o: lib/checkobsolescentfunctions.cpp lib/cxx11emu.h lib/checkobsolescentfunctions.h lib/config.h lib/check.h lib/token.h lib/valueflow.h lib/mathlib.h lib/tokenize.h lib/errorlogger.h lib/suppressions.h lib/tokenlist.h lib/settings.h lib/library.h lib/standards.h lib/timer.h lib/symboldatabase.h lib/utils.h $(CXX) ${INCLUDE_FOR_LIB} $(CPPFLAGS) $(CFG) $(CXXFLAGS) $(UNDEF_STRICT_ANSI) -std=c++0x -c -o $(SRCDIR)/checkobsolescentfunctions.o $(SRCDIR)/checkobsolescentfunctions.cpp -$(SRCDIR)/checkother.o: lib/checkother.cpp lib/cxx11emu.h lib/checkother.h lib/config.h lib/check.h lib/token.h lib/valueflow.h lib/mathlib.h lib/tokenize.h lib/errorlogger.h lib/suppressions.h lib/tokenlist.h lib/settings.h lib/library.h lib/standards.h lib/timer.h lib/symboldatabase.h lib/utils.h +$(SRCDIR)/checkother.o: lib/checkother.cpp lib/cxx11emu.h lib/checkother.h lib/config.h lib/check.h lib/token.h lib/valueflow.h lib/mathlib.h lib/tokenize.h lib/errorlogger.h lib/suppressions.h lib/tokenlist.h lib/settings.h lib/library.h lib/standards.h lib/timer.h lib/astutils.h lib/symboldatabase.h lib/utils.h $(CXX) ${INCLUDE_FOR_LIB} $(CPPFLAGS) $(CFG) $(CXXFLAGS) $(UNDEF_STRICT_ANSI) -std=c++0x -c -o $(SRCDIR)/checkother.o $(SRCDIR)/checkother.cpp $(SRCDIR)/checkpostfixoperator.o: lib/checkpostfixoperator.cpp lib/cxx11emu.h lib/checkpostfixoperator.h lib/config.h lib/check.h lib/token.h lib/valueflow.h lib/mathlib.h lib/tokenize.h lib/errorlogger.h lib/suppressions.h lib/tokenlist.h lib/settings.h lib/library.h lib/standards.h lib/timer.h lib/symboldatabase.h lib/utils.h diff --git a/lib/astutils.cpp b/lib/astutils.cpp new file mode 100644 index 000000000..ba37e36c8 --- /dev/null +++ b/lib/astutils.cpp @@ -0,0 +1,102 @@ +/* + * Cppcheck - A tool for static C/C++ code analysis + * Copyright (C) 2007-2015 Daniel Marjamäki and Cppcheck team. + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + + +//--------------------------------------------------------------------------- +#include "astutils.h" + +bool astIsIntegral(const Token *tok, bool unknown) +{ + // TODO: handle arrays + if (tok->isNumber()) + return MathLib::isInt(tok->str()); + + if (tok->isName()) { + if (tok->variable()) + return tok->variable()->isIntegralType(); + + return unknown; + } + if (tok->str() == "(") { + // cast + if (Token::Match(tok, "( const| float|double )")) + return false; + + // Function call + if (tok->previous()->function()) { + if (Token::Match(tok->previous()->function()->retDef, "float|double")) + return false; + else if (Token::Match(tok->previous()->function()->retDef, "bool|char|short|int|long")) + return true; + } + + if (tok->strAt(-1) == "sizeof") + return true; + + return unknown; + } + + if (tok->astOperand2() && (tok->str() == "." || tok->str() == "::")) + return astIsIntegral(tok->astOperand2(), unknown); + + if (tok->astOperand1() && tok->str() != "?") + return astIsIntegral(tok->astOperand1(), unknown); + + return unknown; +} + +bool astIsFloat(const Token *tok, bool unknown) +{ + // TODO: handle arrays + if (tok->isNumber()) + return MathLib::isFloat(tok->str()); + + if (tok->isName()) { + if (tok->variable()) + return tok->variable()->isFloatingType(); + + return unknown; + } + if (tok->str() == "(") { + // cast + if (Token::Match(tok, "( const| float|double )")) + return true; + + // Function call + if (tok->previous()->function()) + return Token::Match(tok->previous()->function()->retDef, "float|double"); + + if (tok->strAt(-1) == "sizeof") + return false; + + return unknown; + } + + if (tok->astOperand2() && (tok->str() == "." || tok->str() == "::")) + return astIsFloat(tok->astOperand2(), unknown); + + if (tok->astOperand1() && tok->str() != "?" && astIsFloat(tok->astOperand1(), unknown)) + return true; + if (tok->astOperand2() && astIsFloat(tok->astOperand2(), unknown)) + return true; + + if (tok->isOp()) + return false; + + return unknown; +} diff --git a/lib/astutils.h b/lib/astutils.h new file mode 100644 index 000000000..aecbdb829 --- /dev/null +++ b/lib/astutils.h @@ -0,0 +1,33 @@ +/* + * Cppcheck - A tool for static C/C++ code analysis + * Copyright (C) 2007-2015 Daniel Marjamäki and Cppcheck team. + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + + +//--------------------------------------------------------------------------- +#ifndef astutilsH +#define astutilsH +//--------------------------------------------------------------------------- + +#include "symboldatabase.h" +#include "token.h" + +/** Is expression of integral type? */ +bool astIsIntegral(const Token *tok, bool unknown); +/** Is expression of floating point type? */ +bool astIsFloat(const Token *tok, bool unknown); + +#endif // astutilsH diff --git a/lib/checkcondition.cpp b/lib/checkcondition.cpp index b5b81ccb1..4da844e6f 100644 --- a/lib/checkcondition.cpp +++ b/lib/checkcondition.cpp @@ -21,6 +21,7 @@ //--------------------------------------------------------------------------- #include "checkcondition.h" +#include "astutils.h" #include "checkother.h" #include "symboldatabase.h" diff --git a/lib/checkother.cpp b/lib/checkother.cpp index 51340ca74..c5da3c42a 100644 --- a/lib/checkother.cpp +++ b/lib/checkother.cpp @@ -19,6 +19,7 @@ //--------------------------------------------------------------------------- #include "checkother.h" +#include "astutils.h" #include "mathlib.h" #include "symboldatabase.h" @@ -32,86 +33,6 @@ namespace { CheckOther instance; } -bool astIsIntegral(const Token *tok, bool unknown) -{ - // TODO: handle arrays - if (tok->isNumber()) - return MathLib::isInt(tok->str()); - - if (tok->isName()) { - if (tok->variable()) - return tok->variable()->isIntegralType(); - - return unknown; - } - if (tok->str() == "(") { - // cast - if (Token::Match(tok, "( const| float|double )")) - return false; - - // Function call - if (tok->previous()->function()) { - if (Token::Match(tok->previous()->function()->retDef, "float|double")) - return false; - else if (Token::Match(tok->previous()->function()->retDef, "bool|char|short|int|long")) - return true; - } - - if (tok->strAt(-1) == "sizeof") - return true; - - return unknown; - } - - if (tok->astOperand2() && (tok->str() == "." || tok->str() == "::")) - return astIsIntegral(tok->astOperand2(), unknown); - - if (tok->astOperand1() && tok->str() != "?") - return astIsIntegral(tok->astOperand1(), unknown); - - return unknown; -} - -bool astIsFloat(const Token *tok, bool unknown) -{ - // TODO: handle arrays - if (tok->isNumber()) - return MathLib::isFloat(tok->str()); - - if (tok->isName()) { - if (tok->variable()) - return tok->variable()->isFloatingType(); - - return unknown; - } - if (tok->str() == "(") { - // cast - if (Token::Match(tok, "( const| float|double )")) - return true; - - // Function call - if (tok->previous()->function()) - return Token::Match(tok->previous()->function()->retDef, "float|double"); - - if (tok->strAt(-1) == "sizeof") - return false; - - return unknown; - } - - if (tok->astOperand2() && (tok->str() == "." || tok->str() == "::")) - return astIsFloat(tok->astOperand2(), unknown); - - if (tok->astOperand1() && tok->str() != "?" && astIsFloat(tok->astOperand1(), unknown)) - return true; - if (tok->astOperand2() && astIsFloat(tok->astOperand2(), unknown)) - return true; - - if (tok->isOp()) - return false; - - return unknown; -} bool isConstExpression(const Token *tok, const std::set &constFunctions) { diff --git a/lib/checkother.h b/lib/checkother.h index 488103d19..6fe208a52 100644 --- a/lib/checkother.h +++ b/lib/checkother.h @@ -35,10 +35,6 @@ bool isSameExpression(const Tokenizer *tokenizer, const Token *tok1, const Token bool isWithoutSideEffects(const Tokenizer *tokenizer, const Token* tok); -/** Is expression of floating point type? */ -bool astIsFloat(const Token *tok, bool unknown); - - /// @addtogroup Checks /// @{ diff --git a/lib/lib.pri b/lib/lib.pri index bd71969b9..5761f4bb1 100644 --- a/lib/lib.pri +++ b/lib/lib.pri @@ -6,6 +6,7 @@ include($$PWD/../externals/tinyxml/tinyxml.pri) BASEPATH = ../lib/ INCLUDEPATH += ../externals/tinyxml HEADERS += $${BASEPATH}check.h \ + $${BASEPATH}astutils.h \ $${BASEPATH}check.h \ $${BASEPATH}check64bit.h \ $${BASEPATH}checkassert.h \ @@ -50,7 +51,8 @@ HEADERS += $${BASEPATH}check.h \ $${BASEPATH}valueflow.h \ -SOURCES += $${BASEPATH}check.cpp \ +SOURCES += $${BASEPATH}astutils.cpp \ + $${BASEPATH}check.cpp \ $${BASEPATH}check64bit.cpp \ $${BASEPATH}checkassert.cpp \ $${BASEPATH}checkautovariables.cpp \