From 0fb33f96901e4fffb18c0b9064fa8314b1eb609b Mon Sep 17 00:00:00 2001 From: Devin Coughlin Date: Fri, 19 Aug 2016 22:04:45 +0000 Subject: [PATCH] [www] Add nullability questions to analyzer FAQ. llvm-svn: 279330 --- clang/www/analyzer/faq.html | 54 +++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 54 insertions(+) diff --git a/clang/www/analyzer/faq.html b/clang/www/analyzer/faq.html index 26ed91a..516233b 100644 --- a/clang/www/analyzer/faq.html +++ b/clang/www/analyzer/faq.html @@ -30,6 +30,8 @@ null?
  • How do I tell the static analyzer that I don't care about a specific unused instance variable in Objective C?
  • How do I tell the static analyzer that I don't care about a specific unlocalized string?
  • How do I tell the analyzer that my instance variable does not need to be released in -dealloc under Manual Retain/Release?
  • +
  • How do I decide whether a method's return type should be _Nullable or _Nonnull?
  • +
  • How do I tell the analyzer that I am intentionally violating nullability?
  • The analyzer assumes that a loop body is never entered. How can I tell it that the loop body will be entered at least once?
  • How can I suppress a specific analyzer warning?
  • How can I selectively exclude code the analyzer examines?
  • @@ -115,6 +117,58 @@ by either adding assert(_ivar == nil) or an explicit release [_ivar release] (which will be a no-op when the variable is nil) in -dealloc.

    +

    Q: How do I decide whether a method's return type should be _Nullable or _Nonnull?

    + +

    Depending on the implementation of the method, this puts you in one of five situations: +

      +
    1. You actually never return nil.
    2. +
    3. You do return nil sometimes, and callers are supposed to handle that. This +includes cases where your method is documented to return nil given certain +inputs.
    4. +
    5. You return nil based on some external condition (such as an out-of-memory +error), but the client can't do anything about it either.
    6. +
    7. You return nil only when the caller passes input documented to be invalid. +That means it's the client's fault.
    8. +
    9. You return nil in some totally undocumented case.
    10. +
    +

    + +

    In (1) you should annotate the method as returning a _Nonnull +object.

    +

    In (2) the method should be marked _Nullable.

    +

    In (3) you should probably annotate the method _Nonnull. Why? +Because no callers will actually check for nil, given that they can't do +anything about the situation and don't know what went wrong. At this point +things have gone so poorly that there's basically no way to recover.

    +

    The least happy case is (4) because the resulting program will almost +certainly either crash or just silently do the wrong thing. +If this is a new method or you control the callers, you can use +NSParameterAssert() (or the equivalent) to check the precondition and +remove the nil return. But if you don't control the callers and they rely on +this behavior, you should return mark the method _Nonnull and return +nil cast to _Nonnull anyway. +(Note that (4) doesn't apply in cases where the caller can't know they passed +bad parameters. For example, ++[NSData dataWithContentsOfFile:options:error:] will fail if the file +doesn't exist, but there's no way to check for that in advance. This means +you're really in (2).)

    +

    If you're in (5), document it, then figure out if you're now in (2), (3), or +(4). :-)

    + +

    Q: How do I tell the analyzer that I am intentionally violating nullability?

    + +

    In some cases, it may make sense for methods to intentionally violate +nullability. For example, your method may — for reasons of backward +compatibility — chose to return nil and log an error message in a method +with a non-null return type when the client violated a documented precondition +rather than check the precondition with NSAssert(). In these cases, you +can suppress the analyzer warning with a cast: +

    +    return (id _Nonnull)nil;
    +
    +Note that this cast does not affect code generation. +

    +

    Q: The analyzer assumes that a loop body is never entered. How can I tell it that the loop body will be entered at least once?

    example use assert -- 2.7.4