LCOV - code coverage report
Current view: top level - test - testcondition.cpp (source / functions) Hit Total Coverage
Test: lcov.info Lines: 1608 1608 100.0 %
Date: 2024-04-28 12:00:40 Functions: 74 74 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 "checkcondition.h"
      20             : #include "errortypes.h"
      21             : #include "fixture.h"
      22             : #include "helpers.h"
      23             : #include "platform.h"
      24             : #include "settings.h"
      25             : #include "tokenize.h"
      26             : 
      27             : #include <limits>
      28             : #include <string>
      29             : #include <vector>
      30             : 
      31             : class TestCondition : public TestFixture {
      32             : public:
      33           2 :     TestCondition() : TestFixture("TestCondition") {}
      34             : 
      35             : private:
      36           1 :     const Settings settings0 = settingsBuilder().library("qt.cfg").library("std.cfg").severity(Severity::style).severity(Severity::warning).build();
      37           1 :     /*const*/ Settings settings1 = settingsBuilder().severity(Severity::style).severity(Severity::warning).build();
      38             : 
      39           1 :     void run() override {
      40           1 :         const char cfg[] = "<?xml version=\"1.0\"?>\n"
      41             :                            "<def>\n"
      42             :                            "  <function name=\"bar\"> <pure/> </function>\n"
      43             :                            "</def>";
      44           1 :         settings1 = settingsBuilder(settings1).libraryxml(cfg, sizeof(cfg)).build();
      45             : 
      46           1 :         TEST_CASE(assignAndCompare);   // assignment and comparison don't match
      47           1 :         TEST_CASE(mismatchingBitAnd);  // overlapping bitmasks
      48           1 :         TEST_CASE(comparison);         // CheckCondition::comparison test cases
      49           1 :         TEST_CASE(multicompare);       // mismatching comparisons
      50           1 :         TEST_CASE(overlappingElseIfCondition);  // overlapping conditions in if and else-if
      51           1 :         TEST_CASE(oppositeElseIfCondition); // opposite conditions in if and else-if
      52             : 
      53           1 :         TEST_CASE(checkBadBitmaskCheck);
      54             : 
      55           1 :         TEST_CASE(incorrectLogicOperator1);
      56           1 :         TEST_CASE(incorrectLogicOperator2);
      57           1 :         TEST_CASE(incorrectLogicOperator3);
      58           1 :         TEST_CASE(incorrectLogicOperator4);
      59           1 :         TEST_CASE(incorrectLogicOperator5); // complex expressions
      60           1 :         TEST_CASE(incorrectLogicOperator6); // char literals
      61           1 :         TEST_CASE(incorrectLogicOperator7); // opposite expressions: (expr || !expr)
      62           1 :         TEST_CASE(incorrectLogicOperator8); // !
      63           1 :         TEST_CASE(incorrectLogicOperator9);
      64           1 :         TEST_CASE(incorrectLogicOperator10); // enum
      65           1 :         TEST_CASE(incorrectLogicOperator11);
      66           1 :         TEST_CASE(incorrectLogicOperator12);
      67           1 :         TEST_CASE(incorrectLogicOperator13);
      68           1 :         TEST_CASE(incorrectLogicOperator14);
      69           1 :         TEST_CASE(incorrectLogicOperator15);
      70           1 :         TEST_CASE(incorrectLogicOperator16); // #10070
      71           1 :         TEST_CASE(incorrectLogicOperator17);
      72           1 :         TEST_CASE(secondAlwaysTrueFalseWhenFirstTrueError);
      73           1 :         TEST_CASE(incorrectLogicOp_condSwapping);
      74           1 :         TEST_CASE(testBug5895);
      75           1 :         TEST_CASE(testBug5309);
      76             : 
      77           1 :         TEST_CASE(modulo);
      78             : 
      79           1 :         TEST_CASE(oppositeInnerCondition);
      80           1 :         TEST_CASE(oppositeInnerConditionPointers);
      81           1 :         TEST_CASE(oppositeInnerConditionClass);
      82           1 :         TEST_CASE(oppositeInnerConditionUndeclaredVariable);
      83           1 :         TEST_CASE(oppositeInnerConditionAlias);
      84           1 :         TEST_CASE(oppositeInnerCondition2);
      85           1 :         TEST_CASE(oppositeInnerCondition3);
      86           1 :         TEST_CASE(oppositeInnerConditionAnd);
      87           1 :         TEST_CASE(oppositeInnerConditionOr);
      88           1 :         TEST_CASE(oppositeInnerConditionEmpty);
      89           1 :         TEST_CASE(oppositeInnerConditionFollowVar);
      90             : 
      91           1 :         TEST_CASE(identicalInnerCondition);
      92             : 
      93           1 :         TEST_CASE(identicalConditionAfterEarlyExit);
      94           1 :         TEST_CASE(innerConditionModified);
      95             : 
      96           1 :         TEST_CASE(clarifyCondition1);     // if (a = b() < 0)
      97           1 :         TEST_CASE(clarifyCondition2);     // if (a & b == c)
      98           1 :         TEST_CASE(clarifyCondition3);     // if (! a & b)
      99           1 :         TEST_CASE(clarifyCondition4);     // ticket #3110
     100           1 :         TEST_CASE(clarifyCondition5);     // #3609 CWinTraits<WS_CHILD|WS_VISIBLE>..
     101           1 :         TEST_CASE(clarifyCondition6);     // #3818
     102           1 :         TEST_CASE(clarifyCondition7);
     103           1 :         TEST_CASE(clarifyCondition8);
     104             : 
     105           1 :         TEST_CASE(alwaysTrue);
     106           1 :         TEST_CASE(alwaysTrueSymbolic);
     107           1 :         TEST_CASE(alwaysTrueInfer);
     108           1 :         TEST_CASE(alwaysTrueContainer);
     109           1 :         TEST_CASE(alwaysTrueLoop);
     110           1 :         TEST_CASE(alwaysTrueTryCatch);
     111           1 :         TEST_CASE(multiConditionAlwaysTrue);
     112           1 :         TEST_CASE(duplicateCondition);
     113             : 
     114           1 :         TEST_CASE(checkInvalidTestForOverflow);
     115           1 :         TEST_CASE(checkConditionIsAlwaysTrueOrFalseInsideIfWhile);
     116           1 :         TEST_CASE(alwaysTrueFalseInLogicalOperators);
     117           1 :         TEST_CASE(pointerAdditionResultNotNull);
     118           1 :         TEST_CASE(duplicateConditionalAssign);
     119             : 
     120           1 :         TEST_CASE(checkAssignmentInCondition);
     121           1 :         TEST_CASE(compareOutOfTypeRange);
     122           1 :         TEST_CASE(knownConditionCast); // #9976
     123           1 :         TEST_CASE(knownConditionIncrementLoop); // #9808
     124           1 :         TEST_CASE(knownConditionAfterBailout); // #12526
     125           1 :     }
     126             : 
     127             : #define check(...) check_(__FILE__, __LINE__, __VA_ARGS__)
     128         722 :     void check_(const char* file, int line, const char code[], const Settings &settings, const char* filename = "test.cpp") {
     129        2166 :         std::vector<std::string> files(1, filename);
     130        1444 :         Tokenizer tokenizer(settings, *this);
     131         722 :         PreprocessorHelper::preprocess(code, files, tokenizer, *this);
     132             : 
     133             :         // Tokenizer..
     134         723 :         ASSERT_LOC(tokenizer.simplifyTokens1(""), file, line);
     135             : 
     136             :         // Run checks..
     137         721 :         runChecks<CheckCondition>(tokenizer, this);
     138         721 :     }
     139             : 
     140         708 :     void check_(const char* file, int line, const char code[], const char* filename = "test.cpp", bool inconclusive = false) {
     141        2124 :         const Settings settings = settingsBuilder(settings0).certainty(Certainty::inconclusive, inconclusive).build();
     142         708 :         check_(file, line, code, settings, filename);
     143         707 :     }
     144             : 
     145           1 :     void assignAndCompare() {
     146             :         // &
     147           1 :         check("void foo(int x)\n"
     148             :               "{\n"
     149             :               "    int y = x & 4;\n"
     150             :               "    if (y == 3);\n"
     151             :               "}");
     152           1 :         ASSERT_EQUALS("[test.cpp:3] -> [test.cpp:4]: (style) Mismatching assignment and comparison, comparison 'y==3' is always false.\n", errout_str());
     153             : 
     154           1 :         check("void foo(int x)\n"
     155             :               "{\n"
     156             :               "    int y = x & 4;\n"
     157             :               "    if (y != 3);\n"
     158             :               "}");
     159           1 :         ASSERT_EQUALS("[test.cpp:3] -> [test.cpp:4]: (style) Mismatching assignment and comparison, comparison 'y!=3' is always true.\n", errout_str());
     160             : 
     161             :         // |
     162           1 :         check("void foo(int x) {\n"
     163             :               "    int y = x | 0x14;\n"
     164             :               "    if (y == 0x710);\n"
     165             :               "}");
     166           1 :         ASSERT_EQUALS("[test.cpp:2] -> [test.cpp:3]: (style) Mismatching assignment and comparison, comparison 'y==0x710' is always false.\n", errout_str());
     167             : 
     168           1 :         check("void foo(int x) {\n"
     169             :               "    int y = x | 0x14;\n"
     170             :               "    if (y == 0x71f);\n"
     171             :               "}");
     172           1 :         ASSERT_EQUALS("", errout_str());
     173             : 
     174             :         // various simple assignments
     175           1 :         check("void foo(int x) {\n"
     176             :               "    int y = (x+1) | 1;\n"
     177             :               "    if (y == 2);\n"
     178             :               "}");
     179           1 :         ASSERT_EQUALS("[test.cpp:2] -> [test.cpp:3]: (style) Mismatching assignment and comparison, comparison 'y==2' is always false.\n", errout_str());
     180             : 
     181           1 :         check("void foo() {\n"
     182             :               "    int y = 1 | x();\n"
     183             :               "    if (y == 2);\n"
     184             :               "}");
     185           1 :         ASSERT_EQUALS("[test.cpp:2] -> [test.cpp:3]: (style) Mismatching assignment and comparison, comparison 'y==2' is always false.\n", errout_str());
     186             : 
     187             :         // multiple conditions
     188           1 :         check("void foo(int x) {\n"
     189             :               "    int y = x & 4;\n"
     190             :               "    if ((y == 3) && (z == 1));\n"
     191             :               "}");
     192           1 :         ASSERT_EQUALS("[test.cpp:2] -> [test.cpp:3]: (style) Mismatching assignment and comparison, comparison 'y==3' is always false.\n", errout_str());
     193             : 
     194           1 :         check("void foo(int x) {\n"
     195             :               "    int y = x & 4;\n"
     196             :               "    if ((x==123) || ((y == 3) && (z == 1)));\n"
     197             :               "}");
     198           1 :         ASSERT_EQUALS("[test.cpp:2] -> [test.cpp:3]: (style) Mismatching assignment and comparison, comparison 'y==3' is always false.\n", errout_str());
     199             : 
     200           1 :         check("void f(int x) {\n"
     201             :               "    int y = x & 7;\n"
     202             :               "    if (setvalue(&y) && y != 8);\n"
     203             :               "}");
     204           1 :         ASSERT_EQUALS("", errout_str());
     205             : 
     206             :         // recursive checking into scopes
     207           1 :         check("void f(int x) {\n"
     208             :               "    int y = x & 7;\n"
     209             :               "    if (z) y=0;\n"
     210             :               "    else { if (y==8); }\n" // always false
     211             :               "}");
     212           1 :         ASSERT_EQUALS("[test.cpp:2] -> [test.cpp:4]: (style) Mismatching assignment and comparison, comparison 'y==8' is always false.\n", errout_str());
     213             : 
     214             :         // while
     215           1 :         check("void f(int x) {\n"
     216             :               "    int y = x & 7;\n"
     217             :               "    while (y==8);\n" // local variable => always false
     218             :               "}");
     219           1 :         ASSERT_EQUALS("[test.cpp:2] -> [test.cpp:3]: (style) Mismatching assignment and comparison, comparison 'y==8' is always false.\n", errout_str());
     220             : 
     221           1 :         check("void f(int x) {\n"
     222             :               "    extern int y; y = x & 7;\n"
     223             :               "    while (y==8);\n" // non-local variable => no error
     224             :               "}");
     225           1 :         ASSERT_EQUALS("", errout_str());
     226             : 
     227           1 :         check("void f(int x) {\n"
     228             :               "    int a = 100;\n"
     229             :               "    while (x) {\n"
     230             :               "        int y = 16 | a;\n"
     231             :               "        while (y != 0) y--;\n"
     232             :               "    }\n"
     233             :               "}");
     234           1 :         ASSERT_EQUALS("", errout_str());
     235             : 
     236           1 :         check("void g(int x);\n"
     237             :               "void f(int x) {\n"
     238             :               "    int a = 100;\n"
     239             :               "    while (x) {\n"
     240             :               "        int y = 16 | a;\n"
     241             :               "        while (y != 0) g(y);\n"
     242             :               "    }\n"
     243             :               "}");
     244           1 :         ASSERT_EQUALS(
     245             :             "[test.cpp:5] -> [test.cpp:6]: (style) Mismatching assignment and comparison, comparison 'y!=0' is always true.\n",
     246             :             errout_str());
     247             : 
     248           1 :         check("void g(int &x);\n"
     249             :               "void f(int x) {\n"
     250             :               "    int a = 100;\n"
     251             :               "    while (x) {\n"
     252             :               "        int y = 16 | a;\n"
     253             :               "        while (y != 0) g(y);\n"
     254             :               "    }\n"
     255             :               "}");
     256           1 :         ASSERT_EQUALS("", errout_str());
     257             : 
     258             :         // calling function
     259           1 :         check("void f(int x) {\n"
     260             :               "    int y = x & 7;\n"
     261             :               "    do_something();\n"
     262             :               "    if (y==8);\n" // local variable => always false
     263             :               "}");
     264           1 :         ASSERT_EQUALS("[test.cpp:2] -> [test.cpp:4]: (style) Mismatching assignment and comparison, comparison 'y==8' is always false.\n", errout_str());
     265             : 
     266           1 :         check("void f(int x) {\n"
     267             :               "    int y = x & 7;\n"
     268             :               "    do_something(&y);\n" // passing variable => no error
     269             :               "    if (y==8);\n"
     270             :               "}");
     271           1 :         ASSERT_EQUALS("", errout_str());
     272             : 
     273           1 :         check("void do_something(int);\n"
     274             :               "void f(int x) {\n"
     275             :               "    int y = x & 7;\n"
     276             :               "    do_something(y);\n"
     277             :               "    if (y==8);\n"
     278             :               "}");
     279           1 :         ASSERT_EQUALS("[test.cpp:3] -> [test.cpp:5]: (style) Mismatching assignment and comparison, comparison 'y==8' is always false.\n", errout_str());
     280             : 
     281           1 :         check("void f(int x) {\n"
     282             :               "    extern int y; y = x & 7;\n"
     283             :               "    do_something();\n"
     284             :               "    if (y==8);\n" // non-local variable => no error
     285             :               "}");
     286           1 :         ASSERT_EQUALS("", errout_str());
     287             : 
     288             :         // #4434 : false positive: ?:
     289           1 :         check("void f(int x) {\n"
     290             :               "    x = x & 1;\n"
     291             :               "    x = x & 1 ? 1 : -1;\n"
     292             :               "    if(x != -1) { }\n"
     293             :               "}");
     294           1 :         ASSERT_EQUALS("", errout_str());
     295             : 
     296             :         // #4735
     297           1 :         check("void f() {\n"
     298             :               "    int x = *(char*)&0x12345678;\n"
     299             :               "    if (x==18) { }\n"
     300             :               "}");
     301           1 :         ASSERT_EQUALS("", errout_str());
     302             : 
     303             :         // bailout: no variable info
     304           1 :         check("void foo(int x) {\n"
     305             :               "    y = 2 | x;\n"  // y not declared => no error
     306             :               "    if(y == 1) {}\n"
     307             :               "}");
     308           1 :         ASSERT_EQUALS("", errout_str());
     309             : 
     310             :         // bailout: negative number
     311           1 :         check("void foo(int x) {\n"
     312             :               "    int y = -2 | x;\n" // negative number => no error
     313             :               "    if (y==1) {}\n"
     314             :               "}");
     315           1 :         ASSERT_EQUALS("", errout_str());
     316             : 
     317             :         // bailout: pass variable to function
     318           1 :         check("void foo(int x) {\n"
     319             :               "    int y = 2 | x;\n"
     320             :               "    bar(&y);\n"  // pass variable to function => no error
     321             :               "    if (y==1) {}\n"
     322             :               "}");
     323           1 :         ASSERT_EQUALS("", errout_str());
     324             : 
     325             :         // no crash on unary operator& (#5643)
     326             :         // #11610
     327           1 :         check("SdrObject* ApplyGraphicToObject() {\n"
     328             :               "    if (&rHitObject) {}\n"
     329             :               "    else if (rHitObject.IsClosedObj() && !&rHitObject) { }\n"
     330             :               "}");
     331           1 :         ASSERT_EQUALS("[test.cpp:2]: (style) Condition '&rHitObject' is always true\n"
     332             :                       "[test.cpp:3]: (style) Condition '!&rHitObject' is always false\n",
     333             :                       errout_str());
     334             : 
     335             :         // #5695: increment
     336           1 :         check("void f(int a0, int n) {\n"
     337             :               "  int c = a0 & 3;\n"
     338             :               "  for (int a = 0; a < n; a++) {\n"
     339             :               "    c++;\n"
     340             :               "    if (c == 4)\n"
     341             :               "      c  = 0;\n"
     342             :               "  }\n"
     343             :               "}");
     344           1 :         ASSERT_EQUALS("", errout_str());
     345             : 
     346           1 :         check("void f(int a) {\n" // #6662
     347             :               "  int x = a & 1;\n"
     348             :               "  while (x <= 4) {\n"
     349             :               "    if (x != 5) {}\n"
     350             :               "  }\n"
     351             :               "}");
     352           1 :         ASSERT_EQUALS("[test.cpp:2] -> [test.cpp:4]: (style) Mismatching assignment and comparison, comparison 'x!=5' is always true.\n", errout_str());
     353             : 
     354           1 :         check("void f(int a) {\n" // #6662
     355             :               "  int x = a & 1;\n"
     356             :               "  while ((x += 4) < 10) {\n"
     357             :               "    if (x != 5) {}\n"
     358             :               "  }\n"
     359             :               "}");
     360           1 :         ASSERT_EQUALS("", errout_str());
     361             : 
     362           1 :         check("void f() {\n"
     363             :               "    int x = 100;\n"
     364             :               "    while (x) {\n"
     365             :               "        g(x);\n"
     366             :               "    }\n"
     367             :               "}");
     368           1 :         ASSERT_EQUALS("", errout_str());
     369             : 
     370           1 :         check("void g(int x);\n"
     371             :               "void f() {\n"
     372             :               "    int x = 100;\n"
     373             :               "    while (x) {\n"
     374             :               "        g(x);\n"
     375             :               "    }\n"
     376             :               "}");
     377           1 :         ASSERT_EQUALS("[test.cpp:4]: (style) Condition 'x' is always true\n", errout_str());
     378             : 
     379           1 :         check("void g(int & x);\n"
     380             :               "void f() {\n"
     381             :               "    int x = 100;\n"
     382             :               "    while (x) {\n"
     383             :               "        g(x);\n"
     384             :               "    }\n"
     385             :               "}");
     386           1 :         ASSERT_EQUALS("", errout_str());
     387             : 
     388             :     }
     389             : 
     390           1 :     void mismatchingBitAnd() {
     391           1 :         check("void f(int a) {\n"
     392             :               "    int b = a & 0xf0;\n"
     393             :               "    b &= 1;\n"
     394             :               "}");
     395           1 :         ASSERT_EQUALS("[test.cpp:2] -> [test.cpp:3]: (style) Mismatching bitmasks. Result is always 0 (X = Y & 0xf0; Z = X & 0x1; => Z=0).\n", errout_str());
     396             : 
     397           1 :         check("void f(int a) {\n"
     398             :               "    int b = a & 0xf0;\n"
     399             :               "    int c = b & 1;\n"
     400             :               "}");
     401           1 :         ASSERT_EQUALS("[test.cpp:2] -> [test.cpp:3]: (style) Mismatching bitmasks. Result is always 0 (X = Y & 0xf0; Z = X & 0x1; => Z=0).\n", errout_str());
     402             : 
     403           1 :         check("void f(int a) {\n"
     404             :               "    int b = a;"
     405             :               "    switch (x) {\n"
     406             :               "    case 1: b &= 1; break;\n"
     407             :               "    case 2: b &= 2; break;\n"
     408             :               "    };\n"
     409             :               "}");
     410           1 :         ASSERT_EQUALS("", errout_str());
     411             :     }
     412             : 
     413           1 :     void comparison() {
     414             :         // CheckCondition::comparison test cases
     415             :         // '=='
     416           1 :         check("void f(int a) {\n assert( (a & 0x07) == 8U );\n}");
     417           1 :         ASSERT_EQUALS("[test.cpp:2]: (style) Expression '(X & 0x7) == 0x8' is always false.\n",errout_str());
     418           1 :         check("void f(int a) {\n assert( (a & b & 4 & c ) == 3 );\n}");
     419           1 :         ASSERT_EQUALS("[test.cpp:2]: (style) Expression '(X & 0x4) == 0x3' is always false.\n", errout_str());
     420           1 :         check("void f(int a) {\n assert( (a | 0x07) == 8U );\n}");
     421           1 :         ASSERT_EQUALS("[test.cpp:2]: (style) Expression '(X | 0x7) == 0x8' is always false.\n",errout_str());
     422           1 :         check("void f(int a) {\n assert( (a & 0x07) == 7U );\n}");
     423           1 :         ASSERT_EQUALS("", errout_str());
     424           1 :         check("void f(int a) {\n assert( (a | 0x01) == -15 );\n}");
     425           1 :         ASSERT_EQUALS("", errout_str());
     426             :         // '!='
     427           1 :         check("void f(int a) {\n assert( (a & 0x07) != 8U );\n}");
     428           1 :         ASSERT_EQUALS("[test.cpp:2]: (style) Expression '(X & 0x7) != 0x8' is always true.\n",errout_str());
     429           1 :         check("void f(int a) {\n assert( (a | 0x07) != 8U );\n}");
     430           1 :         ASSERT_EQUALS("[test.cpp:2]: (style) Expression '(X | 0x7) != 0x8' is always true.\n",errout_str());
     431           1 :         check("void f(int a) {\n assert( (a & 0x07) != 7U );\n}");
     432           1 :         ASSERT_EQUALS("", errout_str());
     433           1 :         check("void f(int a) {\n assert( (a | 0x07) != 7U );\n}");
     434           1 :         ASSERT_EQUALS("", errout_str());
     435             :         // '>='
     436           1 :         check("void f(int a) {\n assert( (a & 0x07) >= 8U );\n}");
     437           1 :         ASSERT_EQUALS("[test.cpp:2]: (style) Expression '(X & 0x7) >= 0x8' is always false.\n",errout_str());
     438           1 :         check("void f(unsigned int a) {\n assert( (a | 0x7) >= 7U );\n}");
     439           1 :         ASSERT_EQUALS("[test.cpp:2]: (style) Expression '(X | 0x7) >= 0x7' is always true.\n",errout_str());
     440           1 :         check("void f(int a) {\n assert( (a & 0x07) >= 7U );\n}");
     441           1 :         ASSERT_EQUALS("",errout_str());
     442           1 :         check("void f(int a) {\n assert( (a | 0x07) >= 8U );\n}");
     443           1 :         ASSERT_EQUALS("",errout_str()); //correct for negative 'a'
     444             :         // '>'
     445           1 :         check("void f(int a) {\n assert( (a & 0x07) > 7U );\n}");
     446           1 :         ASSERT_EQUALS("[test.cpp:2]: (style) Expression '(X & 0x7) > 0x7' is always false.\n",errout_str());
     447           1 :         check("void f(unsigned int a) {\n assert( (a | 0x7) > 6U );\n}");
     448           1 :         ASSERT_EQUALS("[test.cpp:2]: (style) Expression '(X | 0x7) > 0x6' is always true.\n",errout_str());
     449           1 :         check("void f(int a) {\n assert( (a & 0x07) > 6U );\n}");
     450           1 :         ASSERT_EQUALS("",errout_str());
     451           1 :         check("void f(int a) {\n assert( (a | 0x07) > 7U );\n}");
     452           1 :         ASSERT_EQUALS("",errout_str()); //correct for negative 'a'
     453             :         // '<='
     454           1 :         check("void f(int a) {\n assert( (a & 0x07) <= 7U );\n}");
     455           1 :         ASSERT_EQUALS("[test.cpp:2]: (style) Expression '(X & 0x7) <= 0x7' is always true.\n",errout_str());
     456           1 :         check("void f(unsigned int a) {\n assert( (a | 0x08) <= 7U );\n}");
     457           1 :         ASSERT_EQUALS("[test.cpp:2]: (style) Expression '(X | 0x8) <= 0x7' is always false.\n",errout_str());
     458           1 :         check("void f(int a) {\n assert( (a & 0x07) <= 6U );\n}");
     459           1 :         ASSERT_EQUALS("",errout_str());
     460           1 :         check("void f(int a) {\n assert( (a | 0x08) <= 7U );\n}");
     461           1 :         ASSERT_EQUALS("",errout_str()); //correct for negative 'a'
     462             :         // '<'
     463           1 :         check("void f(int a) {\n assert( (a & 0x07) < 8U );\n}");
     464           1 :         ASSERT_EQUALS("[test.cpp:2]: (style) Expression '(X & 0x7) < 0x8' is always true.\n",errout_str());
     465           1 :         check("void f(unsigned int a) {\n assert( (a | 0x07) < 7U );\n}");
     466           1 :         ASSERT_EQUALS("[test.cpp:2]: (style) Expression '(X | 0x7) < 0x7' is always false.\n",errout_str());
     467           1 :         check("void f(int a) {\n assert( (a & 0x07) < 3U );\n}");
     468           1 :         ASSERT_EQUALS("",errout_str());
     469           1 :         check("void f(int a) {\n assert( (a | 0x07) < 7U );\n}");
     470           1 :         ASSERT_EQUALS("",errout_str()); //correct for negative 'a'
     471             : 
     472           1 :         check("void f(int i) {\n" // #11998
     473             :               "    if ((i & 0x100) == 0x200) {}\n"
     474             :               "    if (0x200 == (i & 0x100)) {}\n"
     475             :               "}\n");
     476           1 :         ASSERT_EQUALS("[test.cpp:2] -> [test.cpp:3]: (style) The if condition is the same as the previous if condition\n"
     477             :                       "[test.cpp:2]: (style) Expression '(X & 0x100) == 0x200' is always false.\n"
     478             :                       "[test.cpp:3]: (style) Expression '(X & 0x100) == 0x200' is always false.\n",
     479             :                       errout_str());
     480             :     }
     481             : 
     482             : #define checkPureFunction(code) checkPureFunction_(code, __FILE__, __LINE__)
     483           1 :     void multicompare() {
     484           1 :         check("void foo(int x)\n"
     485             :               "{\n"
     486             :               "    if (x & 7);\n"
     487             :               "    else { if (x == 1); }\n"
     488             :               "}");
     489           1 :         ASSERT_EQUALS("[test.cpp:4]: (style) Expression is always false because 'else if' condition matches previous condition at line 3.\n", errout_str());
     490             : 
     491           1 :         check("void foo(int x)\n"
     492             :               "{\n"
     493             :               "    if (x & 7);\n"
     494             :               "    else { if (x & 1); }\n"
     495             :               "}");
     496           1 :         ASSERT_EQUALS("[test.cpp:4]: (style) Expression is always false because 'else if' condition matches previous condition at line 3.\n", errout_str());
     497             : 
     498           1 :         check("extern int bar() __attribute__((pure));\n"
     499             :               "void foo(int x)\n"
     500             :               "{\n"
     501             :               "    if ( bar() >1 && b) {}\n"
     502             :               "    else if (bar() >1 && b) {}\n"
     503             :               "}");
     504           1 :         ASSERT_EQUALS("[test.cpp:5]: (style) Expression is always false because 'else if' condition matches previous condition at line 4.\n", errout_str());
     505             : 
     506           1 :         checkPureFunction("extern int bar();\n"
     507             :                           "void foo(int x)\n"
     508             :                           "{\n"
     509             :                           "    if ( bar() >1 && b) {}\n"
     510             :                           "    else if (bar() >1 && b) {}\n"
     511             :                           "}");
     512           1 :         ASSERT_EQUALS("[test.cpp:5]: (style) Expression is always false because 'else if' condition matches previous condition at line 4.\n", errout_str());
     513             : 
     514             :         // 7284
     515           1 :         check("void foo() {\n"
     516             :               "    if (a) {}\n"
     517             :               "    else if (!!a) {}\n"
     518             :               "}");
     519           1 :         ASSERT_EQUALS("[test.cpp:3]: (style) Expression is always false because 'else if' condition matches previous condition at line 2.\n", errout_str());
     520             : 
     521             :         // #11059
     522           1 :         check("int f();\n"
     523             :               "void g() {\n"
     524             :               "    int i = f();\n"
     525             :               "    if (i == 3) {}\n"
     526             :               "    else if ((i = f()) == 5) {}\n"
     527             :               "    else if (i == 3) {}\n"
     528             :               "}\n");
     529           1 :         ASSERT_EQUALS("", errout_str());
     530             : 
     531           1 :         check("int f();\n"
     532             :               "void g() {\n"
     533             :               "    int i = f();\n"
     534             :               "    if (i == 3) {}\n"
     535             :               "    else if ((i = f()) == 5) {}\n"
     536             :               "    else if (i != 3) {}\n"
     537             :               "}\n");
     538           1 :         ASSERT_EQUALS("", errout_str());
     539             :     }
     540             : 
     541           1 :     void checkPureFunction_(const char code[], const char* file, int line) {
     542             :         // Tokenize..
     543           2 :         SimpleTokenizer tokenizer(settings1, *this);
     544           1 :         ASSERT_LOC(tokenizer.tokenize(code), file, line);
     545             : 
     546           1 :         runChecks<CheckCondition>(tokenizer, this);
     547           1 :     }
     548             : 
     549           1 :     void overlappingElseIfCondition() {
     550           1 :         check("void f(int a, int &b) {\n"
     551             :               "    if (a) { b = 1; }\n"
     552             :               "    else { if (a) { b = 2; } }\n"
     553             :               "}");
     554           1 :         ASSERT_EQUALS("[test.cpp:3]: (style) Expression is always false because 'else if' condition matches previous condition at line 2.\n", errout_str());
     555             : 
     556           1 :         check("void f(int a, int &b) {\n"
     557             :               "    if (a) { b = 1; }\n"
     558             :               "    else { if (a) { b = 2; } }\n"
     559             :               "}");
     560           1 :         ASSERT_EQUALS("[test.cpp:3]: (style) Expression is always false because 'else if' condition matches previous condition at line 2.\n", errout_str());
     561             : 
     562           1 :         check("void f(int a, int &b) {\n"
     563             :               "    if (a == 1) { b = 1; }\n"
     564             :               "    else { if (a == 2) { b = 2; }\n"
     565             :               "    else { if (a == 1) { b = 3; } } }\n"
     566             :               "}");
     567           1 :         ASSERT_EQUALS("[test.cpp:4]: (style) Expression is always false because 'else if' condition matches previous condition at line 2.\n", errout_str());
     568             : 
     569           1 :         check("void f(int a, int &b) {\n"
     570             :               "    if (a == 1) { b = 1; }\n"
     571             :               "    else { if (a == 2) { b = 2; }\n"
     572             :               "    else { if (a == 2) { b = 3; } } }\n"
     573             :               "}");
     574           1 :         ASSERT_EQUALS("[test.cpp:4]: (style) Expression is always false because 'else if' condition matches previous condition at line 3.\n", errout_str());
     575             : 
     576           1 :         check("void f(int a, int &b) {\n"
     577             :               "    if (a++) { b = 1; }\n"
     578             :               "    else { if (a++) { b = 2; }\n"
     579             :               "    else { if (a++) { b = 3; } } }\n"
     580             :               "}");
     581           1 :         ASSERT_EQUALS("", errout_str());
     582             : 
     583           1 :         check("void f(int a, int &b) {\n"
     584             :               "    if (!strtok(NULL, \" \")) { b = 1; }\n"
     585             :               "    else { if (!strtok(NULL, \" \")) { b = 2; } }\n"
     586             :               "}");
     587           1 :         ASSERT_EQUALS("", errout_str());
     588             : 
     589             :         {
     590           1 :             check("void f(Class &c) {\n"
     591             :                   "    if (c.dostuff() == 3) {}\n"
     592             :                   "    else { if (c.dostuff() == 3) {} }\n"
     593             :                   "}");
     594           1 :             ASSERT_EQUALS("", errout_str());
     595             : 
     596           1 :             check("void f(const Class &c) {\n"
     597             :                   "    if (c.dostuff() == 3) {}\n"
     598             :                   "    else { if (c.dostuff() == 3) {} }\n"
     599             :                   "}");
     600           1 :             ASSERT_EQUALS("[test.cpp:3]: (style) Expression is always false because 'else if' condition matches previous condition at line 2.\n", errout_str());
     601             :         }
     602             : 
     603           1 :         check("void f(int a, int &b) {\n"
     604             :               "   x = x / 2;\n"
     605             :               "   if (x < 100) { b = 1; }\n"
     606             :               "   else { x = x / 2; if (x < 100) { b = 2; } }\n"
     607             :               "}");
     608           1 :         ASSERT_EQUALS("", errout_str());
     609             : 
     610           1 :         check("void f(int i) {\n"
     611             :               "   if(i == 0x02e2000000 || i == 0xa0c6000000)\n"
     612             :               "       foo(i);\n"
     613             :               "}");
     614           1 :         ASSERT_EQUALS("", errout_str());
     615             : 
     616             :         // ticket 3689 ( avoid false positive )
     617           1 :         check("int fitInt(long long int nValue){\n"
     618             :               "    if( nValue < 0x7fffffffLL )\n"
     619             :               "    {\n"
     620             :               "        return 32;\n"
     621             :               "    }\n"
     622             :               "    if( nValue < 0x7fffffffffffLL )\n"
     623             :               "    {\n"
     624             :               "        return 48;\n"
     625             :               "    }\n"
     626             :               "    else {\n"
     627             :               "        if( nValue < 0x7fffffffffffffffLL )\n"
     628             :               "        {\n"
     629             :               "            return 64;\n"
     630             :               "        } else\n"
     631             :               "        {\n"
     632             :               "            return -1;\n"
     633             :               "        }\n"
     634             :               "    }\n"
     635             :               "}");
     636           1 :         ASSERT_EQUALS("", errout_str());
     637             : 
     638           1 :         check("void f(WIDGET *widget) {\n"
     639             :               "  if (dynamic_cast<BUTTON*>(widget)){}\n"
     640             :               "  else if (dynamic_cast<LABEL*>(widget)){}\n"
     641             :               "}");
     642           1 :         ASSERT_EQUALS("", errout_str());
     643             : 
     644           1 :         check("class B { virtual void v() {} };\n" // #11037
     645             :               "class D1 : public B {};\n"
     646             :               "class D2 : public B {};\n"
     647             :               "void f(const std::shared_ptr<B>&p) {\n"
     648             :               "    const auto d1 = dynamic_cast<D1*>(p.get());\n"
     649             :               "    const auto d2 = dynamic_cast<D2*>(p.get());\n"
     650             :               "    if (d1) {}\n"
     651             :               "    else if (d2) {}\n"
     652             :               "}\n");
     653           1 :         ASSERT_EQUALS("", errout_str());
     654             : 
     655           1 :         check("void f(int x) {\n" // #6482
     656             :               "  if (x & 1) {}\n"
     657             :               "  else if (x == 0) {}\n"
     658             :               "}");
     659           1 :         ASSERT_EQUALS("", errout_str());
     660             : 
     661           1 :         check("void f(int x) {\n"
     662             :               "  if (x & 15) {}\n"
     663             :               "  else if (x == 40) {}\n"
     664             :               "}");
     665           1 :         ASSERT_EQUALS("[test.cpp:3]: (style) Expression is always false because 'else if' condition matches previous condition at line 2.\n", errout_str());
     666             : 
     667           1 :         check("void f(int x) {\n"
     668             :               "  if (x == sizeof(double)) {}\n"
     669             :               "  else { if (x == sizeof(long double)) {} }"
     670             :               "}");
     671           1 :         ASSERT_EQUALS("", errout_str());
     672             : 
     673           1 :         check("void f(int x) {\n"
     674             :               "  if (x & 0x08) {}\n"
     675             :               "  else if (x & 0xF8) {}\n"
     676             :               "}");
     677           1 :         ASSERT_EQUALS("", errout_str());
     678             : 
     679           1 :         check("void f(int x) {\n"
     680             :               "  if (x & 0xF8) {}\n"
     681             :               "  else if (x & 0x08) {}\n"
     682             :               "}");
     683           1 :         ASSERT_EQUALS("[test.cpp:3]: (style) Expression is always false because 'else if' condition matches previous condition at line 2.\n", errout_str());
     684             : 
     685           1 :         check("void f(bool a, bool b) {\n"
     686             :               "   if(a && b){}\n"
     687             :               "   else if( !!b && !!a){}\n"
     688             :               "}");
     689           1 :         ASSERT_EQUALS("[test.cpp:3]: (style) Expression is always false because 'else if' condition matches previous condition at line 2.\n", errout_str());
     690             : 
     691           1 :         check("void f(bool a, bool b) {\n"
     692             :               "   if(a && b){}\n"
     693             :               "   else if( !!b && a){}\n"
     694             :               "}");
     695           1 :         ASSERT_EQUALS("[test.cpp:3]: (style) Expression is always false because 'else if' condition matches previous condition at line 2.\n", errout_str());
     696             : 
     697           1 :         check("void f(bool a, bool b) {\n"
     698             :               "   if(a && b){}\n"
     699             :               "   else if( b && !!a){}\n"
     700             :               "}");
     701           1 :         ASSERT_EQUALS("[test.cpp:3]: (style) Expression is always false because 'else if' condition matches previous condition at line 2.\n", errout_str());
     702             : 
     703           1 :         check("void f(bool a, bool b) {\n"
     704             :               "   if(a && b){}\n"
     705             :               "   else if( b && !(!a)){}\n"
     706             :               "}");
     707           1 :         ASSERT_EQUALS("[test.cpp:3]: (style) Expression is always false because 'else if' condition matches previous condition at line 2.\n", errout_str());
     708             : 
     709           1 :         check("void f(bool a, bool b) {\n"
     710             :               "   if(a && b){}\n"
     711             :               "   else if( !!b && !(!a)){}\n"
     712             :               "}");
     713           1 :         ASSERT_EQUALS("[test.cpp:3]: (style) Expression is always false because 'else if' condition matches previous condition at line 2.\n", errout_str());
     714             : 
     715           1 :         check("void f(bool a, bool b) {\n"
     716             :               "   if(a && b){}\n"
     717             :               "   else if( !!(b) && !!(a+b)){}\n"
     718             :               "}");
     719           1 :         ASSERT_EQUALS("", errout_str());
     720             : 
     721             :         // #8168
     722           1 :         check("enum MaskValues\n"
     723             :               "{\n"
     724             :               "    Value1 = 0x00000001,\n"
     725             :               "    Value2 = 0x00000002\n"
     726             :               "};\n"
     727             :               "void TestFunction(int value) {\n"
     728             :               "    if ( value & (int)Value1 ) {}\n"
     729             :               "    else if ( value & (int)Value2 ) {}\n"
     730             :               "}");
     731           1 :         ASSERT_EQUALS("", errout_str());
     732             : 
     733           1 :         check("void f(size_t x) {\n"
     734             :               "    if (x == sizeof(int)) {}\n"
     735             :               "    else { if (x == sizeof(long))} {}\n"
     736             :               "}\n");
     737           1 :         ASSERT_EQUALS("", errout_str());
     738             : 
     739           1 :         check("void f(size_t x) {\n"
     740             :               "    if (x == sizeof(long)) {}\n"
     741             :               "    else { if (x == sizeof(long long))} {}\n"
     742             :               "}\n");
     743           1 :         ASSERT_EQUALS("", errout_str());
     744             :     }
     745             : 
     746           1 :     void oppositeElseIfCondition() {
     747           1 :         setMultiline();
     748             : 
     749           1 :         check("void f(int x) {\n"
     750             :               "    if (x) {}\n"
     751             :               "    else if (!x) {}\n"
     752             :               "}");
     753           1 :         ASSERT_EQUALS("test.cpp:3:style:Expression is always true because 'else if' condition is opposite to previous condition at line 2.\n"
     754             :                       "test.cpp:2:note:first condition\n"
     755             :                       "test.cpp:3:note:else if condition is opposite to first condition\n", errout_str());
     756             : 
     757           1 :         check("void f(int x) {\n"
     758             :               "    int y = x;\n"
     759             :               "    if (x) {}\n"
     760             :               "    else if (!y) {}\n"
     761             :               "}");
     762           1 :         ASSERT_EQUALS("test.cpp:4:style:Expression is always true because 'else if' condition is opposite to previous condition at line 3.\n"
     763             :                       "test.cpp:2:note:'y' is assigned value 'x' here.\n"
     764             :                       "test.cpp:3:note:first condition\n"
     765             :                       "test.cpp:4:note:else if condition is opposite to first condition\n", errout_str());
     766             :     }
     767             : 
     768           1 :     void checkBadBitmaskCheck() {
     769           1 :         check("bool f(int x) {\n"
     770             :               "    bool b = x | 0x02;\n"
     771             :               "    return b;\n"
     772             :               "}");
     773           1 :         ASSERT_EQUALS("[test.cpp:2]: (warning) Result of operator '|' is always true if one operand is non-zero. Did you intend to use '&'?\n", errout_str());
     774             : 
     775           1 :         check("bool f(int x) {\n"
     776             :               "    bool b = 0x02 | x;\n"
     777             :               "    return b;\n"
     778             :               "}");
     779           1 :         ASSERT_EQUALS("[test.cpp:2]: (warning) Result of operator '|' is always true if one operand is non-zero. Did you intend to use '&'?\n", errout_str());
     780             : 
     781           1 :         check("int f(int x) {\n"
     782             :               "    int b = x | 0x02;\n"
     783             :               "    return b;\n"
     784             :               "}");
     785           1 :         ASSERT_EQUALS("", errout_str());
     786             : 
     787           1 :         check("bool f(int x) {\n"
     788             :               "    bool b = x & 0x02;\n"
     789             :               "    return b;\n"
     790             :               "}");
     791           1 :         ASSERT_EQUALS("", errout_str());
     792             : 
     793           1 :         check("bool f(int x) {\n"
     794             :               "    if(x | 0x02)\n"
     795             :               "        return b;\n"
     796             :               "}");
     797           1 :         ASSERT_EQUALS("[test.cpp:2]: (warning) Result of operator '|' is always true if one operand is non-zero. Did you intend to use '&'?\n", errout_str());
     798             : 
     799           1 :         check("bool f(int x) {\n"
     800             :               "    int y = 0x1;\n"
     801             :               "    if(b) y = 0;\n"
     802             :               "    if(x | y)\n"
     803             :               "        return b;\n"
     804             :               "}");
     805           1 :         ASSERT_EQUALS("", errout_str());
     806             : 
     807           1 :         check("bool f(int x) {\n"
     808             :               "    foo(a && (x | 0x02));\n"
     809             :               "}");
     810           1 :         ASSERT_EQUALS("[test.cpp:2]: (warning) Result of operator '|' is always true if one operand is non-zero. Did you intend to use '&'?\n", errout_str());
     811             : 
     812           1 :         check("int f(int x) {\n"
     813             :               "    return (x | 0x02) ? 0 : 5;\n"
     814             :               "}");
     815           1 :         ASSERT_EQUALS("[test.cpp:2]: (warning) Result of operator '|' is always true if one operand is non-zero. Did you intend to use '&'?\n", errout_str());
     816             : 
     817           1 :         check("int f(int x) {\n"
     818             :               "    return x ? (x | 0x02) : 5;\n"
     819             :               "}");
     820           1 :         ASSERT_EQUALS("", errout_str());
     821             : 
     822           1 :         check("bool f(int x) {\n"
     823             :               "    return x | 0x02;\n"
     824             :               "}");
     825           1 :         ASSERT_EQUALS("[test.cpp:2]: (warning) Result of operator '|' is always true if one operand is non-zero. Did you intend to use '&'?\n", errout_str());
     826             : 
     827           1 :         check("bool f(int x) {\n"
     828             :               "  if (x) {\n"
     829             :               "    return x | 0x02;\n"
     830             :               "  }\n"
     831             :               "  return 0;\n"
     832             :               "}");
     833           1 :         ASSERT_EQUALS("[test.cpp:3]: (warning) Result of operator '|' is always true if one operand is non-zero. Did you intend to use '&'?\n", errout_str());
     834             : 
     835           1 :         check("const bool f(int x) {\n"
     836             :               "    return x | 0x02;\n"
     837             :               "}");
     838           1 :         ASSERT_EQUALS("[test.cpp:2]: (warning) Result of operator '|' is always true if one operand is non-zero. Did you intend to use '&'?\n", errout_str());
     839             : 
     840           1 :         check("struct F {\n"
     841             :               "  static const bool f(int x) {\n"
     842             :               "      return x | 0x02;\n"
     843             :               "  }\n"
     844             :               "};");
     845           1 :         ASSERT_EQUALS("[test.cpp:3]: (warning) Result of operator '|' is always true if one operand is non-zero. Did you intend to use '&'?\n", errout_str());
     846             : 
     847           1 :         check("struct F {\n"
     848             :               "  typedef bool b_t;\n"
     849             :               "};\n"
     850             :               "F::b_t f(int x) {\n"
     851             :               "  return x | 0x02;\n"
     852             :               "}");
     853           1 :         ASSERT_EQUALS("[test.cpp:5]: (warning) Result of operator '|' is always true if one operand is non-zero. Did you intend to use '&'?\n", errout_str());
     854             : 
     855           1 :         check("int f(int x) {\n"
     856             :               "    return x | 0x02;\n"
     857             :               "}");
     858           1 :         ASSERT_EQUALS("", errout_str());
     859             : 
     860           1 :         check("void create_rop_masks_4( rop_mask_bits *bits) {\n"
     861             :               "DWORD mask_offset;\n"
     862             :               "BYTE *and_bits = bits->and;\n"
     863             :               "rop_mask *rop_mask;\n"
     864             :               "and_bits[mask_offset] |= (rop_mask->and & 0x0f);\n"
     865             :               "}");
     866           1 :         ASSERT_EQUALS("", errout_str());
     867             : 
     868           1 :         check("void f(unsigned a, unsigned b) {\n"
     869             :               "  unsigned cmd1 = b & 0x0F;\n"
     870             :               "  if (cmd1 | a) {\n"
     871             :               "    if (b == 0x0C) {}\n"
     872             :               "  }\n"
     873             :               "}");
     874           1 :         ASSERT_EQUALS("", errout_str());
     875             : 
     876           1 :         check("void f(int i) {\n" // #11082
     877             :               "    int j = 0;\n"
     878             :               "    if (i | j) {}\n"
     879             :               "}\n");
     880           1 :         ASSERT_EQUALS("[test.cpp:3]: (style) Operator '|' with one operand equal to zero is redundant.\n", errout_str());
     881             : 
     882           1 :         check("#define EIGHTTOIS(x) (((x) << 8) | (x))\n"
     883             :               "int f() {\n"
     884             :               "    return EIGHTTOIS(0);\n"
     885             :               "}\n");
     886           1 :         ASSERT_EQUALS("", errout_str());
     887             : 
     888           1 :         check("#define O_RDONLY 0\n"
     889             :               "void f(const char* s, int* pFd) {\n"
     890             :               "    *pFd = open(s, O_RDONLY | O_BINARY, 0);\n"
     891             :               "}\n");
     892           1 :         ASSERT_EQUALS("", errout_str());
     893             : 
     894           1 :         check("const int FEATURE_BITS = x |\n"
     895             :               "#if FOO_ENABLED\n"
     896             :               "    FEATURE_FOO |\n"
     897             :               "#endif\n"
     898             :               "#if BAR_ENABLED\n"
     899             :               "    FEATURE_BAR |\n"
     900             :               "#endif\n"
     901             :               "    0;");
     902           1 :         ASSERT_EQUALS("", errout_str());
     903             : 
     904           1 :         check("enum precedence { PC0, UNARY };\n"
     905             :               "int x = PC0   | UNARY;\n"
     906             :               "int y = UNARY | PC0;\n");
     907           1 :         ASSERT_EQUALS("", errout_str());
     908             : 
     909           1 :         check("#define MASK 0\n"
     910             :               "#define SHIFT 1\n"
     911             :               "int x = 1 | (MASK << SHIFT);\n");
     912           1 :         ASSERT_EQUALS("", errout_str());
     913             :     }
     914             : 
     915             : 
     916           1 :     void incorrectLogicOperator1() {
     917           1 :         check("void f(int x) {\n"
     918             :               "    if ((x != 1) || (x != 3))\n"
     919             :               "        a++;\n"
     920             :               "}");
     921           1 :         ASSERT_EQUALS("[test.cpp:2]: (warning) Logical disjunction always evaluates to true: x != 1 || x != 3.\n", errout_str());
     922             : 
     923           1 :         check("void f(int x) {\n"
     924             :               "    if (1 != x || 3 != x)\n"
     925             :               "        a++;\n"
     926             :               "}");
     927           1 :         ASSERT_EQUALS("[test.cpp:2]: (warning) Logical disjunction always evaluates to true: x != 1 || x != 3.\n", errout_str());
     928             : 
     929           1 :         check("void f(int x) {\n"
     930             :               "  if (x<0 && !x) {}\n"
     931             :               "}");
     932           1 :         ASSERT_EQUALS("[test.cpp:2]: (warning) Logical conjunction always evaluates to false: x < 0 && !x.\n", errout_str());
     933             : 
     934           1 :         check("void f(int x) {\n"
     935             :               "  if (x==0 && x) {}\n"
     936             :               "}");
     937           1 :         ASSERT_EQUALS("[test.cpp:2]: (warning) Logical conjunction always evaluates to false: x == 0 && x.\n", errout_str());
     938             : 
     939           1 :         check("void f(int x) {\n" // ast..
     940             :               "    if (y == 1 && x == 1 && x == 7) { }\n"
     941             :               "}");
     942           1 :         ASSERT_EQUALS("[test.cpp:2]: (warning) Logical conjunction always evaluates to false: x == 1 && x == 7.\n", errout_str());
     943             : 
     944           1 :         check("void f(int x, int y) {\n"
     945             :               "    if (x != 1 || y != 1)\n"
     946             :               "        a++;\n"
     947             :               "}");
     948           1 :         ASSERT_EQUALS("", errout_str());
     949             : 
     950           1 :         check("void f(int x, int y) {\n"
     951             :               "    if ((y == 1) && (x != 1) || (x != 3))\n"
     952             :               "        a++;\n"
     953             :               "}");
     954           1 :         ASSERT_EQUALS("", errout_str());
     955             : 
     956           1 :         check("void f(int x, int y) {\n"
     957             :               "    if ((x != 1) || (x != 3) && (y == 1))\n"
     958             :               "        a++;\n"
     959             :               "}"
     960             :               );
     961           1 :         ASSERT_EQUALS("[test.cpp:2] -> [test.cpp:2]: (style) Condition 'x!=3' is always true\n", errout_str());
     962             : 
     963           1 :         check("void f(int x) {\n"
     964             :               "    if ((x != 1) && (x != 3))\n"
     965             :               "        a++;\n"
     966             :               "}");
     967           1 :         ASSERT_EQUALS("", errout_str());
     968             : 
     969           1 :         check("void f(int x) {\n"
     970             :               "    if ((x == 1) || (x == 3))\n"
     971             :               "        a++;\n"
     972             :               "}");
     973           1 :         ASSERT_EQUALS("", errout_str());
     974             : 
     975           1 :         check("void f(int x, int y) {\n"
     976             :               "    if ((x != 1) || (y != 3))\n"
     977             :               "        a++;\n"
     978             :               "}");
     979           1 :         ASSERT_EQUALS("", errout_str());
     980             : 
     981           1 :         check("void f(int x, int y) {\n"
     982             :               "    if ((x != hotdog) || (y != hotdog))\n"
     983             :               "        a++;\n"
     984             :               "}");
     985           1 :         ASSERT_EQUALS("", errout_str());
     986             : 
     987           1 :         check("void f(int x, int y) {\n"
     988             :               "    if ((x != 5) || (y != 5))\n"
     989             :               "        a++;\n"
     990             :               "}");
     991           1 :         ASSERT_EQUALS("", errout_str());
     992             : 
     993             : 
     994           1 :         check("void f(int x) {\n"
     995             :               "    if ((x != 5) || (x != 6))\n"
     996             :               "        a++;\n"
     997             :               "}");
     998           1 :         ASSERT_EQUALS("[test.cpp:2]: (warning) Logical disjunction always evaluates to true: x != 5 || x != 6.\n", errout_str());
     999             : 
    1000           1 :         check("void f(unsigned int a, unsigned int b, unsigned int c) {\n"
    1001             :               "    if((a != b) || (c != b) || (c != a))\n"
    1002             :               "    {\n"
    1003             :               "        return true;\n"
    1004             :               "    }\n"
    1005             :               "    return false;\n"
    1006             :               "}");
    1007           1 :         ASSERT_EQUALS("[test.cpp:2] -> [test.cpp:2]: (style) Condition 'c!=a' is always false\n", errout_str());
    1008             :     }
    1009             : 
    1010           1 :     void incorrectLogicOperator2() {
    1011           1 :         check("void f(float x) {\n"
    1012             :               "    if ((x == 1) && (x == 1.0))\n"
    1013             :               "        a++;\n"
    1014             :               "}");
    1015           1 :         ASSERT_EQUALS("", errout_str());
    1016             : 
    1017           1 :         check("void f(int x) {\n"
    1018             :               "    if ((x == 1) && (x == 0x00000001))\n"
    1019             :               "        a++;\n"
    1020             :               "}");
    1021           1 :         ASSERT_EQUALS("[test.cpp:2] -> [test.cpp:2]: (style) Condition 'x==0x00000001' is always true\n", errout_str());
    1022             : 
    1023           1 :         check("void f(int x) {\n"
    1024             :               "    if (x == 1 && x == 3)\n"
    1025             :               "        a++;\n"
    1026             :               "}");
    1027           1 :         ASSERT_EQUALS("[test.cpp:2]: (warning) Logical conjunction always evaluates to false: x == 1 && x == 3.\n", errout_str());
    1028             : 
    1029           1 :         check("void f(int x) {\n"
    1030             :               "    if (x == 1.0 && x == 3.0)\n"
    1031             :               "        a++;\n"
    1032             :               "}");
    1033           1 :         ASSERT_EQUALS("", errout_str()); // float comparisons with == and != are not checked right now - such comparison is a bad idea
    1034             : 
    1035           1 :         check("void f(float x) {\n"
    1036             :               "    if (x == 1 && x == 1.0)\n"
    1037             :               "        a++;\n"
    1038             :               "}");
    1039           1 :         ASSERT_EQUALS("", errout_str());
    1040             : 
    1041           1 :         check("void bar(float f) {\n" // #5246
    1042             :               "    if ((f > 0) && (f < 1)) {}\n"
    1043             :               "}");
    1044           1 :         ASSERT_EQUALS("", errout_str());
    1045             : 
    1046           1 :         check("void f(int x) {\n"
    1047             :               "    if (x < 1 && x > 1)\n"
    1048             :               "        a++;\n"
    1049             :               "}");
    1050           1 :         ASSERT_EQUALS("[test.cpp:2]: (warning) Logical conjunction always evaluates to false: x < 1 && x > 1.\n", errout_str());
    1051             : 
    1052           1 :         check("void f(int x) {\n"
    1053             :               "    if (x < 1.0 && x > 1.0)\n"
    1054             :               "        a++;\n"
    1055             :               "}");
    1056           1 :         ASSERT_EQUALS("[test.cpp:2]: (warning) Logical conjunction always evaluates to false: x < 1.0 && x > 1.0.\n", errout_str());
    1057             : 
    1058           1 :         check("void f(int x) {\n"
    1059             :               "    if (x < 1 && x > 1.0)\n"
    1060             :               "        a++;\n"
    1061             :               "}");
    1062           1 :         ASSERT_EQUALS("[test.cpp:2]: (warning) Logical conjunction always evaluates to false: x < 1 && x > 1.0.\n", errout_str());
    1063             : 
    1064           1 :         check("void f(int x) {\n"
    1065             :               "    if (x >= 1.0 && x <= 1.001)\n"
    1066             :               "        a++;\n"
    1067             :               "}");
    1068           1 :         ASSERT_EQUALS("", errout_str());
    1069             : 
    1070           1 :         check("void f(int x) {\n"
    1071             :               "    if (x < 1 && x > 3)\n"
    1072             :               "        a++;\n"
    1073             :               "}");
    1074           1 :         ASSERT_EQUALS("[test.cpp:2]: (warning) Logical conjunction always evaluates to false: x < 1 && x > 3.\n", errout_str());
    1075             : 
    1076           1 :         check("void f(float x) {\n"
    1077             :               "    if (x < 1.0 && x > 3.0)\n"
    1078             :               "        a++;\n"
    1079             :               "}");
    1080           1 :         ASSERT_EQUALS("[test.cpp:2]: (warning) Logical conjunction always evaluates to false: x < 1.0 && x > 3.0.\n", errout_str());
    1081             : 
    1082           1 :         check("void f(int x) {\n"
    1083             :               "    if (1 > x && 3 < x)\n"
    1084             :               "        a++;\n"
    1085             :               "}");
    1086           1 :         ASSERT_EQUALS("[test.cpp:2]: (warning) Logical conjunction always evaluates to false: x < 1 && x > 3.\n", errout_str());
    1087             : 
    1088           1 :         check("void f(int x) {\n"
    1089             :               "    if (x < 3 && x > 1)\n"
    1090             :               "        a++;\n"
    1091             :               "}");
    1092           1 :         ASSERT_EQUALS("", errout_str());
    1093             : 
    1094           1 :         check("void f(int x) {\n"
    1095             :               "    if (x > 3 || x < 10)\n"
    1096             :               "        a++;\n"
    1097             :               "}");
    1098           1 :         ASSERT_EQUALS("[test.cpp:2]: (warning) Logical disjunction always evaluates to true: x > 3 || x < 10.\n", errout_str());
    1099             : 
    1100           1 :         check("void f(int x) {\n"
    1101             :               "    if (x >= 3 || x <= 10)\n"
    1102             :               "        a++;\n"
    1103             :               "}");
    1104           1 :         ASSERT_EQUALS("[test.cpp:2]: (warning) Logical disjunction always evaluates to true: x >= 3 || x <= 10.\n", errout_str());
    1105             : 
    1106           1 :         check("void f(int x) {\n"
    1107             :               "    if (x >= 3 || x < 10)\n"
    1108             :               "        a++;\n"
    1109             :               "}");
    1110           1 :         ASSERT_EQUALS("[test.cpp:2]: (warning) Logical disjunction always evaluates to true: x >= 3 || x < 10.\n", errout_str());
    1111             : 
    1112           1 :         check("void f(int x) {\n"
    1113             :               "    if (x > 3 || x <= 10)\n"
    1114             :               "        a++;\n"
    1115             :               "}");
    1116           1 :         ASSERT_EQUALS("[test.cpp:2]: (warning) Logical disjunction always evaluates to true: x > 3 || x <= 10.\n", errout_str());
    1117             : 
    1118           1 :         check("void f(int x) {\n"
    1119             :               "    if (x > 3 || x < 3)\n"
    1120             :               "        a++;\n"
    1121             :               "}");
    1122           1 :         ASSERT_EQUALS("", errout_str());
    1123             : 
    1124           1 :         check("void f(int x) {\n"
    1125             :               "    if (x >= 3 || x <= 3)\n"
    1126             :               "        a++;\n"
    1127             :               "}"
    1128             :               );
    1129           1 :         ASSERT_EQUALS("[test.cpp:2]: (warning) Logical disjunction always evaluates to true: x >= 3 || x <= 3.\n", errout_str());
    1130             : 
    1131           1 :         check("void f(int x) {\n"
    1132             :               "    if (x >= 3 || x < 3)\n"
    1133             :               "        a++;\n"
    1134             :               "}"
    1135             :               );
    1136           1 :         ASSERT_EQUALS("[test.cpp:2]: (warning) Logical disjunction always evaluates to true: x >= 3 || x < 3.\n", errout_str());
    1137             : 
    1138           1 :         check("void f(int x) {\n"
    1139             :               "    if (x > 3 || x <= 3)\n"
    1140             :               "        a++;\n"
    1141             :               "}"
    1142             :               );
    1143           1 :         ASSERT_EQUALS("[test.cpp:2]: (warning) Logical disjunction always evaluates to true: x > 3 || x <= 3.\n", errout_str());
    1144             : 
    1145           1 :         check("void f(int x) {\n"
    1146             :               "   if((x==3) && (x!=4))\n"
    1147             :               "        a++;\n"
    1148             :               "}");
    1149           1 :         ASSERT_EQUALS("[test.cpp:2]: (style) Redundant condition: The condition 'x != 4' is redundant since 'x == 3' is sufficient.\n", errout_str());
    1150             : 
    1151           1 :         check("void f(const std::string &s) {\n" // #8860
    1152             :               "    const std::size_t p = s.find(\"42\");\n"
    1153             :               "    const std::size_t * const ptr = &p;\n"
    1154             :               "    if(p != std::string::npos && p == 0 && *ptr != 1){;}\n"
    1155             :               "}");
    1156           1 :         ASSERT_EQUALS("[test.cpp:4] -> [test.cpp:4]: (style) Condition '*ptr!=1' is always true\n", errout_str());
    1157             : 
    1158           1 :         check("void f(int x) {\n"
    1159             :               "    if ((x!=4) && (x==3))\n"
    1160             :               "        a++;\n"
    1161             :               "}");
    1162           1 :         ASSERT_EQUALS("[test.cpp:2]: (style) Redundant condition: The condition 'x != 4' is redundant since 'x == 3' is sufficient.\n", errout_str());
    1163             : 
    1164           1 :         check("void f(int x) {\n"
    1165             :               "    if ((x==3) || (x!=4))\n"
    1166             :               "        a++;\n"
    1167             :               "}");
    1168           1 :         ASSERT_EQUALS("[test.cpp:2]: (style) Redundant condition: The condition 'x == 3' is redundant since 'x != 4' is sufficient.\n", errout_str());
    1169             : 
    1170           1 :         check("void f(int x) {\n"
    1171             :               "    if ((x!=4) || (x==3))\n"
    1172             :               "        a++;\n"
    1173             :               "}");
    1174           1 :         ASSERT_EQUALS("[test.cpp:2]: (style) Redundant condition: The condition 'x == 3' is redundant since 'x != 4' is sufficient.\n", errout_str());
    1175             : 
    1176           1 :         check("void f(int x) {\n"
    1177             :               "    if ((x==3) && (x!=3))\n"
    1178             :               "        a++;\n"
    1179             :               "}");
    1180           1 :         ASSERT_EQUALS("[test.cpp:2]: (warning) Logical conjunction always evaluates to false: x == 3 && x != 3.\n", errout_str());
    1181             : 
    1182           1 :         check("void f(int x) {\n"
    1183             :               "    if ((x==6) || (x!=6))\n"
    1184             :               "        a++;\n"
    1185             :               "}");
    1186           1 :         ASSERT_EQUALS("[test.cpp:2]: (warning) Logical disjunction always evaluates to true: x == 6 || x != 6.\n", errout_str());
    1187             : 
    1188           1 :         check("void f(int x) {\n"
    1189             :               "    if (x > 10 || x < 3)\n"
    1190             :               "        a++;\n"
    1191             :               "}");
    1192           1 :         ASSERT_EQUALS("", errout_str());
    1193             : 
    1194           1 :         check("void f(int x) {\n"
    1195             :               "    if (x > 5 && x == 1)\n"
    1196             :               "        a++;\n"
    1197             :               "}");
    1198           1 :         ASSERT_EQUALS("[test.cpp:2]: (warning) Logical conjunction always evaluates to false: x > 5 && x == 1.\n", errout_str());
    1199             : 
    1200           1 :         check("void f(int x) {\n"
    1201             :               "    if (x > 5 && x == 6)\n"
    1202             :               "        a++;\n"
    1203             :               "}");
    1204           1 :         ASSERT_EQUALS("[test.cpp:2]: (style) Redundant condition: The condition 'x > 5' is redundant since 'x == 6' is sufficient.\n", errout_str());
    1205             : 
    1206             :         // #3419
    1207           1 :         check("void f() {\n"
    1208             :               "    if ( &q != &a && &q != &b ) { }\n"
    1209             :               "}");
    1210           1 :         ASSERT_EQUALS("", errout_str());
    1211             : 
    1212             :         // #3676
    1213           1 :         check("void f(int m_x2, int w, int x) {\n"
    1214             :               "    if (x + w - 1 > m_x2 || m_x2 < 0 )\n"
    1215             :               "        m_x2 = x + w - 1;\n"
    1216             :               "}");
    1217           1 :         ASSERT_EQUALS("", errout_str());
    1218             : 
    1219           1 :         check("void f(float x) {\n" // x+1 => x
    1220             :               "  if (x <= 1.0e20 && x >= -1.0e20) {}\n"
    1221             :               "}");
    1222           1 :         ASSERT_EQUALS("", errout_str());
    1223             : 
    1224           1 :         check("void f(float x) {\n" // x+1 => x
    1225             :               "  if (x >= 1.0e20 && x <= 1.0e21) {}\n"
    1226             :               "}");
    1227           1 :         ASSERT_EQUALS("", errout_str());
    1228             : 
    1229           1 :         check("void f(float x) {\n" // x+1 => x
    1230             :               "  if (x <= -1.0e20 && x >= -1.0e21) {}\n"
    1231             :               "}");
    1232           1 :         ASSERT_EQUALS("", errout_str());
    1233             :     }
    1234             : 
    1235           1 :     void incorrectLogicOperator3() {
    1236           1 :         check("void f(int x, bool& b) {\n"
    1237             :               "    b = x > 5 && x == 1;\n"
    1238             :               "    c = x < 1 && x == 3;\n"
    1239             :               "    d = x >= 5 && x == 1;\n"
    1240             :               "    e = x <= 1 && x == 3;\n"
    1241             :               "}");
    1242           1 :         ASSERT_EQUALS("[test.cpp:2]: (warning) Logical conjunction always evaluates to false: x > 5 && x == 1.\n"
    1243             :                       "[test.cpp:3]: (warning) Logical conjunction always evaluates to false: x < 1 && x == 3.\n"
    1244             :                       "[test.cpp:4]: (warning) Logical conjunction always evaluates to false: x >= 5 && x == 1.\n"
    1245             :                       "[test.cpp:5]: (warning) Logical conjunction always evaluates to false: x <= 1 && x == 3.\n", errout_str());
    1246             :     }
    1247             : 
    1248           1 :     void incorrectLogicOperator4() {
    1249           1 :         check("#define ZERO 0\n"
    1250             :               "void f(int x) {\n"
    1251             :               "  if (x && x != ZERO) {}\n"
    1252             :               "}");
    1253           1 :         ASSERT_EQUALS("", errout_str());
    1254             : 
    1255           1 :         check("void f(int N) {\n" // #9789
    1256             :               "    T a[20] = { 0 };\n"
    1257             :               "    for (int i = 0; i < N; ++i) {\n"
    1258             :               "        if (0 < a[i] && a[i] < 1) {}\n"
    1259             :               "    }\n"
    1260             :               "}\n");
    1261           1 :         ASSERT_EQUALS("", errout_str());
    1262             :     }
    1263             : 
    1264           1 :     void incorrectLogicOperator5() { // complex expressions
    1265           1 :         check("void f(int x) {\n"
    1266             :               "  if (x+3 > 2 || x+3 < 10) {}\n"
    1267             :               "}");
    1268           1 :         ASSERT_EQUALS("[test.cpp:2]: (warning) Logical disjunction always evaluates to true: x+3 > 2 || x+3 < 10.\n", errout_str());
    1269             :     }
    1270             : 
    1271           1 :     void incorrectLogicOperator6() { // char literals
    1272           1 :         check("void f(char x) {\n"
    1273             :               "  if (x == '1' || x == '2') {}\n"
    1274             :               "}", "test.cpp", true);
    1275           1 :         ASSERT_EQUALS("", errout_str());
    1276             : 
    1277           1 :         check("void f(char x) {\n"
    1278             :               "  if (x == '1' && x == '2') {}\n"
    1279             :               "}", "test.cpp", true);
    1280           1 :         ASSERT_EQUALS("[test.cpp:2]: (warning) Logical conjunction always evaluates to false: x == '1' && x == '2'.\n", errout_str());
    1281             : 
    1282           1 :         check("int f(char c) {\n"
    1283             :               "  return (c >= 'a' && c <= 'z');\n"
    1284             :               "}", "test.cpp", true);
    1285           1 :         ASSERT_EQUALS("", errout_str());
    1286             : 
    1287           1 :         check("int f(char c) {\n"
    1288             :               "  return (c <= 'a' && c >= 'z');\n"
    1289             :               "}", "test.cpp", true);
    1290           1 :         ASSERT_EQUALS("[test.cpp:2]: (warning, inconclusive) Logical conjunction always evaluates to false: c <= 'a' && c >= 'z'.\n", errout_str());
    1291             : 
    1292           1 :         check("int f(char c) {\n"
    1293             :               "  return (c <= 'a' && c >= 'z');\n"
    1294             :               "}", "test.cpp", false);
    1295           1 :         ASSERT_EQUALS("[test.cpp:2] -> [test.cpp:2]: (style) Return value 'c>='z'' is always false\n", errout_str());
    1296             :     }
    1297             : 
    1298           1 :     void incorrectLogicOperator7() { // opposite expressions
    1299           1 :         check("void f(int i) {\n"
    1300             :               "  if (i || !i) {}\n"
    1301             :               "}");
    1302           1 :         ASSERT_EQUALS("[test.cpp:2]: (warning) Logical disjunction always evaluates to true: i || !(i).\n", errout_str());
    1303             : 
    1304           1 :         check("void f(int a, int b) {\n"
    1305             :               "  if (a>b || a<=b) {}\n"
    1306             :               "}");
    1307           1 :         ASSERT_EQUALS("[test.cpp:2]: (warning) Logical disjunction always evaluates to true: a > b || a <= b.\n", errout_str());
    1308             : 
    1309           1 :         check("void f(int a, int b) {\n"
    1310             :               "  if (a>b || a<b) {}\n"
    1311             :               "}");
    1312           1 :         ASSERT_EQUALS("", errout_str());
    1313             : 
    1314             :         // #6064 False positive incorrectLogicOperator - invalid assumption about template type?
    1315           1 :         check("template<typename T> T icdf( const T uniform ) {\n"
    1316             :               "   if ((0<uniform) && (uniform<1))\n"
    1317             :               "     {}\n"
    1318             :               "}");
    1319           1 :         ASSERT_EQUALS("", errout_str());
    1320             : 
    1321             :         // #6081 False positive: incorrectLogicOperator, with close negative comparisons
    1322           1 :         check("double neg = -1.0 - 1.0e-13;\n"
    1323             :               "void foo() {\n"
    1324             :               "    if ((neg < -1.0) && (neg > -1.0 - 1.0e-12))\n"
    1325             :               "        return;\n"
    1326             :               "    else\n"
    1327             :               "        return;\n"
    1328             :               "}");
    1329           1 :         ASSERT_EQUALS("", errout_str());
    1330             :     }
    1331             : 
    1332           1 :     void incorrectLogicOperator8() { // opposite expressions
    1333           1 :         check("void f(int i) {\n"
    1334             :               "  if (!(i!=10) && !(i!=20)) {}\n"
    1335             :               "}");
    1336           1 :         ASSERT_EQUALS("[test.cpp:2]: (warning) Logical conjunction always evaluates to false: !(i != 10) && !(i != 20).\n", errout_str());
    1337             :     }
    1338             : 
    1339           1 :     void incorrectLogicOperator9() { //  #6069 "False positive incorrectLogicOperator due to dynamic_cast"
    1340           1 :         check("class MyType;\n"
    1341             :               "class OtherType;\n"
    1342             :               "void foo (OtherType* obj) {\n"
    1343             :               "    assert((!obj) || dynamic_cast<MyType*>(obj));\n"
    1344             :               "}");
    1345           1 :         ASSERT_EQUALS("", errout_str());
    1346             :     }
    1347             : 
    1348           1 :     void incorrectLogicOperator10() { //  #7794 - enum
    1349           1 :         check("typedef enum { A, B } Type_t;\n"
    1350             :               "void f(Type_t t) {\n"
    1351             :               "    if ((t == A) && (t == B))\n"
    1352             :               "    {}\n"
    1353             :               "}");
    1354           1 :         ASSERT_EQUALS("[test.cpp:3]: (warning) Logical conjunction always evaluates to false: t == 0 && t == 1.\n", errout_str());
    1355             :     }
    1356             : 
    1357           1 :     void incorrectLogicOperator11() {
    1358           1 :         check("void foo(int i, const int n) { if ( i < n && i == n ) {} }");
    1359           1 :         ASSERT_EQUALS("[test.cpp:1]: (warning) Logical conjunction always evaluates to false: i < n && i == n.\n", errout_str());
    1360             : 
    1361           1 :         check("void foo(int i, const int n) { if ( i > n && i == n ) {} }");
    1362           1 :         ASSERT_EQUALS("[test.cpp:1]: (warning) Logical conjunction always evaluates to false: i > n && i == n.\n", errout_str());
    1363             : 
    1364           1 :         check("void foo(int i, const int n) { if ( i == n && i > n ) {} }");
    1365           1 :         ASSERT_EQUALS("[test.cpp:1]: (warning) Logical conjunction always evaluates to false: i == n && i > n.\n", errout_str());
    1366             : 
    1367           1 :         check("void foo(int i, const int n) { if ( i == n && i < n ) {} }");
    1368           1 :         ASSERT_EQUALS("[test.cpp:1]: (warning) Logical conjunction always evaluates to false: i == n && i < n.\n", errout_str());
    1369             :     }
    1370             : 
    1371           1 :     void incorrectLogicOperator12() { // #8696
    1372           1 :         check("struct A {\n"
    1373             :               "    void f() const;\n"
    1374             :               "};\n"
    1375             :               "void foo(A a, A b) {\n"
    1376             :               "  A x = b;\n"
    1377             :               "  A y = b;\n"
    1378             :               "  y.f();\n"
    1379             :               "  if (a > x && a < y)\n"
    1380             :               "    return;\n"
    1381             :               "}");
    1382           1 :         ASSERT_EQUALS(
    1383             :             "[test.cpp:5] -> [test.cpp:6] -> [test.cpp:8]: (warning) Logical conjunction always evaluates to false: a > x && a < y.\n",
    1384             :             errout_str());
    1385             : 
    1386           1 :         check("struct A {\n"
    1387             :               "    void f();\n"
    1388             :               "};\n"
    1389             :               "void foo(A a, A b) {\n"
    1390             :               "  A x = b;\n"
    1391             :               "  A y = b;\n"
    1392             :               "  y.f();\n"
    1393             :               "  if (a > x && a < y)\n"
    1394             :               "    return;\n"
    1395             :               "}");
    1396           1 :         ASSERT_EQUALS("", errout_str());
    1397             : 
    1398           1 :         check("void foo(A a, A b) {\n"
    1399             :               "  A x = b;\n"
    1400             :               "  A y = b;\n"
    1401             :               "  y.f();\n"
    1402             :               "  if (a > x && a < y)\n"
    1403             :               "    return;\n"
    1404             :               "}");
    1405           1 :         ASSERT_EQUALS("", errout_str());
    1406             : 
    1407           1 :         check("void foo(A a, A b) {\n"
    1408             :               "  const A x = b;\n"
    1409             :               "  const A y = b;\n"
    1410             :               "  y.f();\n"
    1411             :               "  if (a > x && a < y)\n"
    1412             :               "    return;\n"
    1413             :               "}");
    1414           1 :         ASSERT_EQUALS(
    1415             :             "[test.cpp:2] -> [test.cpp:3] -> [test.cpp:5]: (warning) Logical conjunction always evaluates to false: a > x && a < y.\n",
    1416             :             errout_str());
    1417             : 
    1418           1 :         check("struct A {\n"
    1419             :               "    void f() const;\n"
    1420             :               "};\n"
    1421             :               "void foo(A a) {\n"
    1422             :               "  A x = a;\n"
    1423             :               "  A y = a;\n"
    1424             :               "  y.f();\n"
    1425             :               "  if (a > x && a < y)\n"
    1426             :               "    return;\n"
    1427             :               "}");
    1428           1 :         ASSERT_EQUALS("[test.cpp:8]: (style) Condition 'a>x' is always false\n"
    1429             :                       "[test.cpp:8]: (style) Condition 'a<y' is always false\n",
    1430             :                       errout_str());
    1431             : 
    1432           1 :         check("struct A {\n"
    1433             :               "    void f();\n"
    1434             :               "};\n"
    1435             :               "void foo(A a) {\n"
    1436             :               "  A x = a;\n"
    1437             :               "  A y = a;\n"
    1438             :               "  y.f();\n"
    1439             :               "  if (a > x && a < y)\n"
    1440             :               "    return;\n"
    1441             :               "}");
    1442           1 :         ASSERT_EQUALS("[test.cpp:8]: (style) Condition 'a>x' is always false\n", errout_str());
    1443             : 
    1444           1 :         check("void foo(A a) {\n"
    1445             :               "  A x = a;\n"
    1446             :               "  A y = a;\n"
    1447             :               "  y.f();\n"
    1448             :               "  if (a > x && a < y)\n"
    1449             :               "    return;\n"
    1450             :               "}");
    1451           1 :         ASSERT_EQUALS("[test.cpp:5]: (style) Condition 'a>x' is always false\n", errout_str());
    1452             : 
    1453           1 :         check("void foo(A a) {\n"
    1454             :               "  const A x = a;\n"
    1455             :               "  const A y = a;\n"
    1456             :               "  y.f();\n"
    1457             :               "  if (a > x && a < y)\n"
    1458             :               "    return;\n"
    1459             :               "}");
    1460           1 :         ASSERT_EQUALS("[test.cpp:5]: (style) Condition 'a>x' is always false\n"
    1461             :                       "[test.cpp:5]: (style) Condition 'a<y' is always false\n",
    1462             :                       errout_str());
    1463             :     }
    1464             : 
    1465           1 :     void incorrectLogicOperator13() {
    1466             :         // 8780
    1467           1 :         check("void f(const int &v) {\n"
    1468             :               "    const int x=v;\n"
    1469             :               "    if ((v == 1) && (x == 2)) {;}\n"
    1470             :               "}");
    1471           1 :         ASSERT_EQUALS("[test.cpp:2] -> [test.cpp:3]: (warning) Logical conjunction always evaluates to false: v == 1 && x == 2.\n", errout_str());
    1472             : 
    1473           1 :         check("void f2(const int *v) {\n"
    1474             :               "    const int *x=v;\n"
    1475             :               "    if ((*v == 1) && (*x == 2)) {;}\n"
    1476             :               "}");
    1477           1 :         ASSERT_EQUALS("[test.cpp:2] -> [test.cpp:3]: (warning) Logical conjunction always evaluates to false: *(v) == 1 && *(x) == 2.\n", errout_str());
    1478             :     }
    1479             : 
    1480           1 :     void incorrectLogicOperator14() {
    1481           1 :         check("static const std ::string h;\n"
    1482             :               "class i {\n"
    1483             :               "public:\n"
    1484             :               "  struct j {\n"
    1485             :               "    std ::string k;\n"
    1486             :               "    std ::string l;\n"
    1487             :               "  };\n"
    1488             :               "  struct a {\n"
    1489             :               "    enum { m = 1 };\n"
    1490             :               "  };\n"
    1491             :               "} b;\n"
    1492             :               "namespace n {\n"
    1493             :               "class c;\n"
    1494             :               "}\n"
    1495             :               "struct o {\n"
    1496             :               "  enum { p, d, q, r };\n"
    1497             :               "  enum { e, f };\n"
    1498             :               "\n"
    1499             :               "public:\n"
    1500             :               "  class j {\n"
    1501             :               "  public:\n"
    1502             :               "    class s {\n"
    1503             :               "      std ::string a;\n"
    1504             :               "    };\n"
    1505             :               "  };\n"
    1506             :               "};\n"
    1507             :               "namespace n {\n"
    1508             :               "class b;\n"
    1509             :               "}\n"
    1510             :               "namespace aa {\n"
    1511             :               "class d {\n"
    1512             :               "public:\n"
    1513             :               "  char t;\n"
    1514             :               "  enum {} u;\n"
    1515             :               "};\n"
    1516             :               "} // namespace aa\n"
    1517             :               "namespace aa {\n"
    1518             :               "struct e {};\n"
    1519             :               "} // namespace aa\n"
    1520             :               "class a;\n"
    1521             :               "class w {\n"
    1522             :               "public:\n"
    1523             :               "  enum { x };\n"
    1524             :               "  struct {\n"
    1525             :               "  } y;\n"
    1526             :               "  std ::string z;\n"
    1527             :               "};\n"
    1528             :               "class ab {\n"
    1529             :               "  friend class c;\n"
    1530             :               "\n"
    1531             :               "public:\n"
    1532             :               "  class ac {\n"
    1533             :               "    void e(const ac &v) const;\n"
    1534             :               "  };\n"
    1535             :               "};\n"
    1536             :               "class f;\n"
    1537             :               "class ad {\n"
    1538             :               "  friend class e;\n"
    1539             :               "  enum { e, ae, ag, ah, ai, aj, ak, a, b };\n"
    1540             :               "  class c {};\n"
    1541             :               "  class d {\n"
    1542             :               "    enum am { f, an, ao, ap, aq, ar, b, as, at, c, au };\n"
    1543             :               "    enum av { aw, ax, ay, az, e, ba, bb, bc, bd, a };\n"
    1544             :               "    struct b {\n"
    1545             :               "      am action;\n"
    1546             :               "      av c;\n"
    1547             :               "    };\n"
    1548             :               "  };\n"
    1549             :               "  class e {\n"
    1550             :               "  public:\n"
    1551             :               "    std ::string e;\n"
    1552             :               "    class f {\n"
    1553             :               "    } f;\n"
    1554             :               "    class be {\n"
    1555             :               "    public:\n"
    1556             :               "    };\n"
    1557             :               "    std ::vector<be> bf;\n"
    1558             :               "    enum { bg, b } c;\n"
    1559             :               "  };\n"
    1560             :               "  struct bh {\n"
    1561             :               "    std ::map<int, d> b;\n"
    1562             :               "  };\n"
    1563             :               "  std ::map<std ::string, bh> bi;\n"
    1564             :               "  struct {\n"
    1565             :               "    int b;\n"
    1566             :               "    char bj;\n"
    1567             :               "  } bk;\n"
    1568             :               "  class a {\n"
    1569             :               "  public:\n"
    1570             :               "    std ::set<std ::string> b;\n"
    1571             :               "  };\n"
    1572             :               "};\n"
    1573             :               "class bl;\n"
    1574             :               "class al;\n"
    1575             :               "class bm;\n"
    1576             :               "class f;\n"
    1577             :               "class b;\n"
    1578             :               "class bn;\n"
    1579             :               "namespace bo {\n"
    1580             :               "class bp {\n"
    1581             :               "public:\n"
    1582             :               "  typedef std ::pair<const f *, std ::string> bq;\n"
    1583             :               "  typedef std ::list<bq> br;\n"
    1584             :               "};\n"
    1585             :               "const bo ::bp *dg(const f *a, const al *b);\n"
    1586             :               "} // namespace bo\n"
    1587             :               "const bn *dh(const f *d, bo ::bp ::br &bs);\n"
    1588             :               "class f {\n"
    1589             :               "public:\n"
    1590             :               "  struct bt {};\n"
    1591             :               "  std ::vector<a> f;\n"
    1592             :               "};\n"
    1593             :               "class bu;\n"
    1594             :               "class a;\n"
    1595             :               "class c;\n"
    1596             :               "struct bv {};\n"
    1597             :               "class af {\n"
    1598             :               "private:\n"
    1599             :               "public:\n"
    1600             :               "  enum { b, d, e, f, c, bw };\n"
    1601             :               "  void a(int c);\n"
    1602             :               "  af *bx() const;\n"
    1603             :               "};\n"
    1604             :               "namespace by {\n"
    1605             :               "class b;\n"
    1606             :               "}\n"
    1607             :               "class b {\n"
    1608             :               "public:\n"
    1609             :               "  bool d, c;\n"
    1610             :               "};\n"
    1611             :               "class bz;\n"
    1612             :               "class f;\n"
    1613             :               "class ca {\n"
    1614             :               "  friend class b;\n"
    1615             :               "\n"
    1616             :               "public:\n"
    1617             :               "  const bm *cb() const { return cc; }\n"
    1618             :               "  f *d(f *e, bool f) const;\n"
    1619             :               "  int e() { return ++cd; }\n"
    1620             :               "  bl *const c;\n"
    1621             :               "  bm *cc;\n"
    1622             :               "  std ::map<std ::string, int> ce;\n"
    1623             :               "  int cd;\n"
    1624             :               "  bz *a;\n"
    1625             :               "};\n"
    1626             :               "namespace n {\n"
    1627             :               "class c;\n"
    1628             :               "class d;\n"
    1629             :               "} // namespace n\n"
    1630             :               "class cf {\n"
    1631             :               "public:\n"
    1632             :               "  explicit cf(const std ::string &aname);\n"
    1633             :               "  cf(const std ::string &aname, const ca *cg, const al *ch, bl *ci)\n"
    1634             :               "      : cj(cg), ck(ch), cl(ci), cn(aname) {}\n"
    1635             :               "\n"
    1636             :               "protected:\n"
    1637             :               "  const ca *const cj;\n"
    1638             :               "  const al *const ck;\n"
    1639             :               "  bl *const cl;\n"
    1640             :               "  const std ::string cn;\n"
    1641             :               "};\n"
    1642             :               "class cm : public cf {\n"
    1643             :               "public:\n"
    1644             :               "  void cp();\n"
    1645             :               "  std ::string d() const;\n"
    1646             :               "};\n"
    1647             :               "struct co {\n"
    1648             :               "  co();\n"
    1649             :               "  const bu *a;\n"
    1650             :               "  enum f {};\n"
    1651             :               "  enum {\n"
    1652             :               "    b = (1 << 0),\n"
    1653             :               "    c = (1 << 1),\n"
    1654             :               "  };\n"
    1655             :               "  void d(bool e);\n"
    1656             :               "};\n"
    1657             :               "class bu {\n"
    1658             :               "  friend class e;\n"
    1659             :               "\n"
    1660             :               "public:\n"
    1661             :               "  struct f {};\n"
    1662             :               "  enum { d, cr, cq, ct, cs, e, a, b, c, dd, cu, cv, cw, cx, cy, cz, da };\n"
    1663             :               "  const f *db;\n"
    1664             :               "  const af *dc;\n"
    1665             :               "} f{};\n"
    1666             :               "class bm {\n"
    1667             :               "public:\n"
    1668             :               "  std ::list<bu> df;\n"
    1669             :               "  std ::vector<const bu *> de;\n"
    1670             :               "  mutable std ::set<std ::string> f;\n"
    1671             :               "};\n"
    1672             :               "void cm ::cp() {\n"
    1673             :               "  const bm *a = cj->cb();\n"
    1674             :               "  for (const bu *b : a->de)\n"
    1675             :               "    for (af *c = b->dc->bx();;) {\n"
    1676             :               "      af *d = c;\n"
    1677             :               "      af *e = c;\n"
    1678             :               "      bool f(d);\n"
    1679             :               "      bool g(e);\n"
    1680             :               "      if (f && g)\n"
    1681             :               "        ;\n"
    1682             :               "    }\n"
    1683             :               "}");
    1684           1 :         ASSERT_EQUALS("[test.cpp:200] -> [test.cpp:200]: (style) Condition 'g' is always true\n", errout_str());
    1685             :     }
    1686             : 
    1687           1 :     void incorrectLogicOperator15() {
    1688             :         // 10022
    1689           1 :         check("struct PipeRoute {\n"
    1690             :               "    std::deque<int> points;\n"
    1691             :               "    std::deque<int> estimates;\n"
    1692             :               "};\n"
    1693             :               "void CleanPipeRoutes(std::map<int, PipeRoute*>& pipeRoutes) {\n"
    1694             :               "    for (auto it = pipeRoutes.begin(); it != pipeRoutes.end(); ) {\n"
    1695             :               "        PipeRoute* curRoute = it->second;\n"
    1696             :               "        if (curRoute->points.empty() && curRoute->estimates.size() != 2)\n"
    1697             :               "        {\n"
    1698             :               "            delete curRoute;\n"
    1699             :               "            it = pipeRoutes.erase(it);\n"
    1700             :               "        }\n"
    1701             :               "        else\n"
    1702             :               "        {\n"
    1703             :               "            ++it;\n"
    1704             :               "        }\n"
    1705             :               "    }\n"
    1706             :               "}\n");
    1707           1 :         ASSERT_EQUALS("", errout_str());
    1708             :     }
    1709             : 
    1710           1 :     void incorrectLogicOperator16() { // #10070
    1711           1 :         check("void foo(void* p) {\n"
    1712             :               "    if (!p || p == -1) { }\n"
    1713             :               "}\n");
    1714           1 :         ASSERT_EQUALS("", errout_str());
    1715             :     }
    1716             : 
    1717           1 :     void incorrectLogicOperator17() { // #12471
    1718           1 :         check("struct R {\n"
    1719             :               "    void set() { i = 1; }\n"
    1720             :               "    int get() const { return i; }\n"
    1721             :               "    int i;\n"
    1722             :               "};\n"
    1723             :               "struct P {\n"
    1724             :               "    void f();\n"
    1725             :               "    R* r;\n"
    1726             :               "};\n"
    1727             :               "void P::f() {\n"
    1728             :               "    int a = r->get();\n"
    1729             :               "    r->set();\n"
    1730             :               "    if (a == 0 && r->get()) {}\n"
    1731             :               "}\n");
    1732           1 :         ASSERT_EQUALS("", errout_str());
    1733             :     }
    1734             : 
    1735           1 :     void secondAlwaysTrueFalseWhenFirstTrueError() {
    1736           1 :         check("void f(void) {\n" // #8892
    1737             :               "    const char c[1] = { \'x\' }; \n"
    1738             :               "    if(c[0] == \'x\'){;}\n"
    1739             :               "}");
    1740           1 :         ASSERT_EQUALS("[test.cpp:3]: (style) Condition 'c[0]=='x'' is always true\n", errout_str());
    1741             : 
    1742           1 :         check("void f(int x) {\n"
    1743             :               "    if (x > 5 && x != 1)\n"
    1744             :               "        a++;\n"
    1745             :               "}");
    1746           1 :         ASSERT_EQUALS("[test.cpp:2]: (style) Redundant condition: The condition 'x != 1' is redundant since 'x > 5' is sufficient.\n", errout_str());
    1747             : 
    1748           1 :         check("void f(int x) {\n"
    1749             :               "    if (x > 5 && x != 6)\n"
    1750             :               "        a++;\n"
    1751             :               "}");
    1752           1 :         ASSERT_EQUALS("", errout_str());
    1753             : 
    1754           1 :         check("void f(int x) {\n"
    1755             :               "    if ((x > 5) && (x != 1))\n"
    1756             :               "        a++;\n"
    1757             :               "}");
    1758           1 :         ASSERT_EQUALS("[test.cpp:2]: (style) Redundant condition: The condition 'x != 1' is redundant since 'x > 5' is sufficient.\n", errout_str());
    1759             : 
    1760           1 :         check("void f(int x) {\n"
    1761             :               "    if ((x > 5) && (x != 6))\n"
    1762             :               "        a++;\n"
    1763             :               "}");
    1764           1 :         ASSERT_EQUALS("", errout_str());
    1765             : 
    1766           1 :         check("void f(int x, bool& b) {\n"
    1767             :               "    b = x > 3 || x == 4;\n"
    1768             :               "    c = x < 5 || x == 4;\n"
    1769             :               "    d = x >= 3 || x == 4;\n"
    1770             :               "    e = x <= 5 || x == 4;\n"
    1771             :               "}");
    1772           1 :         ASSERT_EQUALS("[test.cpp:2]: (style) Redundant condition: The condition 'x == 4' is redundant since 'x > 3' is sufficient.\n"
    1773             :                       "[test.cpp:3]: (style) Redundant condition: The condition 'x == 4' is redundant since 'x < 5' is sufficient.\n"
    1774             :                       "[test.cpp:4]: (style) Redundant condition: The condition 'x == 4' is redundant since 'x >= 3' is sufficient.\n"
    1775             :                       "[test.cpp:5]: (style) Redundant condition: The condition 'x == 4' is redundant since 'x <= 5' is sufficient.\n",
    1776             :                       errout_str());
    1777             : 
    1778           1 :         check("void f(int x, bool& b) {\n"
    1779             :               "    b = x > 5 || x != 1;\n"
    1780             :               "    c = x < 1 || x != 3;\n"
    1781             :               "    d = x >= 5 || x != 1;\n"
    1782             :               "    e = x <= 1 || x != 3;\n"
    1783             :               "}");
    1784           1 :         ASSERT_EQUALS("[test.cpp:2]: (style) Redundant condition: The condition 'x > 5' is redundant since 'x != 1' is sufficient.\n"
    1785             :                       "[test.cpp:3]: (style) Redundant condition: The condition 'x < 1' is redundant since 'x != 3' is sufficient.\n"
    1786             :                       "[test.cpp:4]: (style) Redundant condition: The condition 'x >= 5' is redundant since 'x != 1' is sufficient.\n"
    1787             :                       "[test.cpp:5]: (style) Redundant condition: The condition 'x <= 1' is redundant since 'x != 3' is sufficient.\n",
    1788             :                       errout_str());
    1789             : 
    1790           1 :         check("void f(int x, bool& b) {\n"
    1791             :               "    b = x > 6 && x > 5;\n"
    1792             :               "    c = x > 5 || x > 6;\n"
    1793             :               "    d = x < 6 && x < 5;\n"
    1794             :               "    e = x < 5 || x < 6;\n"
    1795             :               "}");
    1796           1 :         ASSERT_EQUALS("[test.cpp:2]: (style) Redundant condition: The condition 'x > 5' is redundant since 'x > 6' is sufficient.\n"
    1797             :                       "[test.cpp:3]: (style) Redundant condition: The condition 'x > 6' is redundant since 'x > 5' is sufficient.\n"
    1798             :                       "[test.cpp:4]: (style) Redundant condition: The condition 'x < 6' is redundant since 'x < 5' is sufficient.\n"
    1799             :                       "[test.cpp:5]: (style) Redundant condition: The condition 'x < 5' is redundant since 'x < 6' is sufficient.\n",
    1800             :                       errout_str());
    1801             : 
    1802           1 :         check("void f(double x, bool& b) {\n"
    1803             :               "    b = x > 6.5 && x > 5.5;\n"
    1804             :               "    c = x > 5.5 || x > 6.5;\n"
    1805             :               "    d = x < 6.5 && x < 5.5;\n"
    1806             :               "    e = x < 5.5 || x < 6.5;\n"
    1807             :               "}");
    1808           1 :         ASSERT_EQUALS("[test.cpp:2]: (style) Redundant condition: The condition 'x > 5.5' is redundant since 'x > 6.5' is sufficient.\n"
    1809             :                       "[test.cpp:3]: (style) Redundant condition: The condition 'x > 6.5' is redundant since 'x > 5.5' is sufficient.\n"
    1810             :                       "[test.cpp:4]: (style) Redundant condition: The condition 'x < 6.5' is redundant since 'x < 5.5' is sufficient.\n"
    1811             :                       "[test.cpp:5]: (style) Redundant condition: The condition 'x < 5.5' is redundant since 'x < 6.5' is sufficient.\n",
    1812             :                       errout_str());
    1813             : 
    1814           1 :         check("void f(const char *p) {\n" // #10320
    1815             :               "    if (!p || !*p || *p != 'x') {}\n"
    1816             :               "}\n");
    1817           1 :         ASSERT_EQUALS("[test.cpp:2]: (style) Redundant condition: The condition '!*p' is redundant since '*p != 'x'' is sufficient.\n",
    1818             :                       errout_str());
    1819             :     }
    1820             : 
    1821           1 :     void incorrectLogicOp_condSwapping() {
    1822           1 :         check("void f(int x) {\n"
    1823             :               "    if (x < 1 && x > 3)\n"
    1824             :               "        a++;\n"
    1825             :               "}");
    1826           1 :         ASSERT_EQUALS("[test.cpp:2]: (warning) Logical conjunction always evaluates to false: x < 1 && x > 3.\n", errout_str());
    1827             : 
    1828           1 :         check("void f(int x) {\n"
    1829             :               "    if (1 > x && x > 3)\n"
    1830             :               "        a++;\n"
    1831             :               "}");
    1832           1 :         ASSERT_EQUALS("[test.cpp:2]: (warning) Logical conjunction always evaluates to false: x < 1 && x > 3.\n", errout_str());
    1833             : 
    1834           1 :         check("void f(int x) {\n"
    1835             :               "    if (x < 1 && 3 < x)\n"
    1836             :               "        a++;\n"
    1837             :               "}");
    1838           1 :         ASSERT_EQUALS("[test.cpp:2]: (warning) Logical conjunction always evaluates to false: x < 1 && x > 3.\n", errout_str());
    1839             : 
    1840           1 :         check("void f(int x) {\n"
    1841             :               "    if (1 > x && 3 < x)\n"
    1842             :               "        a++;\n"
    1843             :               "}");
    1844           1 :         ASSERT_EQUALS("[test.cpp:2]: (warning) Logical conjunction always evaluates to false: x < 1 && x > 3.\n", errout_str());
    1845             : 
    1846           1 :         check("void f(int x) {\n"
    1847             :               "    if (x > 3 && x < 1)\n"
    1848             :               "        a++;\n"
    1849             :               "}");
    1850           1 :         ASSERT_EQUALS("[test.cpp:2]: (warning) Logical conjunction always evaluates to false: x > 3 && x < 1.\n", errout_str());
    1851             : 
    1852           1 :         check("void f(int x) {\n"
    1853             :               "    if (3 < x && x < 1)\n"
    1854             :               "        a++;\n"
    1855             :               "}");
    1856           1 :         ASSERT_EQUALS("[test.cpp:2]: (warning) Logical conjunction always evaluates to false: x > 3 && x < 1.\n", errout_str());
    1857             : 
    1858           1 :         check("void f(int x) {\n"
    1859             :               "    if (x > 3 && 1 > x)\n"
    1860             :               "        a++;\n"
    1861             :               "}");
    1862           1 :         ASSERT_EQUALS("[test.cpp:2]: (warning) Logical conjunction always evaluates to false: x > 3 && x < 1.\n", errout_str());
    1863             : 
    1864           1 :         check("void f(int x) {\n"
    1865             :               "    if (3 < x && 1 > x)\n"
    1866             :               "        a++;\n"
    1867             :               "}");
    1868           1 :         ASSERT_EQUALS("[test.cpp:2]: (warning) Logical conjunction always evaluates to false: x > 3 && x < 1.\n", errout_str());
    1869             :     }
    1870             : 
    1871           1 :     void modulo() {
    1872           1 :         check("bool f(bool& b1, bool& b2, bool& b3) {\n"
    1873             :               "    b1 = a % 5 == 4;\n"
    1874             :               "    b2 = a % c == 100000;\n"
    1875             :               "    b3 = a % 5 == c;\n"
    1876             :               "    return a % 5 == 5-p;\n"
    1877             :               "}");
    1878           1 :         ASSERT_EQUALS("", errout_str());
    1879             : 
    1880           1 :         check("bool f(bool& b1, bool& b2, bool& b3, bool& b4, bool& b5) {\n"
    1881             :               "    b1 = a % 5 < 5;\n"
    1882             :               "    b2 = a % 5 <= 5;\n"
    1883             :               "    b3 = a % 5 == 5;\n"
    1884             :               "    b4 = a % 5 != 5;\n"
    1885             :               "    b5 = a % 5 >= 5;\n"
    1886             :               "    return a % 5 > 5;\n"
    1887             :               "}");
    1888           1 :         ASSERT_EQUALS(
    1889             :             "[test.cpp:2]: (warning) Comparison of modulo result is predetermined, because it is always less than 5.\n"
    1890             :             "[test.cpp:3]: (warning) Comparison of modulo result is predetermined, because it is always less than 5.\n"
    1891             :             "[test.cpp:4]: (warning) Comparison of modulo result is predetermined, because it is always less than 5.\n"
    1892             :             "[test.cpp:5]: (warning) Comparison of modulo result is predetermined, because it is always less than 5.\n"
    1893             :             "[test.cpp:6]: (warning) Comparison of modulo result is predetermined, because it is always less than 5.\n"
    1894             :             "[test.cpp:7]: (warning) Comparison of modulo result is predetermined, because it is always less than 5.\n",
    1895             :             errout_str());
    1896             : 
    1897           1 :         check("void f(bool& b1, bool& b2) {\n"
    1898             :               "    b1 = bar() % 5 < 889;\n"
    1899             :               "    if(x[593] % 5 <= 5)\n"
    1900             :               "        b2 = x.a % 5 == 5;\n"
    1901             :               "}");
    1902           1 :         ASSERT_EQUALS(
    1903             :             "[test.cpp:2]: (warning) Comparison of modulo result is predetermined, because it is always less than 5.\n"
    1904             :             "[test.cpp:3]: (warning) Comparison of modulo result is predetermined, because it is always less than 5.\n"
    1905             :             "[test.cpp:4]: (warning) Comparison of modulo result is predetermined, because it is always less than 5.\n",
    1906             :             errout_str());
    1907             : 
    1908           1 :         check("void f() {\n"
    1909             :               "    if (a % 2 + b % 2 == 2)\n"
    1910             :               "        foo();\n"
    1911             :               "}");
    1912           1 :         ASSERT_EQUALS("", errout_str());
    1913             :     }
    1914             : 
    1915           1 :     void oppositeInnerCondition() {
    1916           1 :         check("void foo(int a, int b) {\n"
    1917             :               "    if(a==b)\n"
    1918             :               "        if(a!=b)\n"
    1919             :               "            cout << a;\n"
    1920             :               "}");
    1921           1 :         ASSERT_EQUALS("[test.cpp:2] -> [test.cpp:3]: (warning) Opposite inner 'if' condition leads to a dead code block.\n", errout_str());
    1922             : 
    1923           1 :         check("bool foo(int a, int b) {\n"
    1924             :               "    if(a==b)\n"
    1925             :               "        return a!=b;\n"
    1926             :               "    return false;\n"
    1927             :               "}");
    1928           1 :         ASSERT_EQUALS("[test.cpp:2] -> [test.cpp:3]: (warning) Opposite inner 'return' condition leads to a dead code block.\n", errout_str());
    1929             : 
    1930           1 :         check("void foo(int a, int b) {\n"
    1931             :               "    if(a==b)\n"
    1932             :               "        if(b!=a)\n"
    1933             :               "            cout << a;\n"
    1934             :               "}");
    1935           1 :         ASSERT_EQUALS("[test.cpp:2] -> [test.cpp:3]: (warning) Opposite inner 'if' condition leads to a dead code block.\n", errout_str());
    1936             : 
    1937           1 :         check("void foo(int a) {\n"
    1938             :               "    if(a >= 50) {\n"
    1939             :               "        if(a < 50)\n"
    1940             :               "            cout << a;\n"
    1941             :               "        else\n"
    1942             :               "            cout << 100;\n"
    1943             :               "    }\n"
    1944             :               "}");
    1945           1 :         ASSERT_EQUALS("[test.cpp:2] -> [test.cpp:3]: (warning) Opposite inner 'if' condition leads to a dead code block.\n", errout_str());
    1946             : 
    1947             :         // #4186
    1948           1 :         check("void foo(int a) {\n"
    1949             :               "    if(a >= 50) {\n"
    1950             :               "        if(a > 50)\n"
    1951             :               "            cout << a;\n"
    1952             :               "        else\n"
    1953             :               "            cout << 100;\n"
    1954             :               "    }\n"
    1955             :               "}");
    1956           1 :         ASSERT_EQUALS("", errout_str());
    1957             : 
    1958             :         // 4170
    1959           1 :         check("class foo {\n"
    1960             :               "    void bar() {\n"
    1961             :               "        if (tok == '(') {\n"
    1962             :               "            next();\n"
    1963             :               "            if (tok == ',') {\n"
    1964             :               "                next();\n"
    1965             :               "                if (tok != ',') {\n"
    1966             :               "                    op->reg2 = asm_parse_reg();\n"
    1967             :               "                }\n"
    1968             :               "                skip(',');\n"
    1969             :               "            }\n"
    1970             :               "        }\n"
    1971             :               "    }\n"
    1972             :               "    void next();\n"
    1973             :               "    const char *tok;\n"
    1974             :               "};");
    1975           1 :         ASSERT_EQUALS("", errout_str());
    1976             : 
    1977           1 :         check("void foo(int i)\n"
    1978             :               "{\n"
    1979             :               "   if(i > 5) {\n"
    1980             :               "       i = bar();\n"
    1981             :               "       if(i < 5) {\n"
    1982             :               "           cout << a;\n"
    1983             :               "       }\n"
    1984             :               "    }\n"
    1985             :               "}");
    1986           1 :         ASSERT_EQUALS("", errout_str());
    1987             : 
    1988           1 :         check("void foo(int& i) {\n"
    1989             :               "    i=6;\n"
    1990             :               "}\n"
    1991             :               "void bar(int i) {\n"
    1992             :               "    if(i>5) {\n"
    1993             :               "        foo(i);\n"
    1994             :               "        if(i<5) {\n"
    1995             :               "        }\n"
    1996             :               "    }\n"
    1997             :               "}");
    1998           1 :         ASSERT_EQUALS("", errout_str());
    1999             : 
    2000           1 :         check("void foo(int& i);\n"
    2001             :               "void bar() {\n"
    2002             :               "    int i; i = func();\n"
    2003             :               "    if(i>5) {\n"
    2004             :               "        foo(i);\n"
    2005             :               "        if(i<5) {\n"
    2006             :               "        }\n"
    2007             :               "    }\n"
    2008             :               "}");
    2009           1 :         ASSERT_EQUALS("", errout_str());
    2010             : 
    2011           1 :         check("void foo(int i);\n"
    2012             :               "void bar(int i) {\n"
    2013             :               "    if(i>5) {\n"
    2014             :               "        foo(i);\n"
    2015             :               "        if(i<5) {\n"
    2016             :               "        }\n"
    2017             :               "    }\n"
    2018             :               "}");
    2019           1 :         ASSERT_EQUALS("[test.cpp:3] -> [test.cpp:5]: (warning) Opposite inner 'if' condition leads to a dead code block.\n", errout_str());
    2020             : 
    2021           1 :         check("void foo(const int &i);\n"
    2022             :               "void bar(int i) {\n"
    2023             :               "    if(i>5) {\n"
    2024             :               "        foo(i);\n"
    2025             :               "        if(i<5) {\n"
    2026             :               "        }\n"
    2027             :               "    }\n"
    2028             :               "}");
    2029           1 :         ASSERT_EQUALS("[test.cpp:3] -> [test.cpp:5]: (warning) Opposite inner 'if' condition leads to a dead code block.\n", errout_str());
    2030             : 
    2031           1 :         check("void foo(int i);\n"
    2032             :               "void bar() {\n"
    2033             :               "    int i; i = func();\n"
    2034             :               "    if(i>5) {\n"
    2035             :               "        foo(i);\n"
    2036             :               "        if(i<5) {\n"
    2037             :               "        }\n"
    2038             :               "    }\n"
    2039             :               "}");
    2040           1 :         ASSERT_EQUALS("[test.cpp:4] -> [test.cpp:6]: (warning) Opposite inner 'if' condition leads to a dead code block.\n", errout_str());
    2041             : 
    2042           1 :         check("class C { void f(int &i) const; };\n" // #7028 - variable is changed by const method
    2043             :               "void foo(C c, int i) {\n"
    2044             :               "  if (i==5) {\n"
    2045             :               "    c.f(i);\n"
    2046             :               "    if (i != 5) {}\n"
    2047             :               "  }\n"
    2048             :               "}");
    2049           1 :         ASSERT_EQUALS("", errout_str());
    2050             : 
    2051             :         // see linux revision 1f80c0cc
    2052           1 :         check("int generic_write_sync(int,int,int);\n"
    2053             :               "\n"
    2054             :               "void cifs_writev(int i) {\n"
    2055             :               "   int rc = __generic_file_aio_write();\n"
    2056             :               "   if (rc > 0){\n"
    2057             :               "       err = generic_write_sync(file, iocb->ki_pos - rc, rc);\n"
    2058             :               "       if(rc < 0) {\n"  // <- condition is always false
    2059             :               "           err = rc;\n"
    2060             :               "       }\n"
    2061             :               "    }\n"
    2062             :               "}");
    2063           1 :         ASSERT_EQUALS("[test.cpp:5] -> [test.cpp:7]: (warning) Opposite inner 'if' condition leads to a dead code block.\n", errout_str());
    2064             : 
    2065             : 
    2066             :         // #5874 - array
    2067           1 :         check("void testOppositeConditions2() {\n"
    2068             :               "  int array[2] = { 0, 0 };\n"
    2069             :               "  if (array[0] < 2) {\n"
    2070             :               "    array[0] += 5;\n"
    2071             :               "    if (array[0] > 2) {}\n"
    2072             :               "  }\n"
    2073             :               "}");
    2074           1 :         ASSERT_EQUALS("", errout_str());
    2075             : 
    2076             :         // #6227 - FP caused by simplifications of casts and known variables
    2077           1 :         check("void foo(A *a) {\n"
    2078             :               "   if(a) {\n"
    2079             :               "       B *b = dynamic_cast<B*>(a);\n"
    2080             :               "       if(!b) {}\n"
    2081             :               "    }\n"
    2082             :               "}");
    2083           1 :         ASSERT_EQUALS("", errout_str());
    2084             : 
    2085           1 :         check("void foo(int a) {\n"
    2086             :               "   if(a) {\n"
    2087             :               "       int b = a;\n"
    2088             :               "       if(!b) {}\n"
    2089             :               "    }\n"
    2090             :               "}");
    2091           1 :         ASSERT_EQUALS("[test.cpp:3] -> [test.cpp:2] -> [test.cpp:4]: (warning) Opposite inner 'if' condition leads to a dead code block.\n", errout_str());
    2092             : 
    2093           1 :         check("void foo(unsigned u) {\n"
    2094             :               "  if (u != 0) {\n"
    2095             :               "    for (int i=0; i<32; i++) {\n"
    2096             :               "      if (u == 0) {}\n"  // <- don't warn
    2097             :               "      u = x;\n"
    2098             :               "    }\n"
    2099             :               "  }\n"
    2100             :               "}");
    2101           1 :         ASSERT_EQUALS("", errout_str());
    2102             : 
    2103             :         // #8186
    2104           1 :         check("void f() {\n"
    2105             :               "  for (int i=0;i<4;i++) {\n"
    2106             :               "    if (i==5) {}\n"
    2107             :               "  }\n"
    2108             :               "}");
    2109           1 :         ASSERT_EQUALS("[test.cpp:2] -> [test.cpp:3]: (warning) Opposite inner 'if' condition leads to a dead code block.\n", errout_str());
    2110             : 
    2111             :         // #8938
    2112           1 :         check("void Delete(SS_CELLCOORD upperleft) {\n"
    2113             :               "    if ((upperleft.Col == -1) && (upperleft.Row == -1)) {\n"
    2114             :               "        GetActiveCell(&(upperleft.Col), &(upperleft.Row));\n"
    2115             :               "        if (upperleft.Row == -1) {}\n"
    2116             :               "    }\n"
    2117             :               "}");
    2118           1 :         ASSERT_EQUALS("", errout_str());
    2119             : 
    2120             :         // #9702
    2121           1 :         check("struct A {\n"
    2122             :               "    void DoTest() {\n"
    2123             :               "        if (!IsSet()) {\n"
    2124             :               "            m_value = true;\n"
    2125             :               "            if (IsSet());\n"
    2126             :               "        }\n"
    2127             :               "    }\n"
    2128             :               "    bool IsSet() const { return m_value; }\n"
    2129             :               "    bool m_value = false;\n"
    2130             :               "};");
    2131           1 :         ASSERT_EQUALS("", errout_str());
    2132             :     }
    2133             : 
    2134           1 :     void oppositeInnerConditionPointers() {
    2135           1 :         check("void f(struct ABC *abc) {\n"
    2136             :               "   struct AB *ab = abc->ab;\n"
    2137             :               "   if (ab->a == 123){\n"
    2138             :               "       do_something(abc);\n" // might change ab->a
    2139             :               "       if (ab->a != 123) {\n"
    2140             :               "           err = rc;\n"
    2141             :               "       }\n"
    2142             :               "    }\n"
    2143             :               "}");
    2144           1 :         ASSERT_EQUALS("", errout_str());
    2145             : 
    2146           1 :         check("void Fred::f() {\n" // daca: ace
    2147             :               "  if (this->next_ == map_man_->table_) {\n"
    2148             :               "    this->next_ = n;\n"
    2149             :               "    if (this->next_ != map_man_->table_) {}\n"
    2150             :               "  }\n"
    2151             :               "}");
    2152           1 :         ASSERT_EQUALS("", errout_str());
    2153             : 
    2154           1 :         check("void test(float *f) {\n" // #7405
    2155             :               "  if(*f>10) {\n"
    2156             :               "    (*f) += 0.1f;\n"
    2157             :               "    if(*f<10) {}\n"
    2158             :               "  }\n"
    2159             :               "}");
    2160           1 :         ASSERT_EQUALS("", errout_str());
    2161             : 
    2162           1 :         check("int * f(int * x, int * y) {\n"
    2163             :               "    if(!x) return x;\n"
    2164             :               "    return y;\n"
    2165             :               "}");
    2166           1 :         ASSERT_EQUALS("", errout_str());
    2167             :     }
    2168             : 
    2169           1 :     void oppositeInnerConditionClass() {
    2170             :         // #6095 - calling member function that might change the state
    2171           1 :         check("void f() {\n"
    2172             :               "  const Fred fred;\n" // <- fred is const, warn
    2173             :               "  if (fred.isValid()) {\n"
    2174             :               "    fred.dostuff();\n"
    2175             :               "    if (!fred.isValid()) {}\n"
    2176             :               "  }\n"
    2177             :               "}");
    2178           1 :         ASSERT_EQUALS("[test.cpp:3] -> [test.cpp:5]: (warning) Opposite inner 'if' condition leads to a dead code block.\n", errout_str());
    2179             : 
    2180           1 :         check("class Fred { public: bool isValid() const; void dostuff() const; };\n"
    2181             :               "void f() {\n"
    2182             :               "  Fred fred;\n"
    2183             :               "  if (fred.isValid()) {\n"
    2184             :               "    fred.dostuff();\n" // <- dostuff() is const, warn
    2185             :               "    if (!fred.isValid()) {}\n"
    2186             :               "  }\n"
    2187             :               "}");
    2188           1 :         ASSERT_EQUALS("[test.cpp:4] -> [test.cpp:6]: (warning) Opposite inner 'if' condition leads to a dead code block.\n", errout_str());
    2189             : 
    2190           1 :         check("void f() {\n"
    2191             :               "  Fred fred;\n"
    2192             :               "  if (fred.isValid()) {\n"
    2193             :               "    fred.dostuff();\n"
    2194             :               "    if (!fred.isValid()) {}\n"
    2195             :               "  }\n"
    2196             :               "}");
    2197           1 :         ASSERT_EQUALS("", errout_str());
    2198             : 
    2199             :         // #6385 "crash in Variable::getFlag()"
    2200           1 :         check("class TranslationHandler {\n"
    2201             :               "QTranslator *mTranslator;\n"
    2202             :               "void SetLanguage() {\n"
    2203             :               "   if (mTranslator) {\n"
    2204             :               "             qApp->removeTranslator(mTranslator);\n"
    2205             :               "        }\n"
    2206             :               "   }\n"
    2207             :               "};");
    2208           1 :         ASSERT_EQUALS("", errout_str()); // just don't crash...
    2209             : 
    2210           1 :         check("bool f(std::ofstream &CFileStream) {\n" // #8198
    2211             :               "  if(!CFileStream.good()) { return; }\n"
    2212             :               "  CFileStream << \"abc\";\n"
    2213             :               "  if (!CFileStream.good()) {}\n"
    2214             :               "}");
    2215           1 :         ASSERT_EQUALS("", errout_str());
    2216             :     }
    2217             : 
    2218           1 :     void oppositeInnerConditionUndeclaredVariable() {
    2219             :         // #5731 - fp when undeclared variable is used
    2220           1 :         check("void f() {\n"
    2221             :               "   if (x == -1){\n"
    2222             :               "       x = do_something();\n"
    2223             :               "       if (x != -1) {}\n"
    2224             :               "    }\n"
    2225             :               "}");
    2226           1 :         ASSERT_EQUALS("", errout_str());
    2227             : 
    2228             :         // #5750 - another fp when undeclared variable is used
    2229           1 :         check("void f() {\n"
    2230             :               "   if (r < w){\n"
    2231             :               "       r += 3;\n"
    2232             :               "       if (r > w) {}\n"
    2233             :               "    }\n"
    2234             :               "}");
    2235           1 :         ASSERT_EQUALS("", errout_str());
    2236             : 
    2237             :         // #6574 - another fp when undeclared variable is used
    2238           1 :         check("void foo() {\n"
    2239             :               "   if(i) {\n"
    2240             :               "       i++;\n"
    2241             :               "       if(!i) {}\n"
    2242             :               "    }\n"
    2243             :               "}");
    2244           1 :         ASSERT_EQUALS("", errout_str());
    2245             : 
    2246             :         // undeclared array
    2247           1 :         check("void f(int x) {\n"
    2248             :               "  if (a[x] > 0) {\n"
    2249             :               "    a[x] -= dt;\n"
    2250             :               "    if (a[x] < 0) {}\n"
    2251             :               "  }\n"
    2252             :               "}");
    2253           1 :         ASSERT_EQUALS("", errout_str());
    2254             : 
    2255             :         // #6313 - false positive: opposite conditions in nested if blocks when condition changed
    2256           1 :         check("void Foo::Bar() {\n"
    2257             :               "   if(var){\n"
    2258             :               "      --var;\n"
    2259             :               "      if(!var){}\n"
    2260             :               "      else {}\n"
    2261             :               "   }\n"
    2262             :               "}");
    2263           1 :         ASSERT_EQUALS("", errout_str());
    2264             : 
    2265             :         // daca hyphy
    2266           1 :         check("bool f() {\n"
    2267             :               "  if (rec.lLength==0) {\n"
    2268             :               "    rec.Delete(i);\n"
    2269             :               "    if (rec.lLength!=0) {}\n"
    2270             :               "  }\n"
    2271             :               "}");
    2272           1 :         ASSERT_EQUALS("", errout_str());
    2273             :     }
    2274             : 
    2275           1 :     void oppositeInnerConditionAlias() {
    2276           1 :         check("void f() {\n"
    2277             :               "  struct S s;\n"
    2278             :               "  bool hasFailed = false;\n"
    2279             :               "  s.status = &hasFailed;\n"
    2280             :               "\n"
    2281             :               "  if (! hasFailed) {\n"
    2282             :               "    doStuff(&s);\n"
    2283             :               "    if (hasFailed) {}\n"
    2284             :               "  }\n"
    2285             :               "}");
    2286           1 :         ASSERT_EQUALS("[test.cpp:6]: (style) Condition '!hasFailed' is always true\n", errout_str());
    2287             :     }
    2288             : 
    2289           1 :     void oppositeInnerCondition2() {
    2290             :         // first comparison: <
    2291           1 :         check("void f(int x) {\n"
    2292             :               "\n"
    2293             :               "  if (x<4) {\n"
    2294             :               "    if (x==5) {}\n" // <- Warning
    2295             :               "  }\n"
    2296             :               "}");
    2297           1 :         ASSERT_EQUALS("[test.cpp:3] -> [test.cpp:4]: (warning) Opposite inner 'if' condition leads to a dead code block.\n",
    2298             :                       errout_str());
    2299           1 :         check("void f(int x) {\n"
    2300             :               "\n"
    2301             :               "  if (x<4) {\n"
    2302             :               "    if (x!=5) {}\n"
    2303             :               "  }\n"
    2304             :               "}");
    2305           1 :         ASSERT_EQUALS("[test.cpp:3] -> [test.cpp:4]: (style) Condition 'x!=5' is always true\n", errout_str());
    2306           1 :         check("void f(int x) {\n"
    2307             :               "\n"
    2308             :               "  if (x<4) {\n"
    2309             :               "    if (x>5) {}\n" // <- Warning
    2310             :               "  }\n"
    2311             :               "}");
    2312           1 :         ASSERT_EQUALS("[test.cpp:3] -> [test.cpp:4]: (warning) Opposite inner 'if' condition leads to a dead code block.\n",
    2313             :                       errout_str());
    2314           1 :         check("void f(int x) {\n"
    2315             :               "\n"
    2316             :               "  if (x<4) {\n"
    2317             :               "    if (x>=5) {}\n" // <- Warning
    2318             :               "  }\n"
    2319             :               "}");
    2320           1 :         ASSERT_EQUALS("[test.cpp:3] -> [test.cpp:4]: (warning) Opposite inner 'if' condition leads to a dead code block.\n",
    2321             :                       errout_str());
    2322           1 :         check("void f(int x) {\n"
    2323             :               "\n"
    2324             :               "  if (x<4) {\n"
    2325             :               "    if (x<5) {}\n"
    2326             :               "  }\n"
    2327             :               "}");
    2328           1 :         ASSERT_EQUALS("[test.cpp:3] -> [test.cpp:4]: (style) Condition 'x<5' is always true\n", errout_str());
    2329           1 :         check("void f(int x) {\n"
    2330             :               "\n"
    2331             :               "  if (x<4) {\n"
    2332             :               "    if (x<=5) {}\n"
    2333             :               "  }\n"
    2334             :               "}");
    2335           1 :         ASSERT_EQUALS("[test.cpp:3] -> [test.cpp:4]: (style) Condition 'x<=5' is always true\n", errout_str());
    2336             : 
    2337           1 :         check("void f(int x) {\n"
    2338             :               "\n"
    2339             :               "  if (x<5) {\n"
    2340             :               "    if (x==4) {}\n"
    2341             :               "  }\n"
    2342             :               "}");
    2343           1 :         ASSERT_EQUALS("", errout_str());
    2344           1 :         check("void f(int x) {\n"
    2345             :               "\n"
    2346             :               "  if (x<5) {\n"
    2347             :               "    if (x!=4) {}\n"
    2348             :               "  }\n"
    2349             :               "}");
    2350           1 :         ASSERT_EQUALS("", errout_str());
    2351           1 :         check("void f(int x) {\n"
    2352             :               "\n"
    2353             :               "  if (x<5) {\n"
    2354             :               "    if (x!=6) {}\n"
    2355             :               "  }\n"
    2356             :               "}");
    2357           1 :         ASSERT_EQUALS("[test.cpp:3] -> [test.cpp:4]: (style) Condition 'x!=6' is always true\n", errout_str());
    2358           1 :         check("void f(int x) {\n"
    2359             :               "\n"
    2360             :               "  if (x<5) {\n"
    2361             :               "    if (x>4) {}\n" // <- Warning
    2362             :               "  }\n"
    2363             :               "}");
    2364           1 :         ASSERT_EQUALS("[test.cpp:3] -> [test.cpp:4]: (style) Condition 'x>4' is always false\n", errout_str());
    2365           1 :         check("void f(int x) {\n"
    2366             :               "\n"
    2367             :               "  if (x<5) {\n"
    2368             :               "    if (x>=4) {}\n"
    2369             :               "  }\n"
    2370             :               "}");
    2371           1 :         ASSERT_EQUALS("", errout_str());
    2372           1 :         check("void f(int x) {\n"
    2373             :               "\n"
    2374             :               "  if (x<5) {\n"
    2375             :               "    if (x<4) {}\n"
    2376             :               "  }\n"
    2377             :               "}");
    2378           1 :         ASSERT_EQUALS("", errout_str());
    2379           1 :         check("void f(int x) {\n"
    2380             :               "\n"
    2381             :               "  if (x<5) {\n"
    2382             :               "    if (x<=4) {}\n"
    2383             :               "  }\n"
    2384             :               "}");
    2385           1 :         ASSERT_EQUALS("[test.cpp:3] -> [test.cpp:4]: (style) Condition 'x<=4' is always true\n", errout_str());
    2386             : 
    2387             :         // first comparison: >
    2388           1 :         check("void f(int x) {\n"
    2389             :               "\n"
    2390             :               "  if (x>4) {\n"
    2391             :               "    if (x==5) {}\n"
    2392             :               "  }\n"
    2393             :               "}");
    2394           1 :         ASSERT_EQUALS("", errout_str());
    2395           1 :         check("void f(int x) {\n"
    2396             :               "\n"
    2397             :               "  if (x>4) {\n"
    2398             :               "    if (x>5) {}\n"
    2399             :               "  }\n"
    2400             :               "}");
    2401           1 :         ASSERT_EQUALS("", errout_str());
    2402           1 :         check("void f(int x) {\n"
    2403             :               "\n"
    2404             :               "  if (x>4) {\n"
    2405             :               "    if (x>=5) {}\n" // <- Warning
    2406             :               "  }\n"
    2407             :               "}");
    2408           1 :         ASSERT_EQUALS("[test.cpp:3] -> [test.cpp:4]: (style) Condition 'x>=5' is always true\n", errout_str());
    2409           1 :         check("void f(int x) {\n"
    2410             :               "\n"
    2411             :               "  if (x>4) {\n"
    2412             :               "    if (x<5) {}\n" // <- Warning
    2413             :               "  }\n"
    2414             :               "}");
    2415           1 :         ASSERT_EQUALS("[test.cpp:3] -> [test.cpp:4]: (style) Condition 'x<5' is always false\n", errout_str());
    2416           1 :         check("void f(int x) {\n"
    2417             :               "\n"
    2418             :               "  if (x>4) {\n"
    2419             :               "    if (x<=5) {}\n"
    2420             :               "  }\n"
    2421             :               "}");
    2422           1 :         ASSERT_EQUALS("", errout_str());
    2423             : 
    2424           1 :         check("void f(int x) {\n"
    2425             :               "\n"
    2426             :               "  if (x>5) {\n"
    2427             :               "    if (x==4) {}\n" // <- Warning
    2428             :               "  }\n"
    2429             :               "}");
    2430           1 :         ASSERT_EQUALS("[test.cpp:3] -> [test.cpp:4]: (warning) Opposite inner 'if' condition leads to a dead code block.\n",
    2431             :                       errout_str());
    2432           1 :         check("void f(int x) {\n"
    2433             :               "\n"
    2434             :               "  if (x>5) {\n"
    2435             :               "    if (x>4) {}\n" // <- Warning
    2436             :               "  }\n"
    2437             :               "}");
    2438           1 :         ASSERT_EQUALS("[test.cpp:3] -> [test.cpp:4]: (style) Condition 'x>4' is always true\n", errout_str());
    2439           1 :         check("void f(int x) {\n"
    2440             :               "\n"
    2441             :               "  if (x>5) {\n"
    2442             :               "    if (x>=4) {}\n" // <- Warning
    2443             :               "  }\n"
    2444             :               "}");
    2445           1 :         ASSERT_EQUALS("[test.cpp:3] -> [test.cpp:4]: (style) Condition 'x>=4' is always true\n", errout_str());
    2446           1 :         check("void f(int x) {\n"
    2447             :               "\n"
    2448             :               "  if (x>5) {\n"
    2449             :               "    if (x<4) {}\n" // <- Warning
    2450             :               "  }\n"
    2451             :               "}");
    2452           1 :         ASSERT_EQUALS("[test.cpp:3] -> [test.cpp:4]: (warning) Opposite inner 'if' condition leads to a dead code block.\n",
    2453             :                       errout_str());
    2454           1 :         check("void f(int x) {\n"
    2455             :               "\n"
    2456             :               "  if (x>5) {\n"
    2457             :               "    if (x<=4) {}\n" // <- Warning
    2458             :               "  }\n"
    2459             :               "}");
    2460           1 :         ASSERT_EQUALS("[test.cpp:3] -> [test.cpp:4]: (warning) Opposite inner 'if' condition leads to a dead code block.\n",
    2461             :                       errout_str());
    2462             : 
    2463           1 :         check("void f(int x) {\n"
    2464             :               "  if (x < 4) {\n"
    2465             :               "    if (10 < x) {}\n"
    2466             :               "  }\n"
    2467             :               "}");
    2468           1 :         ASSERT_EQUALS("[test.cpp:2] -> [test.cpp:3]: (warning) Opposite inner 'if' condition leads to a dead code block.\n", errout_str());
    2469             :     }
    2470             : 
    2471           1 :     void oppositeInnerCondition3() {
    2472           1 :         check("void f3(char c) { if(c=='x') if(c=='y') {}}");
    2473           1 :         ASSERT_EQUALS("[test.cpp:1] -> [test.cpp:1]: (warning) Opposite inner 'if' condition leads to a dead code block.\n", errout_str());
    2474             : 
    2475           1 :         check("void f4(char *p) { if(*p=='x') if(*p=='y') {}}");
    2476           1 :         ASSERT_EQUALS("[test.cpp:1] -> [test.cpp:1]: (warning) Opposite inner 'if' condition leads to a dead code block.\n", errout_str());
    2477             : 
    2478           1 :         check("void f5(const char * const p) { if(*p=='x') if(*p=='y') {}}");
    2479           1 :         ASSERT_EQUALS("[test.cpp:1] -> [test.cpp:1]: (warning) Opposite inner 'if' condition leads to a dead code block.\n", errout_str());
    2480             : 
    2481           1 :         check("void f5(const char * const p) { if('x'==*p) if('y'==*p) {}}");
    2482           1 :         ASSERT_EQUALS("[test.cpp:1] -> [test.cpp:1]: (warning) Opposite inner 'if' condition leads to a dead code block.\n", errout_str());
    2483             : 
    2484           1 :         check("void f6(char * const p) { if(*p=='x') if(*p=='y') {}}");
    2485           1 :         ASSERT_EQUALS("[test.cpp:1] -> [test.cpp:1]: (warning) Opposite inner 'if' condition leads to a dead code block.\n", errout_str());
    2486             : 
    2487           1 :         check("void f7(const char * p) { if(*p=='x') if(*p=='y') {}}");
    2488           1 :         ASSERT_EQUALS("[test.cpp:1] -> [test.cpp:1]: (warning) Opposite inner 'if' condition leads to a dead code block.\n", errout_str());
    2489             : 
    2490           1 :         check("void f8(int i) { if(i==4) if(i==2) {}}");
    2491           1 :         ASSERT_EQUALS("[test.cpp:1] -> [test.cpp:1]: (warning) Opposite inner 'if' condition leads to a dead code block.\n", errout_str());
    2492             : 
    2493           1 :         check("void f9(int *p) { if (*p==4) if(*p==2) {}}");
    2494           1 :         ASSERT_EQUALS("[test.cpp:1] -> [test.cpp:1]: (warning) Opposite inner 'if' condition leads to a dead code block.\n", errout_str());
    2495             : 
    2496           1 :         check("void f10(int * const p) { if (*p==4) if(*p==2) {}}");
    2497           1 :         ASSERT_EQUALS("[test.cpp:1] -> [test.cpp:1]: (warning) Opposite inner 'if' condition leads to a dead code block.\n", errout_str());
    2498             : 
    2499           1 :         check("void f11(const int *p) { if (*p==4) if(*p==2) {}}");
    2500           1 :         ASSERT_EQUALS("[test.cpp:1] -> [test.cpp:1]: (warning) Opposite inner 'if' condition leads to a dead code block.\n", errout_str());
    2501             : 
    2502           1 :         check("void f12(const int * const p) { if (*p==4) if(*p==2) {}}");
    2503           1 :         ASSERT_EQUALS("[test.cpp:1] -> [test.cpp:1]: (warning) Opposite inner 'if' condition leads to a dead code block.\n", errout_str());
    2504             : 
    2505           1 :         check("struct foo {\n"
    2506             :               "    int a;\n"
    2507             :               "    int b;\n"
    2508             :               "};\n"
    2509             :               "void f(foo x) { if(x.a==4) if(x.b==2) {}}");
    2510           1 :         ASSERT_EQUALS("", errout_str());
    2511             : 
    2512           1 :         check("struct foo {\n"
    2513             :               "    int a;\n"
    2514             :               "    int b;\n"
    2515             :               "};\n"
    2516             :               "void f(foo x) { if(x.a==4) if(x.b==4) {}}");
    2517           1 :         ASSERT_EQUALS("", errout_str());
    2518             : 
    2519           1 :         check("void f3(char a, char b) { if(a==b) if(a==0) {}}");
    2520           1 :         ASSERT_EQUALS("", errout_str());
    2521             : 
    2522           1 :         check("void f(int x) { if (x == 1) if (x != 1) {} }");
    2523           1 :         ASSERT_EQUALS("[test.cpp:1] -> [test.cpp:1]: (warning) Opposite inner 'if' condition leads to a dead code block.\n", errout_str());
    2524             :     }
    2525             : 
    2526           1 :     void oppositeInnerConditionAnd() {
    2527           1 :         check("void f(int x) {\n"
    2528             :               "  if (a>3 && x > 100) {\n"
    2529             :               "    if (x < 10) {}\n"
    2530             :               "  }"
    2531             :               "}");
    2532           1 :         ASSERT_EQUALS("[test.cpp:2] -> [test.cpp:3]: (warning) Opposite inner 'if' condition leads to a dead code block.\n", errout_str());
    2533             : 
    2534           1 :         check("void f(bool x, const int a, const int b) {\n"
    2535             :               "        if(x && a < b)\n"
    2536             :               "            if( x && a > b){}\n"
    2537             :               "}\n");
    2538           1 :         ASSERT_EQUALS("[test.cpp:2] -> [test.cpp:3]: (warning) Opposite inner 'if' condition leads to a dead code block.\n", errout_str());
    2539             :     }
    2540             : 
    2541           1 :     void oppositeInnerConditionOr()
    2542             :     {
    2543           1 :         check("void f(int x) {\n"
    2544             :               "    if (x == 1 || x == 2) {\n"
    2545             :               "        if (x == 3) {}\n"
    2546             :               "    }\n"
    2547             :               "}\n");
    2548           1 :         ASSERT_EQUALS("[test.cpp:2] -> [test.cpp:3]: (warning) Opposite inner 'if' condition leads to a dead code block.\n",
    2549             :                       errout_str());
    2550             : 
    2551           1 :         check("void f(int x) {\n"
    2552             :               "    if (x == 1 || x == 2) {\n"
    2553             :               "        if (x == 1) {}\n"
    2554             :               "    }\n"
    2555             :               "}\n");
    2556           1 :         ASSERT_EQUALS("", errout_str());
    2557             : 
    2558           1 :         check("void f(int x) {\n"
    2559             :               "    if (x == 1 || x == 2) {\n"
    2560             :               "        if (x == 2) {}\n"
    2561             :               "    }\n"
    2562             :               "}\n");
    2563           1 :         ASSERT_EQUALS("", errout_str());
    2564             : 
    2565           1 :         check("void f(std::string x) {\n"
    2566             :               "    if (x == \"1\" || x == \"2\") {\n"
    2567             :               "        if (x == \"1\") {}\n"
    2568             :               "    }\n"
    2569             :               "}\n");
    2570           1 :         ASSERT_EQUALS("", errout_str());
    2571             : 
    2572           1 :         check("void f(int x) {\n"
    2573             :               "    if (x < 1 || x > 3) {\n"
    2574             :               "        if (x == 3) {}\n"
    2575             :               "    }\n"
    2576             :               "}\n");
    2577           1 :         ASSERT_EQUALS("[test.cpp:2] -> [test.cpp:3]: (warning) Opposite inner 'if' condition leads to a dead code block.\n",
    2578             :                       errout_str());
    2579             :     }
    2580             : 
    2581           1 :     void oppositeInnerConditionEmpty() {
    2582           1 :         check("void f1(const std::string &s) { if(s.size() > 42) if(s.empty()) {}}");
    2583           1 :         ASSERT_EQUALS("[test.cpp:1] -> [test.cpp:1]: (warning) Opposite inner 'if' condition leads to a dead code block.\n", errout_str());
    2584             : 
    2585           1 :         check("void f1(const std::string &s) { if(s.size() > 0) if(s.empty()) {}}");
    2586           1 :         ASSERT_EQUALS("[test.cpp:1] -> [test.cpp:1]: (warning) Opposite inner 'if' condition leads to a dead code block.\n", errout_str());
    2587             : 
    2588           1 :         check("void f1(const std::string &s) { if(s.size() < 0) if(s.empty()) {}} "); // <- CheckOther reports: checking if unsigned expression is less than zero
    2589           1 :         ASSERT_EQUALS("[test.cpp:1] -> [test.cpp:1]: (style) Condition 's.empty()' is always false\n", errout_str());
    2590             : 
    2591           1 :         check("void f1(const std::string &s) { if(s.empty()) if(s.size() > 42) {}}");
    2592           1 :         ASSERT_EQUALS("[test.cpp:1] -> [test.cpp:1]: (warning) Opposite inner 'if' condition leads to a dead code block.\n", errout_str());
    2593             : 
    2594           1 :         check("template<class T> void f1(const T &s) { if(s.size() > 42) if(s.empty()) {}}");
    2595           1 :         ASSERT_EQUALS("", errout_str()); //We don't know the type of T so we don't know the relationship between size() and empty(). e.g. s might be a 50 tonne truck with nothing in it.
    2596             : 
    2597           1 :         check("void f2(const std::wstring &s) { if(s.empty()) if(s.size() > 42) {}}");
    2598           1 :         ASSERT_EQUALS("[test.cpp:1] -> [test.cpp:1]: (warning) Opposite inner 'if' condition leads to a dead code block.\n", errout_str());
    2599             : 
    2600           1 :         check("void f1(QString s) { if(s.isEmpty()) if(s.length() > 42) {}}");
    2601           1 :         ASSERT_EQUALS("[test.cpp:1] -> [test.cpp:1]: (warning) Opposite inner 'if' condition leads to a dead code block.\n", errout_str());
    2602             : 
    2603           1 :         check("void f1(const std::string &s, bool b) { if(s.empty() || ((s.size() == 1) && b)) {}}");
    2604           1 :         ASSERT_EQUALS("", errout_str());
    2605             : 
    2606           1 :         check("void f1(const std::string &x, const std::string &y) { if(x.size() > 42) if(y.empty()) {}}");
    2607           1 :         ASSERT_EQUALS("", errout_str());
    2608             : 
    2609           1 :         check("void f1(const std::string &x, const std::string &y) { if(y.empty()) if(x.size() > 42) {}}");
    2610           1 :         ASSERT_EQUALS("", errout_str());
    2611             : 
    2612           1 :         check("void f1(const std::string v[10]) { if(v[0].size() > 42) if(v[1].empty()) {}}");
    2613           1 :         ASSERT_EQUALS("", errout_str());
    2614             : 
    2615           1 :         check("void f1(const std::string &s) { if(s.size() <= 1) if(s.empty()) {}}");
    2616           1 :         ASSERT_EQUALS("", errout_str());
    2617             : 
    2618           1 :         check("void f1(const std::string &s) { if(s.size() <= 2) if(s.empty()) {}}");
    2619           1 :         ASSERT_EQUALS("", errout_str());
    2620             : 
    2621           1 :         check("void f1(const std::string &s) { if(s.size() < 2) if(s.empty()) {}}");
    2622           1 :         ASSERT_EQUALS("", errout_str());
    2623             : 
    2624           1 :         check("void f1(const std::string &s) { if(s.size() >= 0) if(s.empty()) {}} "); // CheckOther says: Unsigned expression 's.size()' can't be negative so it is unnecessary to test it. [unsignedPositive]
    2625           1 :         ASSERT_EQUALS("", errout_str());
    2626             : 
    2627             :         // TODO: These are identical condition since size cannot be negative
    2628           1 :         check("void f1(const std::string &s) { if(s.size() <= 0) if(s.empty()) {}}");
    2629           1 :         ASSERT_EQUALS("", errout_str());
    2630             : 
    2631             :         // TODO: These are identical condition since size cannot be negative
    2632           1 :         check("void f1(const std::string &s) { if(s.size() < 1) if(s.empty()) {}}");
    2633           1 :         ASSERT_EQUALS("", errout_str());
    2634             :     }
    2635             : 
    2636           1 :     void oppositeInnerConditionFollowVar() {
    2637           1 :         check("struct X {\n"
    2638             :               "    void f() {\n"
    2639             :               "        const int flag = get();\n"
    2640             :               "        if (flag) {\n"
    2641             :               "            bar();\n"
    2642             :               "            if (!get()) {}\n"
    2643             :               "        }\n"
    2644             :               "    }\n"
    2645             :               "    void bar();\n"
    2646             :               "    int get() const;\n"
    2647             :               "};");
    2648           1 :         ASSERT_EQUALS("", errout_str());
    2649             : 
    2650           1 :         check("struct CD {\n"
    2651             :               "    bool state;\n"
    2652             :               "    void foo()  {\n"
    2653             :               "        const bool flag = this->get();\n"
    2654             :               "        if (flag) {\n"
    2655             :               "            this->bar();\n"
    2656             :               "            if (!this->get()) return;\n"
    2657             :               "        }\n"
    2658             :               "    }\n"
    2659             :               "    bool get() const;\n"
    2660             :               "    void bar();\n"
    2661             :               "};\n");
    2662           1 :         ASSERT_EQUALS("", errout_str());
    2663             : 
    2664           1 :         check("class C {\n"
    2665             :               "public:\n"
    2666             :               "  bool f() const { return x > 0; }\n"
    2667             :               "  void g();\n"
    2668             :               "  int x = 0;\n"
    2669             :               "};\n"
    2670             :               "\n"
    2671             :               "void C::g() {\n"
    2672             :               "  bool b = f();\n"
    2673             :               "  x += 1;\n"
    2674             :               "  if (!b && f()) {}\n"
    2675             :               "}");
    2676           1 :         ASSERT_EQUALS("", errout_str());
    2677             : 
    2678           1 :         check("void f(double d) {\n"
    2679             :               "    if (d != 0) {\n"
    2680             :               "        int i = d;\n"
    2681             :               "        if (i == 0) {}\n"
    2682             :               "    }\n"
    2683             :               "}\n");
    2684           1 :         ASSERT_EQUALS("", errout_str());
    2685             :     }
    2686             : 
    2687           1 :     void identicalInnerCondition() {
    2688           1 :         check("void f1(int a, int b) { if(a==b) if(a==b) {}}");
    2689           1 :         ASSERT_EQUALS("[test.cpp:1] -> [test.cpp:1]: (warning) Identical inner 'if' condition is always true.\n", errout_str());
    2690             : 
    2691           1 :         check("void f2(int a, int b) { if(a!=b) if(a!=b) {}}");
    2692           1 :         ASSERT_EQUALS("[test.cpp:1] -> [test.cpp:1]: (warning) Identical inner 'if' condition is always true.\n", errout_str());
    2693             : 
    2694             :         // #6645 false negative: condition is always false
    2695           1 :         check("void f(bool a, bool b) {\n"
    2696             :               "  if(a && b) {\n"
    2697             :               "     if(a) {}\n"
    2698             :               "     else  {}\n"
    2699             :               "  }\n"
    2700             :               "}");
    2701           1 :         ASSERT_EQUALS("[test.cpp:2] -> [test.cpp:3]: (warning) Identical inner 'if' condition is always true.\n", errout_str());
    2702             : 
    2703           1 :         check("bool f(int a, int b) {\n"
    2704             :               "    if(a == b) { return a == b; }\n"
    2705             :               "    return false;\n"
    2706             :               "}");
    2707           1 :         ASSERT_EQUALS("[test.cpp:2] -> [test.cpp:2]: (warning) Identical inner 'return' condition is always true.\n", errout_str());
    2708             : 
    2709           1 :         check("bool f(bool a) {\n"
    2710             :               "    if(a) { return a; }\n"
    2711             :               "    return false;\n"
    2712             :               "}");
    2713           1 :         ASSERT_EQUALS("", errout_str());
    2714             : 
    2715           1 :         check("int* f(int* a, int * b) {\n"
    2716             :               "    if(a) { return a; }\n"
    2717             :               "    return b;\n"
    2718             :               "}");
    2719           1 :         ASSERT_EQUALS("", errout_str());
    2720             : 
    2721           1 :         check("int* f(std::shared_ptr<int> a, std::shared_ptr<int> b) {\n"
    2722             :               "    if(a.get()) { return a.get(); }\n"
    2723             :               "    return b.get();\n"
    2724             :               "}");
    2725           1 :         ASSERT_EQUALS("", errout_str());
    2726             : 
    2727           1 :         check("struct A { int * x; };\n"
    2728             :               "int* f(A a, int * b) {\n"
    2729             :               "    if(a.x) { return a.x; }\n"
    2730             :               "    return b;\n"
    2731             :               "}");
    2732           1 :         ASSERT_EQUALS("", errout_str());
    2733             : 
    2734           1 :         check("void f() {\n"
    2735             :               "    uint32_t value;\n"
    2736             :               "    get_value(&value);\n"
    2737             :               "    int opt_function_capable = (value >> 28) & 1;\n"
    2738             :               "    if (opt_function_capable) {\n"
    2739             :               "        value = 0;\n"
    2740             :               "        get_value (&value);\n"
    2741             :               "        if ((value >> 28) & 1) {}\n"
    2742             :               "    }\n"
    2743             :               "}");
    2744           1 :         ASSERT_EQUALS("", errout_str());
    2745             :     }
    2746             : 
    2747           1 :     void identicalConditionAfterEarlyExit() {
    2748           1 :         check("void f(int x) {\n" // #8137
    2749             :               "  if (x > 100) { return; }\n"
    2750             :               "  if (x > 100) {}\n"
    2751             :               "}");
    2752           1 :         ASSERT_EQUALS("[test.cpp:2] -> [test.cpp:3]: (warning) Identical condition 'x>100', second condition is always false\n", errout_str());
    2753             : 
    2754           1 :         check("bool f(int x) {\n"
    2755             :               "  if (x > 100) { return false; }\n"
    2756             :               "  return x > 100;\n"
    2757             :               "}");
    2758           1 :         ASSERT_EQUALS("[test.cpp:2] -> [test.cpp:3]: (warning) Identical condition and return expression 'x>100', return value is always false\n", errout_str());
    2759             : 
    2760           1 :         check("void f(int x) {\n"
    2761             :               "  if (x > 100) { return; }\n"
    2762             :               "  if (x > 100 || y > 100) {}\n"
    2763             :               "}");
    2764           1 :         ASSERT_EQUALS("[test.cpp:2] -> [test.cpp:3]: (warning) Identical condition 'x>100', second condition is always false\n", errout_str());
    2765             : 
    2766           1 :         check("void f(int x) {\n"
    2767             :               "  if (x > 100) { return; }\n"
    2768             :               "  if (x > 100 && y > 100) {}\n"
    2769             :               "}");
    2770           1 :         ASSERT_EQUALS("[test.cpp:2] -> [test.cpp:3]: (warning) Identical condition 'x>100', second condition is always false\n", errout_str());
    2771             : 
    2772           1 :         check("void f(int x) {\n"
    2773             :               "  if (x > 100) { return; }\n"
    2774             :               "  if (abc) {}\n"
    2775             :               "  if (x > 100) {}\n"
    2776             :               "}");
    2777           1 :         ASSERT_EQUALS("[test.cpp:2] -> [test.cpp:4]: (warning) Identical condition 'x>100', second condition is always false\n", errout_str());
    2778             : 
    2779           1 :         check("void f(int x) {\n"
    2780             :               "  if (x > 100) { return; }\n"
    2781             :               "  while (abc) { y = x; }\n"
    2782             :               "  if (x > 100) {}\n"
    2783             :               "}");
    2784           1 :         ASSERT_EQUALS("[test.cpp:2] -> [test.cpp:4]: (warning) Identical condition 'x>100', second condition is always false\n", errout_str());
    2785             : 
    2786           1 :         ASSERT_THROW_INTERNAL(check("void f(int x) {\n"  // #8217 - crash for incomplete code
    2787             :                                     "  if (x > 100) { return; }\n"
    2788             :                                     "  X(do);\n"
    2789             :                                     "  if (x > 100) {}\n"
    2790             :                                     "}"),
    2791             :                               SYNTAX);
    2792             : 
    2793           1 :         check("void f(const int *i) {\n"
    2794             :               "  if (!i) return;\n"
    2795             :               "  if (!num1tok) { *num1 = *num2; }\n"
    2796             :               "  if (!i) {}\n"
    2797             :               "}");
    2798           1 :         ASSERT_EQUALS("[test.cpp:2] -> [test.cpp:4]: (warning) Identical condition '!i', second condition is always false\n", errout_str());
    2799             : 
    2800           1 :         check("void C::f(Tree &coreTree) {\n" // daca
    2801             :               "  if(!coreTree.build())\n"
    2802             :               "    return;\n"
    2803             :               "  coreTree.dostuff();\n"
    2804             :               "  if(!coreTree.build()) {}\n"
    2805             :               "}");
    2806           1 :         ASSERT_EQUALS("", errout_str());
    2807             : 
    2808           1 :         check("struct C { void f(const Tree &coreTree); };\n"
    2809             :               "void C::f(const Tree &coreTree) {\n"
    2810             :               "  if(!coreTree.build())\n"
    2811             :               "    return;\n"
    2812             :               "  coreTree.dostuff();\n"
    2813             :               "  if(!coreTree.build()) {}\n"
    2814             :               "}");
    2815           1 :         ASSERT_EQUALS("[test.cpp:3] -> [test.cpp:6]: (warning) Identical condition '!coreTree.build()', second condition is always false\n", errout_str());
    2816             : 
    2817           1 :         check("void f(int x) {\n" // daca: labplot
    2818             :               "  switch(type) {\n"
    2819             :               "  case 1:\n"
    2820             :               "    if (x == 0) return 1;\n"
    2821             :               "    else return 2;\n"
    2822             :               "  case 2:\n"
    2823             :               "    if (x == 0) return 3;\n"
    2824             :               "    else return 4;\n"
    2825             :               "  }\n"
    2826             :               "  return 0;\n"
    2827             :               "}");
    2828           1 :         ASSERT_EQUALS("", errout_str());
    2829             : 
    2830           1 :         check("static int failed = 0;\n"
    2831             :               "void f() {\n"
    2832             :               "  if (failed) return;\n"
    2833             :               "  checkBuffer();\n"
    2834             :               "  if (failed) {}\n"
    2835             :               "}");
    2836           1 :         ASSERT_EQUALS("", errout_str());
    2837             : 
    2838             :         // daca icu
    2839           1 :         check("void f(const uint32_t *section, int32_t  start) {\n"
    2840             :               "  if(10<=section[start]) { return; }\n"
    2841             :               "  if(++start<100 && 10<=section[start]) { }\n"
    2842             :               "}");
    2843           1 :         ASSERT_EQUALS("", errout_str());
    2844             : 
    2845             :         // daca iqtree
    2846           1 :         check("void readNCBITree(std::istream &in) {\n"
    2847             :               "  char ch;\n"
    2848             :               "  in >> ch;\n"
    2849             :               "  if (ch != '|') return;\n"
    2850             :               "  in >> ch;\n"
    2851             :               "  if (ch != '|') {}\n"
    2852             :               "}");
    2853           1 :         ASSERT_EQUALS("", errout_str());
    2854             : 
    2855             :         // #8924
    2856           1 :         check("struct A {\n"
    2857             :               "    void f() {\n"
    2858             :               "        if (this->FileIndex >= 0) return;\n"
    2859             :               "        this->FileIndex = 1 ;\n"
    2860             :               "        if (this->FileIndex < 0) return;\n"
    2861             :               "    }\n"
    2862             :               "    int FileIndex;\n"
    2863             :               "};");
    2864           1 :         ASSERT_EQUALS("[test.cpp:5]: (style) Condition 'this->FileIndex<0' is always false\n", errout_str());
    2865             : 
    2866             :         // #8858 - #if
    2867           1 :         check("short Do() {\n"
    2868             :               "    short ret = bar1();\n"
    2869             :               "    if ( ret )\n"
    2870             :               "        return ret;\n"
    2871             :               "#ifdef FEATURE\n"
    2872             :               "    ret = bar2();\n"
    2873             :               "#endif\n"
    2874             :               "    return ret;\n"
    2875             :               "}");
    2876           1 :         ASSERT_EQUALS("", errout_str());
    2877             : 
    2878             :         // #10456
    2879           1 :         check("int f() {\n"
    2880             :               "    int i = 0;\n"
    2881             :               "    auto f = [&](bool b) { if (b) ++i; };\n"
    2882             :               "    if (i) return i;\n"
    2883             :               "    f(true);\n"
    2884             :               "    if (i) return i;\n"
    2885             :               "    return 0;\n"
    2886             :               "}\n");
    2887           1 :         ASSERT_EQUALS("", errout_str());
    2888             : 
    2889             :         // #11478
    2890           1 :         check("struct S {\n"
    2891             :               "    void run();\n"
    2892             :               "    bool b = false;\n"
    2893             :               "    const std::function<void(S&)> f;\n"
    2894             :               "};\n"
    2895             :               "void S::run() {\n"
    2896             :               "    while (true) {\n"
    2897             :               "        if (b)\n"
    2898             :               "            return;\n"
    2899             :               "        f(*this);\n"
    2900             :               "        if (b)\n"
    2901             :               "            return;\n"
    2902             :               "    }\n"
    2903             :               "}\n");
    2904           1 :         ASSERT_EQUALS("", errout_str());
    2905             :     }
    2906             : 
    2907           1 :     void innerConditionModified() {
    2908           1 :         check("void f(int x, int y) {\n"
    2909             :               "  if (x == 0) {\n"
    2910             :               "    x += y;\n"
    2911             :               "    if (x == 0) {}\n"
    2912             :               "  }\n"
    2913             :               "}");
    2914           1 :         ASSERT_EQUALS("", errout_str());
    2915             : 
    2916           1 :         check("void f(int x) {\n"
    2917             :               "  if (x == 0) {\n"
    2918             :               "    x += y;\n"
    2919             :               "    if (x == 1) {}\n"
    2920             :               "  }\n"
    2921             :               "}");
    2922           1 :         ASSERT_EQUALS("", errout_str());
    2923             : 
    2924           1 :         check("void f(int * x, int * y) {\n"
    2925             :               "  if (x[*y] == 0) {\n"
    2926             :               "    (*y)++;\n"
    2927             :               "    if (x[*y] == 0) {}\n"
    2928             :               "  }\n"
    2929             :               "}");
    2930           1 :         ASSERT_EQUALS("", errout_str());
    2931             :     }
    2932             : 
    2933             :     // clarify conditions with = and comparison
    2934           1 :     void clarifyCondition1() {
    2935           1 :         check("void f() {\n"
    2936             :               "    if (x = b() < 0) {}\n" // don't simplify and verify this code
    2937             :               "}");
    2938           1 :         ASSERT_EQUALS("[test.cpp:2]: (style) Suspicious condition (assignment + comparison); Clarify expression with parentheses.\n", errout_str());
    2939             : 
    2940           1 :         check("void f(int i) {\n"
    2941             :               "    for (i = 0; i < 10; i++) {}\n"
    2942             :               "}");
    2943           1 :         ASSERT_EQUALS("", errout_str());
    2944             : 
    2945           1 :         check("void f() {\n"
    2946             :               "    x = a<int>(); if (x) {}\n"
    2947             :               "}");
    2948           1 :         ASSERT_EQUALS("", errout_str());
    2949             : 
    2950           1 :         check("void f() {\n"
    2951             :               "    if (x = b < 0 ? 1 : 2) {}\n" // don't simplify and verify this code
    2952             :               "}");
    2953           1 :         ASSERT_EQUALS("", errout_str());
    2954             : 
    2955           1 :         check("void f() {\n"
    2956             :               "    int y = rand(), z = rand();\n"
    2957             :               "    if (y || (!y && z));\n"
    2958             :               "}");
    2959           1 :         ASSERT_EQUALS("[test.cpp:3]: (style) Redundant condition: !y. 'y || (!y && z)' is equivalent to 'y || z'\n", errout_str());
    2960             : 
    2961           1 :         check("void f() {\n"
    2962             :               "    int y = rand(), z = rand();\n"
    2963             :               "    if (y || !y && z);\n"
    2964             :               "}");
    2965           1 :         ASSERT_EQUALS("[test.cpp:3]: (style) Redundant condition: !y. 'y || (!y && z)' is equivalent to 'y || z'\n", errout_str());
    2966             : 
    2967           1 :         check("void f() {\n"
    2968             :               "    if (!a || a && b) {}\n"
    2969             :               "}");
    2970           1 :         ASSERT_EQUALS("[test.cpp:2]: (style) Redundant condition: a. '!a || (a && b)' is equivalent to '!a || b'\n", errout_str());
    2971             : 
    2972             : 
    2973           1 :         check("void f(const Token *tok) {\n"
    2974             :               "    if (!tok->next()->function() ||\n"
    2975             :               "        (tok->next()->function() && tok->next()->function()->isConstructor()));\n"
    2976             :               "}");
    2977           1 :         ASSERT_EQUALS("[test.cpp:2]: (style) Redundant condition: tok->next()->function(). '!A || (A && B)' is equivalent to '!A || B'\n", errout_str());
    2978             : 
    2979           1 :         check("void f() {\n"
    2980             :               "    if (!tok->next()->function() ||\n"
    2981             :               "        (!tok->next()->function() && tok->next()->function()->isConstructor()));\n"
    2982             :               "}");
    2983           1 :         ASSERT_EQUALS("", errout_str());
    2984             : 
    2985           1 :         check("void f() {\n"
    2986             :               "    if (!tok->next()->function() ||\n"
    2987             :               "        (!tok2->next()->function() && tok->next()->function()->isConstructor()));\n"
    2988             :               "}");
    2989           1 :         ASSERT_EQUALS("", errout_str());
    2990             : 
    2991           1 :         check("void f(const Token *tok) {\n"
    2992             :               "    if (!tok->next(1)->function(1) ||\n"
    2993             :               "        (tok->next(1)->function(1) && tok->next(1)->function(1)->isConstructor()));\n"
    2994             :               "}");
    2995           1 :         ASSERT_EQUALS("[test.cpp:2]: (style) Redundant condition: tok->next(1)->function(1). '!A || (A && B)' is equivalent to '!A || B'\n", errout_str());
    2996             : 
    2997           1 :         check("void f() {\n"
    2998             :               "    if (!tok->next()->function(1) ||\n"
    2999             :               "        (tok->next()->function(2) && tok->next()->function()->isConstructor()));\n"
    3000             :               "}");
    3001           1 :         ASSERT_EQUALS("", errout_str());
    3002             : 
    3003           1 :         check("void f() {\n"
    3004             :               "   int y = rand(), z = rand();\n"
    3005             :               "   if (y==0 || y!=0 && z);\n"
    3006             :               "}");
    3007           1 :         ASSERT_EQUALS("[test.cpp:3]: (style) Redundant condition: y!=0. 'y==0 || (y!=0 && z)' is equivalent to 'y==0 || z'\n", errout_str());
    3008             : 
    3009           1 :         check("void f() {\n"
    3010             :               "  if (x>0 || (x<0 && y)) {}\n"
    3011             :               "}");
    3012           1 :         ASSERT_EQUALS("", errout_str());
    3013             : 
    3014             :         // Test Token::expressionString, TODO move this test
    3015           1 :         check("void f() {\n"
    3016             :               "  if (!dead || (dead && (*it).ticks > 0)) {}\n"
    3017             :               "}");
    3018           1 :         ASSERT_EQUALS("[test.cpp:2]: (style) Redundant condition: dead. '!dead || (dead && (*it).ticks>0)' is equivalent to '!dead || (*it).ticks>0'\n", errout_str());
    3019             : 
    3020           1 :         check("void f() {\n"
    3021             :               "  if (!x || (x && (2>(y-1)))) {}\n"
    3022             :               "}");
    3023           1 :         ASSERT_EQUALS("[test.cpp:2]: (style) Redundant condition: x. '!x || (x && 2>(y-1))' is equivalent to '!x || 2>(y-1)'\n", errout_str());
    3024             : 
    3025           1 :         check("void f(bool a, bool b) {\n"
    3026             :               "    if (a || (a && b)) {}\n"
    3027             :               "}");
    3028           1 :         ASSERT_EQUALS("[test.cpp:2]: (style) Redundant condition: a. 'a || (a && b)' is equivalent to 'a'\n", errout_str());
    3029             : 
    3030           1 :         check("void f(bool a, bool b) {\n"
    3031             :               "    if (a && (a || b)) {}\n"
    3032             :               "}");
    3033           1 :         ASSERT_EQUALS("[test.cpp:2]: (style) Redundant condition: a. 'a && (a || b)' is equivalent to 'a'\n", errout_str());
    3034             :     }
    3035             : 
    3036             :     // clarify conditions with bitwise operator and comparison
    3037           1 :     void clarifyCondition2() {
    3038           1 :         check("void f() {\n"
    3039             :               "    if (x & 3 == 2) {}\n"
    3040             :               "}");
    3041           1 :         ASSERT_EQUALS("[test.cpp:2]: (style) Suspicious condition (bitwise operator + comparison); Clarify expression with parentheses.\n"
    3042             :                       "[test.cpp:2]: (style) Boolean result is used in bitwise operation. Clarify expression with parentheses.\n"
    3043             :                       "[test.cpp:2]: (style) Condition 'x&3==2' is always false\n", errout_str());
    3044             : 
    3045           1 :         check("void f() {\n"
    3046             :               "    if (a & fred1.x == fred2.y) {}\n"
    3047             :               "}");
    3048           1 :         ASSERT_EQUALS("[test.cpp:2]: (style) Suspicious condition (bitwise operator + comparison); Clarify expression with parentheses.\n"
    3049             :                       "[test.cpp:2]: (style) Boolean result is used in bitwise operation. Clarify expression with parentheses.\n"
    3050             :                       , errout_str());
    3051             :     }
    3052             : 
    3053             :     // clarify condition that uses ! operator and then bitwise operator
    3054           1 :     void clarifyCondition3() {
    3055           1 :         check("void f(int w) {\n"
    3056             :               "    if(!w & 0x8000) {}\n"
    3057             :               "}");
    3058           1 :         ASSERT_EQUALS("[test.cpp:2]: (style) Boolean result is used in bitwise operation. Clarify expression with parentheses.\n", errout_str());
    3059             : 
    3060           1 :         check("void f(int w) {\n"
    3061             :               "    if((!w) & 0x8000) {}\n"
    3062             :               "}");
    3063           1 :         ASSERT_EQUALS("", errout_str());
    3064             : 
    3065           1 :         check("void f() {\n"
    3066             :               "    if (x == foo() & 2) {}\n"
    3067             :               "}");
    3068           1 :         ASSERT_EQUALS("[test.cpp:2]: (style) Boolean result is used in bitwise operation. Clarify expression with parentheses.\n", errout_str());
    3069             : 
    3070           1 :         check("void f() {\n"
    3071             :               "    if (2 & x == foo()) {}\n"
    3072             :               "}");
    3073           1 :         ASSERT_EQUALS("[test.cpp:2]: (style) Boolean result is used in bitwise operation. Clarify expression with parentheses.\n", errout_str());
    3074             : 
    3075           1 :         check("void f() {\n"
    3076             :               "    if (2 & (x == foo())) {}\n"
    3077             :               "}");
    3078           1 :         ASSERT_EQUALS("", errout_str());
    3079             : 
    3080           1 :         check("void f(std::list<int> &ints) { }");
    3081           1 :         ASSERT_EQUALS("", errout_str());
    3082             : 
    3083           1 :         check("void f() { A<x &> a; }");
    3084           1 :         ASSERT_EQUALS("", errout_str());
    3085             : 
    3086           1 :         check("void f() { a(x<y|z,0); }", "test.c");  // filename is c => there are never templates
    3087           1 :         ASSERT_EQUALS("[test.c:1]: (style) Boolean result is used in bitwise operation. Clarify expression with parentheses.\n", errout_str());
    3088             : 
    3089           1 :         check("class A<B&,C>;", "test.cpp");
    3090           1 :         ASSERT_EQUALS("", errout_str());
    3091             : 
    3092           1 :         check("void f() {\n"
    3093             :               "    if (result != (char *)&inline_result) { }\n" // don't simplify and verify cast
    3094             :               "}");
    3095           1 :         ASSERT_EQUALS("", errout_str());
    3096             : 
    3097             :         // #8495
    3098           1 :         check("void f(bool a, bool b) {\n"
    3099             :               "    C & a & b;\n"
    3100             :               "}");
    3101           1 :         ASSERT_EQUALS("", errout_str());
    3102             :     }
    3103             : 
    3104           1 :     void clarifyCondition4() { // ticket #3110
    3105           1 :         check("typedef double SomeType;\n"
    3106             :               "typedef std::pair<std::string,SomeType> PairType;\n"
    3107             :               "struct S\n"
    3108             :               "{\n"
    3109             :               "     bool operator()\n"
    3110             :               "         ( PairType const & left\n"
    3111             :               "         , PairType const & right) const\n"
    3112             :               "     {\n"
    3113             :               "         return left.first < right.first;\n"
    3114             :               "     }\n"
    3115             :               "}");
    3116           1 :         ASSERT_EQUALS("", errout_str());
    3117             :     }
    3118             : 
    3119           1 :     void clarifyCondition5() { // ticket #3609 (using | in template instantiation)
    3120           1 :         check("template<bool B> struct CWinTraits;\n"
    3121             :               "CWinTraits<WS_CHILD|WS_VISIBLE>::GetWndStyle(0);");
    3122           1 :         ASSERT_EQUALS("", errout_str());
    3123             :     }
    3124             : 
    3125           1 :     void clarifyCondition6() {
    3126           1 :         check("template<class Y>\n"
    3127             :               "SharedPtr& operator=( SharedPtr<Y> const & r ) {\n"
    3128             :               "    px = r.px;\n"
    3129             :               "    return *this;\n"
    3130             :               "}");
    3131           1 :         ASSERT_EQUALS("", errout_str());
    3132             :     }
    3133             : 
    3134           1 :     void clarifyCondition7() {
    3135             :         // Ensure that binary and unary &, and & in declarations are distinguished properly
    3136           1 :         check("void f(bool error) {\n"
    3137             :               "    bool & withoutSideEffects=found.first->second;\n" // Declaring a reference to a boolean; & is no operator at all
    3138             :               "    execute(secondExpression, &programMemory, &result, &error);\n" // Unary &
    3139             :               "}");
    3140           1 :         ASSERT_EQUALS("", errout_str());
    3141             :     }
    3142             : 
    3143           1 :     void clarifyCondition8() {
    3144             :         // don't warn when boolean result comes from function call, array index, etc
    3145             :         // the operator precedence is not unknown then
    3146           1 :         check("bool a();\n"
    3147             :               "bool f(bool b) {\n"
    3148             :               "    return (a() & b);\n"
    3149             :               "}");
    3150           1 :         ASSERT_EQUALS("", errout_str());
    3151             : 
    3152           1 :         check("bool f(bool *a, bool b) {\n"
    3153             :               "    return (a[10] & b);\n"
    3154             :               "}");
    3155           1 :         ASSERT_EQUALS("", errout_str());
    3156             : 
    3157           1 :         check("struct A { bool a; };\n"
    3158             :               "bool f(struct A a, bool b) {\n"
    3159             :               "    return (a.a & b);\n"
    3160             :               "}");
    3161           1 :         ASSERT_EQUALS("", errout_str());
    3162             : 
    3163           1 :         check("struct A { bool a; };\n"
    3164             :               "bool f(struct A a, bool b) {\n"
    3165             :               "    return (A::a & b);\n"
    3166             :               "}");
    3167           1 :         ASSERT_EQUALS("", errout_str());
    3168             :     }
    3169             : 
    3170           1 :     void testBug5895() {
    3171           1 :         check("void png_parse(uint64_t init, int buf_size) {\n"
    3172             :               "    if (init == 0x89504e470d0a1a0a || init == 0x8a4d4e470d0a1a0a)\n"
    3173             :               "        ;\n"
    3174             :               "}");
    3175           1 :         ASSERT_EQUALS("", errout_str());
    3176             :     }
    3177             : 
    3178           1 :     void testBug5309() {
    3179           1 :         check("extern uint64_t value;\n"
    3180             :               "void foo() {\n"
    3181             :               "    if( ( value >= 0x7ff0000000000001ULL )\n"
    3182             :               "            && ( value <= 0x7fffffffffffffffULL ) );\n"
    3183             :               "}");
    3184           1 :         ASSERT_EQUALS("", errout_str());
    3185             :     }
    3186             : 
    3187           1 :     void alwaysTrue() {
    3188             : 
    3189           1 :         check("void f(const struct S *s) {\n" //#8196
    3190             :               "  int x1 = s->x;\n"
    3191             :               "  int x2 = s->x;\n"
    3192             :               "  if (x1 == 10 && x2 == 10) {}\n" // <<
    3193             :               "}");
    3194           1 :         ASSERT_EQUALS("[test.cpp:4] -> [test.cpp:4]: (style) Condition 'x2==10' is always true\n", errout_str());
    3195             : 
    3196           1 :         check("void f ()\n"// #8220
    3197             :               "{\n"
    3198             :               "    int a;\n"
    3199             :               "    int b = 0;\n"
    3200             :               "    int ret;\n"
    3201             :               " \n"
    3202             :               "    a = rand();\n"
    3203             :               "    while (((0 < a) && (a < 2)) && ((8 < a) && (a < 10))) \n"
    3204             :               "    {\n"
    3205             :               "        b += a;\n"
    3206             :               "        a ++;\n"
    3207             :               "    }\n"
    3208             :               "    ret = b;\n"
    3209             :               "}");
    3210           1 :         ASSERT_EQUALS("[test.cpp:8] -> [test.cpp:8]: (style) Condition '8<a' is always false\n", errout_str());
    3211             : 
    3212           1 :         check("void f() {\n" // #4842
    3213             :               "  int x = 0;\n"
    3214             :               "  if (a) { return; }\n" // <- this is just here to fool simplifyKnownVariabels
    3215             :               "  if (!x) {}\n"
    3216             :               "}");
    3217           1 :         ASSERT_EQUALS("[test.cpp:4]: (style) Condition '!x' is always true\n", errout_str());
    3218             : 
    3219           1 :         check("bool f(int x) {\n"
    3220             :               "  if(x == 0) { x++; return x == 0; }\n"
    3221             :               "  return false;\n"
    3222             :               "}");
    3223           1 :         ASSERT_EQUALS("[test.cpp:2] -> [test.cpp:2]: (style) Return value 'x==0' is always false\n", errout_str());
    3224             : 
    3225           1 :         check("void f() {\n" // #6898 (Token::expressionString)
    3226             :               "  int x = 0;\n"
    3227             :               "  A(x++ == 1);\n"
    3228             :               "  A(x++ == 2);\n"
    3229             :               "}");
    3230           1 :         ASSERT_EQUALS("[test.cpp:3]: (style) Condition 'x++==1' is always false\n"
    3231             :                       "[test.cpp:4]: (style) Condition 'x++==2' is always false\n",
    3232             :                       errout_str());
    3233             : 
    3234           1 :         check("bool foo(int bar) {\n"
    3235             :               "  bool ret = false;\n"
    3236             :               "  if (bar == 1)\n"
    3237             :               "    return ret;\n" // <- #9326 - FP condition is always false
    3238             :               "  if (bar == 2)\n"
    3239             :               "    ret = true;\n"
    3240             :               "  return ret;\n"
    3241             :               "}");
    3242           1 :         ASSERT_EQUALS("", errout_str());
    3243             : 
    3244           1 :         check("void f1(const std::string &s) { if(s.empty()) if(s.size() == 0) {}}");
    3245           1 :         ASSERT_EQUALS("[test.cpp:1] -> [test.cpp:1]: (style) Condition 's.size()==0' is always true\n", errout_str());
    3246             : 
    3247           1 :         check("void f() {\n"
    3248             :               "   int buf[42];\n"
    3249             :               "   if( buf != 0) {}\n"
    3250             :               "}");
    3251           1 :         ASSERT_EQUALS("[test.cpp:3]: (style) Condition 'buf!=0' is always true\n", errout_str()); // #8924
    3252             : 
    3253           1 :         check("void f() {\n"
    3254             :               "   int buf[42];\n"
    3255             :               "   if( !buf ) {}\n"
    3256             :               "}");
    3257           1 :         ASSERT_EQUALS("[test.cpp:3]: (style) Condition '!buf' is always false\n", errout_str());
    3258             : 
    3259           1 :         check("void f() {\n"
    3260             :               "   int buf[42];\n"
    3261             :               "   bool b = buf;\n"
    3262             :               "   if( b ) {}\n"
    3263             :               "}");
    3264           1 :         ASSERT_EQUALS("[test.cpp:4]: (style) Condition 'b' is always true\n", errout_str());
    3265             : 
    3266           1 :         check("void f() {\n"
    3267             :               "   int buf[42];\n"
    3268             :               "   bool b = buf;\n"
    3269             :               "   if( !b ) {}\n"
    3270             :               "}");
    3271           1 :         ASSERT_EQUALS("[test.cpp:4]: (style) Condition '!b' is always false\n", errout_str());
    3272             : 
    3273           1 :         check("void f() {\n"
    3274             :               "   int buf[42];\n"
    3275             :               "   int * p = nullptr;\n"
    3276             :               "   if( buf == p ) {}\n"
    3277             :               "}");
    3278           1 :         ASSERT_EQUALS("[test.cpp:4]: (style) Condition 'buf==p' is always false\n", errout_str());
    3279             : 
    3280           1 :         check("void f(bool x) {\n"
    3281             :               "   int buf[42];\n"
    3282             :               "   if( buf || x ) {}\n"
    3283             :               "}");
    3284           1 :         ASSERT_EQUALS("[test.cpp:3]: (style) Condition 'buf' is always true\n", errout_str());
    3285             : 
    3286           1 :         check("void f(int * p) {\n"
    3287             :               "   int buf[42];\n"
    3288             :               "   if( buf == p ) {}\n"
    3289             :               "}");
    3290           1 :         ASSERT_EQUALS("", errout_str());
    3291             : 
    3292           1 :         check("void f() {\n"
    3293             :               "   int buf[42];\n"
    3294             :               "   int p[42];\n"
    3295             :               "   if( buf == p ) {}\n"
    3296             :               "}");
    3297           1 :         ASSERT_EQUALS("", errout_str());
    3298             : 
    3299           1 :         check("void f() {\n"
    3300             :               "   int buf[42];\n"
    3301             :               "   if( buf == 1) {}\n"
    3302             :               "}");
    3303           1 :         ASSERT_EQUALS("", errout_str());
    3304             : 
    3305             :         // Avoid FP when condition comes from macro
    3306           1 :         check("#define NOT !\n"
    3307             :               "void f() {\n"
    3308             :               "  int x = 0;\n"
    3309             :               "  if (a) { return; }\n" // <- this is just here to fool simplifyKnownVariabels
    3310             :               "  if (NOT x) {}\n"
    3311             :               "}");
    3312           1 :         ASSERT_EQUALS("", errout_str());
    3313             : 
    3314           1 :         check("#define M  x != 0\n"
    3315             :               "void f() {\n"
    3316             :               "  int x = 0;\n"
    3317             :               "  if (a) { return; }\n" // <- this is just here to fool simplifyKnownVariabels
    3318             :               "  if (M) {}\n"
    3319             :               "}");
    3320           1 :         ASSERT_EQUALS("", errout_str());
    3321             : 
    3322           1 :         check("#define IF(X)  if (X && x())\n"
    3323             :               "void f() {\n"
    3324             :               "  IF(1) {}\n"
    3325             :               "}");
    3326           1 :         ASSERT_EQUALS("", errout_str());
    3327             : 
    3328             :         // Avoid FP for sizeof condition
    3329           1 :         check("void f() {\n"
    3330             :               "  if (sizeof(char) != 123) {}\n"
    3331             :               "  if (123 != sizeof(char)) {}\n"
    3332             :               "}");
    3333           1 :         ASSERT_EQUALS("", errout_str());
    3334             : 
    3335           1 :         check("void f() {\n"
    3336             :               "  int x = 123;\n"
    3337             :               "  if (sizeof(char) != x) {}\n"
    3338             :               "  if (x != sizeof(char)) {}\n"
    3339             :               "}");
    3340           1 :         TODO_ASSERT_EQUALS("[test.cpp:3]: (style) Condition 'sizeof(char)!=x' is always true\n"
    3341             :                            "[test.cpp:4]: (style) Condition 'x!=sizeof(char)' is always true\n", "", errout_str());
    3342             : 
    3343             :         // Don't warn in assertions. Condition is often 'always true' by intention.
    3344             :         // If platform,defines,etc cause an 'always false' assertion then that is not very dangerous neither
    3345           1 :         check("void f() {\n"
    3346             :               "  int x = 0;\n"
    3347             :               "  assert(x == 0);\n"
    3348             :               "}");
    3349           1 :         ASSERT_EQUALS("", errout_str());
    3350             : 
    3351             :         // #9363 - do not warn about value passed to function
    3352           1 :         check("void f(bool b) {\n"
    3353             :               "    if (b) {\n"
    3354             :               "        if (bar(!b)) {}\n"
    3355             :               "    }\n"
    3356             :               "}");
    3357           1 :         ASSERT_EQUALS("", errout_str());
    3358             : 
    3359             : 
    3360             :         // #7783  FP knownConditionTrueFalse on assert(0 && "message")
    3361           1 :         check("void foo(int x) {\n"
    3362             :               "    if (x<0)\n"
    3363             :               "    {\n"
    3364             :               "        assert(0 && \"bla\");\n"
    3365             :               "        ASSERT(0 && \"bla\");\n"
    3366             :               "        assert_foo(0 && \"bla\");\n"
    3367             :               "        ASSERT_FOO(0 && \"bla\");\n"
    3368             :               "        assert((int)(0==0));\n"
    3369             :               "        assert((int)(0==0) && \"bla\");\n"
    3370             :               "    }\n"
    3371             :               "}");
    3372           1 :         ASSERT_EQUALS("", errout_str());
    3373             : 
    3374             :         // #7750 char literals in boolean expressions
    3375           1 :         check("void f() {\n"
    3376             :               "  if('a'){}\n"
    3377             :               "  if(L'b'){}\n"
    3378             :               "  if(1 && 'c'){}\n"
    3379             :               "  int x = 'd' ? 1 : 2;\n"
    3380             :               "}");
    3381           1 :         ASSERT_EQUALS("", errout_str());
    3382             : 
    3383             :         // #8206 - knownCondition always false
    3384           1 :         check("void f(int i)\n"
    3385             :               "{\n"
    3386             :               "        if(i > 4)\n"
    3387             :               "          for( int x = 0; i < 3; ++x){}\n" // <<
    3388             :               "}");
    3389           1 :         ASSERT_EQUALS("[test.cpp:3] -> [test.cpp:4]: (style) Condition 'i<3' is always false\n", errout_str());
    3390             : 
    3391             :         // Skip literals
    3392           1 :         check("void f() { if(true) {} }");
    3393           1 :         ASSERT_EQUALS("", errout_str());
    3394             : 
    3395           1 :         check("void f() { if(false) {} }");
    3396           1 :         ASSERT_EQUALS("", errout_str());
    3397             : 
    3398           1 :         check("void f() { if(!true) {} }");
    3399           1 :         ASSERT_EQUALS("", errout_str());
    3400             : 
    3401           1 :         check("void f() { if(!false) {} }");
    3402           1 :         ASSERT_EQUALS("", errout_str());
    3403             : 
    3404           1 :         check("void f() { if(0) {} }");
    3405           1 :         ASSERT_EQUALS("", errout_str());
    3406             : 
    3407           1 :         check("void f() { if(1) {} }");
    3408           1 :         ASSERT_EQUALS("", errout_str());
    3409             : 
    3410           1 :         check("void f(int i) {\n"
    3411             :               "    bool b = false;\n"
    3412             :               "    if (i == 0) b = true;\n"
    3413             :               "    else if (!b && i == 1) {}\n"
    3414             :               "    if (b)\n"
    3415             :               "    {}\n"
    3416             :               "}");
    3417           1 :         ASSERT_EQUALS("[test.cpp:4]: (style) Condition '!b' is always true\n", errout_str());
    3418             : 
    3419           1 :         check("bool f() { return nullptr; }");
    3420           1 :         ASSERT_EQUALS("", errout_str());
    3421             : 
    3422           1 :         check("enum E { A };\n"
    3423             :               "bool f() { return A; }");
    3424           1 :         ASSERT_EQUALS("", errout_str());
    3425             : 
    3426           1 :         check("bool f() {\n"
    3427             :               "    const int x = 0;\n"
    3428             :               "    return x;\n"
    3429             :               "}");
    3430           1 :         ASSERT_EQUALS("", errout_str());
    3431             : 
    3432           1 :         check("int f(void){return 1/abs(10);}");
    3433           1 :         ASSERT_EQUALS("", errout_str());
    3434             : 
    3435           1 :         check("bool f() {\n"
    3436             :               "    int x = 0;\n"
    3437             :               "    return x;\n"
    3438             :               "}");
    3439           1 :         ASSERT_EQUALS("", errout_str());
    3440             : 
    3441           1 :         check("bool f() {\n"
    3442             :               "    const int a = 50;\n"
    3443             :               "    const int b = 52;\n"
    3444             :               "    return a+b;\n"
    3445             :               "}");
    3446           1 :         ASSERT_EQUALS("[test.cpp:4]: (style) Return value 'a+b' is always true\n", errout_str());
    3447             : 
    3448           1 :         check("int f() {\n"
    3449             :               "    int a = 50;\n"
    3450             :               "    int b = 52;\n"
    3451             :               "    a++;\n"
    3452             :               "    b++;\n"
    3453             :               "    return a+b;\n"
    3454             :               "}");
    3455           1 :         ASSERT_EQUALS("", errout_str());
    3456             : 
    3457           1 :         check("bool& g();\n"
    3458             :               "bool f() {\n"
    3459             :               "    bool & b = g();\n"
    3460             :               "    b = false;\n"
    3461             :               "    return b;\n"
    3462             :               "}");
    3463           1 :         ASSERT_EQUALS("", errout_str());
    3464             : 
    3465           1 :         check("struct A {\n"
    3466             :               "    bool b;\n"
    3467             :               "    bool f() {\n"
    3468             :               "        b = false;\n"
    3469             :               "        return b;\n"
    3470             :               "    }\n"
    3471             :               "};");
    3472           1 :         ASSERT_EQUALS("", errout_str());
    3473             : 
    3474           1 :         check("bool f(long maxtime) {\n"
    3475             :               "  if (std::time(0) > maxtime)\n"
    3476             :               "    return std::time(0) > maxtime;\n"
    3477             :               "}");
    3478           1 :         ASSERT_EQUALS("", errout_str());
    3479             : 
    3480           1 :         check("void foo(double param) {\n"
    3481             :               "  while(bar()) {\n"
    3482             :               "    if (param<0.)\n"
    3483             :               "       return;\n"
    3484             :               "  }\n"
    3485             :               "  if (param<0.)\n"
    3486             :               "    return;\n"
    3487             :               "}");
    3488           1 :         ASSERT_EQUALS("", errout_str());
    3489             : 
    3490           1 :         check("void foo(int i) {\n"
    3491             :               "  if (i==42)\n"
    3492             :               "  {\n"
    3493             :               "    bar();\n"
    3494             :               "  }\n"
    3495             :               "  if (cond && (42==i))\n"
    3496             :               "    return;\n"
    3497             :               "}");
    3498           1 :         ASSERT_EQUALS("", errout_str());
    3499             : 
    3500             :         // 8842 crash
    3501           1 :         check("class a {\n"
    3502             :               "  int b;\n"
    3503             :               "  c(b);\n"
    3504             :               "  void f() {\n"
    3505             :               "    if (b) return;\n"
    3506             :               "  }\n"
    3507             :               "};");
    3508           1 :         ASSERT_EQUALS("", errout_str());
    3509             : 
    3510           1 :         check("void f(const char* x, const char* t) {\n"
    3511             :               "    if (!(strcmp(x, y) == 0)) { return; }\n"
    3512             :               "}");
    3513           1 :         ASSERT_EQUALS("", errout_str());
    3514             : 
    3515           1 :         check("void f(const int a[]){ if (a == 0){} }");
    3516           1 :         ASSERT_EQUALS("", errout_str());
    3517             : 
    3518           1 :         check("struct S {\n"
    3519             :               "  bool operator<(const S&);\n"
    3520             :               "};\n"
    3521             :               "int main() {\n"
    3522             :               "  S s;\n"
    3523             :               "  bool c = s<s;\n"
    3524             :               "  if (c) return 0;\n"
    3525             :               "  else return 42;\n"
    3526             :               "}");
    3527           1 :         ASSERT_EQUALS("", errout_str());
    3528             : 
    3529           1 :         check("long X::g(bool unknown, int& result) {\n"
    3530             :               "    long ret = 0;\n"
    3531             :               "    bool f = false;\n"
    3532             :               "    f = f || unknown;\n"
    3533             :               "    f ? result = 42 : ret = -1;\n"
    3534             :               "    return ret;\n"
    3535             :               "}");
    3536           1 :         ASSERT_EQUALS("", errout_str());
    3537             : 
    3538           1 :         check("int f(void *handle) {\n"
    3539             :               "    if (!handle) return 0;\n"
    3540             :               "    if (handle) return 1;\n"
    3541             :               "    else return 0;\n"
    3542             :               "}");
    3543           1 :         ASSERT_EQUALS("[test.cpp:2] -> [test.cpp:3]: (style) Condition 'handle' is always true\n", errout_str());
    3544             : 
    3545           1 :         check("int f(void *handle) {\n"
    3546             :               "    if (handle == 0) return 0;\n"
    3547             :               "    if (handle) return 1;\n"
    3548             :               "    else return 0;\n"
    3549             :               "}");
    3550           1 :         ASSERT_EQUALS("[test.cpp:3]: (style) Condition 'handle' is always true\n", errout_str());
    3551             : 
    3552           1 :         check("int f(void *handle) {\n"
    3553             :               "    if (handle != 0) return 0;\n"
    3554             :               "    if (handle) return 1;\n"
    3555             :               "    else return 0;\n"
    3556             :               "}");
    3557           1 :         ASSERT_EQUALS("[test.cpp:2] -> [test.cpp:3]: (warning) Identical condition 'handle!=0', second condition is always false\n", errout_str());
    3558             : 
    3559           1 :         check("int f(void *handle) {\n"
    3560             :               "    if (handle != nullptr) return 0;\n"
    3561             :               "    if (handle) return 1;\n"
    3562             :               "    else return 0;\n"
    3563             :               "}");
    3564           1 :         ASSERT_EQUALS("[test.cpp:2] -> [test.cpp:3]: (warning) Identical condition 'handle!=nullptr', second condition is always false\n", errout_str());
    3565             : 
    3566           1 :         check("void f(void* x, void* y) {\n"
    3567             :               "    if (x == nullptr && y == nullptr)\n"
    3568             :               "        return;\n"
    3569             :               "    if (x == nullptr || y == nullptr)\n"
    3570             :               "        return;\n"
    3571             :               "}");
    3572           1 :         ASSERT_EQUALS("", errout_str());
    3573             : 
    3574           1 :         check("void* g();\n"
    3575             :               "void f(void* a, void* b) {\n"
    3576             :               "    while (a) {\n"
    3577             :               "        a = g();\n"
    3578             :               "        if (a == b)\n"
    3579             :               "            break;\n"
    3580             :               "    }\n"
    3581             :               "    if (a) {}\n"
    3582             :               "}");
    3583           1 :         ASSERT_EQUALS("", errout_str());
    3584             : 
    3585           1 :         check("void* g();\n"
    3586             :               "void f(void* a, void* b) {\n"
    3587             :               "    while (a) {\n"
    3588             :               "        a = g();\n"
    3589             :               "    }\n"
    3590             :               "    if (a) {}\n"
    3591             :               "}");
    3592           1 :         ASSERT_EQUALS("[test.cpp:3] -> [test.cpp:6]: (style) Condition 'a' is always false\n", errout_str());
    3593             : 
    3594           1 :         check("void f(int * x, bool b) {\n"
    3595             :               "    if (!x && b) {}\n"
    3596             :               "    else if (x) {}\n"
    3597             :               "}");
    3598           1 :         ASSERT_EQUALS("", errout_str());
    3599             : 
    3600           1 :         check("void f() {\n"
    3601             :               "    const std::string x=\"xyz\";\n"
    3602             :               "    if(!x.empty()){}\n"
    3603             :               "}");
    3604           1 :         ASSERT_EQUALS("[test.cpp:3]: (style) Condition '!x.empty()' is always true\n", errout_str());
    3605             : 
    3606           1 :         check("std::string g();\n"
    3607             :               "void f() {\n"
    3608             :               "    const std::string msg = g();\n"
    3609             :               "    if(!msg.empty()){}\n"
    3610             :               "}");
    3611           1 :         ASSERT_EQUALS("", errout_str());
    3612             : 
    3613           1 :         check("void f(int *array, int size ) {\n"
    3614             :               "    for(int i = 0; i < size; ++i) {\n"
    3615             :               "        if(array == 0)\n"
    3616             :               "            continue;\n"
    3617             :               "        if(array){}\n"
    3618             :               "    }\n"
    3619             :               "}");
    3620           1 :         ASSERT_EQUALS("[test.cpp:5]: (style) Condition 'array' is always true\n", errout_str());
    3621             : 
    3622           1 :         check("void f(int *array, int size ) {\n"
    3623             :               "    for(int i = 0; i < size; ++i) {\n"
    3624             :               "        if(array == 0)\n"
    3625             :               "            continue;\n"
    3626             :               "        else if(array){}\n"
    3627             :               "    }\n"
    3628             :               "}");
    3629           1 :         ASSERT_EQUALS("[test.cpp:5]: (style) Condition 'array' is always true\n", errout_str());
    3630             : 
    3631             :         // #9277
    3632           1 :         check("int f() {\n"
    3633             :               "    constexpr bool x = true;\n"
    3634             :               "    if constexpr (x)\n"
    3635             :               "        return 0;\n"
    3636             :               "    else\n"
    3637             :               "        return 1;\n"
    3638             :               "}");
    3639           1 :         ASSERT_EQUALS("", errout_str());
    3640             : 
    3641             :         // #9954
    3642           1 :         check("void f() {\n"
    3643             :               "    const size_t a(8 * sizeof(short));\n"
    3644             :               "    const size_t b(8 * sizeof(int));\n"
    3645             :               "    if constexpr (a == 16 && b == 16) {}\n"
    3646             :               "    else if constexpr (a == 16 && b == 32) {}\n"
    3647             :               "}\n");
    3648           1 :         ASSERT_EQUALS("", errout_str());
    3649             : 
    3650             :         // #9319
    3651           1 :         check("struct S {\n"
    3652             :               "  int a;\n"
    3653             :               "  int b;\n"
    3654             :               "};\n"
    3655             :               "void g(S s, bool& x);\n"
    3656             :               "void f() {\n"
    3657             :               "  bool x = false;\n"
    3658             :               "  g({0, 1}, x);\n"
    3659             :               "  if (x) {}\n"
    3660             :               "}");
    3661           1 :         ASSERT_EQUALS("", errout_str());
    3662             : 
    3663             :         // #9318
    3664           1 :         check("class A {};\n"
    3665             :               "class B : public A {};\n"
    3666             :               "void f(A* x) {\n"
    3667             :               "  if (!x)\n"
    3668             :               "    return;\n"
    3669             :               "  auto b = dynamic_cast<B*>(x);\n"
    3670             :               "  if (b) {}\n"
    3671             :               "}");
    3672           1 :         ASSERT_EQUALS("", errout_str());
    3673             : 
    3674           1 :         check("int foo() {\n"
    3675             :               "    auto x = getX();\n"
    3676             :               "    if (x == nullptr)\n"
    3677             :               "        return 1;\n"
    3678             :               "    auto y = dynamic_cast<Y*>(x)\n"
    3679             :               "    if (y == nullptr)\n"
    3680             :               "        return 2;\n"
    3681             :               "    return 3;\n"
    3682             :               "}\n");
    3683           1 :         ASSERT_EQUALS("", errout_str());
    3684             : 
    3685             :         // handleKnownValuesInLoop
    3686           1 :         check("bool g();\n"
    3687             :               "void f(bool x) {\n"
    3688             :               "    if (x) while(x) x = g();\n"
    3689             :               "}");
    3690           1 :         ASSERT_EQUALS("", errout_str());
    3691             : 
    3692             :         // isLikelyStream
    3693           1 :         check("void f(std::istringstream& iss) {\n"
    3694             :               "   std::string x;\n"
    3695             :               "   while (iss) {\n"
    3696             :               "       iss >> x;\n"
    3697             :               "       if (!iss) break;\n"
    3698             :               "   }\n"
    3699             :               "}");
    3700           1 :         ASSERT_EQUALS("", errout_str());
    3701             : 
    3702             :         // #9332
    3703           1 :         check("struct A { void* g(); };\n"
    3704             :               "void f() {\n"
    3705             :               "    A a;\n"
    3706             :               "    void* b = a.g();\n"
    3707             :               "    if (!b) return;\n"
    3708             :               "    void* c = a.g();\n"
    3709             :               "    if (!c) return;\n"
    3710             :               "    bool compare = c == b;\n"
    3711             :               "}");
    3712           1 :         ASSERT_EQUALS("", errout_str());
    3713             : 
    3714             :         // #9361
    3715           1 :         check("void f(char c) {\n"
    3716             :               "    if (c == '.') {}\n"
    3717             :               "    else if (isdigit(c) != 0) {}\n"
    3718             :               "}");
    3719           1 :         ASSERT_EQUALS("", errout_str());
    3720             : 
    3721             :         // #9351
    3722           1 :         check("int f(int x) {\n"
    3723             :               "    const bool b = x < 42;\n"
    3724             :               "    if(b) return b?0:-1;\n"
    3725             :               "    return 42;\n"
    3726             :               "}");
    3727           1 :         ASSERT_EQUALS("[test.cpp:3] -> [test.cpp:3]: (style) Condition 'b' is always true\n", errout_str());
    3728             : 
    3729             :         // #9362
    3730           1 :         check("uint8_t g();\n"
    3731             :               "void f() {\n"
    3732             :               "    const uint8_t v = g();\n"
    3733             :               "    if((v != 0x00)) {\n"
    3734             :               "        if( (v & 0x01) == 0x00) {}\n"
    3735             :               "    }\n"
    3736             :               "}");
    3737           1 :         ASSERT_EQUALS("", errout_str());
    3738             : 
    3739             :         // #9367
    3740           1 :         check("void f(long x) {\n"
    3741             :               "    if (x <= 0L)\n"
    3742             :               "        return;\n"
    3743             :               "    if (x % 360L == 0)\n"
    3744             :               "        return;\n"
    3745             :               "}");
    3746           1 :         ASSERT_EQUALS("", errout_str());
    3747             : 
    3748           1 :         check("int f(int a, int b) {\n"
    3749             :               "    static const int x = 10;\n"
    3750             :               "    return x == 1 ? a : b;\n"
    3751             :               "}");
    3752           1 :         ASSERT_EQUALS("", errout_str());
    3753             : 
    3754           1 :         check("const bool x = false;\n"
    3755             :               "void f() {\n"
    3756             :               "    if (x) {}\n"
    3757             :               "}");
    3758           1 :         ASSERT_EQUALS("", errout_str());
    3759             : 
    3760           1 :         check("const bool x = false;\n"
    3761             :               "void f() {\n"
    3762             :               "    if (!x) {}\n"
    3763             :               "}");
    3764           1 :         ASSERT_EQUALS("", errout_str());
    3765             : 
    3766             :         // #9709
    3767           1 :         check("void f(int a) {\n"
    3768             :               "    bool ok = false;\n"
    3769             :               "    const char * r = nullptr;\n"
    3770             :               "    do_something(&r);\n"
    3771             :               "    if (r != nullptr)\n"
    3772             :               "        ok = a != 0;\n"
    3773             :               "    if (ok) {}\n"
    3774             :               "}");
    3775           1 :         ASSERT_EQUALS("", errout_str());
    3776             : 
    3777             :         // #9816
    3778           1 :         check("bool g();\n"
    3779             :               "void f() {\n"
    3780             :               "    bool b = false;\n"
    3781             :               "    do {\n"
    3782             :               "        do {\n"
    3783             :               "            if (g())\n"
    3784             :               "                break;\n"
    3785             :               "            b = true;\n"
    3786             :               "        } while(false);\n"
    3787             :               "    } while(!b);\n"
    3788             :               "}\n");
    3789           1 :         ASSERT_EQUALS("", errout_str());
    3790             : 
    3791             :         // #9865
    3792           1 :         check("void f(const std::string &s) {\n"
    3793             :               "    for (std::string::const_iterator it = s.begin(); it != s.end(); ++it) {\n"
    3794             :               "        const unsigned char c = static_cast<unsigned char>(*it);\n"
    3795             :               "        if (c == '0') {}\n"
    3796             :               "        else if ((c == 'a' || c == 'A')\n"
    3797             :               "                 || (c == 'b' || c == 'B')) {}\n"
    3798             :               "        else {}\n"
    3799             :               "    }\n"
    3800             :               "}\n");
    3801           1 :         ASSERT_EQUALS("", errout_str());
    3802             : 
    3803             :         // #9711
    3804           1 :         check("int main(int argc, char* argv[]) {\n"
    3805             :               "  int foo = 0;\n"
    3806             :               "  struct option options[] = {\n"
    3807             :               "    {\"foo\", no_argument, &foo, \'f\'},\n"
    3808             :               "    {NULL, 0, NULL, 0},\n"
    3809             :               "  };\n"
    3810             :               "  getopt_long(argc, argv, \"f\", options, NULL);\n"
    3811             :               "  if (foo) {}\n"
    3812             :               "}\n");
    3813           1 :         ASSERT_EQUALS("", errout_str());
    3814             : 
    3815             :         // TODO: if (!v) is a known condition as well
    3816           1 :         check("struct a {\n"
    3817             :               "  int *b();\n"
    3818             :               "};\n"
    3819             :               "bool g(a c, a* d) {\n"
    3820             :               "  a *v, *e = v = &c;\n"
    3821             :               "  if (!v)\n"
    3822             :               "    return true;\n"
    3823             :               "  int *f = v->b();\n"
    3824             :               "  if (f)\n"
    3825             :               "    v = nullptr;\n"
    3826             :               "  if (v == nullptr && e) {}\n"
    3827             :               "  return d;\n"
    3828             :               "}\n");
    3829           1 :         ASSERT_EQUALS("[test.cpp:11]: (style) Condition 'e' is always true\n", errout_str());
    3830             : 
    3831             :         // #10037
    3832           1 :         check("struct a {\n"
    3833             :               "    int* p;\n"
    3834             :               "};\n"
    3835             :               "void g(a*);\n"
    3836             :               "void f() {\n"
    3837             :               "    struct a b;\n"
    3838             :               "    uint32_t p = (uint32_t) -1;\n"
    3839             :               "    b.p = (void *) &p;\n"
    3840             :               "    int r = g(&b);\n"
    3841             :               "    if (r == 0)\n"
    3842             :               "        if (p != (uint32_t) -1) {}\n"
    3843             :               "}\n");
    3844           1 :         ASSERT_EQUALS("", errout_str());
    3845             : 
    3846             :         // #9890
    3847           1 :         check("int g(int);\n"
    3848             :               "bool h(int*);\n"
    3849             :               "int f(int *x) {\n"
    3850             :               "    int y = g(0);\n"
    3851             :               "    if (!y) {\n"
    3852             :               "        if (h(x)) {\n"
    3853             :               "            y = g(1);\n"
    3854             :               "            if (y) {}\n"
    3855             :               "            return 0;\n"
    3856             :               "        }\n"
    3857             :               "        if (!y) {}\n"
    3858             :               "    }\n"
    3859             :               "    return 0;\n"
    3860             :               "}\n");
    3861           1 :         ASSERT_EQUALS("[test.cpp:5] -> [test.cpp:11]: (style) Condition '!y' is always true\n", errout_str());
    3862             : 
    3863             :         // #10134
    3864           1 :         check("bool foo(bool b);\n"
    3865             :               "bool thud(const std::vector<std::wstring>& Arr, const std::wstring& Str) {\n"
    3866             :               "  if (Arr.empty() && Str.empty())\n"
    3867             :               "    return false;\n"
    3868             :               "  bool OldFormat = Arr.empty() && !Str.empty();\n"
    3869             :               "  if (OldFormat)\n"
    3870             :               "    return foo(OldFormat);\n"
    3871             :               "  return false;\n"
    3872             :               "}\n");
    3873           1 :         ASSERT_EQUALS("", errout_str());
    3874             : 
    3875             :         // #10208
    3876           1 :         check("bool GetFirst(std::string &first);\n"
    3877             :               "bool GetNext(std::string &next);\n"
    3878             :               "void g(const std::string& name);\n"
    3879             :               "void f() {\n"
    3880             :               "  for (std::string name; name.empty() ? GetFirst(name) : GetNext(name);)\n"
    3881             :               "    g(name);\n"
    3882             :               "}\n");
    3883           1 :         ASSERT_EQUALS("", errout_str());
    3884             : 
    3885           1 :         check("bool GetFirst(std::string &first);\n"
    3886             :               "bool GetNext(std::string &next);\n"
    3887             :               "void g(const std::string& name);\n"
    3888             :               "void f() {\n"
    3889             :               "  for (std::string name{}; name.empty() ? GetFirst(name) : GetNext(name);)\n"
    3890             :               "    g(name);\n"
    3891             :               "}\n");
    3892           1 :         ASSERT_EQUALS("", errout_str());
    3893             : 
    3894           1 :         check("bool GetFirst(std::string &first);\n"
    3895             :               "bool GetNext(std::string &next);\n"
    3896             :               "void g(const std::string& name);\n"
    3897             :               "void f() {\n"
    3898             :               "  for (std::string name{'a', 'b'}; name.empty() ? GetFirst(name) : GetNext(name);)\n"
    3899             :               "    g(name);\n"
    3900             :               "}\n");
    3901           1 :         ASSERT_EQUALS("", errout_str());
    3902             : 
    3903           1 :         check("bool GetFirst(const std::string &first);\n"
    3904             :               "bool GetNext(const std::string &next);\n"
    3905             :               "void g(const std::string& name);\n"
    3906             :               "void f() {\n"
    3907             :               "  for (std::string name; name.empty() ? GetFirst(name) : GetNext(name);)\n"
    3908             :               "    g(name);\n"
    3909             :               "}\n");
    3910           1 :         ASSERT_EQUALS("[test.cpp:5]: (style) Condition 'name.empty()' is always true\n", errout_str());
    3911             : 
    3912             :         // #10278
    3913           1 :         check("void foo(unsigned int x) {\n"
    3914             :               "    if ((100 - x) > 0) {}\n"
    3915             :               "}\n");
    3916           1 :         ASSERT_EQUALS("", errout_str());
    3917             : 
    3918             :         // #10298
    3919           1 :         check("void foo(unsigned int x) {\n"
    3920             :               "    if (x == -1) {}\n"
    3921             :               "}\n");
    3922           1 :         ASSERT_EQUALS("", errout_str());
    3923             : 
    3924             :         // #10121
    3925           1 :         check("struct AB {\n"
    3926             :               "    int a;\n"
    3927             :               "};\n"
    3928             :               "struct ABC {\n"
    3929             :               "    AB* ab;\n"
    3930             :               "};\n"
    3931             :               "void g(ABC*);\n"
    3932             :               "int f(struct ABC *abc) {\n"
    3933             :               "    int err = 0;\n"
    3934             :               "    AB *ab = abc->ab;\n"
    3935             :               "    if (ab->a == 123){\n"
    3936             :               "        g(abc);\n"
    3937             :               "        if (ab->a != 123) {\n"
    3938             :               "            err = 1;\n"
    3939             :               "        }\n"
    3940             :               "    }\n"
    3941             :               "    return err;\n"
    3942             :               "}\n");
    3943           1 :         ASSERT_EQUALS("", errout_str());
    3944             : 
    3945             :         // #10323
    3946           1 :         check("void foo(int x) {\n"
    3947             :               "    if(x)\n"
    3948             :               "        if(x == 1) {}\n"
    3949             :               "}\n");
    3950           1 :         ASSERT_EQUALS("", errout_str());
    3951             : 
    3952           1 :         check("void foo(int x) {\n"
    3953             :               "    if(x) {}\n"
    3954             :               "    else\n"
    3955             :               "        if(x == 1) {}\n"
    3956             :               "}\n");
    3957           1 :         ASSERT_EQUALS("[test.cpp:2] -> [test.cpp:4]: (style) Condition 'x==1' is always false\n", errout_str());
    3958             : 
    3959             :         // do not report both unsignedLessThanZero and knownConditionTrueFalse
    3960           1 :         check("void foo(unsigned int max) {\n"
    3961             :               "    unsigned int num = max - 1;\n"
    3962             :               "    if (num < 0) {}\n" // <- do not report knownConditionTrueFalse
    3963             :               "}");
    3964           1 :         ASSERT_EQUALS("", errout_str());
    3965             : 
    3966             :         // #10297
    3967           1 :         check("void foo(size_t len, int start) {\n"
    3968             :               "    if (start < 0) {\n"
    3969             :               "        start = len+start;\n"
    3970             :               "        if (start < 0) {}\n"
    3971             :               "    }\n"
    3972             :               "}\n");
    3973           1 :         ASSERT_EQUALS("", errout_str());
    3974             : 
    3975             :         // #10362
    3976           1 :         check("int tok;\n"
    3977             :               "void next();\n"
    3978             :               "void parse_attribute() {\n"
    3979             :               "    if (tok == '(') {\n"
    3980             :               "        int parenthesis = 0;\n"
    3981             :               "        do {\n"
    3982             :               "            if (tok == '(')\n"
    3983             :               "                parenthesis++;\n"
    3984             :               "            else if (tok == ')')\n"
    3985             :               "                parenthesis--;\n"
    3986             :               "            next();\n"
    3987             :               "        } while (parenthesis && tok != -1);\n"
    3988             :               "    }\n"
    3989             :               "}\n");
    3990           1 :         ASSERT_EQUALS("", errout_str());
    3991             : 
    3992             :         // #7843
    3993           1 :         check("void f(int i) {\n"
    3994             :               "    if(abs(i) == -1) {}\n"
    3995             :               "}\n");
    3996           1 :         ASSERT_EQUALS("[test.cpp:2]: (style) Condition 'abs(i)==-1' is always false\n", errout_str());
    3997             : 
    3998             :         // #7844
    3999           1 :         check("void f(int i) {\n"
    4000             :               "    if(i > 0 && abs(i) == i) {}\n"
    4001             :               "}\n");
    4002           1 :         ASSERT_EQUALS("[test.cpp:2]: (style) Condition 'abs(i)==i' is always true\n", errout_str());
    4003             : 
    4004           1 :         check("void f(int i) {\n"
    4005             :               "    if(i < 0 && abs(i) == i) {}\n"
    4006             :               "}\n");
    4007           1 :         ASSERT_EQUALS("[test.cpp:2] -> [test.cpp:2]: (style) Condition 'abs(i)==i' is always false\n", errout_str());
    4008             : 
    4009           1 :         check("void f(int i) {\n"
    4010             :               "    if(i > -3 && abs(i) == i) {}\n"
    4011             :               "}\n");
    4012           1 :         ASSERT_EQUALS("", errout_str());
    4013             : 
    4014             :         // #9948
    4015           1 :         check("bool f(bool a, bool b) {\n"
    4016             :               "    return a || ! b || ! a;\n"
    4017             :               "}\n");
    4018           1 :         ASSERT_EQUALS("[test.cpp:2] -> [test.cpp:2]: (style) Return value '!a' is always true\n", errout_str());
    4019             : 
    4020             :         // #10148
    4021           1 :         check("void f(int i) {\n"
    4022             :               "    if (i >= 64) {}\n"
    4023             :               "    else if (i >= 32) {\n"
    4024             :               "        i &= 31;\n"
    4025             :               "        if (i == 0) {}\n"
    4026             :               "        else {}\n"
    4027             :               "    }\n"
    4028             :               "}\n");
    4029           1 :         ASSERT_EQUALS("", errout_str());
    4030             : 
    4031             :         // #10548
    4032           1 :         check("void f() {\n"
    4033             :               "    int i = 0;\n"
    4034             :               "    do {} while (i++ == 0);\n"
    4035             :               "}\n");
    4036           1 :         ASSERT_EQUALS("", errout_str());
    4037             : 
    4038             :         // #10582
    4039           1 :         check("static void fun(message_t *message) {\n"
    4040             :               "    if (message->length >= 1) {\n"
    4041             :               "        switch (data[0]) {}\n"
    4042             :               "    }\n"
    4043             :               "    uint8_t d0 = message->length > 0 ? data[0] : 0xff;\n"
    4044             :               "}\n");
    4045           1 :         ASSERT_EQUALS("", errout_str());
    4046             : 
    4047             :         // #8266
    4048           1 :         check("void f(bool b) {\n"
    4049             :               "    if (b)\n"
    4050             :               "        return;\n"
    4051             :               "    if (g(&b) || b)\n"
    4052             :               "        return;\n"
    4053             :               "}\n");
    4054           1 :         ASSERT_EQUALS("", errout_str());
    4055             : 
    4056             :         // #9720
    4057           1 :         check("bool bar(int &);\n"
    4058             :               "void f(int a, int b) {\n"
    4059             :               "    if (a + b == 3)\n"
    4060             :               "        return;\n"
    4061             :               "    if (bar(a) && (a + b == 3)) {}\n"
    4062             :               "}\n");
    4063           1 :         ASSERT_EQUALS("", errout_str());
    4064             : 
    4065             :         // #10437
    4066           1 :         check("void f() {\n"
    4067             :               "  Obj* PObj = nullptr;\n"
    4068             :               "  bool b = false;\n"
    4069             :               "  if (GetObj(PObj) && PObj != nullptr)\n"
    4070             :               "    b = true;\n"
    4071             :               "  if (b) {}\n"
    4072             :               "}\n");
    4073           1 :         ASSERT_EQUALS("", errout_str());
    4074             : 
    4075             :         // #10223
    4076           1 :         check("static volatile sig_atomic_t is_running;\n"
    4077             :               "static void handler(int signum) {\n"
    4078             :               "    is_running = 0;\n"
    4079             :               "}\n"
    4080             :               "void f() {\n"
    4081             :               "    signal(SIGINT, &handler);\n"
    4082             :               "    is_running = 1;\n"
    4083             :               "    while (is_running) {}\n"
    4084             :               "}\n");
    4085           1 :         ASSERT_EQUALS("", errout_str());
    4086             : 
    4087             :         // #10659
    4088           1 :         check("auto func(const std::tuple<int, int>& t) {\n"
    4089             :               "  auto& [foo, bar] = t;\n"
    4090             :               "  std::cout << foo << bar << std::endl;\n"
    4091             :               "  return foo < bar;\n"
    4092             :               "}\n");
    4093           1 :         ASSERT_EQUALS("", errout_str());
    4094             : 
    4095             :         // #10484
    4096           1 :         check("void f() {\n"
    4097             :               "    static bool init = true;\n"
    4098             :               "    if (init)\n"
    4099             :               "        init = false;\n"
    4100             :               "}\n");
    4101           1 :         ASSERT_EQUALS("[test.cpp:4] -> [test.cpp:3]: (style) The statement 'if (init) init=false' is logically equivalent to 'init=false'.\n", errout_str());
    4102             : 
    4103           1 :         check("void f() {\n"
    4104             :               "    static bool init(true);\n"
    4105             :               "    if (init)\n"
    4106             :               "        init = false;\n"
    4107             :               "}\n");
    4108           1 :         ASSERT_EQUALS("[test.cpp:4] -> [test.cpp:3]: (style) The statement 'if (init) init=false' is logically equivalent to 'init=false'.\n", errout_str());
    4109             : 
    4110           1 :         check("void f() {\n"
    4111             :               "    static bool init{ true };\n"
    4112             :               "    if (init)\n"
    4113             :               "        init = false;\n"
    4114             :               "}\n");
    4115           1 :         ASSERT_EQUALS("[test.cpp:4] -> [test.cpp:3]: (style) The statement 'if (init) init=false' is logically equivalent to 'init=false'.\n", errout_str());
    4116             : 
    4117             :         // #10248
    4118           1 :         check("void f() {\n"
    4119             :               "    static int var(1);\n"
    4120             :               "    if (var == 1) {}\n"
    4121             :               "}\n");
    4122           1 :         ASSERT_EQUALS("", errout_str());
    4123             : 
    4124           1 :         check("void f() {\n"
    4125             :               "    static int var{ 1 };\n"
    4126             :               "    if (var == 1) {}\n"
    4127             :               "}\n");
    4128           1 :         ASSERT_EQUALS("", errout_str());
    4129             : 
    4130           1 :         check("void Fun();\n"
    4131             :               "using Fn = void (*)();\n"
    4132             :               "void f() {\n"
    4133             :               "    static Fn logger = nullptr;\n"
    4134             :               "    if (logger == nullptr)\n"
    4135             :               "        logger = Fun;\n"
    4136             :               "}\n");
    4137           1 :         ASSERT_EQUALS("", errout_str());
    4138             : 
    4139           1 :         check("void Fun();\n"
    4140             :               "using Fn = void (*)();\n"
    4141             :               "void f() {\n"
    4142             :               "    static Fn logger(nullptr);\n"
    4143             :               "    if (logger == nullptr)\n"
    4144             :               "        logger = Fun;\n"
    4145             :               "}\n");
    4146           1 :         ASSERT_EQUALS("", errout_str());
    4147             : 
    4148           1 :         check("void Fun();\n"
    4149             :               "using Fn = void (*)();\n"
    4150             :               "void f() {\n"
    4151             :               "    static Fn logger{ nullptr };\n"
    4152             :               "    if (logger == nullptr)\n"
    4153             :               "        logger = Fun;\n"
    4154             :               "}\n");
    4155           1 :         ASSERT_EQUALS("", errout_str());
    4156             : 
    4157           1 :         check("void Fun();\n"
    4158             :               "typedef void (*Fn)();\n"
    4159             :               "void f() {\n"
    4160             :               "    static Fn logger = nullptr;\n"
    4161             :               "    if (logger == nullptr)\n"
    4162             :               "        logger = Fun;\n"
    4163             :               "}\n");
    4164           1 :         ASSERT_EQUALS("", errout_str());
    4165             : 
    4166           1 :         check("void Fun();\n"
    4167             :               "typedef void (*Fn)();\n"
    4168             :               "void f() {\n"
    4169             :               "    static Fn logger(nullptr);\n"
    4170             :               "    if (logger == nullptr)\n"
    4171             :               "        logger = Fun;\n"
    4172             :               "}\n");
    4173           1 :         ASSERT_EQUALS("", errout_str());
    4174             : 
    4175           1 :         check("void Fun();\n"
    4176             :               "typedef void (*Fn)();\n"
    4177             :               "void f() {\n"
    4178             :               "    static Fn logger{ nullptr };\n"
    4179             :               "    if (logger == nullptr)\n"
    4180             :               "        logger = Fun;\n"
    4181             :               "}\n");
    4182           1 :         ASSERT_EQUALS("", errout_str());
    4183             : 
    4184             :         // #9256
    4185           1 :         check("bool f() {\n"
    4186             :               "    bool b = false;\n"
    4187             :               "    b = true;\n"
    4188             :               "    return b;\n"
    4189             :               "}\n");
    4190           1 :         ASSERT_EQUALS("", errout_str());
    4191             : 
    4192             :         // #10702
    4193           1 :         check("struct Object {\n"
    4194             :               "  int _count=0;\n"
    4195             :               "   void increment() { ++_count;}\n"
    4196             :               "   auto get() const { return _count; }\n"
    4197             :               "};\n"
    4198             :               "struct Modifier {\n"
    4199             :               "Object & _object;\n"
    4200             :               "  explicit Modifier(Object & object) : _object(object) {}\n"
    4201             :               "  void do_something() { _object.increment(); }\n"
    4202             :               "};\n"
    4203             :               "struct Foo {\n"
    4204             :               "  Object _object;\n"
    4205             :               "  void foo() {\n"
    4206             :               "    Modifier mod(_object);\n"
    4207             :               "    if (_object.get()>0)\n"
    4208             :               "      return;\n"
    4209             :               "    mod.do_something();\n"
    4210             :               "    if (_object.get()>0)\n"
    4211             :               "      return;\n"
    4212             :               "  }\n"
    4213             :               "};\n");
    4214           1 :         ASSERT_EQUALS("", errout_str());
    4215             : 
    4216           1 :         check("struct Object {\n"
    4217             :               "  int _count=0;\n"
    4218             :               "   auto get() const;\n"
    4219             :               "};\n"
    4220             :               "struct Modifier {\n"
    4221             :               "Object & _object;\n"
    4222             :               "  explicit Modifier(Object & object);\n"
    4223             :               "  void do_something();\n"
    4224             :               "};\n"
    4225             :               "struct Foo {\n"
    4226             :               "  Object _object;\n"
    4227             :               "  void foo() {\n"
    4228             :               "    Modifier mod(_object);\n"
    4229             :               "    if (_object.get()>0)\n"
    4230             :               "      return;\n"
    4231             :               "    mod.do_something();\n"
    4232             :               "    if (_object.get()>0)\n"
    4233             :               "      return;\n"
    4234             :               "  }\n"
    4235             :               "};\n");
    4236           1 :         ASSERT_EQUALS("", errout_str());
    4237             : 
    4238           1 :         check("void f(const uint32_t u) {\n"
    4239             :               "    const uint32_t v = u < 4;\n"
    4240             :               "    if (v) {\n"
    4241             :               "            const uint32_t w = v < 2;\n"
    4242             :               "            if (w) {}\n"
    4243             :               "    }\n"
    4244             :               "}\n");
    4245           1 :         ASSERT_EQUALS("[test.cpp:4]: (style) Condition 'v<2' is always true\n"
    4246             :                       "[test.cpp:5]: (style) Condition 'w' is always true\n",
    4247             :                       errout_str());
    4248             : 
    4249           1 :         check("void f(double d) {\n" // #10792
    4250             :               "    if (d != 0) {\n"
    4251             :               "        int i = (int)d;\n"
    4252             :               "        if (i == 0) {}\n"
    4253             :               "    }\n"
    4254             :               "}\n");
    4255           1 :         ASSERT_EQUALS("", errout_str());
    4256             : 
    4257           1 :         check("void f(double d) {\n"
    4258             :               "    if (0 != d) {\n"
    4259             :               "        int i = (int)d;\n"
    4260             :               "        if (i == 0) {}\n"
    4261             :               "    }\n"
    4262             :               "}\n");
    4263           1 :         ASSERT_EQUALS("", errout_str());
    4264             : 
    4265           1 :         check("struct A { double d; }\n"
    4266             :               "void f(A a) {\n"
    4267             :               "    if (a.d != 0) {\n"
    4268             :               "        int i = a.d;\n"
    4269             :               "        if (i == 0) {}\n"
    4270             :               "    }\n"
    4271             :               "}\n");
    4272           1 :         ASSERT_EQUALS("", errout_str());
    4273             : 
    4274           1 :         check("void f() {\n"
    4275             :               "    if(strlen(\"abc\") == 3) {;}\n"
    4276             :               "    if(strlen(\"abc\") == 1) {;}\n"
    4277             :               "    if(wcslen(L\"abc\") == 3) {;}\n"
    4278             :               "    if(wcslen(L\"abc\") == 1) {;}\n"
    4279             :               "}\n");
    4280           1 :         ASSERT_EQUALS("[test.cpp:2]: (style) Condition 'strlen(\"abc\")==3' is always true\n"
    4281             :                       "[test.cpp:3]: (style) Condition 'strlen(\"abc\")==1' is always false\n"
    4282             :                       "[test.cpp:4]: (style) Condition 'wcslen(L\"abc\")==3' is always true\n"
    4283             :                       "[test.cpp:5]: (style) Condition 'wcslen(L\"abc\")==1' is always false\n",
    4284             :                       errout_str());
    4285             : 
    4286           1 :         check("int foo(bool a, bool b) {\n"
    4287             :               "  if(!a && b && (!a == !b))\n"
    4288             :               "   return 1;\n"
    4289             :               "  return 0;\n"
    4290             :               "}\n");
    4291           1 :         ASSERT_EQUALS("[test.cpp:2] -> [test.cpp:2]: (style) Condition '!a==!b' is always false\n", errout_str());
    4292             : 
    4293             :         // #10454
    4294           1 :         check("struct S {\n"
    4295             :               "    int f() const { return g() ? 0 : 1; }\n"
    4296             :               "    bool g() const { return u == 18446744073709551615ULL; }\n"
    4297             :               "    unsigned long long u{};\n"
    4298             :               "};\n");
    4299           1 :         ASSERT_EQUALS("", errout_str());
    4300             : 
    4301             :         // #8358
    4302           1 :         check("void f(double d) { if ((d * 0) != 0) {} }");
    4303           1 :         ASSERT_EQUALS("", errout_str());
    4304             : 
    4305             :         // #6870
    4306           1 :         check("struct S {\n"
    4307             :               "    int* p;\n"
    4308             :               "    void f() const;\n"
    4309             :               "    int g();\n"
    4310             :               "};\n"
    4311             :               "void S::f() {\n"
    4312             :               "    if ((p == NULL) || ((p) && (g() >= *p))) {}\n"
    4313             :               "}\n");
    4314           1 :         ASSERT_EQUALS("[test.cpp:7]: (style) Condition 'p' is always true\n", errout_str());
    4315             : 
    4316             :         // #10749
    4317           1 :         check("struct Interface {\n"
    4318             :               "    virtual int method() = 0;\n"
    4319             :               "};\n"
    4320             :               "struct Child : Interface {\n"
    4321             :               "   int method() override { return 0; }\n"
    4322             :               "   auto foo() {\n"
    4323             :               "       if (method() == 0)\n"
    4324             :               "           return true;\n"
    4325             :               "       else\n"
    4326             :               "           return false;\n"
    4327             :               "   }\n"
    4328             :               "};\n"
    4329             :               "struct GrandChild : Child {\n"
    4330             :               "   int method() override  { return 1; }\n"
    4331             :               "};\n");
    4332           1 :         ASSERT_EQUALS("", errout_str());
    4333             : 
    4334             :         // #6855
    4335           1 :         check("struct S { int i; };\n"
    4336             :               "void f(S& s) {\n"
    4337             :               "    if (!(s.i > 0) && (s.i != 0))\n"
    4338             :               "        s.i = 0;\n"
    4339             :               "    else if (s.i < 0)\n"
    4340             :               "        s.s = 0;\n"
    4341             :               "}\n");
    4342           1 :         ASSERT_EQUALS("[test.cpp:3] -> [test.cpp:5]: (style) Condition 's.i<0' is always false\n", errout_str());
    4343             : 
    4344             :         // #6857
    4345           1 :         check("int bar(int i) { return i; }\n"
    4346             :               "void foo() {\n"
    4347             :               "    if (bar(1) == 0 && bar(1) > 0) {}\n"
    4348             :               "}\n");
    4349           1 :         ASSERT_EQUALS("[test.cpp:3]: (style) Condition 'bar(1)==0' is always false\n"
    4350             :                       "[test.cpp:3]: (style) Condition 'bar(1)>0' is always true\n",
    4351             :                       errout_str());
    4352             : 
    4353           1 :         check("struct S { int bar(int i) const; };\n"
    4354             :               "void foo(const S& s) {\n"
    4355             :               "    if (s.bar(1) == 0 && s.bar(1) > 0) {}\n"
    4356             :               "}\n");
    4357           1 :         ASSERT_EQUALS("[test.cpp:3]: (warning) Logical conjunction always evaluates to false: s.bar(1) == 0 && s.bar(1) > 0.\n",
    4358             :                       errout_str());
    4359             : 
    4360           1 :         check("struct B {\n" // #10618
    4361             :               "    void Modify();\n"
    4362             :               "    static void Static();\n"
    4363             :               "    virtual void CalledByModify();\n"
    4364             :               "};\n"
    4365             :               "struct D : B {\n"
    4366             :               "    int i{};\n"
    4367             :               "    void testV();\n"
    4368             :               "    void testS();\n"
    4369             :               "    void CalledByModify() override { i = 0; }\n"
    4370             :               "};\n"
    4371             :               "void D::testV() {\n"
    4372             :               "    i = 1;\n"
    4373             :               "    B::Modify();\n"
    4374             :               "    if (i == 1) {}\n"
    4375             :               "}\n"
    4376             :               "void D::testS() {\n"
    4377             :               "    i = 1;\n"
    4378             :               "    B::Static();\n"
    4379             :               "    if (i == 1) {}\n"
    4380             :               "}\n");
    4381           1 :         ASSERT_EQUALS("[test.cpp:20]: (style) Condition 'i==1' is always true\n", errout_str());
    4382             : 
    4383           1 :         check("typedef struct { bool x; } s_t;\n" // #8446
    4384             :               "unsigned f(bool a, bool b) {\n"
    4385             :               "    s_t s;\n"
    4386             :               "    const unsigned col = a ? (s.x = false) : (b = true);\n"
    4387             :               "    if (!s.x) {}\n"
    4388             :               "    return col;\n"
    4389             :               "}\n");
    4390           1 :         ASSERT_EQUALS("", errout_str());
    4391             : 
    4392           1 :         check("struct S {\n" // #11233
    4393             :               "    static std::string m;\n"
    4394             :               "    static void f() { m = \"abc\"; }\n"
    4395             :               "    static void g() {\n"
    4396             :               "        m.clear();\n"
    4397             :               "        f();\n"
    4398             :               "        if (m.empty()) {}\n"
    4399             :               "    }\n"
    4400             :               "};\n");
    4401           1 :         ASSERT_EQUALS("", errout_str());
    4402             : 
    4403             :         // #11203
    4404           1 :         check("void f() {\n"
    4405             :               "    int i = 10;\n"
    4406             :               "    if(i > 9.9){}\n"
    4407             :               "    float f = 9.9f;\n"
    4408             :               "    if(f < 10) {}\n"
    4409             :               "}\n");
    4410           1 :         ASSERT_EQUALS("[test.cpp:3]: (style) Condition 'i>9.9' is always true\n"
    4411             :                       "[test.cpp:5]: (style) Condition 'f<10' is always true\n",
    4412             :                       errout_str());
    4413           1 :         check("constexpr int f() {\n" // #11238
    4414             :               "    return 1;\n"
    4415             :               "}\n"
    4416             :               "constexpr bool g() {\n"
    4417             :               "    return f() == 1;\n"
    4418             :               "}\n");
    4419           1 :         ASSERT_EQUALS("", errout_str());
    4420             : 
    4421           1 :         check("int g() { return -1; }\n"
    4422             :               "void f() {\n"
    4423             :               "    if (g() == 1 && g() == -1) {}\n"
    4424             :               "}\n");
    4425           1 :         ASSERT_EQUALS("[test.cpp:3]: (style) Condition 'g()==1' is always false\n"
    4426             :                       "[test.cpp:3]: (style) Condition 'g()==-1' is always true\n",
    4427             :                       errout_str());
    4428             : 
    4429             :         // #9817
    4430           1 :         check("void f(float x) {\n"
    4431             :               "    if (x <= 0) {}\n"
    4432             :               "    else if (x < 1) {}\n"
    4433             :               "}\n");
    4434           1 :         ASSERT_EQUALS("", errout_str());
    4435             : 
    4436             :         // #10426
    4437           1 :         check("int f() {\n"
    4438             :               "    std::string s;\n"
    4439             :               "    for (; !s.empty();) {}\n"
    4440             :               "    for (; s.empty();) {}\n"
    4441             :               "    if (s.empty()) {}\n"
    4442             :               "    if ((bool)0) {}\n"
    4443             :               "    return s.empty();"
    4444             :               "}\n");
    4445           1 :         ASSERT_EQUALS("[test.cpp:3]: (style) Condition '!s.empty()' is always false\n"
    4446             :                       "[test.cpp:4]: (style) Condition 's.empty()' is always true\n"
    4447             :                       "[test.cpp:5]: (style) Condition 's.empty()' is always true\n"
    4448             :                       "[test.cpp:6]: (style) Condition '(bool)0' is always false\n"
    4449             :                       "[test.cpp:7]: (style) Return value 's.empty()' is always true\n",
    4450             :                       errout_str());
    4451             : 
    4452           1 :         check("int f(bool b) {\n"
    4453             :               "    if (b) return static_cast<int>(1);\n"
    4454             :               "    return (int)0;\n"
    4455             :               "}\n"
    4456             :               "bool g(bool b) {\n"
    4457             :               "    if (b) return static_cast<int>(1);\n"
    4458             :               "    return (int)0;\n"
    4459             :               "}\n");
    4460           1 :         ASSERT_EQUALS("[test.cpp:6]: (style) Return value 'static_cast<int>(1)' is always true\n"
    4461             :                       "[test.cpp:7]: (style) Return value '(int)0' is always false\n",
    4462             :                       errout_str());
    4463             : 
    4464           1 :         check("int f() { return 3; }\n"
    4465             :               "int g() { return f(); }\n"
    4466             :               "int h() { if (f()) {} }\n"
    4467             :               "int i() { return f() == 3; }\n");
    4468           1 :         ASSERT_EQUALS("[test.cpp:3]: (style) Condition 'f()' is always true\n"
    4469             :                       "[test.cpp:4]: (style) Return value 'f()==3' is always true\n",
    4470             :                       errout_str());
    4471             : 
    4472           1 :         check("int f() {\n"
    4473             :               "    const char *n;\n"
    4474             :               "    return((n=42) &&\n"
    4475             :               "           *n == 'A');\n"
    4476             :               "}\n");
    4477           1 :         ASSERT_EQUALS("", errout_str());
    4478             : 
    4479           1 :         check("void f(std::istringstream& i) {\n" // #9327
    4480             :               "    std::string s;\n"
    4481             :               "    if (!(i >> s))\n"
    4482             :               "        return;\n"
    4483             :               "    if (!(i >> s))\n"
    4484             :               "        return;\n"
    4485             :               "}\n");
    4486           1 :         ASSERT_EQUALS("", errout_str());
    4487             : 
    4488             :         // #11227
    4489           1 :         check("struct S {\n"
    4490             :               "    int get();\n"
    4491             :               "};\n"
    4492             :               "void f(const S* s) {\n"
    4493             :               "    if (!s)\n"
    4494             :               "        return;\n"
    4495             :               "    g(s ? s->get() : 0);\n"
    4496             :               "}\n");
    4497           1 :         ASSERT_EQUALS("[test.cpp:5] -> [test.cpp:7]: (style) Condition 's' is always true\n", errout_str());
    4498             : 
    4499           1 :         check("void f(const char* o) {\n" // #11558
    4500             :               "    if (!o || !o[0])\n"
    4501             :               "        return;\n"
    4502             :               "    if (o[0] == '-' && o[1]) {\n"
    4503             :               "        if (o[1] == '-') {}\n"
    4504             :               "        if (o[1] == '\\0') {}\n"
    4505             :               "    }\n"
    4506             :               "}\n");
    4507             :         if (std::numeric_limits<char>::is_signed) {
    4508           1 :             ASSERT_EQUALS("[test.cpp:6]: (style) Condition 'o[1]=='\\0'' is always false\n", errout_str());
    4509             :         } else {
    4510             :             ASSERT_EQUALS("[test.cpp:4] -> [test.cpp:6]: (style) Condition 'o[1]=='\\0'' is always false\n", errout_str());
    4511             :         }
    4512             : 
    4513           1 :         check("void f(int x) {\n" // #11449
    4514             :               "    int i = x;\n"
    4515             :               "    i = (std::min)(i, 1);\n"
    4516             :               "    if (i == 1) {}\n"
    4517             :               "    int j = x;\n"
    4518             :               "    j = (::std::min)(j, 1);\n"
    4519             :               "    if (j == 1) {}\n"
    4520             :               "}\n");
    4521           1 :         ASSERT_EQUALS("", errout_str());
    4522             : 
    4523           1 :         check("void h(int);\n" // #11679
    4524             :               "bool g(int a) { h(a); return false; }\n"
    4525             :               "bool f(int i) {\n"
    4526             :               "    return g(i);\n"
    4527             :               "}\n");
    4528           1 :         ASSERT_EQUALS("", errout_str());
    4529             : 
    4530           1 :         check("void f(std::string a) {\n" // #11051
    4531             :               "    a = \"x\";\n"
    4532             :               "    if (a == \"x\") {}\n"
    4533             :               "    return a;\n"
    4534             :               "}\n");
    4535           1 :         ASSERT_EQUALS("[test.cpp:3]: (style) Condition 'a==\"x\"' is always true\n", errout_str());
    4536             : 
    4537           1 :         check("void g(bool);\n"
    4538             :               "void f() {\n"
    4539             :               "    int i = 5;\n"
    4540             :               "    int* p = &i;\n"
    4541             :               "    g(i == 7);\n"
    4542             :               "    g(p == nullptr);\n"
    4543             :               "}\n");
    4544           1 :         ASSERT_EQUALS("[test.cpp:5]: (style) Condition 'i==7' is always false\n"
    4545             :                       "[test.cpp:6]: (style) Condition 'p==nullptr' is always false\n",
    4546             :                       errout_str());
    4547             : 
    4548           1 :         check("enum E { E0, E1 };\n"
    4549             :               "void f() {\n"
    4550             :               "    static_assert(static_cast<int>(E::E1) == 1);\n"
    4551             :               "}\n");
    4552           1 :         ASSERT_EQUALS("", errout_str());
    4553             : 
    4554           1 :         check("struct a {\n"
    4555             :               "  bool g();\n"
    4556             :               "  int h();\n"
    4557             :               "};\n"
    4558             :               "void f(a c, int d, int e) {\n"
    4559             :               "  if (c.g() && c.h()) {}\n"
    4560             :               "  else {\n"
    4561             :               "    bool u = false;\n"
    4562             :               "    if (d && e)\n"
    4563             :               "      u = true;\n"
    4564             :               "    if (u) {}\n"
    4565             :               "  }\n"
    4566             :               "}\n");
    4567           1 :         ASSERT_EQUALS("", errout_str());
    4568             : 
    4569           1 :         check("int f(int i) {\n" // #11741
    4570             :               "    i = -i - 1;\n"
    4571             :               "    if (i < 0 || i >= 20)\n"
    4572             :               "        return 0;\n"
    4573             :               "    return 1;\n"
    4574             :               "}\n");
    4575           1 :         ASSERT_EQUALS("", errout_str());
    4576             :     }
    4577             : 
    4578           1 :     void alwaysTrueSymbolic()
    4579             :     {
    4580           1 :         check("void f(const uint32_t x) {\n"
    4581             :               "    uint32_t y[1];\n"
    4582             :               "    y[0]=x;\n"
    4583             :               "    if(x > 0 || y[0] < 42){}\n"
    4584             :               "}\n");
    4585           1 :         ASSERT_EQUALS("[test.cpp:4] -> [test.cpp:4]: (style) Condition 'y[0]<42' is always true\n", errout_str());
    4586             : 
    4587           1 :         check("void f(int x, int y) {\n"
    4588             :               "    if(x < y && x < 42) {\n"
    4589             :               "        --x;\n"
    4590             :               "        if(x == y) {}\n"
    4591             :               "    }\n"
    4592             :               "}\n");
    4593           1 :         ASSERT_EQUALS("[test.cpp:2] -> [test.cpp:4]: (style) Condition 'x==y' is always false\n", errout_str());
    4594             : 
    4595           1 :         check("void f(bool a, bool b) {  if (a == b && a && !b){} }");
    4596           1 :         ASSERT_EQUALS("[test.cpp:1] -> [test.cpp:1]: (style) Condition '!b' is always false\n", errout_str());
    4597             : 
    4598           1 :         check("bool f(bool a, bool b) { if(a && b && (!a)){} }");
    4599           1 :         ASSERT_EQUALS("[test.cpp:1] -> [test.cpp:1]: (style) Condition '!a' is always false\n", errout_str());
    4600             : 
    4601           1 :         check("void f(int x, int y) {\n"
    4602             :               "  if (x < y) {\n"
    4603             :               "    auto z = y - x;\n"
    4604             :               "    if (z < 1) {}\n"
    4605             :               "  }\n"
    4606             :               "}\n");
    4607           1 :         ASSERT_EQUALS("[test.cpp:2] -> [test.cpp:4]: (style) Condition 'z<1' is always false\n", errout_str());
    4608             : 
    4609           1 :         check("bool f(int &index, const int s, const double * const array, double & x) {\n"
    4610             :               "    if (index >= s)\n"
    4611             :               "        return false;\n"
    4612             :               "    else {\n"
    4613             :               "        x = array[index];\n"
    4614             :               "        return (index++) >= s;\n"
    4615             :               "    }\n"
    4616             :               "}\n");
    4617           1 :         ASSERT_EQUALS("[test.cpp:2] -> [test.cpp:6]: (style) Return value '(index++)>=s' is always false\n", errout_str());
    4618             : 
    4619           1 :         check("struct a {\n"
    4620             :               "  a *b() const;\n"
    4621             :               "} c;\n"
    4622             :               "void d() {\n"
    4623             :               "  a *e = nullptr;\n"
    4624             :               "  e = c.b();\n"
    4625             :               "  if (e) {}\n"
    4626             :               "}\n");
    4627           1 :         ASSERT_EQUALS("", errout_str());
    4628             : 
    4629           1 :         check("int g(int i) {\n"
    4630             :               "  if (i < 256)\n"
    4631             :               "    return 1;\n"
    4632             :               "  const int N = 2 * i;\n"
    4633             :               "  i -= 256;\n"
    4634             :               "  if (i == 0)\n"
    4635             :               "    return 0;\n"
    4636             :               "  return N;\n"
    4637             :               "}\n");
    4638           1 :         ASSERT_EQUALS("", errout_str());
    4639             : 
    4640           1 :         check("void f(int i, int j) {\n"
    4641             :               "    if (i < j) {\n"
    4642             :               "        i++;\n"
    4643             :               "        if (i >= j)\n"
    4644             :               "            return;\n"
    4645             :               "        i++;\n"
    4646             :               "        if (i >= j) {}\n"
    4647             :               "    }\n"
    4648             :               "}\n");
    4649           1 :         ASSERT_EQUALS("", errout_str());
    4650             : 
    4651           1 :         check("int get_delta() {\n"
    4652             :               "    clock_t now_ms = (clock() / (CLOCKS_PER_SEC / 1000));\n"
    4653             :               "    static clock_t last_clock_ms = now_ms;\n"
    4654             :               "    clock_t delta = now_ms - last_clock_ms;\n"
    4655             :               "    last_clock_ms = now_ms;\n"
    4656             :               "    if (delta > 50)\n"
    4657             :               "        delta = 50;\n"
    4658             :               "    return delta;\n"
    4659             :               "}\n");
    4660           1 :         ASSERT_EQUALS("", errout_str());
    4661             : 
    4662             :         // #10555
    4663           1 :         check("struct C {\n"
    4664             :               "  int GetI() const { return i; }\n"
    4665             :               "  int i{};\n"
    4666             :               "};\n"
    4667             :               "struct B {\n"
    4668             :               "    C *m_PC{};\n"
    4669             :               "    Modify();\n"
    4670             :               "};\n"
    4671             :               "struct D : B {\n"
    4672             :               "  void test();  \n"
    4673             :               "};\n"
    4674             :               "void D::test() {\n"
    4675             :               "    const int I = m_PC->GetI();\n"
    4676             :               "    Modify();\n"
    4677             :               "    if (m_PC->GetI() != I) {}\n"
    4678             :               "}\n");
    4679           1 :         ASSERT_EQUALS("", errout_str());
    4680             : 
    4681             :         // #10624
    4682           1 :         check("struct Data {\n"
    4683             :               "  Base* PBase{};\n"
    4684             :               "};\n"
    4685             :               "void f(Data* BaseData) {\n"
    4686             :               "  Base* PObj = BaseData->PBase;\n"
    4687             :               "  if (PObj == nullptr)\n"
    4688             :               "    return;\n"
    4689             :               "  Derived* pD = dynamic_cast<Derived*>(PObj);\n"
    4690             :               "  if (pD) {}\n"
    4691             :               "}\n");
    4692           1 :         ASSERT_EQUALS("", errout_str());
    4693             : 
    4694             :         // #9549
    4695           1 :         check("void f(const uint32_t v) {\n"
    4696             :               "    const uint32_t v16 = v >> 16;\n"
    4697             :               "    if (v16) {\n"
    4698             :               "        const uint32_t v8 = v16 >> 8;\n"
    4699             :               "        if (v8) {}\n"
    4700             :               "    }\n"
    4701             :               "}\n");
    4702           1 :         ASSERT_EQUALS("", errout_str());
    4703             : 
    4704             :         // #10649
    4705           1 :         check("void foo(struct diag_msg *msg) {\n"
    4706             :               "    msg = msg->next;\n"
    4707             :               "    if (msg == NULL)\n"
    4708             :               "        return CMD_OK;\n"
    4709             :               "    msg = msg->next;\n"
    4710             :               "    if (msg == NULL)\n"
    4711             :               "        return CMD_OK;\n"
    4712             :               "}\n");
    4713           1 :         ASSERT_EQUALS("", errout_str());
    4714             : 
    4715           1 :         check("int foo(bool a, bool b) {\n"
    4716             :               "  if((!a == !b) && !a && b)\n"
    4717             :               "   return 1;\n"
    4718             :               "  return 0;\n"
    4719             :               "}\n");
    4720           1 :         ASSERT_EQUALS("[test.cpp:2] -> [test.cpp:2]: (style) Condition 'b' is always false\n", errout_str());
    4721             : 
    4722             :         // #11124
    4723           1 :         check("struct Basket {\n"
    4724             :               "    std::vector<int> getApples() const;\n"
    4725             :               "    std::vector<int> getBananas() const;      \n"
    4726             :               "};\n"
    4727             :               "int getFruit(const Basket & b, bool preferApples)\n"
    4728             :               "{\n"
    4729             :               "    std::vector<int> apples = b.getApples();\n"
    4730             :               "    int apple = apples.empty() ? -1 : apples.front();\n"
    4731             :               "    std::vector<int> bananas = b.getBananas();\n"
    4732             :               "    int banana = bananas.empty() ? -1 : bananas.front();\n"
    4733             :               "    int fruit = std::max(apple, banana);\n"
    4734             :               "    if (fruit == -1)\n"
    4735             :               "        return fruit;\n"
    4736             :               "    if (std::min(apple, banana) != -1)\n"
    4737             :               "        fruit = preferApples ? apple : banana;\n"
    4738             :               "    return fruit;\n"
    4739             :               "}\n");
    4740           1 :         ASSERT_EQUALS("", errout_str());
    4741             : 
    4742           1 :         check("void f(const std::string & s, int i) {\n"
    4743             :               "    const char c = s[i];\n"
    4744             :               "    if (!std::isalnum(c)) {}\n"
    4745             :               "}\n");
    4746           1 :         ASSERT_EQUALS("", errout_str());
    4747             : 
    4748           1 :         check("struct S {\n" // #11404
    4749             :               "    int f() const;\n"
    4750             :               "    void g();\n"
    4751             :               "};\n"
    4752             :               "void h(std::vector<S*>::iterator it) {\n"
    4753             :               "    auto i = (*it)->f();\n"
    4754             :               "    (*it)->g();\n"
    4755             :               "    auto j = (*it)->f();\n"
    4756             :               "    if (i == j) {}\n"
    4757             :               "}\n");
    4758           1 :         ASSERT_EQUALS("", errout_str());
    4759             : 
    4760             :         // #11384
    4761           1 :         check("bool f(const int* it, const int* end) {\n"
    4762             :               "    return (it != end) && *it++ &&\n"
    4763             :               "           (it != end) && *it;\n"
    4764             :               "}\n");
    4765           1 :         ASSERT_EQUALS("", errout_str());
    4766             : 
    4767             :         // #12116
    4768           1 :         check("void f(int n) {\n"
    4769             :               "    for (int i = 0; i < N; ++i) {\n"
    4770             :               "        if (i < n) {}\n"
    4771             :               "        else if (i > n) {}\n"
    4772             :               "        else {}\n"
    4773             :               "    }\n"
    4774             :               "}\n");
    4775           1 :         ASSERT_EQUALS("", errout_str());
    4776             :     }
    4777             : 
    4778           1 :     void alwaysTrueInfer() {
    4779           1 :         check("void f(int x) {\n"
    4780             :               "    if (x > 5) {\n"
    4781             :               "        x++;\n"
    4782             :               "        if (x == 1) {}\n"
    4783             :               "    }\n"
    4784             :               "}");
    4785           1 :         ASSERT_EQUALS("[test.cpp:2] -> [test.cpp:4]: (style) Condition 'x==1' is always false\n", errout_str());
    4786             : 
    4787           1 :         check("void f(int x) {\n"
    4788             :               "    if (x > 5) {\n"
    4789             :               "        x++;\n"
    4790             :               "        if (x != 1) {}\n"
    4791             :               "    }\n"
    4792             :               "}");
    4793           1 :         ASSERT_EQUALS("[test.cpp:2] -> [test.cpp:4]: (style) Condition 'x!=1' is always true\n", errout_str());
    4794             : 
    4795             :         // #6890
    4796           1 :         check("void f(int i) {\n"
    4797             :               "    int x = i;\n"
    4798             :               "    if (x >= 1) {}\n"
    4799             :               "    else {\n"
    4800             :               "        x = 8 - x;\n"
    4801             :               "        if (x == -1) {}\n"
    4802             :               "        else {}\n"
    4803             :               "    }\n"
    4804             :               "}");
    4805           1 :         ASSERT_EQUALS("[test.cpp:3] -> [test.cpp:6]: (style) Condition 'x==-1' is always false\n", errout_str());
    4806             : 
    4807           1 :         check("void f(int i) {\n"
    4808             :               "    int x = i;\n"
    4809             :               "    if (x >= 1) {}\n"
    4810             :               "    else {\n"
    4811             :               "        x = 8 - x;\n"
    4812             :               "        if (x != -1) {}\n"
    4813             :               "        else {}\n"
    4814             :               "    }\n"
    4815             :               "}");
    4816           1 :         ASSERT_EQUALS("[test.cpp:3] -> [test.cpp:6]: (style) Condition 'x!=-1' is always true\n", errout_str());
    4817             : 
    4818           1 :         check("void f(int i) {\n"
    4819             :               "    int x = i;\n"
    4820             :               "    if (x >= 1) {}\n"
    4821             :               "    else {\n"
    4822             :               "        x = 8 - x;\n"
    4823             :               "        if (x >= -1) {}\n"
    4824             :               "        else {}\n"
    4825             :               "    }\n"
    4826             :               "}");
    4827           1 :         ASSERT_EQUALS("[test.cpp:3] -> [test.cpp:6]: (style) Condition 'x>=-1' is always true\n", errout_str());
    4828             : 
    4829           1 :         check("void f(int i) {\n"
    4830             :               "    int x = i;\n"
    4831             :               "    if (x >= 1) {}\n"
    4832             :               "    else {\n"
    4833             :               "        x = 8 - x;\n"
    4834             :               "        if (x > -1) {}\n"
    4835             :               "        else {}\n"
    4836             :               "    }\n"
    4837             :               "}");
    4838           1 :         ASSERT_EQUALS("[test.cpp:3] -> [test.cpp:6]: (style) Condition 'x>-1' is always true\n", errout_str());
    4839             : 
    4840           1 :         check("void f(int i) {\n"
    4841             :               "    int x = i;\n"
    4842             :               "    if (x >= 1) {}\n"
    4843             :               "    else {\n"
    4844             :               "        x = 8 - x;\n"
    4845             :               "        if (x < -1) {}\n"
    4846             :               "        else {}\n"
    4847             :               "    }\n"
    4848             :               "}");
    4849           1 :         ASSERT_EQUALS("[test.cpp:3] -> [test.cpp:6]: (style) Condition 'x<-1' is always false\n", errout_str());
    4850             : 
    4851           1 :         check("void f(int i) {\n"
    4852             :               "    int x = i;\n"
    4853             :               "    if (x >= 1) {}\n"
    4854             :               "    else {\n"
    4855             :               "        x = 8 - x;\n"
    4856             :               "        if (x <= -1) {}\n"
    4857             :               "        else {}\n"
    4858             :               "    }\n"
    4859             :               "}");
    4860           1 :         ASSERT_EQUALS("[test.cpp:3] -> [test.cpp:6]: (style) Condition 'x<=-1' is always false\n", errout_str());
    4861             : 
    4862           1 :         check("void f(int i) {\n"
    4863             :               "    int x = i;\n"
    4864             :               "    if (x >= 1) {}\n"
    4865             :               "    else {\n"
    4866             :               "        x = 8 - x;\n"
    4867             :               "        if (x > 7) {}\n"
    4868             :               "        else {}\n"
    4869             :               "    }\n"
    4870             :               "}");
    4871           1 :         ASSERT_EQUALS("[test.cpp:3] -> [test.cpp:6]: (style) Condition 'x>7' is always true\n", errout_str());
    4872             : 
    4873           1 :         check("void f(int i) {\n"
    4874             :               "    int x = i;\n"
    4875             :               "    if (x >= 1) {}\n"
    4876             :               "    else {\n"
    4877             :               "        x = 8 - x;\n"
    4878             :               "        if (x > 9) {}\n"
    4879             :               "        else {}\n"
    4880             :               "    }\n"
    4881             :               "}");
    4882           1 :         ASSERT_EQUALS("", errout_str());
    4883             : 
    4884           1 :         check("void f(int i) {\n"
    4885             :               "    int x = i;\n"
    4886             :               "    if (x >= 1) {}\n"
    4887             :               "    else {\n"
    4888             :               "        x = 8 - x;\n"
    4889             :               "        if (x > 10) {}\n"
    4890             :               "        else {}\n"
    4891             :               "    }\n"
    4892             :               "}");
    4893           1 :         ASSERT_EQUALS("", errout_str());
    4894             : 
    4895             :         // #11100
    4896           1 :         check("struct T {\n"
    4897             :               "  bool m{};\n"
    4898             :               "  void f(bool b);\n"
    4899             :               "  bool get() const { return m; }\n"
    4900             :               "  void set(bool v) { m = v; }\n"
    4901             :               "};\n"
    4902             :               "void T::f(bool b) {\n"
    4903             :               "    bool tmp = get();\n"
    4904             :               "    set(b);\n"
    4905             :               "    if (tmp != get()) {}\n"
    4906             :               "}\n");
    4907           1 :         ASSERT_EQUALS("", errout_str());
    4908             : 
    4909             :         // #9541
    4910           1 :         check("int f(int pos, int a) {\n"
    4911             :               "    if (pos <= 0)\n"
    4912             :               "        pos = 0;\n"
    4913             :               "    else if (pos < a)\n"
    4914             :               "        if(pos > 0)\n"
    4915             :               "            --pos;\n"
    4916             :               "    return pos;\n"
    4917             :               "}");
    4918           1 :         ASSERT_EQUALS("[test.cpp:2] -> [test.cpp:5]: (style) Condition 'pos>0' is always true\n", errout_str());
    4919             : 
    4920             :         // #9721
    4921           1 :         check("void f(int x) {\n"
    4922             :               "    if (x > 127) {\n"
    4923             :               "        if ( (x>255) || (-128>x) )\n"
    4924             :               "            return;\n"
    4925             :               "    }\n"
    4926             :               "}");
    4927           1 :         ASSERT_EQUALS("[test.cpp:2] -> [test.cpp:3]: (style) Condition '-128>x' is always false\n", errout_str());
    4928             : 
    4929             :         // #8778
    4930           1 :         check("void f() {\n"
    4931             :               "    for(int i = 0; i < 19; ++i)\n"
    4932             :               "        if(i<=18) {}\n"
    4933             :               "}\n");
    4934           1 :         ASSERT_EQUALS("[test.cpp:3]: (style) Condition 'i<=18' is always true\n", errout_str());
    4935             : 
    4936             :         // #8209
    4937           1 :         check("void f() {\n"
    4938             :               "    for(int x = 0; x < 3; ++x)\n"
    4939             :               "        if(x == -5) {}\n"
    4940             :               "}");
    4941           1 :         ASSERT_EQUALS("[test.cpp:3]: (style) Condition 'x==-5' is always false\n", errout_str());
    4942             : 
    4943             :         // #8407
    4944           1 :         check("int f(void) {\n"
    4945             :               "    for(int i = 0; i <1; ++i)\n"
    4946             :               "        if(i == 0) return 1; \n" // <<
    4947             :               "        else return 0;\n"
    4948             :               "    return -1;\n"
    4949             :               "}");
    4950           1 :         ASSERT_EQUALS("[test.cpp:3]: (style) Condition 'i==0' is always true\n", errout_str());
    4951             : 
    4952           1 :         check("void f(unsigned int u1, unsigned int u2) {\n"
    4953             :               "    if (u1 <= 10 && u2 >= 20) {\n"
    4954             :               "        if (u1 != u2) {}\n"
    4955             :               "    }\n"
    4956             :               "}\n");
    4957           1 :         ASSERT_EQUALS("[test.cpp:2] -> [test.cpp:3]: (style) Condition 'u1!=u2' is always true\n", errout_str());
    4958             : 
    4959             :         // #10544
    4960           1 :         check("void f(int N) {\n"
    4961             :               "    if (N > 0) {\n"
    4962             :               "        while (N)\n"
    4963             :               "            N = test();\n"
    4964             :               "    }\n"
    4965             :               "}\n");
    4966           1 :         ASSERT_EQUALS("", errout_str());
    4967             : 
    4968             :         // #11098
    4969           1 :         check("void f(unsigned int x) { if (x == -1u) {} }\n");
    4970           1 :         ASSERT_EQUALS("", errout_str());
    4971             : 
    4972           1 :         check("bool f(const int *p, const int *q) {\n"
    4973             :               "    return p != NULL && q != NULL && p == NULL;\n"
    4974             :               "}\n");
    4975           1 :         ASSERT_EQUALS("[test.cpp:2]: (style) Return value 'p==NULL' is always false\n", errout_str());
    4976             : 
    4977           1 :         check("struct S {\n" // #11789
    4978             :               "    std::vector<int> v;\n"
    4979             :               "    void f(int i) const;\n"
    4980             :               "};\n"
    4981             :               "void S::f(int i) const {\n"
    4982             :               "    int j = i - v.size();\n"
    4983             :               "    if (j >= 0) {}\n"
    4984             :               "}\n");
    4985           1 :         ASSERT_EQUALS("", errout_str());
    4986             : 
    4987           1 :         check("void f(int i) {\n" // #12039
    4988             :               "    if ((128 + i < 255 ? 128 + i : 255) > 0) {}\n"
    4989             :               "}\n");
    4990           1 :         ASSERT_EQUALS("", errout_str());
    4991             :     }
    4992             : 
    4993           1 :     void alwaysTrueContainer() {
    4994             :         // #9329
    4995           1 :         check("void c1(std::vector<double>&);\n"
    4996             :               "void c2(std::vector<double>&);\n"
    4997             :               "void foo(int flag) {\n"
    4998             :               "    std::vector<double> g;\n"
    4999             :               "    if (flag)\n"
    5000             :               "        c1(g );\n"
    5001             :               "    else\n"
    5002             :               "        c2(g );\n"
    5003             :               "    if ( !g.empty() )\n"
    5004             :               "        return;\n"
    5005             :               "}");
    5006           1 :         ASSERT_EQUALS("", errout_str());
    5007             : 
    5008           1 :         check("void foo(int flag) {\n"
    5009             :               "    std::vector<double> g;\n"
    5010             :               "    if (flag)\n"
    5011             :               "        c1(g );\n"
    5012             :               "    else\n"
    5013             :               "        c2(g );\n"
    5014             :               "    if ( !g.empty() )\n"
    5015             :               "        return;\n"
    5016             :               "}");
    5017           1 :         ASSERT_EQUALS("", errout_str());
    5018             : 
    5019           1 :         check("struct A {\n"
    5020             :               "    std::vector<int> v;\n"
    5021             :               "    void g();\n"
    5022             :               "    void f(bool b) {\n"
    5023             :               "        v.clear();\n"
    5024             :               "        g();\n"
    5025             :               "        return !v.empty();\n"
    5026             :               "    }\n"
    5027             :               "};\n");
    5028           1 :         ASSERT_EQUALS("", errout_str());
    5029             : 
    5030             :         // #10409
    5031           1 :         check("void foo(const std::string& s) {\n"
    5032             :               "    if( s.size() < 2 ) return;\n"
    5033             :               "    if( s == \"ab\" ) return;\n"
    5034             :               "    if( s.size() < 3 ) return;\n"
    5035             :               "}\n");
    5036           1 :         ASSERT_EQUALS("", errout_str());
    5037             : 
    5038           1 :         check("void foo(const std::string& s) {\n"
    5039             :               "    if( s.size() < 2 ) return;\n"
    5040             :               "    if( s != \"ab\" )\n"
    5041             :               "        if( s.size() < 3 ) return;\n"
    5042             :               "}\n");
    5043           1 :         ASSERT_EQUALS("", errout_str());
    5044             : 
    5045             :         // #10226
    5046           1 :         check("int f(std::vector<int>::iterator it, const std::vector<int>& vector) {\n"
    5047             :               "    if (!(it != vector.end() && it != vector.begin()))\n"
    5048             :               "        throw 0;\n"
    5049             :               "    if (it != vector.end() && *it == 0)\n"
    5050             :               "        return -1;\n"
    5051             :               "    return *it;\n"
    5052             :               "}\n");
    5053           1 :         ASSERT_EQUALS("[test.cpp:4]: (style) Condition 'it!=vector.end()' is always true\n", errout_str());
    5054             : 
    5055             :         // #11303
    5056           1 :         check("void f(int n) {\n"
    5057             :               "    std::vector<char> buffer(n);\n"
    5058             :               "    if(buffer.back() == 0 ||\n"
    5059             :               "       buffer.back() == '\\n' ||\n"
    5060             :               "       buffer.back() == '\\0') {}\n"
    5061             :               "}\n");
    5062             :         if (std::numeric_limits<char>::is_signed) {
    5063           1 :             ASSERT_EQUALS("[test.cpp:5]: (style) Condition 'buffer.back()=='\\0'' is always false\n", errout_str());
    5064             :         } else {
    5065             :             ASSERT_EQUALS("[test.cpp:3] -> [test.cpp:5]: (style) Condition 'buffer.back()=='\\0'' is always false\n", errout_str());
    5066             :         }
    5067             : 
    5068             :         // #9353
    5069           1 :         check("struct X { std::string s; };\n"
    5070             :               "void f(const std::vector<X>&v) {\n"
    5071             :               "    for (std::vector<X>::const_iterator it = v.begin(); it != v.end(); ++it)\n"
    5072             :               "        if (!it->s.empty()) {\n"
    5073             :               "            if (!it->s.empty()) {}\n"
    5074             :               "        }\n"
    5075             :               "}\n");
    5076           1 :         ASSERT_EQUALS("[test.cpp:4] -> [test.cpp:5]: (style) Condition '!it->s.empty()' is always true\n", errout_str());
    5077             : 
    5078           1 :         check("struct X { std::string s; };\n"
    5079             :               "void f(const std::vector<struct X>&v) {\n"
    5080             :               "    for (std::vector<struct X>::const_iterator it = v.begin(); it != v.end(); ++it)\n"
    5081             :               "        if (!it->s.empty()) {\n"
    5082             :               "            if (!it->s.empty()) {}\n"
    5083             :               "        }\n"
    5084             :               "}\n");
    5085           1 :         TODO_ASSERT_EQUALS("[test.cpp:4] -> [test.cpp:5]: (style) Condition '!it->s.empty()' is always true\n", "", errout_str());
    5086             : 
    5087             :         // #10508
    5088           1 :         check("bool f(const std::string& a, const std::string& b) {\n"
    5089             :               "    return a.empty() || (b.empty() && a.empty());\n"
    5090             :               "}\n");
    5091           1 :         ASSERT_EQUALS("[test.cpp:2] -> [test.cpp:2]: (style) Return value 'a.empty()' is always false\n", errout_str());
    5092             : 
    5093           1 :         check("struct A {\n"
    5094             :               "    struct iterator;\n"
    5095             :               "    iterator begin() const;\n"
    5096             :               "    iterator end() const;\n"
    5097             :               "};\n"
    5098             :               "A g();\n"
    5099             :               "void f(bool b) {\n"
    5100             :               "    std::set<int> s;\n"
    5101             :               "    auto v = g();\n"
    5102             :               "    s.insert(v.begin(), v.end());\n"
    5103             :               "    if(!b && s.size() != 1)\n"
    5104             :               "        return;\n"
    5105             :               "    if(!s.empty()) {}\n"
    5106             :               "}\n");
    5107           1 :         ASSERT_EQUALS("", errout_str());
    5108             : 
    5109           1 :         check("int f(std::string s) {\n"
    5110             :               "    if (s.empty())\n"
    5111             :               "        return -1;\n"
    5112             :               "    s += '\\n';\n"
    5113             :               "    if (s.empty())\n"
    5114             :               "        return -1;\n"
    5115             :               "    return -1;\n"
    5116             :               "}\n");
    5117           1 :         ASSERT_EQUALS("[test.cpp:5]: (style) Condition 's.empty()' is always false\n", errout_str());
    5118             : 
    5119           1 :         check("void f(std::string& p) {\n"
    5120             :               "    const std::string d{ \"abc\" };\n"
    5121             :               "    p += d;\n"
    5122             :               "    if(p.empty()) {}\n"
    5123             :               "}\n");
    5124           1 :         ASSERT_EQUALS("[test.cpp:4]: (style) Condition 'p.empty()' is always false\n", errout_str());
    5125             : 
    5126           1 :         check("bool f(int i, FILE* fp) {\n"
    5127             :               "  std::string s = \"abc\";\n"
    5128             :               "  s += std::to_string(i);\n"
    5129             :               "  s += \"\\n\";\n"
    5130             :               "  return fwrite(s.c_str(), 1, s.length(), fp) == s.length();\n"
    5131             :               "}\n");
    5132           1 :         ASSERT_EQUALS("", errout_str());
    5133             : 
    5134           1 :         check("void f(const std::string& s) {\n" // #9148
    5135             :               "    if (s.empty() || s.size() < 1) {}\n"
    5136             :               "}\n");
    5137           1 :         ASSERT_EQUALS("[test.cpp:2] -> [test.cpp:2]: (style) Condition 's.size()<1' is always false\n", errout_str());
    5138             : 
    5139           1 :         check("void bar(std::vector<int>& vv) {\n" // #11464
    5140             :               "    class F {\n"
    5141             :               "    public:\n"
    5142             :               "        F(int, std::vector<int>& lv) : mV(lv) {\n"
    5143             :               "            mV.push_back(0);\n"
    5144             :               "        }\n"
    5145             :               "    private:\n"
    5146             :               "        std::vector<int>& mV;\n"
    5147             :               "    } fi(1, vv);\n"
    5148             :               "}\n"
    5149             :               "void g() {\n"
    5150             :               "    std::vector<int> v;\n"
    5151             :               "    bar(v);\n"
    5152             :               "    if (v.empty()) {}\n"
    5153             :               "}\n");
    5154           1 :         ASSERT_EQUALS("", errout_str());
    5155             : 
    5156           1 :         check("struct F {\n"
    5157             :               "    F(int, std::vector<int>&lv) : mV(lv) {\n"
    5158             :               "        mV.push_back(0);\n"
    5159             :               "    }\n"
    5160             :               "    std::vector<int>& mV;\n"
    5161             :               "};\n"
    5162             :               "void g(std::vector<int>& vv) {\n"
    5163             :               "    F(1, vv);\n"
    5164             :               "}\n"
    5165             :               "void f() {\n"
    5166             :               "    std::vector<int> v;\n"
    5167             :               "    g(v);\n"
    5168             :               "    if (v.empty()) {}\n"
    5169             :               "}\n");
    5170           1 :         ASSERT_EQUALS("", errout_str());
    5171             :     }
    5172             : 
    5173           1 :     void alwaysTrueLoop()
    5174             :     {
    5175           1 :         check("long foo() {\n"
    5176             :               "  bool bUpdated = false;\n"
    5177             :               "  long Ret{};\n"
    5178             :               "  do {\n"
    5179             :               "    Ret = bar();\n"
    5180             :               "    if (Ret == 0) {\n"
    5181             :               "      if (bUpdated)\n"
    5182             :               "        return 1;\n"
    5183             :               "      bUpdated = true;\n"
    5184             :               "    }\n"
    5185             :               "    else\n"
    5186             :               "      bUpdated = false;\n"
    5187             :               "  }\n"
    5188             :               "  while (bUpdated);\n"
    5189             :               "  return Ret;\n"
    5190             :               "}\n");
    5191           1 :         ASSERT_EQUALS("", errout_str());
    5192             : 
    5193           1 :         check("bool foo() {\n"
    5194             :               "  bool bFirst = true;\n"
    5195             :               "  do {\n"
    5196             :               "    if (bFirst)\n"
    5197             :               "      bar();\n"
    5198             :               "    if (baz())\n"
    5199             :               "      break;       \n"
    5200             :               "    bFirst = false;\n"
    5201             :               "  } while (true);\n"
    5202             :               "  return bFirst;\n"
    5203             :               "}\n");
    5204           1 :         ASSERT_EQUALS("", errout_str());
    5205             : 
    5206           1 :         check("void f() {\n"
    5207             :               "   void * pool = NULL;\n"
    5208             :               "   do {\n"
    5209             :               "      pool = malloc(40);\n"
    5210             :               "      if (dostuff())\n"
    5211             :               "         break;\n"
    5212             :               "      pool = NULL;\n"
    5213             :               "   }\n"
    5214             :               "   while (0);\n"
    5215             :               "   if (pool) {}\n"
    5216             :               "}\n");
    5217           1 :         ASSERT_EQUALS("", errout_str());
    5218             : 
    5219             :         // #8499
    5220           1 :         check("void f(void)\n"
    5221             :               "{\n"
    5222             :               "    for (int i = 0; i < 2; ++i)\n"
    5223             :               "    {\n"
    5224             :               "        for (int j = 0; j < 8; ++j)\n"
    5225             :               "        {\n"
    5226             :               "            if ( (i==0|| i==1)\n" // << always true
    5227             :               "              && (j==0) )\n"
    5228             :               "            {;}\n"
    5229             :               "        }\n"
    5230             :               "    }\n"
    5231             :               "}");
    5232           1 :         ASSERT_EQUALS("[test.cpp:7] -> [test.cpp:7]: (style) Condition 'i==1' is always true\n", errout_str());
    5233             : 
    5234             :         // #10863
    5235           1 :         check("void f(const int A[], int Len) {\n"
    5236             :               "  if (Len <= 0)\n"
    5237             :               "    return;\n"
    5238             :               "  int I = 0;\n"
    5239             :               "  while (I < Len) {\n"
    5240             :               "    int K = I + 1;\n"
    5241             :               "    for (; K < Len; K++) {\n"
    5242             :               "      if (A[I] != A[K])\n"
    5243             :               "        break;\n"
    5244             :               "    } \n"
    5245             :               "    I = K;   \n"
    5246             :               "  }\n"
    5247             :               "}\n");
    5248           1 :         ASSERT_EQUALS("", errout_str());
    5249             : 
    5250           1 :         check("void f() {\n" // #11434
    5251             :               "    const int N = 5;\n"
    5252             :               "    bool a[N];\n"
    5253             :               "    for (int i = 0; i < N; a[i++] = false);\n"
    5254             :               "}\n");
    5255           1 :         ASSERT_EQUALS("", errout_str());
    5256             : 
    5257           1 :         check("void f() {\n" // #8192
    5258             :               "    for (int i = 0; i > 10; ++i) {}\n"
    5259             :               "}\n");
    5260           1 :         TODO_ASSERT_EQUALS("[test.cpp:2]: (style) Condition 'i>10' is always false\n", "", errout_str());
    5261             : 
    5262           1 :         check("void f() {\n"
    5263             :               "    for (int i = 1000; i < 20; ++i) {}\n"
    5264             :               "}\n");
    5265           1 :         ASSERT_EQUALS("[test.cpp:2]: (style) Condition 'i<20' is always false\n", errout_str());
    5266             :     }
    5267             : 
    5268           1 :     void alwaysTrueTryCatch()
    5269             :     {
    5270           1 :         check("void g();\n"
    5271             :               "void f(int x)\n"
    5272             :               "{\n"
    5273             :               "    if( x ) {\n"
    5274             :               "        try {\n"
    5275             :               "            g();\n"
    5276             :               "        }\n"
    5277             :               "        catch(...) {\n"
    5278             :               "            return;\n"
    5279             :               "        }\n"
    5280             :               "    }\n"
    5281             :               "    g();\n"
    5282             :               "    if( x ) {\n"
    5283             :               "        g();\n"
    5284             :               "    }\n"
    5285             :               "}\n");
    5286           1 :         ASSERT_EQUALS("", errout_str());
    5287             : 
    5288           1 :         check("void g();\n"
    5289             :               "void h();\n"
    5290             :               "void f(int x) {\n"
    5291             :               "    if( x ) {\n"
    5292             :               "        try {\n"
    5293             :               "            g();\n"
    5294             :               "            return;\n"
    5295             :               "        }\n"
    5296             :               "        catch( ... ) {}\n"
    5297             :               "    }\n"
    5298             :               "    h();\n"
    5299             :               "    if( x ) {\n"
    5300             :               "        g();\n"
    5301             :               "    }\n"
    5302             :               "}\n");
    5303           1 :         ASSERT_EQUALS("", errout_str());
    5304             : 
    5305           1 :         check("void f() {\n" // #10701
    5306             :               "    std::string s;\n"
    5307             :               "    try {\n"
    5308             :               "        try {\n"
    5309             :               "            s = g();\n"
    5310             :               "        }\n"
    5311             :               "        catch (const Err& err) {}\n"
    5312             :               "    }\n"
    5313             :               "    catch (const std::exception& e) {}\n"
    5314             :               "    if (s != \"abc\") {}\n"
    5315             :               "}\n");
    5316           1 :         ASSERT_EQUALS("", errout_str());
    5317             :     }
    5318             : 
    5319           1 :     void multiConditionAlwaysTrue() {
    5320           1 :         check("void f() {\n"
    5321             :               "  int val = 0;\n"
    5322             :               "  if (val < 0) continue;\n"
    5323             :               "  if (val > 0) {}\n"
    5324             :               "}");
    5325           1 :         ASSERT_EQUALS("", errout_str());
    5326             : 
    5327           1 :         check("void f() {\n"
    5328             :               "  int val = 0;\n"
    5329             :               "  if (val < 0) {\n"
    5330             :               "    if (val > 0) {}\n"
    5331             :               "  }\n"
    5332             :               "}");
    5333           1 :         ASSERT_EQUALS("", errout_str());
    5334             : 
    5335           1 :         check("void f() {\n"
    5336             :               "  int val = 0;\n"
    5337             :               "  if (val < 0) {\n"
    5338             :               "    if (val < 0) {}\n"
    5339             :               "  }\n"
    5340             :               "}");
    5341           1 :         ASSERT_EQUALS("", errout_str());
    5342             : 
    5343           1 :         check("void f() {\n"
    5344             :               "  int activate = 0;\n"
    5345             :               "  int foo = 0;\n"
    5346             :               "  if (activate) {}\n"
    5347             :               "  else if (foo) {}\n"
    5348             :               "}");
    5349           1 :         ASSERT_EQUALS("[test.cpp:4]: (style) Condition 'activate' is always false\n"
    5350             :                       "[test.cpp:5]: (style) Condition 'foo' is always false\n", errout_str());
    5351             : 
    5352             :         // #6904
    5353           1 :         check("void f() {\n"
    5354             :               "  const int b[2] = { 1,0 };\n"
    5355             :               "  if(b[1] == 2) {}\n"
    5356             :               "}");
    5357           1 :         ASSERT_EQUALS("[test.cpp:3]: (style) Condition 'b[1]==2' is always false\n", errout_str());
    5358             : 
    5359             :         // #9878
    5360           1 :         check("void f(bool a, bool b) {\n"
    5361             :               "    if (a && b){;}\n"
    5362             :               "    else if (!a && b){;}\n"
    5363             :               "    else if (!a && !b){;}\n"
    5364             :               "    else {;}\n"
    5365             :               "}\n");
    5366           1 :         ASSERT_EQUALS("", errout_str());
    5367             :     }
    5368             : 
    5369           1 :     void duplicateCondition() {
    5370           1 :         check("void f(bool x) {\n"
    5371             :               "    if(x) {}\n"
    5372             :               "    if(x) {}\n"
    5373             :               "}");
    5374           1 :         ASSERT_EQUALS("[test.cpp:2] -> [test.cpp:3]: (style) The if condition is the same as the previous if condition\n",
    5375             :                       errout_str());
    5376             : 
    5377           1 :         check("void f(int x) {\n"
    5378             :               "    if(x == 1) {}\n"
    5379             :               "    if(x == 1) {}\n"
    5380             :               "}");
    5381           1 :         ASSERT_EQUALS("[test.cpp:2] -> [test.cpp:3]: (style) The if condition is the same as the previous if condition\n",
    5382             :                       errout_str());
    5383             : 
    5384           1 :         check("void f(int x) {\n"
    5385             :               "    if(x == 1) {}\n"
    5386             :               "    if(x == 2) {}\n"
    5387             :               "}");
    5388           1 :         ASSERT_EQUALS("", errout_str());
    5389             : 
    5390           1 :         check("void f(int x) {\n"
    5391             :               "    if(x == 1) {}\n"
    5392             :               "    if(x != 1) {}\n"
    5393             :               "}");
    5394           1 :         ASSERT_EQUALS("", errout_str());
    5395             : 
    5396           1 :         check("void f(bool x) {\n"
    5397             :               "    if(x) {}\n"
    5398             :               "    g();\n"
    5399             :               "    if(x) {}\n"
    5400             :               "}");
    5401           1 :         ASSERT_EQUALS("", errout_str());
    5402             : 
    5403           1 :         check("void f(int x) {\n"
    5404             :               "    if(x == 1) { x++; }\n"
    5405             :               "    if(x == 1) {}\n"
    5406             :               "}");
    5407           1 :         ASSERT_EQUALS("", errout_str());
    5408             : 
    5409             :         // #8996
    5410           1 :         check("void g(int** v);\n"
    5411             :               "void f() {\n"
    5412             :               "  int a = 0;\n"
    5413             :               "  int b = 0;\n"
    5414             :               "  int* d[] = {&a, &b};\n"
    5415             :               "  g(d);\n"
    5416             :               "  if (a) {}\n"
    5417             :               "  if (b) {}\n"
    5418             :               "}");
    5419           1 :         ASSERT_EQUALS("", errout_str());
    5420             : 
    5421             :         // #9311
    5422           1 :         check("struct c {\n"
    5423             :               "  int* p;\n"
    5424             :               "};\n"
    5425             :               "void g(struct c* v);\n"
    5426             :               "void f() {\n"
    5427             :               "  int a = 0;\n"
    5428             :               "  int b = 0;\n"
    5429             :               "  struct c d[] = {{&a}, {&b}};\n"
    5430             :               "  g(d);\n"
    5431             :               "  if (a) {}\n"
    5432             :               "  if (b) {}\n"
    5433             :               "}");
    5434           1 :         ASSERT_EQUALS("", errout_str());
    5435             : 
    5436             :         // #8993
    5437           1 :         check("void f(const std::string& x) {\n"
    5438             :               "  auto y = x;\n"
    5439             :               "  if (x.empty()) y = \"1\";\n"
    5440             :               "  if (y.empty()) return;\n"
    5441             :               "}");
    5442           1 :         ASSERT_EQUALS("", errout_str());
    5443             : 
    5444             :         // #9106
    5445           1 :         check("struct A {int b;};\n"
    5446             :               "void f(A a, int c) {\n"
    5447             :               "    if (a.b) a.b = c;\n"
    5448             :               "    if (a.b) {}\n"
    5449             :               "}");
    5450           1 :         ASSERT_EQUALS("", errout_str());
    5451             : 
    5452           1 :         check("struct A {\n"
    5453             :               "    int a;\n"
    5454             :               "    void b() const {\n"
    5455             :               "        return a == 1;\n"
    5456             :               "    }\n"
    5457             :               "    void c();\n"
    5458             :               "    void d() {\n"
    5459             :               "        if(b()) {\n"
    5460             :               "            c();\n"
    5461             :               "        }\n"
    5462             :               "        if (b()) {\n"
    5463             :               "            a = 3;\n"
    5464             :               "        }\n"
    5465             :               "    }\n"
    5466             :               "}\n");
    5467           1 :         ASSERT_EQUALS("", errout_str());
    5468             : 
    5469           1 :         check("struct A {\n"
    5470             :               "    int a;\n"
    5471             :               "    void b() const {\n"
    5472             :               "        return a == 1;\n"
    5473             :               "    }\n"
    5474             :               "    void d() {\n"
    5475             :               "        if(b()) {\n"
    5476             :               "            a = 2;\n"
    5477             :               "        }\n"
    5478             :               "        if (b()) {\n"
    5479             :               "            a = 3;\n"
    5480             :               "        }\n"
    5481             :               "    }\n"
    5482             :               "}\n");
    5483           1 :         ASSERT_EQUALS("", errout_str());
    5484             : 
    5485           1 :         check("struct A {\n"
    5486             :               "    int a;\n"
    5487             :               "    void b() const {\n"
    5488             :               "        return a == 1;\n"
    5489             :               "    }\n"
    5490             :               "    void d() {\n"
    5491             :               "        if(b()) {\n"
    5492             :               "        }\n"
    5493             :               "        if (b()) {\n"
    5494             :               "            a = 3;\n"
    5495             :               "        }\n"
    5496             :               "    }\n"
    5497             :               "}\n");
    5498           1 :         ASSERT_EQUALS("[test.cpp:7] -> [test.cpp:9]: (style) The if condition is the same as the previous if condition\n",
    5499             :                       errout_str());
    5500             : 
    5501           1 :         check("void f(bool a, bool b) {\n"
    5502             :               "    auto g = [&] { b = !a; };\n"
    5503             :               "    if (b)\n"
    5504             :               "        g();\n"
    5505             :               "    if (b) {}\n"
    5506             :               "}\n");
    5507           1 :         ASSERT_EQUALS("", errout_str());
    5508             : 
    5509           1 :         check("void g(bool& a);\n"
    5510             :               "void f(bool b) {\n"
    5511             :               "    auto h = std::bind(&g, std::ref(b));\n"
    5512             :               "    if (b)\n"
    5513             :               "        h();\n"
    5514             :               "    if (b) {}\n"
    5515             :               "}\n");
    5516           1 :         ASSERT_EQUALS("", errout_str());
    5517             : 
    5518           1 :         check("void f(int *i) {\n"
    5519             :               "  if (*i == 0) {\n"
    5520             :               "    *i = 1;\n"
    5521             :               "  }\n"
    5522             :               "  if (*i == 0) {\n"
    5523             :               "  }\n"
    5524             :               "}\n");
    5525           1 :         ASSERT_EQUALS("", errout_str());
    5526             : 
    5527           1 :         check("void g(std::function<void()>);\n"
    5528             :               "void f(std::vector<int> v) {\n"
    5529             :               "    auto x = [&v] { v.push_back(1); };\n"
    5530             :               "    if(v.empty()) {\n"
    5531             :               "        g(x);\n"
    5532             :               "    }\n"
    5533             :               "    if(v.empty())\n"
    5534             :               "        return;\n"
    5535             :               "    return;\n"
    5536             :               "}\n");
    5537           1 :         ASSERT_EQUALS("", errout_str());
    5538             : 
    5539           1 :         check("struct S { int i; };\n"
    5540             :               "int f(const S& s) {\n"
    5541             :               "    int a = 0, b = 0;\n"
    5542             :               "    if (s.i == 0)\n"
    5543             :               "        a = 1;\n"
    5544             :               "    if (s.i == 0)\n"
    5545             :               "        b = 1;\n"
    5546             :               "    return a + b;\n"
    5547             :               "}\n");
    5548           1 :         ASSERT_EQUALS("[test.cpp:4] -> [test.cpp:6]: (style) The if condition is the same as the previous if condition\n", errout_str());
    5549             : 
    5550             :         // do not crash
    5551           1 :         check("void assign(const MMA& other) {\n"
    5552             :               "    if (mPA.cols != other.mPA.cols || mPA.rows != other.mPA.rows)\n"
    5553             :               "        ;\n"
    5554             :               "    if (other.mPA.cols > 0 && other.mPA.rows > 0)\n"
    5555             :               "        ;\n"
    5556             :               "}");
    5557             :     }
    5558             : 
    5559           1 :     void checkInvalidTestForOverflow() {
    5560           1 :         check("void f(char *p, unsigned int x) {\n"
    5561             :               "    assert((p + x) < p);\n"
    5562             :               "}");
    5563           1 :         ASSERT_EQUALS("[test.cpp:2]: (warning) Invalid test for overflow '(p+x)<p'; pointer overflow is undefined behavior. Some mainstream compilers remove such overflow tests when optimising the code and assume it's always false.\n", errout_str());
    5564             : 
    5565           1 :         check("void f(char *p, unsigned int x) {\n"
    5566             :               "    assert((p + x) >= p);\n"
    5567             :               "}");
    5568           1 :         ASSERT_EQUALS("[test.cpp:2]: (warning) Invalid test for overflow '(p+x)>=p'; pointer overflow is undefined behavior. Some mainstream compilers remove such overflow tests when optimising the code and assume it's always true.\n", errout_str());
    5569             : 
    5570           1 :         check("void f(char *p, unsigned int x) {\n"
    5571             :               "    assert(p > (p + x));\n"
    5572             :               "}");
    5573           1 :         ASSERT_EQUALS("[test.cpp:2]: (warning) Invalid test for overflow 'p>(p+x)'; pointer overflow is undefined behavior. Some mainstream compilers remove such overflow tests when optimising the code and assume it's always false.\n", errout_str());
    5574             : 
    5575           1 :         check("void f(char *p, unsigned int x) {\n"
    5576             :               "    assert(p <= (p + x));\n"
    5577             :               "}");
    5578           1 :         ASSERT_EQUALS("[test.cpp:2]: (warning) Invalid test for overflow 'p<=(p+x)'; pointer overflow is undefined behavior. Some mainstream compilers remove such overflow tests when optimising the code and assume it's always true.\n", errout_str());
    5579             : 
    5580           1 :         check("void f(signed int x) {\n" // unsigned overflow => don't warn
    5581             :               "    assert(x + 100U < x);\n"
    5582             :               "}");
    5583           1 :         ASSERT_EQUALS("", errout_str());
    5584             : 
    5585             : 
    5586             :         // x + c < x
    5587             : 
    5588             : #define MSG(EXPR, RESULT)   "[test.cpp:1]: (warning) Invalid test for overflow '" EXPR "'; signed integer overflow is undefined behavior. Some mainstream compilers remove such overflow tests when optimising the code and assume it's always " RESULT ".\n"
    5589             : 
    5590           1 :         check("int f(int x) { return x + 10 > x; }");
    5591           1 :         ASSERT_EQUALS(MSG("x+10>x", "true"), errout_str());
    5592             : 
    5593           1 :         check("int f(int x) { return x + 10 >= x; }");
    5594           1 :         ASSERT_EQUALS(MSG("x+10>=x", "true"), errout_str());
    5595             : 
    5596           1 :         check("int f(int x) { return x + 10 < x; }");
    5597           1 :         ASSERT_EQUALS(MSG("x+10<x", "false"), errout_str());
    5598             : 
    5599           1 :         check("int f(int x) { return x + 10 <= x; }");
    5600           1 :         ASSERT_EQUALS(MSG("x+10<=x", "false"), errout_str());
    5601             : 
    5602           1 :         check("int f(int x) { return x - 10 > x; }");
    5603           1 :         ASSERT_EQUALS(MSG("x-10>x", "false"), errout_str());
    5604             : 
    5605           1 :         check("int f(int x) { return x - 10 >= x; }");
    5606           1 :         ASSERT_EQUALS(MSG("x-10>=x", "false"), errout_str());
    5607             : 
    5608           1 :         check("int f(int x) { return x - 10 < x; }");
    5609           1 :         ASSERT_EQUALS(MSG("x-10<x", "true"), errout_str());
    5610             : 
    5611           1 :         check("int f(int x) { return x - 10 <= x; }");
    5612           1 :         ASSERT_EQUALS(MSG("x-10<=x", "true"), errout_str());
    5613             : 
    5614             :         // x + y < x
    5615             : #undef MSG
    5616             : #define MSG(EXPR, RESULT)   "[test.cpp:1]: (warning) Invalid test for overflow '" EXPR "'; signed integer overflow is undefined behavior. Some mainstream compilers removes handling of overflows when optimising the code and change the code to '" RESULT "'.\n"
    5617             : 
    5618           1 :         check("int f(int x, int y) { return x + y < x; }");
    5619           1 :         ASSERT_EQUALS(MSG("x+y<x", "y<0"), errout_str());
    5620             : 
    5621           1 :         check("int f(int x, int y) { return x + y <= x; }");
    5622           1 :         ASSERT_EQUALS(MSG("x+y<=x", "y<=0"), errout_str());
    5623             : 
    5624           1 :         check("int f(int x, int y) { return x + y > x; }");
    5625           1 :         ASSERT_EQUALS(MSG("x+y>x", "y>0"), errout_str());
    5626             : 
    5627           1 :         check("int f(int x, int y) { return x + y >= x; }");
    5628           1 :         ASSERT_EQUALS(MSG("x+y>=x", "y>=0"), errout_str());
    5629             : 
    5630             :         // x - y < x
    5631           1 :         check("int f(int x, int y) { return x - y < x; }");
    5632           1 :         ASSERT_EQUALS(MSG("x-y<x", "y>0"), errout_str());
    5633             : 
    5634           1 :         check("int f(int x, int y) { return x - y <= x; }");
    5635           1 :         ASSERT_EQUALS(MSG("x-y<=x", "y>=0"), errout_str());
    5636             : 
    5637           1 :         check("int f(int x, int y) { return x - y > x; }");
    5638           1 :         ASSERT_EQUALS(MSG("x-y>x", "y<0"), errout_str());
    5639             : 
    5640           1 :         check("int f(int x, int y) { return x - y >= x; }");
    5641           1 :         ASSERT_EQUALS(MSG("x-y>=x", "y<=0"), errout_str());
    5642             :     }
    5643             : 
    5644           1 :     void checkConditionIsAlwaysTrueOrFalseInsideIfWhile() {
    5645           1 :         check("void f() {\n"
    5646             :               "    enum states {A,B,C};\n"
    5647             :               "    const unsigned g_flags = B|C;\n"
    5648             :               "    if(g_flags & A) {}\n"
    5649             :               "}");
    5650           1 :         ASSERT_EQUALS("[test.cpp:4]: (style) Condition 'g_flags&A' is always false\n", errout_str());
    5651             : 
    5652           1 :         check("void f() {\n"
    5653             :               "    int a = 5;"
    5654             :               "    if(a) {}\n"
    5655             :               "}");
    5656           1 :         ASSERT_EQUALS("[test.cpp:2]: (style) Condition 'a' is always true\n", errout_str());
    5657             : 
    5658           1 :         check("void f() {\n"
    5659             :               "    int a = 5;"
    5660             :               "    while(a + 1) { a--; }\n"
    5661             :               "}");
    5662           1 :         ASSERT_EQUALS("", errout_str());
    5663             : 
    5664           1 :         check("void f() {\n"
    5665             :               "    int a = 5;"
    5666             :               "    while(a + 1) { return; }\n"
    5667             :               "}");
    5668           1 :         ASSERT_EQUALS("[test.cpp:2]: (style) Condition 'a+1' is always true\n", errout_str());
    5669             :     }
    5670             : 
    5671           1 :     void alwaysTrueFalseInLogicalOperators() {
    5672           1 :         check("bool f();\n"
    5673             :               "void foo() { bool x = true; if(x||f()) {}}");
    5674           1 :         ASSERT_EQUALS("[test.cpp:2]: (style) Condition 'x' is always true\n", errout_str());
    5675             : 
    5676           1 :         check("void foo(bool b) { bool x = true; if(x||b) {}}");
    5677           1 :         ASSERT_EQUALS("[test.cpp:1]: (style) Condition 'x' is always true\n", errout_str());
    5678             : 
    5679           1 :         check("void foo(bool b) { if(true||b) {}}");
    5680           1 :         ASSERT_EQUALS("", errout_str());
    5681             : 
    5682           1 :         check("bool f();\n"
    5683             :               "void foo() { bool x = false; if(x||f()) {}}");
    5684           1 :         ASSERT_EQUALS("[test.cpp:2]: (style) Condition 'x' is always false\n", errout_str());
    5685             : 
    5686           1 :         check("bool f();\n"
    5687             :               "void foo() { bool x = false; if(x&&f()) {}}");
    5688           1 :         ASSERT_EQUALS("[test.cpp:2]: (style) Condition 'x' is always false\n", errout_str());
    5689             : 
    5690           1 :         check("void foo(bool b) { bool x = false; if(x&&b) {}}");
    5691           1 :         ASSERT_EQUALS("[test.cpp:1]: (style) Condition 'x' is always false\n", errout_str());
    5692             : 
    5693           1 :         check("void foo(bool b) { if(false&&b) {}}");
    5694           1 :         ASSERT_EQUALS("", errout_str());
    5695             : 
    5696           1 :         check("bool f();\n"
    5697             :               "void foo() { bool x = true; if(x&&f()) {}}");
    5698           1 :         ASSERT_EQUALS("[test.cpp:2]: (style) Condition 'x' is always true\n", errout_str());
    5699             : 
    5700             :         // #9578
    5701           1 :         check("bool f(const std::string &s) {\n"
    5702             :               "        return s.size()>2U && s[0]=='4' && s[0]=='2';\n"
    5703             :               "}\n");
    5704           1 :         ASSERT_EQUALS("[test.cpp:2] -> [test.cpp:2]: (style) Return value 's[0]=='2'' is always false\n", errout_str());
    5705             : 
    5706           1 :         check("void f(int i) { if (i == 1 || 2) {} }\n"); // #12487
    5707           1 :         ASSERT_EQUALS("[test.cpp:1]: (style) Condition 'i==1||2' is always true\n", errout_str());
    5708             : 
    5709           1 :         check("enum E { E1 = 1, E2 = 2 };\n"
    5710             :               "void f(int i) { if (i == E1 || E2) {} }\n");
    5711           1 :         ASSERT_EQUALS("[test.cpp:2]: (style) Condition 'i==E1||E2' is always true\n", errout_str());
    5712             :     }
    5713             : 
    5714           1 :     void pointerAdditionResultNotNull() {
    5715           1 :         check("void f(char *ptr) {\n"
    5716             :               "  if (ptr + 1 != 0);\n"
    5717             :               "}");
    5718           1 :         ASSERT_EQUALS("[test.cpp:2]: (warning) Comparison is wrong. Result of 'ptr+1' can't be 0 unless there is pointer overflow, and pointer overflow is undefined behaviour.\n", errout_str());
    5719             :     }
    5720             : 
    5721           1 :     void duplicateConditionalAssign() {
    5722           1 :         setMultiline();
    5723             : 
    5724           1 :         check("void f(int& x, int y) {\n"
    5725             :               "    if (x == y)\n"
    5726             :               "        x = y;\n"
    5727             :               "}");
    5728           1 :         ASSERT_EQUALS("test.cpp:3:style:Assignment 'x=y' is redundant with condition 'x==y'.\n"
    5729             :                       "test.cpp:2:note:Condition 'x==y'\n"
    5730             :                       "test.cpp:3:note:Assignment 'x=y' is redundant\n", errout_str());
    5731             : 
    5732           1 :         check("void f(int& x, int y) {\n"
    5733             :               "    if (x != y)\n"
    5734             :               "        x = y;\n"
    5735             :               "}");
    5736           1 :         ASSERT_EQUALS("test.cpp:2:style:The statement 'if (x!=y) x=y' is logically equivalent to 'x=y'.\n"
    5737             :                       "test.cpp:3:note:Assignment 'x=y'\n"
    5738             :                       "test.cpp:2:note:Condition 'x!=y' is redundant\n", errout_str());
    5739             : 
    5740           1 :         check("void f(int& x, int y) {\n"
    5741             :               "    if (x == y)\n"
    5742             :               "        x = y;\n"
    5743             :               "    else\n"
    5744             :               "        x = 1;\n"
    5745             :               "}");
    5746           1 :         ASSERT_EQUALS("test.cpp:3:style:Assignment 'x=y' is redundant with condition 'x==y'.\n"
    5747             :                       "test.cpp:2:note:Condition 'x==y'\n"
    5748             :                       "test.cpp:3:note:Assignment 'x=y' is redundant\n", errout_str());
    5749             : 
    5750           1 :         check("void f(int& x, int y) {\n"
    5751             :               "    if (x != y)\n"
    5752             :               "        x = y;\n"
    5753             :               "    else\n"
    5754             :               "        x = 1;\n"
    5755             :               "}");
    5756           1 :         ASSERT_EQUALS("", errout_str());
    5757             : 
    5758           1 :         check("void f(int& x, int y) {\n"
    5759             :               "    if (x == y)\n"
    5760             :               "        x = y + 1;\n"
    5761             :               "}");
    5762           1 :         ASSERT_EQUALS("", errout_str());
    5763             : 
    5764           1 :         check("void g();\n"
    5765             :               "void f(int& x, int y) {\n"
    5766             :               "    if (x == y) {\n"
    5767             :               "        x = y;\n"
    5768             :               "        g();\n"
    5769             :               "    }\n"
    5770             :               "}");
    5771           1 :         ASSERT_EQUALS("", errout_str());
    5772             : 
    5773           1 :         check("bool f(bool b) {\n"
    5774             :               "    if (b)\n"
    5775             :               "        b = false;\n"
    5776             :               "    else\n"
    5777             :               "        g();\n"
    5778             :               "    return b;\n"
    5779             :               "}\n");
    5780           1 :         ASSERT_EQUALS("", errout_str());
    5781             : 
    5782           1 :         check("void f(int& i) {\n"
    5783             :               "    if (!i)\n"
    5784             :               "        i = 1; \n"
    5785             :               "}\n");
    5786           1 :         ASSERT_EQUALS("", errout_str());
    5787             : 
    5788           1 :         check("struct S {\n" // #9406
    5789             :               "    S() : b(false) {}\n"
    5790             :               "    void f() {\n"
    5791             :               "        if (b) b = true;\n"
    5792             :               "        if (b) b = false;\n"
    5793             :               "        if (!b) b = true;\n"
    5794             :               "        if (!b) b = false;\n"
    5795             :               "    }\n"
    5796             :               "    bool b;\n"
    5797             :               "};\n");
    5798           1 :         ASSERT_EQUALS("test.cpp:4:style:The statement 'if (b) b=true' is redundant.\n"
    5799             :                       "test.cpp:4:note:Assignment 'b=true'\n"
    5800             :                       "test.cpp:4:note:Condition 'b' is redundant\n"
    5801             :                       "test.cpp:5:style:The statement 'if (b) b=false' is logically equivalent to 'b=false'.\n"
    5802             :                       "test.cpp:5:note:Assignment 'b=false'\n"
    5803             :                       "test.cpp:5:note:Condition 'b' is redundant\n"
    5804             :                       "test.cpp:6:style:The statement 'if (!b) b=true' is logically equivalent to 'b=true'.\n"
    5805             :                       "test.cpp:6:note:Assignment 'b=true'\n"
    5806             :                       "test.cpp:6:note:Condition '!b' is redundant\n"
    5807             :                       "test.cpp:7:style:The statement 'if (!b) b=false' is redundant.\n"
    5808             :                       "test.cpp:7:note:Assignment 'b=false'\n"
    5809             :                       "test.cpp:7:note:Condition '!b' is redundant\n",
    5810             :                       errout_str());
    5811             :     }
    5812             : 
    5813           1 :     void checkAssignmentInCondition() {
    5814           1 :         check("void f(std::string s) {\n"
    5815             :               "    if (s=\"123\"){}\n"
    5816             :               "}");
    5817           1 :         ASSERT_EQUALS("[test.cpp:2]: (style) Suspicious assignment in condition. Condition 's=\"123\"' is always true.\n", errout_str());
    5818             : 
    5819           1 :         check("void f(std::string *p) {\n"
    5820             :               "    if (p=foo()){}\n"
    5821             :               "}");
    5822           1 :         ASSERT_EQUALS("", errout_str());
    5823             : 
    5824           1 :         check("void f(uint32_t u) {\n" // #2490
    5825             :               "    if ((u = 0x00000000) || (u = 0xffffffff)) {}\n"
    5826             :               "}\n");
    5827           1 :         ASSERT_EQUALS("[test.cpp:2]: (style) Condition 'u=0x00000000' is always false\n"
    5828             :                       "[test.cpp:2]: (style) Condition 'u=0xffffffff' is always true\n",
    5829             :                       errout_str());
    5830             :     }
    5831             : 
    5832           1 :     void compareOutOfTypeRange() {
    5833           1 :         const Settings settingsUnix64 = settingsBuilder().severity(Severity::style).platform(Platform::Type::Unix64).build();
    5834             : 
    5835           1 :         check("void f(unsigned char c) {\n"
    5836             :               "  if (c == 256) {}\n"
    5837             :               "}", settingsUnix64);
    5838           1 :         ASSERT_EQUALS("[test.cpp:2]: (style) Comparing expression of type 'unsigned char' against value 256. Condition is always false.\n", errout_str());
    5839             : 
    5840           1 :         check("void f(unsigned char* b, int i) {\n" // #6372
    5841             :               "  if (b[i] == 256) {}\n"
    5842             :               "}", settingsUnix64);
    5843           1 :         ASSERT_EQUALS("[test.cpp:2]: (style) Comparing expression of type 'unsigned char' against value 256. Condition is always false.\n", errout_str());
    5844             : 
    5845           1 :         check("void f(unsigned char c) {\n"
    5846             :               "  if (c == 255) {}\n"
    5847             :               "}", settingsUnix64);
    5848           1 :         ASSERT_EQUALS("", errout_str());
    5849             : 
    5850           1 :         check("void f(bool b) {\n"
    5851             :               "  if (b == true) {}\n"
    5852             :               "}", settingsUnix64);
    5853           1 :         ASSERT_EQUALS("", errout_str());
    5854             : 
    5855             :         // #10372
    5856           1 :         check("void f(signed char x) {\n"
    5857             :               "  if (x == 0xff) {}\n"
    5858             :               "}", settingsUnix64);
    5859           1 :         ASSERT_EQUALS("[test.cpp:2]: (style) Comparing expression of type 'signed char' against value 255. Condition is always false.\n", errout_str());
    5860             : 
    5861           1 :         check("void f(short x) {\n"
    5862             :               "  if (x == 0xffff) {}\n"
    5863             :               "}", settingsUnix64);
    5864           1 :         ASSERT_EQUALS("[test.cpp:2]: (style) Comparing expression of type 'signed short' against value 65535. Condition is always false.\n", errout_str());
    5865             : 
    5866           1 :         check("void f(int x) {\n"
    5867             :               "  if (x == 0xffffffff) {}\n"
    5868             :               "}", settingsUnix64);
    5869           1 :         ASSERT_EQUALS("", errout_str());
    5870             : 
    5871           1 :         check("void f(long x) {\n"
    5872             :               "  if (x == ~0L) {}\n"
    5873             :               "}", settingsUnix64);
    5874           1 :         ASSERT_EQUALS("", errout_str());
    5875             : 
    5876           1 :         check("void f(long long x) {\n"
    5877             :               "  if (x == ~0LL) {}\n"
    5878             :               "}", settingsUnix64);
    5879           1 :         ASSERT_EQUALS("", errout_str());
    5880             : 
    5881           1 :         check("int f(int x) {\n"
    5882             :               "    const int i = 0xFFFFFFFF;\n"
    5883             :               "    if (x == i) {}\n"
    5884             :               "}", settingsUnix64);
    5885           1 :         ASSERT_EQUALS("", errout_str());
    5886             : 
    5887           1 :         check("void f() {\n"
    5888             :               "  char c;\n"
    5889             :               "  if ((c = foo()) != -1) {}\n"
    5890             :               "}", settingsUnix64);
    5891           1 :         ASSERT_EQUALS("", errout_str());
    5892             : 
    5893           1 :         check("void f(int x) {\n"
    5894             :               "  if (x < 3000000000) {}\n"
    5895             :               "}", settingsUnix64);
    5896           1 :         ASSERT_EQUALS("[test.cpp:2]: (style) Comparing expression of type 'signed int' against value 3000000000. Condition is always true.\n", errout_str());
    5897             : 
    5898           1 :         check("void f(const signed char i) {\n" // #8545
    5899             :               "    if (i >  -129) {}\n" // warn
    5900             :               "    if (i >= -128) {}\n" // warn
    5901             :               "    if (i >= -127) {}\n"
    5902             :               "    if (i <  +128) {}\n" // warn
    5903             :               "    if (i <= +127) {}\n" // warn
    5904             :               "    if (i <= +126) {}\n"
    5905             :               "}\n", settingsUnix64);
    5906           1 :         ASSERT_EQUALS("[test.cpp:2]: (style) Comparing expression of type 'const signed char' against value -129. Condition is always true.\n"
    5907             :                       "[test.cpp:3]: (style) Comparing expression of type 'const signed char' against value -128. Condition is always true.\n"
    5908             :                       "[test.cpp:5]: (style) Comparing expression of type 'const signed char' against value 128. Condition is always true.\n"
    5909             :                       "[test.cpp:6]: (style) Comparing expression of type 'const signed char' against value 127. Condition is always true.\n",
    5910             :                       errout_str());
    5911             : 
    5912           1 :         check("void f(const unsigned char u) {\n"
    5913             :               "    if (u >  0) {}\n"
    5914             :               "    if (u <  0) {}\n" // warn
    5915             :               "    if (u >= 0) {}\n" // warn
    5916             :               "    if (u <= 0) {}\n"
    5917             :               "    if (u >  255) {}\n" // warn
    5918             :               "    if (u <  255) {}\n"
    5919             :               "    if (u >= 255) {}\n"
    5920             :               "    if (u <= 255) {}\n" // warn
    5921             :               "    if (0   <  u) {}\n"
    5922             :               "    if (0   >  u) {}\n" // warn
    5923             :               "    if (0   <= u) {}\n" // warn
    5924             :               "    if (0   >= u) {}\n"
    5925             :               "    if (255 <  u) {}\n" // warn
    5926             :               "    if (255 >  u) {}\n"
    5927             :               "    if (255 <= u) {}\n"
    5928             :               "    if (255 >= u) {}\n" // warn
    5929             :               "}\n", settingsUnix64);
    5930           1 :         ASSERT_EQUALS("[test.cpp:3]: (style) Comparing expression of type 'const unsigned char' against value 0. Condition is always false.\n"
    5931             :                       "[test.cpp:4]: (style) Comparing expression of type 'const unsigned char' against value 0. Condition is always true.\n"
    5932             :                       "[test.cpp:6]: (style) Comparing expression of type 'const unsigned char' against value 255. Condition is always false.\n"
    5933             :                       "[test.cpp:9]: (style) Comparing expression of type 'const unsigned char' against value 255. Condition is always true.\n"
    5934             :                       "[test.cpp:11]: (style) Comparing expression of type 'const unsigned char' against value 0. Condition is always false.\n"
    5935             :                       "[test.cpp:12]: (style) Comparing expression of type 'const unsigned char' against value 0. Condition is always true.\n"
    5936             :                       "[test.cpp:14]: (style) Comparing expression of type 'const unsigned char' against value 255. Condition is always false.\n"
    5937             :                       "[test.cpp:17]: (style) Comparing expression of type 'const unsigned char' against value 255. Condition is always true.\n",
    5938             :                       errout_str());
    5939             :     }
    5940             : 
    5941           1 :     void knownConditionCast() { // #9976
    5942           1 :         check("void f(int i) {\n"
    5943             :               "    if (i < 0 || (unsigned)i > 5) {}\n"
    5944             :               "}\n");
    5945           1 :         ASSERT_EQUALS("", errout_str());
    5946             :     }
    5947             : 
    5948           1 :     void knownConditionIncrementLoop() { // #9808
    5949           1 :         check("void f() {\n"
    5950             :               "    int a = 0;\n"
    5951             :               "    while (++a < 5) {}\n"
    5952             :               "    if (a == 1) {}\n"
    5953             :               "    std::cout << a;\n"
    5954             :               "}\n");
    5955           1 :         ASSERT_EQUALS("", errout_str());
    5956             :     }
    5957             : 
    5958           1 :     void knownConditionAfterBailout() { // #12526
    5959           1 :         check(
    5960             :             "#include <list>\n"
    5961             :             "int func()\n"
    5962             :             "{\n"
    5963             :             "  return VALUE_1;"
    5964             :             "}\n"
    5965             :             "\n"
    5966             :             "struct S1 {\n"
    5967             :             "  bool b{};\n"
    5968             :             "};\n"
    5969             :             "\n"
    5970             :             "struct S {\n"
    5971             :             "  void f(const std::list<int>& l) const\n"
    5972             :             "  {\n"
    5973             :             "    if (mS.b)\n"
    5974             :             "      return;\n"
    5975             :             "    for (int i : l)\n"
    5976             :             "    {\n"
    5977             :             "      (void)i;\n"
    5978             :             "      if (mS.b)\n"
    5979             :             "        continue;\n"
    5980             :             "    }\n"
    5981             :             "  }\n"
    5982             :             "\n"
    5983             :             "  S1 mS;\n"
    5984             :             "};"
    5985             :             );
    5986           1 :         ASSERT_EQUALS("[test.cpp:13] -> [test.cpp:18]: (style) Condition 'mS.b' is always false\n", errout_str());
    5987             :     }
    5988             : };
    5989             : 
    5990             : REGISTER_TEST(TestCondition)

Generated by: LCOV version 1.14