[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


http://llvm.org/bugs/show_bug.cgi?id=15498

            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
/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;
}

-- 
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