OSNumber and CFNumberRef, much like NSNumber*, can also be accidentally mistaken for a numeric value, so it is worth it to support this type in our new NumberObjectConversion checker.
Details
Diff Detail
- Repository
- rL LLVM
Event Timeline
lib/StaticAnalyzer/Checkers/NumberObjectConversionChecker.cpp | ||
---|---|---|
72 ↗ | (On Diff #75011) | I'd keep the names more specific. By reading this code alone it looks like you are just checking for any ObjC object. |
111 ↗ | (On Diff #75011) | Why do we need a case split here? Would calling getCanonicalType().getUnqualifiedType() result in a wrong result for ObjC? |
129 ↗ | (On Diff #75011) | Let's just recommend nullptr for C++, but allow both NULL and nullptr. |
152 ↗ | (On Diff #75011) | Please, use more a expressive name. I'd prefer a super long name if it's more expressive. |
test/Analysis/number-object-conversion.c | ||
14 ↗ | (On Diff #75011) | How about:
|
Ouch, i think i forgot about OSNumber, including tests.
lib/StaticAnalyzer/Checkers/NumberObjectConversionChecker.cpp | ||
---|---|---|
111 ↗ | (On Diff #75011) | It'd result in a wrong result for CFNumberRef, which is a typedef we shouldn't remove (turning this into struct __CFNumber * would be ugly). I'd probably rather avoid the case split by removing the .getCanonicalType() part, because rarely anybody makes typedefs for NSNumber* or OSBoolean* etc (such as in tests with the word "sugared"). Or i could descend down to the necessary typedef for C objects, discarding all user's typedefs but not library typedefs. But that'd be even more complicated and probably not very useful for such minor matter. |
lib/StaticAnalyzer/Checkers/NumberObjectConversionChecker.cpp | ||
---|---|---|
149 ↗ | (On Diff #75011) | probably it would make sense to move "MatchFinder F;" to the line 276 (closer to the place where it's actually being used)(or maybe i'm missing smth ?) |
lib/StaticAnalyzer/Checkers/NumberObjectConversionChecker.cpp | ||
---|---|---|
111 ↗ | (On Diff #75011) |
I see. Displaying "CFNumberRef" is definitely the right thing to do! Please, add a comment to explain this. |
lib/StaticAnalyzer/Checkers/NumberObjectConversionChecker.cpp | ||
---|---|---|
149 ↗ | (On Diff #75011) | Yep, great idea. |
test/Analysis/number-object-conversion.c | ||
14 ↗ | (On Diff #75011) |
Because there's otherwise no obvious boolean value around, i wanted to point out what exactly is going on.
They don't necessarily compare the value. Maybe "take"?
Not sure it's worth keeping for other objects ("'NSNumber *' pointer" sounds like a pointer to a pointer). |
test/Analysis/number-object-conversion.c | ||
---|---|---|
23 ↗ | (On Diff #75411) | Comparing a pointer value of type '[CFNumberRef|NSNumber *]' to a primitive [boolean|integer] value; did you mean to compare the result of calling [API Name]. |
14 ↗ | (On Diff #75011) |
OSBoolean or CFNumber: NSNumber or OSNumber: Comparing a pointer value of type '[NSNumber *]' to a scalar [boolean|integer] value; instead, either compare the pointer to [NULL|nullptr|nil] or call a method on '[NSNumber *]' to get the scalar value. |
test/Analysis/number-object-conversion.cpp | ||
32 ↗ | (On Diff #75411) | Converting a pointer value of type '[CFNumberRef|NSNumber *]' to a primitive [boolean|integer] value; did you mean to call [APIName]. |
41 ↗ | (On Diff #75411) | Same as cast. |
- Update warning messages. I think it's better to pattern-match for integer sizes after all when we're suggesting API, this especially looks ugly for OSNumber (which is rare).
- Add tests for converting CFNumberRef into intptr_t.
- An unrelated change: Move casts to bools to non-pedantic mode (i mistakenly thought this check is loud).
Do not suggest any API when we're not sure (was already advised by Anna but i missed it somehow).
Minor nit below.
Thanks for iterating so much on this!
Anna.
test/Analysis/number-object-conversion.cpp | ||
---|---|---|
46 ↗ | (On Diff #75612) | Minor nit: Here, we want to use scalar instead of primitive so that both parts of the sentence are consistent. Devin did not like "scalar", but that's what it is called in the API docs, so I think should use that word in this specific case. (We can keep 'primitive' for the error messages that do not have "to get the ... value") Sorry, this is a bit confusing. |
- Fix warning messages, finally, hopefully.
- Make handling of macros much more careful, because errors of form x == Y, where X is an NSNumber pointer, and Y is a custom macro that expands to 0, were found.
LGTM.
test/Analysis/number-object-conversion.m | ||
---|---|---|
98 ↗ | (On Diff #76043) | This is great! And a good catch. |