Menu

why knownConditionTrueFalse

2019-08-30
2019-08-30
  • Sander Bouwhuis

    Sander Bouwhuis - 2019-08-30

    I have the following function:

     1 // This function finds the positions of the nibbles in the checksum table
     2 void CDataCodec::FindPosInChecksumTable(uint8 u8Data, int32 *pi32Low, int32 *pi32High) const
     3 {
     4   try
     5   {
     6     CHECK_MEM_LEAKS
     7 
     8     uint8 u8Nibble;
     9 
    10     // Set the low nibble
    11     u8Nibble = uint8(u8Data & 0xf0);
    12 
    13     // Find the low nibble in the checksum look-up table
    14     for(*pi32Low=0;*pi32Low<16;(*pi32Low)++)
    15     {
    16       // Do we have the correct low nibble value?
    17       if(u8Nibble == uint8(g_u8ChecksumTable[*pi32Low] & 0xf0))
    18         break;
    19     }
    20 
    21     // Set the high nibble
    22     u8Nibble = uint8(u8Data & 0x0f);
    23 
    24     // Find the high nibble in the checksum look-up table
    25     for(*pi32High=0;*pi32High<16;(*pi32High)++)
    26     {
    27       // Do we have the correct high nibble value?
    28       if(u8Nibble == uint8(g_u8ChecksumTable[*pi32High] & 0x0f))
    29         break;
    30     }
    31   }
    32   catch(...) { OnException(nullptr, __FILE__, __LINE__, __FUNCSIG__, __TIMESTAMP__, nullptr); }
    33 }
    

    But, I get 2 errors stating:

    line 14 : 'Condition '*pi32Low<16' is always true'
    line 25 : 'Condition '*pi32High<16' is always true'*
    

    Clearly, the value of pi32Low and pi32High can be [0,MAX_INT32] (after initialization in the for loop)?

     

    Last edit: Sander Bouwhuis 2019-08-30
  • versat

    versat - 2019-08-30

    Seems to be another false positive, i can reproduce this with 1.89 dev.
    The values clearly can be from 0 to 16 in the for loops. And the loops are exited when 16 is reached.
    Here is a small compilable example that shows the false positive:

    #include <stdio.h>
    
    void f(int * pA)
    {
        for(*pA = 0; *pA < 10; (*pA)++)
        {
            printf("*pA: %d\n", *pA);
        }
    }
    
    int main()
    {
        int a;
        f(&a);
        return 0;
    }
    

    Output of Cppcheck 1.89 dev:

    $ g++ -fsyntax-only fp_knownConditionTrueFalse.cpp && ./cppcheck --enable=style --debug fp_knownConditionTrueFalse.cpp
    Checking fp_knownConditionTrueFalse.cpp ...
    
    ##file fp_knownConditionTrueFalse.cpp
    3: void f ( int * pA@1 )
    4: {
    5: for ( * pA@1 = 0 ; * pA@1 < 10 ; ( * pA@1 ) ++ )
    6: {
    7: printf ( "*pA: %d\n" , * pA@1 ) ;
    8: }
    9: }
    10:
    11: int main ( )
    12: {
    13: int a@2 ;
    14: f ( & a@2 ) ;
    15: return 0 ;
    16: }
    
    ##Value flow
    Line 5
      * possible Uninit
      pA possible Uninit*
      0 always 0
      * always 0
      < always 1
      10 always 10
    Line 7
      "*pA: %d\n" always "*pA: %d\n"
    Line 14
      & possible {lifetime=a,Uninit*}
      a always Uninit
    Line 15
      0 always 0
    fp_knownConditionTrueFalse.cpp:5:22: style: Condition '*pA<10' is always true [knownConditionTrueFalse]
        for(*pA = 0; *pA < 10; (*pA)++)
                         ^
    fp_knownConditionTrueFalse.cpp:5:13: note: *pA is assigned value 0
        for(*pA = 0; *pA < 10; (*pA)++)
                ^
    fp_knownConditionTrueFalse.cpp:5:22: note: Condition '*pA<10' is always true
        for(*pA = 0; *pA < 10; (*pA)++)
                         ^
    
     
  • versat

    versat - 2019-08-30

    I found a ticket that looks related and added your example: https://trac.cppcheck.net/ticket/9036
    Thanks for reporting!

     

Log in to post a comment.