static analyzer false positive due to bit fields

Hi,

I have discovered another simple false positive report from the static analyzer that seems to be clearly wrong. I think it is related to not processing bit fields correctly.

I have attached the HTML report and copied the problematic function below (in case the attachment doesn’t work).

#pragma inline(Fpga_Xbus_Busy_Wait)

static void Fpga_Xbus_Busy_Wait(void)

{

#ifndef SOLUTION_ENGINE

/* Stores result of the XBUS busy request. */

UINT32 rsp;

#if DXL_DEBUG_ENABLE

/* Initialize the number of loops to 0. */

UNSIGNED fpga_samples = 0;

#endif

/* Make sure that the Xbus is idle. */

do {

rsp = PCI_Rd_Mem_Long(FPGA_PCI_MEM_ADDR+FPGA_STATUS_READ, 0);

#if DXL_DEBUG_ENABLE

fpga_samples++;

#endif

} while(((fpga_status_t *) &rsp)->xbus_busy);

#if DXL_DEBUG_ENABLE

/* Determine if the longest FPGA XBUS wait has been exceeded. */

if(FPGA_longest < fpga_samples)

FPGA_longest = fpga_samples;

#endif

#endif // ifndef SOLUTION ENGINE.

}

The analyzer reports the following error:

build\DXL\Intercom\src\init\fpga.c:119:13: warning: Branch condition evaluates to a garbage value

} while(((fpga_status_t *) &rsp)->xbus_busy);

^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

The function reads from a PCI bus and assigns the value read to the 32 bit variable rsp inside the do loop. The loop condition takes the address of rsp and casts it to a structure pointer, then dereferences the pointer to access the field xbus_busy. The definition of the structure is copied below:

typedef struct

{

UINT32 usb2_armed_status :1;

UINT32 usb1_armed_status :1;

UINT32 xbus_busy :1;

UINT32 :1;

UINT32 column :4;

UINT32 :1;

UINT32 keypad_configuration :2;

UINT32 cept_configuration :2;

UINT32 two_hundred_mhz_dsp :1;

UINT32 hwid :2;

UINT32 version :16;

} fpga_status_t, fpga_configuration_t;

The analyzer seems to miss the fact that xbus_busy is a bit field in a single 32 bit variable, rather than a separate 32 variable in a structure. The error would make sense if the structure fields were independent 32 bit variables. Then xbus_busy would be a 32 bit field at offset 8 bytes past the start of the structure. This offset clearly doesn’t exist in the single 32 bit variable rsp.

HTH

report-030357.html (132 KB)

Hi, Dennis. In general, static analyzer bugs should be reported through http://llvm.org/bugs/, under clang / Static Analyzer. In this case, though, the issue isn't the bitfields but the "reinterpret_cast" of the UINT32 into a struct. This is a known issue, tracked in PR13919 and <rdar://problem/11966749>. I'd suggest attaching a preprocessed file to the PR to make sure we check against your test case when we do get around to fixing this.

Thanks for the report,
Jordan