<div dir="ltr"><div><div><div><div>Hi!<br><br></div>This is a philosophical question to some extent. I think what _Nonnull means at the return value is that in case all the preconditions of a function is met the result will never be null.<br></div>So in case a function has a _Nonnull parameter and a _Nonnull return value and the caller passes null, the function is free to return null.<br><br></div>Of course, passing null to this function was an error in the first place.<br><br></div><div>There is a tradeoff, constraining these values to not being null will reduce the coverage and lots of the errors found by the analyzer are actually in the error handling code.<br></div><div>But having this information might increase the precision of the analysis.<br><br></div><div>I think the reason why it was developed that way there were lots of legacy APIs where the clients relied on the behavior that a _Nonnull function (which was not annotated<br></div><div>in the past of course,) returns null when its precondition is not met.<br><br></div><div>Maybe people started to fix such code and now it makes sense to change this behavior?<br><br></div><div>Regards,<br></div><div>Gábor<br></div></div><div class="gmail_extra"><br><div class="gmail_quote">On 26 April 2018 at 19:12, Timothy J. Wood via cfe-dev <span dir="ltr"><<a href="mailto:cfe-dev@lists.llvm.org" target="_blank">cfe-dev@lists.llvm.org</a>></span> wrote:<br><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><br>
While working on my outError-writing checker, I thought I’d try to use as much of the built-in checker support for tracking which values/regions are marked a non-null as possible rather than adding tracking of every `NSError *` in my own state.<br>
<br>
The tl;dr version of the rest of this is whether the analyzer will mark a _Nonnull result as being constrained to nonnull.<br>
<br>
Here is what I’m doing, which makes it seem like the answer is “no”, but maybe I’m doing it wrong...<br>
<br>
In my test input I have something like:<br>
<br>
@interface NSError : NSObject <NSCopying, NSCoding> {}<br>
+ (instancetype _Nonnull)make; // convenient fiction to make exploded graph smaller while debugging<br>
@end<br>
<br>
...<br>
<br>
- (BOOL)failWithErrorLocal:(<wbr>NSError **)outError;<br>
{<br>
NSError *e = [NSError make]; <br>
if (outError) {<br>
*outError = e;<br>
}<br>
return NO;<br>
}<br>
<br>
Since +make is marked as returning a nonnull result, I was expecting/hoping the checkBind call for that assignment to have a r-value that was constrained to nonnull (and that this would get propagated to *outError if the body of the `if` was executed). But, in my checkBind(), if I do:<br>
<br>
dmsg << " Val " << Val << "\n";<br>
<br>
ConditionTruthVal IsNull = State->isNull(Val);<br>
dmsg << " IsNull.isConstrained() " << IsNull.isConstrained() << "\n";<br>
dmsg << " IsNull.isConstrainedTrue() " << IsNull.isConstrainedTrue() << "\n”;<br>
<br>
I see:<br>
<br>
Val &SymRegion{conj_$4{id _Nonnull}}<br>
IsNull.isConstrained() 0<br>
IsNull.isConstrainedTrue() 0<br>
<br>
If I set a breakpoint on my checkBind() and then finish out to ExprEngine::VisitDeclStmt, I get a exploded graph dot file like:<br>
<br>
<br>
<br><br>
<br>
I’m still not really sure how to read these, but can see that it has bound the local `e` to the nonnull result of +make:<br>
<br>
(e,0,direct) : &SymRegion{conj_$4{NSError * _Nonnull}}<br>
<br>
Thanks,<br>
<br>
-tim<br>
<br>
<br>______________________________<wbr>_________________<br>
cfe-dev mailing list<br>
<a href="mailto:cfe-dev@lists.llvm.org">cfe-dev@lists.llvm.org</a><br>
<a href="http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-dev" rel="noreferrer" target="_blank">http://lists.llvm.org/cgi-bin/<wbr>mailman/listinfo/cfe-dev</a><br>
<br></blockquote></div><br></div>