[cfe-dev] static analyzer false positive due to logic error

Dennis Cote DennisC at harding.ca
Mon Apr 15 10:59:28 PDT 2013


Hi,

 

I have a case where the static analyzer produced a false positive report of a null pointer dereference. I am reporting this because it seems to indicate an error in the logic of the checker. It has assumed two different values for the same variable at different points along the path is used to generate the report.

 

I have copied the relevant section of the HTML report below. At step 1 it assumes Cept_configuration is not null. At step 15 it assumes the same variable is now null (i.e. in contradiction to its previous assumption). This variable is not modified by the code between these two points. The reported error at step 18 is a direct result of the incorrect assumption at step 15.

 

 

 

 		
	
1659

    // If no configuration defined then driver status is unknowable.

1660

    // Therefore, don't bother to do any reads/writes of the signal bits.

1661

    if(Cept_configuration == NU_NULL || !Cept_configuration->globals.cept)

	1

Assuming 'Cept_configuration' is not equal to null

→

	2

←

Taking false branch

→

1662

        return;

1663

	
1664

    // Read all the signalling bits.

1665

    debounced = Cept_Read_Signalling_Bits(fiber, &sbits_in, &driver_status);

1666

	
1667

    // Grab the lock that protects globals before accessing it. 

1668

    NUX_Lock(&Cept_lock, NU_SUSPEND);

1669

	
1670

#if CEPT_DEBOUNCING

1671

      // If we are debouncing the input, then don't update the CEPT driver

1672

      // status (i.e., skip the rest of this function).

1673

      if(old_driver_status >= NU_FALSE || !debounced)

	3

←

Assuming 'old_driver_status' is >= 0

→

