This is an archive of the discontinued LLVM Phabricator instance.

Improvements to CFNumberCreate checker
Needs ReviewPublic

Authored by rgov on Mar 8 2016, 3:48 AM.

Details

Summary

This is an attempt at improving the CFNumber checker which catches disagreements between the programmer-declared CFNumberType of the value (e.g., kCFNumberSInt16Type) and its actual type (hopefully a signed short).

The existing code only checked the expected number of bits. However, there are other ways this could go wrong, such as passing a double where a 64-bit integer is expected, or accidentally interpreting an unsigned integer as a signed integer.

I consider the set of CFNumberTypes as two categories: regular numeric types that map cleanly to standard C data types, such as SInt8, Float, LongLong, etc., and special named types such as CFIndex, NSInteger, and Float32 (which is not necessarily a IEEE 754 float).

For numeric types, they need only agree in signedness, bit width, and numeric type (integer vs real).

For the special named types, I don't want to allow passing, for instance, an int when kCFNumberCFIndexType is specified—that might work without issue on 32-bit, but on 64-bit there will be an overflow. So for these named types, I want to make sure that you are actually passing a CFIndex value (or something typedef'd to CFIndex).

I also extended it to also check CFNumberGetValue, which has the same issues as CFNumberCreate.

The checker is incomplete (for instance, I'd welcome feedback on how the diagnostics should be written) but I'm posting here for some early feedback.

Diff Detail

Event Timeline

rgov updated this revision to Diff 50029.Mar 8 2016, 3:48 AM
rgov retitled this revision from to Improvements to CFNumberCreate checker.
rgov updated this object.
rgov added inline comments.Mar 8 2016, 3:52 AM
lib/StaticAnalyzer/Checkers/BasicObjCFoundationChecks.cpp
352

Since it handles floating point values as well, this function is misnamed.

502

I don't know how to print out the description of the type. Even though T is declared as a QualType, the compiler complains if I try to use T->getAsString() on it.

test/Analysis/CFNumber.c
85

This test is broken, I think because we discard casts, but I think it should be allowed—but we would still want to check that it would not overflow.

zaks.anna edited edge metadata.Mar 29 2016, 11:16 PM

It would be better to stage this as a separate checker and later delete the old checker. (Not a must fix though.) Why are the old tests deleted? My understanding is that the new checker should be more strict than the old one. Is it correct?

We'd need to run this on a bunch of code and see if it reports false positives. People might use unexpected coding patterns.

lib/StaticAnalyzer/Checkers/BasicObjCFoundationChecks.cpp
420

Better to use the new functionality committed in http://reviews.llvm.org/D15921.

441

Best to add a test case in addition to the FIXME. Would casts serve as a false positive suppression mechanism for users?

449

How about rewriting with amore readable version:

if (!checkIntegralType(NumberKind, T, CE, isCreate, C))
  return;
checkSpecialType(NumberKind, T, CE, isCreate, C);
502

I don't think you should mention the name of the expected type since there can be many acceptable ones. I'll get back to you on printing the type, but maybe describing what the issue is would be sufficient? Not sure.

509

We should change it to read as a sentence, even if the sentence is different in each case. For example, printing the target and source type sizes as before gives very valuable information. Type names might not be as useful when those are defined using complex preprocessor logic.

521

We should check if this utility already exists in the compiler somewhere.

566

This is copy and paste from checkIntegralType.

test/Analysis/CFNumber.c
21

What's "should work"? Is it "no warning is expected"?

zaks.anna added inline comments.Mar 31 2016, 9:24 AM
lib/StaticAnalyzer/Checkers/BasicObjCFoundationChecks.cpp
441

Since this a path-sensitive checker it could be a bit trickier to make sure that casts can be used for suppression; you'd need to look at the expression, not the type of the region. (Also, there is probably not much value into having this as a path-sensitive checker.)

rgov added inline comments.Mar 31 2016, 12:41 PM
lib/StaticAnalyzer/Checkers/BasicObjCFoundationChecks.cpp
566

Yes all the reporting code is just placeholders for now.

test/Analysis/CFNumber.c
21

Right, it should not warn.

rgov added a reviewer: NoQ.Jul 7 2016, 1:43 PM