[cfe-dev] [analyzer] _Nonnull types and checking null constraints in checkBind

Timothy J. Wood via cfe-dev cfe-dev at lists.llvm.org
Thu Apr 26 10:12:45 PDT 2018

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.

The tl;dr version of the rest of this is whether the analyzer will mark a _Nonnull result as being constrained to nonnull.

Here is what I’m doing, which makes it seem like the answer is “no”, but maybe I’m doing it wrong...

In my test input I have something like:

	@interface NSError : NSObject <NSCopying, NSCoding> {}
	+ (instancetype _Nonnull)make; // convenient fiction to make exploded graph smaller while debugging


	- (BOOL)failWithErrorLocal:(NSError **)outError;
		NSError *e = [NSError make]; 
		if (outError) {
			*outError = e;
		return NO;

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:

	 dmsg << "  Val " << Val << "\n";

	 ConditionTruthVal IsNull = State->isNull(Val);
	 dmsg << "  IsNull.isConstrained() " << IsNull.isConstrained() << "\n";
	 dmsg << "  IsNull.isConstrainedTrue() " << IsNull.isConstrainedTrue() << "\n”;

I see:

	Val &SymRegion{conj_$4{id _Nonnull}}
	IsNull.isConstrained() 0
	IsNull.isConstrainedTrue() 0

If I set a breakpoint on my checkBind() and then finish out to ExprEngine::VisitDeclStmt, I get a exploded graph dot file like:

-------------- next part --------------
A non-text attachment was scrubbed...
Name: ExprEngine-0d3cbc.dot
Type: application/msword
Size: 3304 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/cfe-dev/attachments/20180426/b11b73a9/attachment.dot>
-------------- next part --------------

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:

	(e,0,direct) : &SymRegion{conj_$4{NSError * _Nonnull}}



More information about the cfe-dev mailing list