LCOV - code coverage report
Current view: top level - test - testpostfixoperator.cpp (source / functions) Hit Total Coverage
Test: lcov.info Lines: 92 92 100.0 %
Date: 2024-04-28 12:00:40 Functions: 14 14 100.0 %
Legend: Lines: hit not hit

          Line data    Source code
       1             : /*
       2             :  * Cppcheck - A tool for static C/C++ code analysis
       3             :  * Copyright (C) 2007-2024 Cppcheck team.
       4             :  *
       5             :  * This program is free software: you can redistribute it and/or modify
       6             :  * it under the terms of the GNU General Public License as published by
       7             :  * the Free Software Foundation, either version 3 of the License, or
       8             :  * (at your option) any later version.
       9             :  *
      10             :  * This program is distributed in the hope that it will be useful,
      11             :  * but WITHOUT ANY WARRANTY; without even the implied warranty of
      12             :  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
      13             :  * GNU General Public License for more details.
      14             :  *
      15             :  * You should have received a copy of the GNU General Public License
      16             :  * along with this program.  If not, see <http://www.gnu.org/licenses/>.
      17             :  */
      18             : 
      19             : #include "checkpostfixoperator.h"
      20             : #include "errortypes.h"
      21             : #include "fixture.h"
      22             : #include "helpers.h"
      23             : #include "settings.h"
      24             : 
      25             : class TestPostfixOperator : public TestFixture {
      26             : public:
      27           1 :     TestPostfixOperator() : TestFixture("TestPostfixOperator") {}
      28             : 
      29             : private:
      30           1 :     const Settings settings = settingsBuilder().severity(Severity::performance).build();
      31             : 
      32             : #define check(code) check_(code, __FILE__, __LINE__)
      33          30 :     void check_(const char code[], const char* file, int line) {
      34             :         // Tokenize..
      35          60 :         SimpleTokenizer tokenizer(settings, *this);
      36          30 :         ASSERT_LOC(tokenizer.tokenize(code), file, line);
      37             : 
      38             :         // Check for postfix operators..
      39          60 :         CheckPostfixOperator checkPostfixOperator(&tokenizer, &settings, this);
      40          30 :         checkPostfixOperator.postfixOperator();
      41          30 :     }
      42             : 
      43           1 :     void run() override {
      44           1 :         TEST_CASE(testsimple);
      45           1 :         TEST_CASE(testfor);
      46           1 :         TEST_CASE(testvolatile);
      47           1 :         TEST_CASE(testiterator);
      48           1 :         TEST_CASE(test2168);
      49           1 :         TEST_CASE(pointerSimplest);
      50           1 :         TEST_CASE(pointer);   // #2321 - postincrement of pointer is OK
      51           1 :         TEST_CASE(testtemplate); // #4686
      52           1 :         TEST_CASE(testmember);
      53           1 :         TEST_CASE(testcomma);
      54           1 :         TEST_CASE(testauto); // #8350
      55           1 :     }
      56             : 
      57           1 :     void testsimple() {
      58           1 :         check("int main()\n"
      59             :               "{\n"
      60             :               "    unsigned int k(0);\n"
      61             :               "    std::cout << k << std::endl;\n"
      62             :               "    k++;\n"
      63             :               "    std::cout << k << std::endl;\n"
      64             :               "    if(k) {\n"
      65             :               "        k++;\n"
      66             :               "    }\n"
      67             :               "    std::cout << k << std::endl;\n"
      68             :               "    k--;\n"
      69             :               "    std::cout << k << std::endl;\n"
      70             :               "    return 0;\n"
      71             :               "}");
      72           1 :         ASSERT_EQUALS("", errout_str());
      73             : 
      74           1 :         check("class K {};"
      75             :               "int main()\n"
      76             :               "{\n"
      77             :               "    K k(0);\n"
      78             :               "    std::cout << k << std::endl;\n"
      79             :               "    k++;\n"
      80             :               "    std::cout << k << std::endl;\n"
      81             :               "    return 0;\n"
      82             :               "}");
      83           1 :         ASSERT_EQUALS("[test.cpp:5]: (performance) Prefer prefix ++/-- operators for non-primitive types.\n", errout_str());
      84             : 
      85           1 :         check("struct K {};"
      86             :               "void foo()\n"
      87             :               "{\n"
      88             :               "    K k(0);\n"
      89             :               "    k++;\n"
      90             :               "}");
      91           1 :         ASSERT_EQUALS("[test.cpp:4]: (performance) Prefer prefix ++/-- operators for non-primitive types.\n", errout_str());
      92             : 
      93           1 :         check("struct K {};\n"
      94             :               "void foo(K& k)\n"
      95             :               "{\n"
      96             :               "    k++;\n"
      97             :               "}");
      98           1 :         ASSERT_EQUALS("[test.cpp:4]: (performance) Prefer prefix ++/-- operators for non-primitive types.\n", errout_str());
      99             : 
     100           1 :         check("union K {};"
     101             :               "void foo()\n"
     102             :               "{\n"
     103             :               "    K k(0);\n"
     104             :               "    k++;\n"
     105             :               "}");
     106           1 :         ASSERT_EQUALS("[test.cpp:4]: (performance) Prefer prefix ++/-- operators for non-primitive types.\n", errout_str());
     107             : 
     108           1 :         check("class K {};"
     109             :               "int main()\n"
     110             :               "{\n"
     111             :               "    K k(1);\n"
     112             :               "    std::cout << k << std::endl;\n"
     113             :               "    if(k) {\n"
     114             :               "        k++;\n"
     115             :               "    }\n"
     116             :               "    std::cout << k << std::endl;\n"
     117             :               "    return 0;\n"
     118             :               "}");
     119           1 :         ASSERT_EQUALS("[test.cpp:6]: (performance) Prefer prefix ++/-- operators for non-primitive types.\n", errout_str());
     120             : 
     121           1 :         check("class K {};"
     122             :               "int main()\n"
     123             :               "{\n"
     124             :               "    K k(1);\n"
     125             :               "    std::cout << k << std::endl;\n"
     126             :               "    if(k) {\n"
     127             :               "        ++k;\n"
     128             :               "    }\n"
     129             :               "    k++;\n"
     130             :               "    std::cout << k << std::endl;\n"
     131             :               "    return 0;\n"
     132             :               "}");
     133           1 :         ASSERT_EQUALS("[test.cpp:8]: (performance) Prefer prefix ++/-- operators for non-primitive types.\n", errout_str());
     134             : 
     135             : 
     136           1 :         check("class K {};"
     137             :               "int main()\n"
     138             :               "{\n"
     139             :               "    K k(0);\n"
     140             :               "    std::cout << k << std::endl;\n"
     141             :               "    k--;\n"
     142             :               "    std::cout << k << std::endl;\n"
     143             :               "    return 0;\n"
     144             :               "}");
     145           1 :         ASSERT_EQUALS("[test.cpp:5]: (performance) Prefer prefix ++/-- operators for non-primitive types.\n", errout_str());
     146             : 
     147           1 :         check("class K {};"
     148             :               "int main()\n"
     149             :               "{\n"
     150             :               "    K k(0);\n"
     151             :               "    std::cout << k << std::endl;\n"
     152             :               "    ++k;\n"
     153             :               "    std::cout << k << std::endl;\n"
     154             :               "    return 0;\n"
     155             :               "}");
     156           1 :         ASSERT_EQUALS("", errout_str());
     157             : 
     158           1 :         check("class K {};"
     159             :               "int main()\n"
     160             :               "{\n"
     161             :               "    K k(0);\n"
     162             :               "    std::cout << k << std::endl;\n"
     163             :               "    --k;\n"
     164             :               "    std::cout << k << std::endl;\n"
     165             :               "    return 0;\n"
     166             :               "}");
     167           1 :         ASSERT_EQUALS("", errout_str());
     168             : 
     169             :         // #9042
     170           1 :         check("template <class T>\n"
     171             :               "class c {\n"
     172             :               "    int i = 0;\n"
     173             :               "    c() { i--; }\n"
     174             :               "};\n"
     175             :               "template <class T>\n"
     176             :               "class s {};\n"
     177             :               "using BOOL = char;");
     178           1 :         ASSERT_EQUALS("", errout_str());
     179             :     }
     180             : 
     181           1 :     void testfor() {
     182           1 :         check("int main()\n"
     183             :               "{\n"
     184             :               "    for ( unsigned int i=0; i <= 10; i++) {\n"
     185             :               "         std::cout << i << std::endl;\n"
     186             :               "    }\n"
     187             :               "    return 0;\n"
     188             :               "}");
     189           1 :         ASSERT_EQUALS("", errout_str());
     190             : 
     191           1 :         check("class K {};\n"
     192             :               "int main()\n"
     193             :               "{\n"
     194             :               "    for ( K i(0); i <= 10; i++) {\n"
     195             :               "         std::cout << i << std::endl;\n"
     196             :               "    }\n"
     197             :               "    return 0;\n"
     198             :               "}");
     199           1 :         ASSERT_EQUALS("[test.cpp:4]: (performance) Prefer prefix ++/-- operators for non-primitive types.\n", errout_str());
     200             : 
     201           1 :         check("class K {};\n"
     202             :               "int main()\n"
     203             :               "{\n"
     204             :               "    for ( K i(0); i <= 10; ++i) {\n"
     205             :               "         std::cout << i << std::endl;\n"
     206             :               "    }\n"
     207             :               "    return 0;\n"
     208             :               "}");
     209           1 :         ASSERT_EQUALS("", errout_str());
     210             : 
     211           1 :         check("class K {};\n"
     212             :               "int main()\n"
     213             :               "{\n"
     214             :               "    for ( K i(10); i > 1; i--) {\n"
     215             :               "         std::cout << i << std::endl;\n"
     216             :               "    }\n"
     217             :               "    return 0;\n"
     218             :               "}");
     219           1 :         ASSERT_EQUALS("[test.cpp:4]: (performance) Prefer prefix ++/-- operators for non-primitive types.\n", errout_str());
     220             : 
     221           1 :         check("class K {};\n"
     222             :               "int main(int argc, char *argv[])\n"
     223             :               "{\n"
     224             :               "    for ( K i=10; i > 1; --i) {\n"
     225             :               "         std::cout << i << std::endl;\n"
     226             :               "    }\n"
     227             :               "    return 0;\n"
     228             :               "}");
     229           1 :         ASSERT_EQUALS("", errout_str());
     230             : 
     231             : 
     232             :     }
     233             : 
     234           1 :     void testvolatile() {
     235           1 :         check("class K {};\n"
     236             :               "int main()\n"
     237             :               "{\n"
     238             :               "    volatile K k(0);\n"
     239             :               "    std::cout << k << std::endl;\n"
     240             :               "    k++;\n"
     241             :               "    std::cout << k << std::endl;\n"
     242             :               "    return 0;\n"
     243             :               "}");
     244           1 :         ASSERT_EQUALS("[test.cpp:6]: (performance) Prefer prefix ++/-- operators for non-primitive types.\n", errout_str());
     245             :     }
     246             : 
     247           1 :     void testiterator() {
     248           1 :         check("class Base {};\n"
     249             :               "int main() {\n"
     250             :               "    std::vector<Base*> v;\n"
     251             :               "    v.push_back(new Base());\n"
     252             :               "    v.push_back(new Base());\n"
     253             :               "    for (std::vector<Base*>::iterator i=v.begin(); i!=v.end(); i++) {\n"
     254             :               "        ;;\n"
     255             :               "    }\n"
     256             :               "    v.clear();\n"
     257             :               "    return 0;\n"
     258             :               "}");
     259           1 :         ASSERT_EQUALS("[test.cpp:6]: (performance) Prefer prefix ++/-- operators for non-primitive types.\n", errout_str());
     260             : 
     261           1 :         check("int main() {\n"
     262             :               "    std::vector<int> v;\n"
     263             :               "    std::vector<int>::iterator it;\n"
     264             :               "    for( int i=0; i < 10; ++i ) v.push_back(i);\n"
     265             :               "        unsigned int total = 0;\n"
     266             :               "    it = v.begin();\n"
     267             :               "    while( it != v.end() ) {\n"
     268             :               "       total += *it;\n"
     269             :               "       it++;\n"
     270             :               "    }\n"
     271             :               "    return 0;\n"
     272             :               "}");
     273           1 :         ASSERT_EQUALS("[test.cpp:9]: (performance) Prefer prefix ++/-- operators for non-primitive types.\n", errout_str());
     274             : 
     275           1 :         check("int main() {\n"
     276             :               "    std::vector<int> v;\n"
     277             :               "    std::vector<int>::const_iterator it;\n"
     278             :               "    for( int i=0; i < 10; ++i ) v.push_back(i);\n"
     279             :               "        unsigned int total = 0;\n"
     280             :               "    it = v.begin();\n"
     281             :               "    while( it != v.end() ) {\n"
     282             :               "       it++;\n"
     283             :               "    }\n"
     284             :               "    return 0;\n"
     285             :               "}");
     286           1 :         ASSERT_EQUALS("[test.cpp:8]: (performance) Prefer prefix ++/-- operators for non-primitive types.\n", errout_str());
     287             : 
     288           1 :         check("int main() {\n"
     289             :               "    std::vector<int> v;\n"
     290             :               "    std::vector<int>::iterator it;\n"
     291             :               "    for( int i=0; i < 10; ++i ) v.push_back(i);\n"
     292             :               "        unsigned int total = 0;\n"
     293             :               "    std::vector<int>::reverse_iterator rit;\n"
     294             :               "    rit= v.rend();\n"
     295             :               "    while( rit != v.rbegin() ) {\n"
     296             :               "       rit--;\n"
     297             :               "    }\n"
     298             :               "    return 0;\n"
     299             :               "}");
     300           1 :         ASSERT_EQUALS("[test.cpp:9]: (performance) Prefer prefix ++/-- operators for non-primitive types.\n", errout_str());
     301             : 
     302             :     }
     303             : 
     304           1 :     void test2168() {
     305           1 :         check("--> declare allocator lock here\n"
     306             :               "int main(){}");
     307           1 :         ASSERT_EQUALS("", errout_str());
     308             :     }
     309             : 
     310           1 :     void pointerSimplest() {
     311           1 :         check("void f(int* p){\n"
     312             :               "    p++;\n"
     313             :               "    std::cout << *p;\n"
     314             :               "}");
     315           1 :         ASSERT_EQUALS("", errout_str());
     316             :     }
     317             : 
     318           1 :     void pointer() {
     319           1 :         check("static struct class * ab;\n"
     320             :               "int * p;\n"
     321             :               "\n"
     322             :               "void f() {\n"
     323             :               "    p++;\n"
     324             :               "}");
     325           1 :         ASSERT_EQUALS("", errout_str());
     326             :     }
     327             : 
     328           1 :     void testtemplate() {
     329           1 :         check("bool foo() {\n"
     330             :               "    std::vector<FilterConfigCacheEntry>::iterator aIter(aImport.begin());\n"
     331             :               "    aIter++;\n"
     332             :               "}");
     333           1 :         ASSERT_EQUALS("[test.cpp:3]: (performance) Prefer prefix ++/-- operators for non-primitive types.\n", errout_str());
     334             :     }
     335             : 
     336           1 :     void testmember() {
     337           1 :         check("bool foo() {\n"
     338             :               "    class A {}; class B {A a;};\n"
     339             :               "    B b;\n"
     340             :               "    b.a++;\n"
     341             :               "}");
     342           1 :         ASSERT_EQUALS("[test.cpp:4]: (performance) Prefer prefix ++/-- operators for non-primitive types.\n", errout_str());
     343             : 
     344           1 :         check("bool foo() {\n"
     345             :               "    class A {}; class B {A a;};\n"
     346             :               "    B b;\n"
     347             :               "    foo(b.a++);\n"
     348             :               "}");
     349           1 :         ASSERT_EQUALS("", errout_str());
     350             :     }
     351             : 
     352           1 :     void testcomma() {
     353           1 :         check("bool foo(int i) {\n"
     354             :               "    class A {};\n"
     355             :               "    A a;\n"
     356             :               "    i++, a++;\n"
     357             :               "}");
     358           1 :         ASSERT_EQUALS("[test.cpp:4]: (performance) Prefer prefix ++/-- operators for non-primitive types.\n", errout_str());
     359             : 
     360           1 :         check("bool foo(int i) {\n"
     361             :               "    class A {};\n"
     362             :               "    A a;\n"
     363             :               "    foo(i, a++);\n"
     364             :               "    foo(a++, i);\n"
     365             :               "}");
     366           1 :         ASSERT_EQUALS("", errout_str());
     367             :     }
     368             : 
     369           1 :     void testauto() { // #8350
     370           1 :         check("enum class Color { Red = 0, Green = 1, };\n"
     371             :               "int fun(const Color color) {\n"
     372             :               "    auto a = 0;\n"
     373             :               "    for (auto i = static_cast<int>(color); i < 10; i++) {\n"
     374             :               "        a += i;\n"
     375             :               "    }\n"
     376             :               "    return a;\n"
     377             :               "}");
     378           1 :         ASSERT_EQUALS("", errout_str());
     379             :     }
     380             : };
     381             : 
     382             : REGISTER_TEST(TestPostfixOperator)

Generated by: LCOV version 1.14