[cfe-dev] Adding a CFG node for the allocation call in a new-expression

John McCall rjmccall at apple.com
Fri Apr 6 11:54:14 PDT 2012


On Apr 6, 2012, at 11:26 AM, Anna Zaks wrote:

> 
> On Apr 6, 2012, at 10:42 AM, Jordan Rose wrote:
> 
>> 
>> On Apr 5, 2012, at 14:28, Anna Zaks wrote:
>> 
>>> 
>>> On Apr 4, 2012, at 10:06 AM, Jordan Rose wrote:
>>> 
>>>> - What does it mean to be PreStmt<CXXNewExpr> if the allocation and the initializer have already happened? (Note that right neither PreStmt nor PostStmt checks are done on CXXNewExpr, but that's easily fixed.)
>>>> 
>>> 
>>> What are the issues with calling PreStmt<CXXNewExpr> before evaluation of any statements related to new (except that it's more difficult to implement)? That's what checker writers would expect from the callback.
>> 
>> Now that the CFG is linearized, it's hard to know what that means. For a normal call, the arguments are evaluated before the PreStmt<CallExpr> callback, then the call itself is inlined or modelled, then there's the PostStmt<CallExpr> callback. For a CXXNewExpr, though, the CFG looks like this:
>> 
>> 1. Evaluate all placement args.
>> 2. CFGAllocation ***
>> 3. Evaluate all constructor args.
>> 4. Evaluate the constructor.
>> 5. Evaluate the CXXNewExpr.
>> 
>> It's impractical to put the PreStmt<CXXNewExpr> call before all of that, because that removes the whole effort of a linearized CFG. The constructor args really might not be evaluated until after the allocation, according to the standard, but moving them is impractical since there /is/ a CXXConstructExpr (or similar) inside the CXXNewExpr, and the CFG treats that like any other expression. IIRC, we don't have any other Pre/Post pairs that stretch across multiple CFG nodes.
>> 
> 
> If I understand correctly, we want to evaluate the arguments of the constructor before PreStmt<CallExpr>, but it is difficult to do because their evaluation is a part of evaluating CXXConstructExpr, which occurs after CFGAllocation in the CFG. But the following order would be best but difficult to implement. The standard allows evaluation of constructor args before allocation, correct?

Correct, they're indeterminately sequenced.  AFAIK, in practice, everyone evaluates the constructor arguments after allocation.  This generally creates better code — for example, if the constructor is an elidable copy-construction, you can just evaluate the constructor argument in-place.  For example:
  struct A { ...; static A make(); };
  ...
  new A(A::make());

Obviously you don't necessarily need to model it that way in the CFG, though.

John.



More information about the cfe-dev mailing list