[LLVMbugs] [Bug 15498] New: Static analyzer incorrectly dirties second bit in a bit field

bugzilla-daemon at llvm.org bugzilla-daemon at llvm.org
Tue Mar 12 11:08:50 PDT 2013


            Bug ID: 15498
           Summary: Static analyzer incorrectly dirties second bit in a
                    bit field
           Product: clang
           Version: 3.2
          Hardware: Macintosh
                OS: MacOS X
            Status: NEW
          Severity: normal
          Priority: P
         Component: Static Analyzer
          Assignee: kremenek at apple.com
          Reporter: curt.clifton at mac.com
                CC: llvmbugs at cs.uiuc.edu
    Classification: Unclassified

Created attachment 10169
  --> http://llvm.org/bugs/attachment.cgi?id=10169&action=edit
Sample file for which clang-sa produces the false positive

Summary: In a struct containing a bit field, assigning to the first bit (using
the ternary operator?) causes clang to mark the second bit as a garbage value.

Steps to Reproduce: Run the analyzer on the attached file like so:

xcrun clang -x objective-c -fobjc-arc -isysroot
--analyze main.m

Expected Results: No warnings.

Actual Results: Warning on line 46 that r.lop is garbage.

Regression: Yes. This warning was not issued in 3.1. 

Notes: It's possible to subvert the warning by capturing the value of r.lop
before assigning to r.negative, then restoring r.lop.

Here's the source of the attachment for easier browsing:

//  main.m
//  BitField
// xcrun clang -x objective-c -fobjc-arc -isysroot
--analyze main.m

#import <Foundation/Foundation.h>

typedef long long ofr_signed_wide;
typedef unsigned long long ofr_unsigned_wide;
#define OFR_WORKING_WIDTH (unsigned int)(CHAR_BIT * sizeof(ofr_signed_wide) -
#define OFR_WORKING_MAX (ofr_signed_wide)((UINTMAX_C(1) << OFR_WORKING_WIDTH) -
#define OFR_DENOMINATOR_WIDTH (OFR_WORKING_WIDTH/2) /* A product must fit in an
ofr_signed_wide */
#define OFR_DENOMINATOR_MAX (ofr_component)( (INTMAX_C(1) <<

typedef unsigned long ofr_component;

struct OFRationalNumberStruct {
    ofr_component numerator, denominator;
    unsigned short negative: 1;
    unsigned short lop: 1;

struct OFRationalNumberStruct OFRationalFromDouble(double d)
    int exponent;
    int mbits;
    ofr_unsigned_wide m;
    struct OFRationalNumberStruct r;

    r.lop = 0;
    mbits = MIN(DBL_MANT_DIG, CHAR_BIT*(int)sizeof(m));
    m = ldexp(frexp(fabs(d), &exponent), mbits);
    ofr_unsigned_wide numerator = m;
    ofr_unsigned_wide denominator = 1;
    exponent = exponent - mbits;
    BOOL negative = d < 0;
    NSCAssert(r.lop == 0 || r.lop == 1, @"lop must be clean");

    r.numerator = (ofr_component)numerator;
    r.denominator = (ofr_component)denominator;
    NSCAssert(r.lop == 0 || r.lop == 1, @"lop must be clean");
    r.negative = negative?1:0; // HERE: clang thinks that this dirties lop
    /* r.lop is unchanged */

    if (r.lop) {
        double rebuilt = (double)r.numerator / (double)r.denominator;
        if (rebuilt == fabs(d))
            r.lop = 0;

    return r;

int main(int argc, const char * argv[])

    @autoreleasepool {

        // insert code here...
        NSLog(@"Hello, World!");

    return 0;

You are receiving this mail because:
You are on the CC list for the bug.
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.llvm.org/pipermail/llvm-bugs/attachments/20130312/640eaf96/attachment.html>

More information about the llvm-bugs mailing list