Hi, Karthik. So, as you’ve seen, the current implementation of “new” just assumes we get a new piece of memory no matter what, with a single exception for placement-new. A few extra assumptions are layered on top if we’re using the normal global new.
What we want is for a new-expression to just do two things:
- get a region by calling the appropriate ‘operator new’
- use that region to evaluate the initializer (whether a constructor, list-initialization, or primitive value to copy)
The first one has to happen before the second one, of course. The second one sometimes happens in its own CXXConstructExpr sub-expression. That’s why we need CXXAllocator in the CFG.
What is the allocator call? It’s pretty much the same as any other function call. We might want a new kind of CallEvent to deal with this (a subclass of AnyFunctionCall), but mostly there’s nothing surprising here. The result of this call should be the result of the CXXNewExpr, except it won’t have the right type yet.
The next thing that needs to happen is that the result of the call is used if there’s a constructor initialization. ExprEngine::VisitCXXConstructExpr has some complicated logic to try to decide which region is being initialized; this logic will have to be taught about ‘new’ as well somehow.
Finally, VisitCXXNewExpr will still have to perform other kinds of initialization besides construction, and will also make sure that the final value has the appropriate type.
Does all that seem reasonable? Did I leave anything out?
P.S. Communication over the next two weeks is likely to be spotty as I’ll be on vacation.