This is an archive of the discontinued LLVM Phabricator instance.

Model Constructor corresponding to a new call
Needs ReviewPublic

Authored by karthikthecool on Jan 24 2014, 6:13 AM.

Details

Reviewers
jordan_rose
Summary

Hi Jordan,
This patch is not yet complete and I'm not completly sure about this patch yet, as in if this is the correct way to model allocator call.
I would like to get a few inputs if i'm in the right direction.

Since we have modelled Allocator in CFG i'm now trying to plugin in the same into SA Core.
I'm a bit confused on what part of VisitCXXNewExpr will go into VisitCXXNewAllocatorCall and if that is required?

In this patch i have just called the relevent allocator function in VisitCXXNewAllocatorCall and proceeded.
In VisitCXXConstructExpr i check if this constructor was call due to a call to new in which case i use the CXXNewExpr to conjure a symbol and use the memregion returned to call the constructor.
Later when VisitCXXNewExpr the same region is returned for the CXXNewExpr and i continue with other initialization.

This seem to work and constructor is now getting inlined and relevent warnings are now being detected but i'm not sure if this approach is correct.

Could you guide me if we can follow this approach? If not how exactly to model VisitCXXNewAllocatorCall call to reuse the allocated memregion in VisitCXXConstructExpr?

Any inputs would be greatly appreciated.

Thanks
Karthik Bhat

Diff Detail

Event Timeline

Let's not worry about the constructor for now. I imagine it will look something like what you've done (I just skimmed it), but for now let's just get the call happening in the right place. You can always use something like clang_analyzer_checkInlined(true) to make sure it's actually happening.

I appreciate that it looks fairly simple to get that part working. :-)

Later, I think we'll want the default region stuff (the "standard global new" model) to appear in VisitCXXAllocatorCall, or even to be in a checker (which would mean using evalCall instead of defaultEvalCall), so that by the time we get to the constructor we can rely on always having a region.

lib/StaticAnalyzer/Core/ExprEngineCXX.cpp
375

Don't forget to change this stack trace message. :-)

karthikthecool updated this revision to Unknown Object (????).Jan 28 2014, 5:06 AM

Hi Jordan,
I suppose you wanted me to inline the allocator call during a call to new first. This patch inlines the allocator call but i'm still facing few problems.
If i code as -

void* operator new(size_t num)
{
  return 0;
}

int main() {
  int* i = new int(1);
  *i = 1;
  delete i;
  return 0;
}

In the above code we are not able to detect the null deref at *i = 1; . I suppose that is because we are conjuring a new symbol in VisitCXXNewExpr which is being used as output of new expression. My doubt was how do i make sure that the VisitCXXNewExpr uses the output of VisitCXXNewAllocatorCall?
I tried something like -

  1. conjure a symbol in VisitCXXNewAllocatorCall.
  2. Bind it to conjured symbol to CXXNewExpr
  3. Call getSVal in VisitCXXNewExpr with the CXXNewExpr and location context to get back the conjured symbol.

but unfortunetly in VisitCXXNewExpr when i call getSVal with CXXNewExpr and LocationContext i get the result as Unknown instead of the symbol conjured in VisitCXXNewAllocatorCall.
How do i make sure that VisitCXXNewExpr uses the result of VisitCXXNewAllocatorCall? It would be great if you could guide me here.

Thanks
Karthik Bhat

I think that's basically the strategy we'll want to use, but I don't even think we should worry about that right now. Incremental development is a good thing. My guess is that it's not working because the CXXNewExpr isn't considered live after the allocator CFG node, so we'll have to go tweak the LiveVariables analysis.

lib/StaticAnalyzer/Core/ExprEngineCallAndReturn.cpp
667–669

I forgot about this. Let's put this under an analyzer-config flag and have it off by default, because it's an important bit of false positive prevention. (Sorry!)

We don't need to be able to inline deallocators to turn this on, just have them in the CFG. But inlining them probably isn't much work after that.