2011-10-28 22:39:46 +02:00
/*
* Cppcheck - A tool for static C / C + + code analysis
2023-01-28 10:16:34 +01:00
* Copyright ( C ) 2007 - 2023 Cppcheck team .
2011-10-28 22:39:46 +02:00
*
* 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 < http : //www.gnu.org/licenses/>.
*/
2014-05-18 19:48:43 +02:00
# ifdef CHECK_INTERNAL
2011-10-28 22:39:46 +02:00
# include "tokenize.h"
# include "checkinternal.h"
2023-01-27 08:18:32 +01:00
# include "fixture.h"
2023-03-02 21:50:14 +01:00
# include "settings.h"
2011-10-28 22:39:46 +02:00
2022-08-19 18:23:15 +02:00
# include <sstream>
2011-10-28 22:39:46 +02:00
class TestInternal : public TestFixture {
public :
2021-08-07 20:51:18 +02:00
TestInternal ( ) : TestFixture ( " TestInternal " ) { }
2011-10-28 22:39:46 +02:00
private :
2015-10-07 18:33:57 +02:00
Settings settings ;
2022-02-10 23:02:24 +01:00
void run ( ) override {
2015-10-07 18:33:57 +02:00
settings . addEnabled ( " internal " ) ;
2020-04-21 17:27:51 +02:00
TEST_CASE ( simplePatternInTokenMatch ) ;
TEST_CASE ( complexPatternInTokenSimpleMatch ) ;
TEST_CASE ( simplePatternSquareBrackets ) ;
TEST_CASE ( simplePatternAlternatives ) ;
TEST_CASE ( missingPercentCharacter ) ;
TEST_CASE ( unknownPattern ) ;
TEST_CASE ( redundantNextPrevious ) ;
2015-01-31 12:56:54 +01:00
TEST_CASE ( internalError ) ;
2014-07-02 15:50:49 +02:00
TEST_CASE ( orInComplexPattern ) ;
2014-12-30 14:21:18 +01:00
TEST_CASE ( extraWhitespace ) ;
2017-05-18 15:21:29 +02:00
TEST_CASE ( checkRedundantTokCheck ) ;
2011-10-28 22:39:46 +02:00
}
2021-11-29 07:34:39 +01:00
# define check(code) check_(code, __FILE__, __LINE__)
void check_ ( const char code [ ] , const char * file , int line ) {
2011-10-28 22:39:46 +02:00
// Clear the error buffer..
errout . str ( " " ) ;
// Tokenize..
Tokenizer tokenizer ( & settings , this ) ;
2012-07-16 13:17:14 +02:00
std : : istringstream istr ( code ) ;
2021-11-29 07:34:39 +01:00
ASSERT_LOC ( tokenizer . tokenize ( istr , " test.cpp " ) , file , line ) ;
2011-10-28 22:39:46 +02:00
// Check..
2023-08-18 12:03:50 +02:00
runChecks < CheckInternal > ( tokenizer , this ) ;
2011-10-28 22:39:46 +02:00
}
2014-11-20 14:20:09 +01:00
void simplePatternInTokenMatch ( ) {
2011-10-28 22:39:46 +02:00
check ( " void f() { \n "
" const Token *tok; \n "
" Token::Match(tok, \" ; \" ); \n "
" } " ) ;
ASSERT_EQUALS ( " [test.cpp:3]: (warning) Found simple pattern inside Token::Match() call: \" ; \" \n " , errout . str ( ) ) ;
check ( " void f() { \n "
" const Token *tok; \n "
" Token::Match(tok, \" %type% \" ); \n "
" } " ) ;
ASSERT_EQUALS ( " " , errout . str ( ) ) ;
2015-01-28 19:48:36 +01:00
check ( " void f() { \n "
" const Token *tok; \n "
" Token::Match(tok, \" %or% \" ); \n "
" } " ) ;
ASSERT_EQUALS ( " [test.cpp:3]: (warning) Found simple pattern inside Token::Match() call: \" %or% \" \n " , errout . str ( ) ) ;
2011-10-28 22:39:46 +02:00
check ( " void f() { \n "
" const Token *tok; \n "
" Token::findmatch(tok, \" ; \" ); \n "
" } " ) ;
ASSERT_EQUALS ( " [test.cpp:3]: (warning) Found simple pattern inside Token::findmatch() call: \" ; \" \n " , errout . str ( ) ) ;
}
2014-11-20 14:20:09 +01:00
void complexPatternInTokenSimpleMatch ( ) {
2011-10-28 22:39:46 +02:00
check ( " void f() { \n "
" const Token *tok; \n "
" Token::simpleMatch(tok, \" %type% \" ); \n "
" } " ) ;
ASSERT_EQUALS ( " [test.cpp:3]: (error) Found complex pattern inside Token::simpleMatch() call: \" %type% \" \n " , errout . str ( ) ) ;
check ( " void f() { \n "
" const Token *tok; \n "
" Token::findsimplematch(tok, \" %type% \" ); \n "
" } " ) ;
ASSERT_EQUALS ( " [test.cpp:3]: (error) Found complex pattern inside Token::findsimplematch() call: \" %type% \" \n " , errout . str ( ) ) ;
check ( " void f() { \n "
" const Token *tok; \n "
" Token::findsimplematch(tok, \" } !!else \" ); \n "
" } " ) ;
ASSERT_EQUALS ( " [test.cpp:3]: (error) Found complex pattern inside Token::findsimplematch() call: \" } !!else \" \n " , errout . str ( ) ) ;
check ( " void f() { \n "
" const Token *tok; \n "
" Token::findsimplematch(tok, \" foobar \" ); \n "
" } " ) ;
ASSERT_EQUALS ( " " , errout . str ( ) ) ;
2014-05-18 20:39:52 +02:00
check ( " void f() { \n "
" const Token *tok; \n "
" Token::findsimplematch(tok, \" % \" ); \n "
" } " ) ;
ASSERT_EQUALS ( " " , errout . str ( ) ) ;
2011-10-28 22:39:46 +02:00
}
2014-11-20 14:20:09 +01:00
void simplePatternSquareBrackets ( ) {
2011-10-28 22:39:46 +02:00
check ( " void f() { \n "
" const Token *tok; \n "
" Token::simpleMatch(tok, \" [ \" ); \n "
" } " ) ;
ASSERT_EQUALS ( " " , errout . str ( ) ) ;
check ( " void f() { \n "
" const Token *tok; \n "
" Token::simpleMatch(tok, \" [ ] \" ); \n "
" } " ) ;
ASSERT_EQUALS ( " " , errout . str ( ) ) ;
check ( " void f() { \n "
" const Token *tok; \n "
" Token::simpleMatch(tok, \" [] \" ); \n "
" } " ) ;
ASSERT_EQUALS ( " [test.cpp:3]: (error) Found complex pattern inside Token::simpleMatch() call: \" [] \" \n " , errout . str ( ) ) ;
check ( " void f() { \n "
" const Token *tok; \n "
" Token::simpleMatch(tok, \" ] [ \" ); \n "
" } " ) ;
ASSERT_EQUALS ( " " , errout . str ( ) ) ;
check ( " void f() { \n "
" const Token *tok; \n "
" Token::simpleMatch(tok, \" ] [ [abc] \" ); \n "
" } " ) ;
ASSERT_EQUALS ( " [test.cpp:3]: (error) Found complex pattern inside Token::simpleMatch() call: \" ] [ [abc] \" \n " , errout . str ( ) ) ;
check ( " void f() { \n "
" const Token *tok; \n "
" Token::simpleMatch(tok, \" [.,;] \" ); \n "
" } " ) ;
ASSERT_EQUALS ( " [test.cpp:3]: (error) Found complex pattern inside Token::simpleMatch() call: \" [.,;] \" \n " , errout . str ( ) ) ;
}
2014-11-20 14:20:09 +01:00
void simplePatternAlternatives ( ) {
2011-10-28 22:39:46 +02:00
check ( " void f() { \n "
" const Token *tok; \n "
" Token::simpleMatch(tok, \" || \" ); \n "
" } " ) ;
ASSERT_EQUALS ( " " , errout . str ( ) ) ;
check ( " void f() { \n "
" const Token *tok; \n "
" Token::simpleMatch(tok, \" | \" ); \n "
" } " ) ;
ASSERT_EQUALS ( " " , errout . str ( ) ) ;
check ( " void f() { \n "
" const Token *tok; \n "
" Token::simpleMatch(tok, \" a|b \" ); \n "
" } " ) ;
ASSERT_EQUALS ( " [test.cpp:3]: (error) Found complex pattern inside Token::simpleMatch() call: \" a|b \" \n " , errout . str ( ) ) ;
check ( " void f() { \n "
" const Token *tok; \n "
" Token::simpleMatch(tok, \" |= 0 \" ); \n "
" } " ) ;
ASSERT_EQUALS ( " " , errout . str ( ) ) ;
check ( " void f() { \n "
" const Token *tok; \n "
" Token::simpleMatch(tok, \" | 0 ) \" ); \n "
" } " ) ;
ASSERT_EQUALS ( " " , errout . str ( ) ) ;
}
2011-10-29 12:13:46 +02:00
2014-11-20 14:20:09 +01:00
void missingPercentCharacter ( ) {
2011-10-29 12:13:46 +02:00
check ( " void f() { \n "
" const Token *tok; \n "
" Token::Match(tok, \" %type% \" ); \n "
" } " ) ;
ASSERT_EQUALS ( " " , errout . str ( ) ) ;
check ( " void f() { \n "
" const Token *tok; \n "
" Token::Match(tok, \" foo %type% bar \" ); \n "
" } " ) ;
ASSERT_EQUALS ( " " , errout . str ( ) ) ;
// Missing % at the end of string
check ( " void f() { \n "
" const Token *tok; \n "
" Token::Match(tok, \" %type \" ); \n "
" } " ) ;
ASSERT_EQUALS ( " [test.cpp:3]: (error) Missing percent end character in Token::Match() pattern: \" %type \" \n " , errout . str ( ) ) ;
// Missing % in the middle of a pattern
check ( " void f() { \n "
" const Token *tok; \n "
" Token::Match(tok, \" foo %type bar \" ); \n "
" } " ) ;
ASSERT_EQUALS ( " [test.cpp:3]: (error) Missing percent end character in Token::Match() pattern: \" foo %type bar \" \n " , errout . str ( ) ) ;
// Bei quiet on single %
check ( " void f() { \n "
" const Token *tok; \n "
" Token::Match(tok, \" foo % %type% bar \" ); \n "
" } " ) ;
ASSERT_EQUALS ( " " , errout . str ( ) ) ;
check ( " void f() { \n "
" const Token *tok; \n "
" Token::Match(tok, \" foo % %type % bar \" ); \n "
" } " ) ;
2012-07-11 17:45:16 +02:00
ASSERT_EQUALS ( " [test.cpp:3]: (error) Missing percent end character in Token::Match() pattern: \" foo % %type % bar \" \n "
2012-07-21 15:54:04 +02:00
" [test.cpp:3]: (error) Unknown pattern used: \" %type % \" \n " , errout . str ( ) ) ;
2011-10-29 12:13:46 +02:00
// Find missing % also in 'alternatives' pattern
check ( " void f() { \n "
" const Token *tok; \n "
" Token::Match(tok, \" foo|%type|bar \" ); \n "
" } " ) ;
2015-01-31 12:56:54 +01:00
ASSERT_EQUALS ( " [test.cpp:3]: (error) Missing percent end character in Token::Match() pattern: \" foo|%type|bar \" \n "
2014-01-05 21:15:41 +01:00
, errout . str ( ) ) ;
2011-10-29 12:13:46 +02:00
// Make sure we don't take %or% for a broken %oror%
check ( " void f() { \n "
" const Token *tok; \n "
" Token::Match(tok, \" foo|%oror%|bar \" ); \n "
" } " ) ;
ASSERT_EQUALS ( " " , errout . str ( ) ) ;
}
2012-05-01 14:36:42 +02:00
2014-11-20 14:20:09 +01:00
void unknownPattern ( ) {
2012-07-11 17:45:16 +02:00
check ( " void f() { \n "
" Token::Match(tok, \" %typ% \" ); \n "
" } " ) ;
2012-07-21 15:54:04 +02:00
ASSERT_EQUALS ( " [test.cpp:2]: (error) Unknown pattern used: \" %typ% \" \n " , errout . str ( ) ) ;
2012-07-11 17:45:16 +02:00
// Make sure we don't take %or% for a broken %oror%
check ( " void f() { \n "
" Token::Match(tok, \" %type% \" ); \n "
" } " ) ;
ASSERT_EQUALS ( " " , errout . str ( ) ) ;
}
2014-11-20 14:20:09 +01:00
void redundantNextPrevious ( ) {
2012-09-07 12:36:40 +02:00
check ( " void f() { \n "
" return tok->next()->previous(); \n "
" } " ) ;
ASSERT_EQUALS ( " [test.cpp:2]: (style) Call to 'Token::next()' followed by 'Token::previous()' can be simplified. \n " , errout . str ( ) ) ;
check ( " void f() { \n "
" return tok->tokAt(5)->previous(); \n "
" } " ) ;
ASSERT_EQUALS ( " [test.cpp:2]: (style) Call to 'Token::tokAt()' followed by 'Token::previous()' can be simplified. \n " , errout . str ( ) ) ;
check ( " void f() { \n "
" return tok->previous()->linkAt(5); \n "
" } " ) ;
ASSERT_EQUALS ( " [test.cpp:2]: (style) Call to 'Token::previous()' followed by 'Token::linkAt()' can be simplified. \n " , errout . str ( ) ) ;
check ( " void f() { \n "
" tok->next()->previous(foo); \n "
" } " ) ;
ASSERT_EQUALS ( " " , errout . str ( ) ) ;
check ( " void f() { \n "
" return tok->next()->next(); \n " // Simplification won't make code much shorter/readable
" } " ) ;
ASSERT_EQUALS ( " " , errout . str ( ) ) ;
check ( " void f() { \n "
" return tok->previous()->previous(); \n " // Simplification won't make code much shorter/readable
" } " ) ;
ASSERT_EQUALS ( " " , errout . str ( ) ) ;
check ( " void f() { \n "
" return tok->tokAt(foo+bar)->tokAt(); \n "
" } " ) ;
ASSERT_EQUALS ( " [test.cpp:2]: (style) Call to 'Token::tokAt()' followed by 'Token::tokAt()' can be simplified. \n " , errout . str ( ) ) ;
check ( " void f() { \n "
" return tok->tokAt(foo+bar)->link(); \n "
" } " ) ;
ASSERT_EQUALS ( " [test.cpp:2]: (style) Call to 'Token::tokAt()' followed by 'Token::link()' can be simplified. \n " , errout . str ( ) ) ;
check ( " void f() { \n "
" tok->tokAt(foo+bar)->link(foo); \n "
" } " ) ;
ASSERT_EQUALS ( " " , errout . str ( ) ) ;
check ( " void f() { \n "
" return tok->next()->next()->str(); \n "
" } " ) ;
ASSERT_EQUALS ( " [test.cpp:2]: (style) Call to 'Token::next()' followed by 'Token::str()' can be simplified. \n " , errout . str ( ) ) ;
2016-08-25 16:09:06 +02:00
check ( " void f() { \n "
" return tok->previous()->next()->str(); \n "
" } " ) ;
ASSERT_EQUALS ( " [test.cpp:2]: (style) Call to 'Token::previous()' followed by 'Token::next()' can be simplified. \n " , errout . str ( ) ) ;
2012-09-07 12:36:40 +02:00
}
2014-11-20 14:20:09 +01:00
void internalError ( ) {
2012-05-01 14:36:42 +02:00
// Make sure cppcheck does not raise an internal error of Token::Match ( Ticket #3727 )
check ( " class DELPHICLASS X; \n "
" class Y { \n "
" private: \n "
" X* x; \n "
" }; \n "
" class Z { \n "
" char z[1]; \n "
" Z(){ \n "
2012-09-05 19:46:44 +02:00
" z[0] = 0; \n "
2012-05-01 14:36:42 +02:00
" } \n "
2013-03-20 15:36:16 +01:00
" }; " ) ;
2012-05-01 14:36:42 +02:00
ASSERT_EQUALS ( " " , errout . str ( ) ) ;
}
2014-01-05 21:15:41 +01:00
2014-11-20 14:20:09 +01:00
void orInComplexPattern ( ) {
2014-07-02 15:50:49 +02:00
check ( " void f() { \n "
" Token::Match(tok, \" || \" ); \n "
" } " ) ;
ASSERT_EQUALS ( " [test.cpp:2]: (error) Token::Match() pattern \" || \" contains \" || \" or \" | \" . Replace it by \" %oror% \" or \" %or% \" . \n " , errout . str ( ) ) ;
check ( " void f() { \n "
" Token::Match(tok, \" | \" ); \n "
" } " ) ;
ASSERT_EQUALS ( " [test.cpp:2]: (error) Token::Match() pattern \" | \" contains \" || \" or \" | \" . Replace it by \" %oror% \" or \" %or% \" . \n " , errout . str ( ) ) ;
check ( " void f() { \n "
" Token::Match(tok, \" [|+-] \" ); \n "
" } " ) ;
ASSERT_EQUALS ( " " , errout . str ( ) ) ;
check ( " void f() { \n "
" Token::Match(tok, \" foo | bar \" ); \n "
" } " ) ;
ASSERT_EQUALS ( " [test.cpp:2]: (error) Token::Match() pattern \" foo | bar \" contains \" || \" or \" | \" . Replace it by \" %oror% \" or \" %or% \" . \n " , errout . str ( ) ) ;
check ( " void f() { \n "
" Token::Match(tok, \" foo | \" ); \n "
" } " ) ;
ASSERT_EQUALS ( " [test.cpp:2]: (error) Token::Match() pattern \" foo | \" contains \" || \" or \" | \" . Replace it by \" %oror% \" or \" %or% \" . \n " , errout . str ( ) ) ;
check ( " void f() { \n "
" Token::Match(tok, \" bar foo| \" ); \n "
" } " ) ;
ASSERT_EQUALS ( " " , errout . str ( ) ) ;
}
2014-12-30 14:21:18 +01:00
void extraWhitespace ( ) {
// whitespace at the end
check ( " void f() { \n "
" const Token *tok; \n "
" Token::Match(tok, \" %str% \" ); \n "
" } " ) ;
ASSERT_EQUALS ( " [test.cpp:3]: (warning) Found extra whitespace inside Token::Match() call: \" %str% \" \n " , errout . str ( ) ) ;
// whitespace at the begin
check ( " void f() { \n "
" const Token *tok; \n "
" Token::Match(tok, \" %str% \" ); \n "
" } " ) ;
ASSERT_EQUALS ( " [test.cpp:3]: (warning) Found extra whitespace inside Token::Match() call: \" %str% \" \n " , errout . str ( ) ) ;
// two whitespaces or more
check ( " void f() { \n "
" const Token *tok; \n "
" Token::Match(tok, \" %str% bar \" ); \n "
" } " ) ;
ASSERT_EQUALS ( " [test.cpp:3]: (warning) Found extra whitespace inside Token::Match() call: \" %str% bar \" \n " , errout . str ( ) ) ;
// test simpleMatch
check ( " void f() { \n "
" const Token *tok; \n "
" Token::simpleMatch(tok, \" foobar \" ); \n "
" } " ) ;
ASSERT_EQUALS ( " [test.cpp:3]: (warning) Found extra whitespace inside Token::simpleMatch() call: \" foobar \" \n " , errout . str ( ) ) ;
// test findmatch
check ( " void f() { \n "
" const Token *tok; \n "
" Token::findmatch(tok, \" %str% \" ); \n "
" } " ) ;
ASSERT_EQUALS ( " [test.cpp:3]: (warning) Found extra whitespace inside Token::findmatch() call: \" %str% \" \n " , errout . str ( ) ) ;
// test findsimplematch
check ( " void f() { \n "
" const Token *tok; \n "
" Token::findsimplematch(tok, \" foobar \" ); \n "
" } " ) ;
ASSERT_EQUALS ( " [test.cpp:3]: (warning) Found extra whitespace inside Token::findsimplematch() call: \" foobar \" \n " , errout . str ( ) ) ;
}
2017-05-18 15:21:29 +02:00
void checkRedundantTokCheck ( ) {
// findsimplematch
check ( " void f() { \n "
" const Token *tok; \n "
" if(tok && Token::findsimplematch(tok, \" foobar \" )) {}; \n "
" } " ) ;
2017-05-30 07:03:15 +02:00
ASSERT_EQUALS ( " [test.cpp:3]: (style) Unnecessary check of \" tok \" , match-function already checks if it is null. \n " , errout . str ( ) ) ;
2017-05-18 15:21:29 +02:00
// findmatch
check ( " void f() { \n "
" const Token *tok; \n "
" if(tok && Token::findmatch(tok, \" %str% foobar \" )) {}; \n "
" } " ) ;
2017-05-30 07:03:15 +02:00
ASSERT_EQUALS ( " [test.cpp:3]: (style) Unnecessary check of \" tok \" , match-function already checks if it is null. \n " , errout . str ( ) ) ;
2017-05-18 15:21:29 +02:00
// Match
check ( " void f() { \n "
" const Token *tok; \n "
" if(tok && Token::Match(tok, \" 5str% foobar \" )) {}; \n "
" } " ) ;
2017-05-30 07:03:15 +02:00
ASSERT_EQUALS ( " [test.cpp:3]: (style) Unnecessary check of \" tok \" , match-function already checks if it is null. \n " , errout . str ( ) ) ;
2017-05-18 15:21:29 +02:00
2019-04-06 07:44:44 +02:00
check ( " void f() { \n "
" const Token *tok; \n "
" if(a && tok && Token::Match(tok, \" 5str% foobar \" )) {}; \n "
" } " ) ;
ASSERT_EQUALS ( " [test.cpp:3]: (style) Unnecessary check of \" tok \" , match-function already checks if it is null. \n " , errout . str ( ) ) ;
check ( " void f() { \n "
" const Token *tok; \n "
" if(a && b && tok && Token::Match(tok, \" 5str% foobar \" )) {}; \n "
" } " ) ;
ASSERT_EQUALS ( " [test.cpp:3]: (style) Unnecessary check of \" tok \" , match-function already checks if it is null. \n " , errout . str ( ) ) ;
check ( " void f() { \n "
" const Token *tok; \n "
2019-10-04 12:30:11 +02:00
" if(a && b && c && tok && Token::Match(tok, \" 5str% foobar \" )) {}; \n "
2019-04-06 07:44:44 +02:00
" } " ) ;
ASSERT_EQUALS ( " [test.cpp:3]: (style) Unnecessary check of \" tok \" , match-function already checks if it is null. \n " , errout . str ( ) ) ;
check ( " void f() { \n "
" const Token *tok; \n "
2019-10-04 12:30:11 +02:00
" if(a && b && c && tok && d && Token::Match(tok, \" 5str% foobar \" )) {}; \n "
2019-04-06 07:44:44 +02:00
" } " ) ;
ASSERT_EQUALS ( " " , errout . str ( ) ) ;
2017-05-18 15:21:29 +02:00
// simpleMatch
check ( " void f() { \n "
" const Token *tok; \n "
" if(tok && Token::simpleMatch(tok, \" foobar \" )) {}; \n "
" } " ) ;
2017-05-30 07:03:15 +02:00
ASSERT_EQUALS ( " [test.cpp:3]: (style) Unnecessary check of \" tok \" , match-function already checks if it is null. \n " , errout . str ( ) ) ;
2017-05-18 15:21:29 +02:00
// Match
check ( " void f() { \n "
" const Token *tok; \n "
" if(tok->previous() && Token::Match(tok->previous(), \" 5str% foobar \" )) {}; \n "
" } " ) ;
2017-05-30 07:03:15 +02:00
ASSERT_EQUALS ( " [test.cpp:3]: (style) Unnecessary check of \" tok->previous() \" , match-function already checks if it is null. \n " , errout . str ( ) ) ;
2017-05-18 15:21:29 +02:00
// don't report:
// tok->previous() vs tok
check ( " void f() { \n "
" const Token *tok; \n "
" if(tok->previous() && Token::Match(tok, \" 5str% foobar \" )) {}; \n "
" } " ) ;
ASSERT_EQUALS ( " " , errout . str ( ) ) ;
// tok vs tok->previous())
check ( " void f() { \n "
" const Token *tok; \n "
" if(tok && Token::Match(tok->previous(), \" 5str% foobar \" )) {}; \n "
" } " ) ;
ASSERT_EQUALS ( " " , errout . str ( ) ) ;
// tok->previous() vs tok->previous()->previous())
check ( " void f() { \n "
" const Token *tok; \n "
" if(tok->previous() && Token::Match(tok->previous()->previous(), \" 5str% foobar \" )) {}; \n "
" } " ) ;
ASSERT_EQUALS ( " " , errout . str ( ) ) ;
2018-01-01 04:19:26 +01:00
// if a && fn(a) triggers, make sure !a || !fn(a) triggers as well!
check ( " void f() { \n "
" const Token *tok; \n "
" if(!tok || !Token::simpleMatch(tok, \" foobar \" )) {}; \n "
" } " ) ;
ASSERT_EQUALS ( " [test.cpp:3]: (style) Unnecessary check of \" tok \" , match-function already checks if it is null. \n " , errout . str ( ) ) ;
2019-04-06 07:44:44 +02:00
check ( " void f() { \n "
" const Token *tok; \n "
" if(a || !tok || !Token::simpleMatch(tok, \" foobar \" )) {}; \n "
" } " ) ;
ASSERT_EQUALS ( " [test.cpp:3]: (style) Unnecessary check of \" tok \" , match-function already checks if it is null. \n " , errout . str ( ) ) ;
2018-01-01 04:19:26 +01:00
// if tok || !Token::simpleMatch...
check ( " void f() { \n "
" const Token *tok; \n "
" if(tok || !Token::simpleMatch(tok, \" foobar \" )) {}; \n "
" } " ) ;
ASSERT_EQUALS ( " " , errout . str ( ) ) ;
// if !tok || Token::simpleMatch...
check ( " void f() { \n "
" const Token *tok; \n "
" if(!tok || Token::simpleMatch(tok, \" foobar \" )) {}; \n "
" } " ) ;
ASSERT_EQUALS ( " " , errout . str ( ) ) ;
// something more complex
check ( " void f() { \n "
" const Token *tok; \n "
" if(!tok->previous()->previous() || !Token::simpleMatch(tok->previous()->previous(), \" foobar \" )) {}; \n "
" } " ) ;
ASSERT_EQUALS ( " [test.cpp:3]: (style) Unnecessary check of \" tok->previous()->previous() \" , match-function already checks if it is null. \n " , errout . str ( ) ) ;
2017-05-18 15:21:29 +02:00
}
2011-10-28 22:39:46 +02:00
} ;
REGISTER_TEST ( TestInternal )
2011-10-29 12:47:12 +02:00
2014-05-18 19:48:43 +02:00
# endif // #ifdef CHECK_INTERNAL