The test case provided demonstrates a regression due to my earlier attempt to fix temporaries in D26839. Neither before nor after, we did not properly copy the symbolic rvalue of the object to the newly created memory region; in different ways though.
In the test case:
- there are two classes - Super (smaller) and Sub (bigger);
- a temporary object of Sub is created;
- a Sub-specific field not present in Super is initialized during construction;
- the temporary Sub-class object is casted to Super to call method m() that is declared in Super;
- a temporary region is retroactively created to represent this-region during method call;
- value of the Super-object is copied over the c++ base-object region;
- the rest of the temporary remains uninitialized;
- m() calls a virtual method mImpl() that resolves to the definition in Sub;
- mImpl() uses the Sub-specific field initialized on step 3 but not copied on step 6, as explained on step 7;
- a false warning regarding usage of uninitialized value is thrown.
The problem (apart from step 5 which is the reason for all the hassle, but needs AST fixes) is of course on step 6, where we should have just copied the whole Sub object. But - surprise! - the value of this object is no longer there in the Environment, because the cast on step 4 was already successfully modeled.
I'm uncertain of the proper solution. We could probably prevent objects from disappearing from the Environment upon unchecked-derived-to-base casts, but that'd require performance evaluations on C++-rich codebases.
For now, i propose to invalidate the Sub-object before binding the Super-object. This way at least we don't produce false accusations.
There's also one open question for the case when the value wasn't removed from the environment, but we still need to bind Super - i'm seeing failing tests when i disable binding Super, but i didn't investigate them yet.
If we are touching names, should we rename Ex to InitWithAdjustments (or smth like this) and ExV correspondingly?