<html>
    <head>
      <base href="http://llvm.org/bugs/" />
    </head>
    <body><table border="1" cellspacing="0" cellpadding="8">
        <tr>
          <th>Bug ID</th>
          <td><a class="bz_bug_link 
          bz_status_NEW "
   title="NEW --- - Static analyzer incorrectly dirties second bit in a bit field"
   href="http://llvm.org/bugs/show_bug.cgi?id=15498">15498</a>
          </td>
        </tr>

        <tr>
          <th>Summary</th>
          <td>Static analyzer incorrectly dirties second bit in a bit field
          </td>
        </tr>

        <tr>
          <th>Product</th>
          <td>clang
          </td>
        </tr>

        <tr>
          <th>Version</th>
          <td>3.2
          </td>
        </tr>

        <tr>
          <th>Hardware</th>
          <td>Macintosh
          </td>
        </tr>

        <tr>
          <th>OS</th>
          <td>MacOS X
          </td>
        </tr>

        <tr>
          <th>Status</th>
          <td>NEW
          </td>
        </tr>

        <tr>
          <th>Severity</th>
          <td>normal
          </td>
        </tr>

        <tr>
          <th>Priority</th>
          <td>P
          </td>
        </tr>

        <tr>
          <th>Component</th>
          <td>Static Analyzer
          </td>
        </tr>

        <tr>
          <th>Assignee</th>
          <td>kremenek@apple.com
          </td>
        </tr>

        <tr>
          <th>Reporter</th>
          <td>curt.clifton@mac.com
          </td>
        </tr>

        <tr>
          <th>CC</th>
          <td>llvmbugs@cs.uiuc.edu
          </td>
        </tr>

        <tr>
          <th>Classification</th>
          <td>Unclassified
          </td>
        </tr></table>
      <p>
        <div>
        <pre>Created <span class=""><a href="attachment.cgi?id=10169" name="attach_10169" title="Sample file for which clang-sa produces the false positive">attachment 10169</a> <a href="attachment.cgi?id=10169&action=edit" title="Sample file for which clang-sa produces the false positive">[details]</a></span>
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
/Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX10.8.sdk
--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
/Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX10.8.sdk
--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) -
1)
#define OFR_WORKING_MAX (ofr_signed_wide)((UINTMAX_C(1) << OFR_WORKING_WIDTH) -
1)
#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) <<
OFR_DENOMINATOR_WIDTH) - 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;
}</pre>
        </div>
      </p>
      <hr>
      <span>You are receiving this mail because:</span>
      
      <ul>
          <li>You are on the CC list for the bug.</li>
      </ul>
    </body>
</html>