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