1674

      {

1675

#endif

1676

        // Update the link LED (even iff this is not part of a CEPT loop). 

1677

        if(driver_status)

	4

←

Assuming 'driver_status' is not equal to 0

→

	5

←

Taking true branch

→

1678

            CEPT_link_okay_led = DSP__LED_ON, CEPT_driver_status = NU_TRUE, CEPT_driver = sbits_in.dcc_id;

1679

        else

1680

            CEPT_link_okay_led = DSP__LED_OFF, CEPT_driver_status = NU_FALSE, CEPT_driver = 0;

1681

	
1682

        // Update the user interface (because status has changed). 

1683

        if(old_driver_status != CEPT_driver_status || old_driver != CEPT_driver)

	6

←

Assuming 'old_driver_status' is equal to 'CEPT_driver_status'

→

	7

←

Taking false branch

→

1684

            (void) NU_Set_Events(&UI_events, UI_CEPT_CHANGED, NU_OR);

1685

	
1686

        // Log the change of CEPT driver status. 

1687

        if(old_driver_status != CEPT_driver_status)

	8

←

Taking false branch

→

1688

        {

1689

            if(CEPT_driver_status)

1690

                LOG_CEPT_LINK_HEALED(Cept_myid, CEPT_driver);

1691

            else

1692

                LOG_CEPT_LINK_FAILED(Cept_myid);

1693

        }

1694

	
1695

        // We have to set our CEPT identifier so it gets output during send. 

1696

        sbits_out->dcc_id = Cept_myid;

1697

	
1698

        // Note that this is not used but should be set for backwards compatibility.

1699

            sbits_out->loop_status = (INT8) -1;

1700

	
1701

        // If no configuration loaded therefore no way to update outgoing bits. 

1702

        if(Cept_myid != 0 && CEPT_driver != 0)

	9

←

Assuming 'Cept_myid' is not equal to 0

→

	10

←

Assuming 'CEPT_driver' is not equal to 0

→

	11

←

Taking true branch

→

1703

        {

1704

            // No change in driver status (from above). Determine loop status.

1705

            // Have to check if the CEPT is looped back onto itself and this

1706

            // will be considered a loop failure (but not a link failure).

1707

            if(CEPT_driver_status && CEPT_driver != Cept_myid)

	12

←

Taking true branch

→

1708

            {

1709

                // Check if this DCC is (still) the loop master. 

1710

                if(sbits_in.loop_id == Cept_myid)

	13

←

Taking true branch

→

1711

                {

1712

                    // Save the new loop identifier (us, same as old). 

1713

                    sbits_out->loop_id = Cept_myid;

1714

	
1715

                    // We have looped back to ourselves so indicate this. 

1716

                    sbits_out->wrapped_around = (UINT8) -1;

1717

                }

1718

                // Check if we are going to be the new loop master. 

1719

                else if(sbits_in.loop_id > Cept_myid)

1720

                {

1721

                    // Start new CEPT loop status bits. 

1722

                    sbits_out->loop_id = Cept_myid;

1723

                    sbits_out->wrapped_around = (UINT8) 0;

1724

                }

1725

                // Unconfigured driver so assume we will be master. 

1726

                else if(sbits_in.loop_id == 0)

1727

                {

1728

                    // Noone is cept master so we will try to start the loop. 

1729

                    sbits_out->loop_id = Cept_myid;

1730

                    sbits_out->wrapped_around = (UINT8) 0;

1731

                }

1732

                // Another DCC is the loop master (lower numbered). 

1733

                else

1734

                {

1735

                    // Someone else is the CEPT master. 

1736

                    sbits_out->loop_id = sbits_in.loop_id;

1737

	
1738

                    // Transfer CEPT loop status from the CEPT master. 

1739

                    sbits_out->wrapped_around = sbits_in.wrapped_around;

1740

                }

1741

            }

1742

            // CEPT driver is not working. 

1743

            else

1744

            {

1745

                // Update the CEPT status bits when CEPT driver not working. 

1746

                sbits_out->loop_id = Cept_myid;

1747

                sbits_out->wrapped_around = (UINT8) 0;

1748

            }

1749

        }

1750

        // If not configured or no driver. 

1751

        else

1752

        {

1753

            // Update the CEPT status bits when CEPT driver not working. 

1754

            sbits_out->loop_id = Cept_myid;

1755

            sbits_out->wrapped_around = (UINT8) 0;

1756

        }

1757

	
1758

        // Read the CEPT loop status and master (inherited from previous DCC). 

1759

        CEPT_status = sbits_out->wrapped_around ? NU_TRUE : NU_FALSE;

	14

←

'?' condition is true

→

1760

	
1761

        // Set the CEPT status iff CEPT loop is complete. 

1762

        if(Cept_configuration != NU_NULL && CEPT_status)

	15

←

Assuming 'Cept_configuration' is equal to null

→

1763

           CEPT_master = sbits_out->loop_id;

1764

	
1765

        // If CEPT status changes then do some stuff. If no change do nothing. 

1766

        if(old_loop_status != CEPT_status || old_master != CEPT_master)

	16

←

Assuming 'old_loop_status' is equal to 'CEPT_status'

→

	17

←

Taking false branch

→

1767

        {

1768

            // Update the user interface (because status has changed). 

1769

            (void) NU_Set_Events(&UI_events, UI_CEPT_CHANGED, NU_OR);

1770

	
1771

            // If the CEPT is dead, disconnect its users. 

1772

            if(!CEPT_status)

1773

                Cept_Teardown();

1774

            // Setup any users (i.e., music) now that cept is alive. 

1775

            else

1776

                Cept_Setup();

1777

	
1778

            // Only log iff there is a configuration and this is part of a loop. 

1779

            if(Cept_configuration->globals.cept)

1780

            {

1781

                // Log the CEPT heal/fail. 

1782

                if(CEPT_status)

1783

                    LOG_CEPT_LOOP_HEALED(Cept_myid, CEPT_master);

1784

                else

1785

                    LOG_CEPT_LOOP_FAILED(Cept_myid);

1786

            }

1787

        }

1788

	
1789

        // Set the loop LED based upon the loop status iff part of CEPT loop. 

1790

        if(CEPT_status && Cept_configuration->globals.cept)

	18

←

Dereference of null pointer

				

 

--

Dennis Cote

Harding Instruments

780-462-7100

 

-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.llvm.org/pipermail/cfe-dev/attachments/20130415/df48fe54/attachment.html>


More information about the cfe-dev mailing list