diff --git a/lib/templatesimplifier.cpp b/lib/templatesimplifier.cpp index 2ddad9ba5..d6b844179 100644 --- a/lib/templatesimplifier.cpp +++ b/lib/templatesimplifier.cpp @@ -212,39 +212,6 @@ void TemplateSimplifier::cleanupAfterSimplify() } } -void TemplateSimplifier::removeTemplates() -{ - for (Token *tok = mTokenList.front(); tok; tok = tok->next()) { - if (!Token::simpleMatch(tok, "template <")) - continue; - if (tok->previous() && !Token::Match(tok->previous(), "[;}]")) - continue; - Token *endToken = tok; - while (nullptr != (endToken = endToken->next())) { - if (endToken->str() == ";") - break; - if (Token::Match(endToken, "[})]]")) { - endToken = nullptr; - break; - } - if (Token::Match(endToken, "[<([]") && endToken->link()) - endToken = endToken->link(); - else if (endToken->str() == "{") { - endToken = endToken->link(); - break; - } - } - if (!endToken) - continue; - Token::eraseTokens(tok, endToken); - tok = endToken; - tok->deletePrevious(); - if (tok->str() == "}") { - tok->str(";"); - tok->link(nullptr); - } - } -} void TemplateSimplifier::checkComplicatedSyntaxErrorsInTemplates() { diff --git a/lib/templatesimplifier.h b/lib/templatesimplifier.h index f973ada52..0f09b7b53 100644 --- a/lib/templatesimplifier.h +++ b/lib/templatesimplifier.h @@ -53,12 +53,6 @@ public: */ void cleanupAfterSimplify(); - /** - * Remove templates, can be used after the simplifications to remove - * the templates that failed to be expanded. - */ - void removeTemplates(); - /** */ void checkComplicatedSyntaxErrorsInTemplates(); diff --git a/lib/tokenize.cpp b/lib/tokenize.cpp index 796a94fcf..541888957 100644 --- a/lib/tokenize.cpp +++ b/lib/tokenize.cpp @@ -4444,8 +4444,6 @@ bool Tokenizer::simplifyTokenList1(const char FileName[]) // this function will just fix so that the syntax is corrected. validate(); // #6847 - invalid code mTemplateSimplifier->cleanupAfterSimplify(); - if (!mSettings->checkUnusedTemplates) - mTemplateSimplifier->removeTemplates(); } // Simplify pointer to standard types (C only) diff --git a/test/testautovariables.cpp b/test/testautovariables.cpp index 464c36432..0f99a5472 100644 --- a/test/testautovariables.cpp +++ b/test/testautovariables.cpp @@ -1869,9 +1869,8 @@ private: " std::vector v;\n" " return by_value(v.begin());\n" "}\n"); - TODO_ASSERT_EQUALS( + ASSERT_EQUALS( "[test.cpp:7] -> [test.cpp:7] -> [test.cpp:3] -> [test.cpp:3] -> [test.cpp:6] -> [test.cpp:7]: (error) Returning object that points to local variable 'v' that will be invalid when returning.\n", - "", errout.str()); check("auto by_ref(int& x) {\n" diff --git a/test/testcondition.cpp b/test/testcondition.cpp index 4c49c34ed..5f988761b 100644 --- a/test/testcondition.cpp +++ b/test/testcondition.cpp @@ -2079,6 +2079,9 @@ private: check("void f1(const std::string &s) { if(s.empty()) if(s.size() > 42) {}} "); ASSERT_EQUALS("[test.cpp:1] -> [test.cpp:1]: (warning) Opposite inner 'if' condition leads to a dead code block.\n", errout.str()); + check("template void f1(const T &s) { if(s.size() > 42) if(s.empty()) {}} "); + ASSERT_EQUALS("[test.cpp:1] -> [test.cpp:1]: (warning) Opposite inner 'if' condition leads to a dead code block.\n", errout.str()); + check("void f2(const std::wstring &s) { if(s.empty()) if(s.size() > 42) {}} "); ASSERT_EQUALS("[test.cpp:1] -> [test.cpp:1]: (warning) Opposite inner 'if' condition leads to a dead code block.\n", errout.str()); diff --git a/test/testconstructors.cpp b/test/testconstructors.cpp index 83e94e6a3..fcce2e1fa 100644 --- a/test/testconstructors.cpp +++ b/test/testconstructors.cpp @@ -347,6 +347,16 @@ private: " int x;\n" "};"); ASSERT_EQUALS("", errout.str()); + + check("template struct A {\n" + " A() : x(0) { }\n" + " A(const T & t) : x(t.x) { }\n" + "private:\n" + " int x;\n" + " int y;\n" + "};"); + ASSERT_EQUALS("[test.cpp:2]: (warning) Member variable 'A::y' is not initialized in the constructor.\n" + "[test.cpp:3]: (warning) Member variable 'A::y' is not initialized in the constructor.\n", errout.str()); } void simple7() { // ticket #4531 diff --git a/test/testgarbage.cpp b/test/testgarbage.cpp index a06270a07..df970843c 100644 --- a/test/testgarbage.cpp +++ b/test/testgarbage.cpp @@ -1365,7 +1365,7 @@ private: ); // #3449 - ASSERT_EQUALS(";\n" + ASSERT_EQUALS("template < typename T > struct A ;\n" "struct B { template < typename T > struct C } ;\n" "{ } ;", checkCode("template struct A;\n" diff --git a/test/testnullpointer.cpp b/test/testnullpointer.cpp index d77aea52f..6922e11df 100644 --- a/test/testnullpointer.cpp +++ b/test/testnullpointer.cpp @@ -67,6 +67,7 @@ private: TEST_CASE(nullpointer24); // #5082 fp: chained assignment TEST_CASE(nullpointer25); // #5061 TEST_CASE(nullpointer26); // #3589 + TEST_CASE(nullpointer27); // #6568 TEST_CASE(nullpointer28); // #6491 TEST_CASE(nullpointer30); // #6392 TEST_CASE(nullpointer31); // #8482 @@ -1321,6 +1322,20 @@ private: ASSERT_EQUALS("", errout.str()); } + void nullpointer27() { // #6568 + check("template\n" + "class Foo {\n" + " Foo& operator = ( Type* );\n" + "};\n" + "template\n" + "Foo& Foo::operator = ( Type* pointer_ ) {\n" + " pointer_=NULL;\n" + " *pointer_=0;\n" + " return *this;\n" + "}"); + ASSERT_EQUALS("[test.cpp:8]: (error) Null pointer dereference: pointer_\n", errout.str()); + } + void nullpointer28() { // #6491 check("typedef struct { int value; } S;\n" "int f(const S *s) { \n" diff --git a/test/testother.cpp b/test/testother.cpp index 0cc34b68d..b4410d11e 100644 --- a/test/testother.cpp +++ b/test/testother.cpp @@ -5004,6 +5004,11 @@ private: ASSERT_EQUALS("", errout.str()); } + check("template void foo(unsigned int x) {\n" + "if (x <= 0);\n" + "}\n"); + ASSERT_EQUALS("[test.cpp:2]: (style) Checking if unsigned expression 'x' is less than zero.\n", errout.str()); + // #8836 check("uint32_t value = 0xFUL;\n" "void f() {\n" @@ -7451,11 +7456,12 @@ private: } void forwardAndUsed() { - check("void f(Foo && foo) {\n" - " g(std::forward(foo));\n" - " Foo s = foo;\n" + check("template\n" + "void f(T && t) {\n" + " g(std::forward(t));\n" + " T s = t;\n" "}"); - ASSERT_EQUALS("[test.cpp:3]: (warning) Access of forwarded variable 'foo'.\n", errout.str()); + ASSERT_EQUALS("[test.cpp:4]: (warning) Access of forwarded variable 't'.\n", errout.str()); } void funcArgNamesDifferent() { diff --git a/test/testsimplifytemplate.cpp b/test/testsimplifytemplate.cpp index 335dd7ae7..6351f1d51 100644 --- a/test/testsimplifytemplate.cpp +++ b/test/testsimplifytemplate.cpp @@ -38,7 +38,6 @@ private: void run() OVERRIDE { settings.addEnabled("portability"); - settings.checkUnusedTemplates = true; TEST_CASE(template1); TEST_CASE(template2); @@ -192,8 +191,6 @@ private: TEST_CASE(templateTypeDeduction2); TEST_CASE(simplifyTemplateArgs); - - TEST_CASE(removeTemplates); } std::string tok(const char code[], bool debugwarnings = false, Settings::PlatformType type = Settings::Native) { @@ -389,8 +386,7 @@ private: // The expected result.. const char expected[] = "class A ; " - "void f ( ) { A a ; } " - "template < typename T > class B { void g ( ) { A < T > b ; b = A < T > :: h ( ) ; } } ; " + "void f ( ) { A a ; } ; " "class A { } ;"; ASSERT_EQUALS(expected, tok(code)); @@ -1389,7 +1385,6 @@ private: "template C3::C3(const C3 &v) { C1 c1; }\n" "C3 c3;"; const char exp[] = "struct C1 ; " - "template < class T > void f ( ) { x = y ? ( C1 < int > :: allocate ( 1 ) ) : 0 ; } " "class C3 ; " "C3 c3 ; " "class C3 { } ; " @@ -2397,7 +2392,6 @@ private: "template class Fred {};\n" "ObjectCache _cache;"; const char exp[] = "class ObjectCache ; " - "template < typename T > class Fred { } ; " "ObjectCache _cache ; " "class ObjectCache { } ;"; ASSERT_EQUALS(exp, tok(code)); @@ -2505,8 +2499,7 @@ private: "template < class T > struct Unconst < const T & > { } ; " "template < class T > struct Unconst < T * const > { } ; " "template < class T1 , class T2 > struct type_equal { enum Anonymous0 { value = 0 } ; } ; " - "template < class T > struct type_equal < T , T > { enum Anonymous1 { value = 1 } ; } ; " - "template < class T > struct template_is_const { enum Anonymous2 { value = ! type_equal < T , Unconst < T > :: type > :: value } ; } ;"; + "template < class T > struct type_equal < T , T > { enum Anonymous1 { value = 1 } ; } ;"; ASSERT_EQUALS(exp1, tok(code1)); } @@ -2746,7 +2739,7 @@ private: const char code[] = "class Fred {\n" " template explicit Fred(T t) { }\n" "}"; - ASSERT_EQUALS("class Fred { template < class T > explicit Fred ( T t ) { } }", tok(code)); + ASSERT_EQUALS("class Fred { }", tok(code)); // #3532 const char code2[] = "class Fred {\n" @@ -3569,26 +3562,6 @@ private: ASSERT_EQUALS("foo = false ; foo ;", tok("template foo = N; foo < ( 1 - 1) ? true : false >;")); } - std::string removeTemplates(const char code[]) { - Settings settings2; - settings2.checkUnusedTemplates = false; - - errout.str(""); - - Tokenizer tokenizer(&settings2, this); - - std::istringstream istr(code); - tokenizer.tokenize(istr, "test.cpp"); - - return tokenizer.tokens()->stringifyList(0, true); - } - - void removeTemplates() { - // #9057 - ASSERT_EQUALS(";", removeTemplates("template using foo = enable_if_t() && sizeof(int) == 4, int>;\n" - "template > struct bar {};\n" - "template using baz = bar;\n")); - } }; REGISTER_TEST(TestSimplifyTemplate) diff --git a/test/testsimplifytokens.cpp b/test/testsimplifytokens.cpp index 200fb160f..a2398605a 100644 --- a/test/testsimplifytokens.cpp +++ b/test/testsimplifytokens.cpp @@ -43,9 +43,7 @@ private: LOAD_LIB_2(settings_std.library, "std.cfg"); LOAD_LIB_2(settings_windows.library, "windows.cfg"); settings0.addEnabled("portability"); - settings0.checkUnusedTemplates = true; settings1.addEnabled("style"); - settings1.checkUnusedTemplates = true; settings_windows.addEnabled("portability"); // Make sure the Tokenizer::simplifyTokenList works. diff --git a/test/testsimplifytypedef.cpp b/test/testsimplifytypedef.cpp index da14bfb2f..4ed3a6d67 100644 --- a/test/testsimplifytypedef.cpp +++ b/test/testsimplifytypedef.cpp @@ -41,9 +41,6 @@ private: void run() OVERRIDE { settings0.addEnabled("style"); settings2.addEnabled("style"); - settings0.checkUnusedTemplates = true; - settings1.checkUnusedTemplates = true; - settings2.checkUnusedTemplates = true; TEST_CASE(simplifyTypedef1) TEST_CASE(simplifyTypedef2) @@ -2530,8 +2527,7 @@ private: "template struct c; " "template struct d { enum { e = c::f }; };"; const char exp [] = "class a ; " - "template < long , class > struct c ; " - "template < int g > struct d { enum Anonymous0 { e = c < g , int ( a :: * ) > :: f } ; } ;"; + "template < long , class > struct c ;"; ASSERT_EQUALS(exp, tok(code, false)); } diff --git a/test/testsimplifyusing.cpp b/test/testsimplifyusing.cpp index 88623ca9e..4df2dc7ff 100644 --- a/test/testsimplifyusing.cpp +++ b/test/testsimplifyusing.cpp @@ -41,9 +41,6 @@ private: void run() OVERRIDE { settings0.addEnabled("style"); settings2.addEnabled("style"); - settings0.checkUnusedTemplates = true; - settings1.checkUnusedTemplates = true; - settings2.checkUnusedTemplates = true; TEST_CASE(simplifyUsing1); TEST_CASE(simplifyUsing2); @@ -492,8 +489,7 @@ private: "class c { " "int i ; i = 0 ; " "c ( ) { i -- ; } " - "} ; " - "template < class T > class s { } ;"; + "} ;"; ASSERT_EQUALS(exp, tok(code, true, Settings::Win64)); } diff --git a/test/testsymboldatabase.cpp b/test/testsymboldatabase.cpp index 7dcd216cd..91918f14c 100644 --- a/test/testsymboldatabase.cpp +++ b/test/testsymboldatabase.cpp @@ -106,7 +106,6 @@ private: void run() OVERRIDE { LOAD_LIB_2(settings1.library, "std.cfg"); - settings1.checkUnusedTemplates = true; settings2.platform(Settings::Unspecified); TEST_CASE(array); diff --git a/test/testtokenize.cpp b/test/testtokenize.cpp index 750cc2d32..668c41730 100644 --- a/test/testtokenize.cpp +++ b/test/testtokenize.cpp @@ -47,10 +47,6 @@ private: void run() OVERRIDE { LOAD_LIB_2(settings_windows.library, "windows.cfg"); - settings0.checkUnusedTemplates = true; - settings1.checkUnusedTemplates = true; - settings2.checkUnusedTemplates = true; - TEST_CASE(tokenize1); TEST_CASE(tokenize2); TEST_CASE(tokenize3); diff --git a/test/testutils.h b/test/testutils.h index e40e4a3d5..5ce5a7d3f 100644 --- a/test/testutils.h +++ b/test/testutils.h @@ -32,7 +32,6 @@ private: public: explicit givenACodeSampleToTokenize(const char sample[], bool createOnly = false, bool cpp = true) : _tokenizer(&_settings, 0) { - _settings.checkUnusedTemplates = true; std::istringstream iss(sample); if (createOnly) _tokenizer.list.createTokens(iss, cpp ? "test.cpp" : "test.c"); diff --git a/test/testvarid.cpp b/test/testvarid.cpp index d01939083..4dada499c 100644 --- a/test/testvarid.cpp +++ b/test/testvarid.cpp @@ -200,7 +200,6 @@ private: errout.str(""); Settings settings; - settings.checkUnusedTemplates = true; settings.platform(Settings::Unix64); settings.standards.c = Standards::C89; settings.standards.cpp = Standards::CPP11; @@ -220,7 +219,6 @@ private: errout.str(""); Settings settings; - settings.checkUnusedTemplates = true; settings.platform(Settings::Unix64); settings.standards.c = Standards::C89; settings.standards.cpp = Standards::CPP11;