-
Notifications
You must be signed in to change notification settings - Fork 421
Bug with simplifying abstract binary expressions #2327
Comments
I think there are two separate issues here:
_$2.result = (_0 ? _$0 : false) ? "true" : (_0 ? _$1 > 0 : false) ? "false" : null; Where does the |
@NTillmann thanks for taking the time to explain. So I guess all these other cases are likely to fail to?
Given that the values in their args might be undefined/null, it seems they can also throw at runtime too. Note that none of these template get used in optimized functions or React components, which is why I'm concerned as they can't get used as abstract function calls will always result in temporals in pure scope, so we've likely had correctness issues for some time now but been unaware because it was being covered up by pure scope. |
The fact that you need the composition of two conditionals to reproduce this makes me think that this is related to the problem with partial joins. |
@trueadm Yes, I think so. |
Some more thoughts regarding my point 1. above: What causes the issue is an interaction of various features:
There could be different solutions:
|
I dug into this more today too. We use a temporal abstract values for In my opinion, they should be temporal abstract values or have unique hashes (which means that CSE won't work anyway), with the exception of maybe Furthmore, on our internal bundle the source of the issues, and the reason why #2321 can't land in its current state is not because of CSE only. It's because the logic in the simplication phase, where we check if two abstract values are equal via |
Looking at this again, I think the key issue is that a (still to be computed) value x that depends on a (still to be computed) value y should always ensure that y is computed in a path that dominates the location of x. Kind of compilers 101. Bugs will happen. Let's fix this. |
Looking at this just from the serializer's point of view, here's simple example that shows the issue: (function () {
let c = __abstract("boolean", "(c)");
let d = __abstract("boolean", "(d)");
let o = {};
global.result = c ? o : d ? o : null;
})(); Prepacking this yields (function () {
var _$0 = this;
var _1 = {};
_$0.result = c ? _1 : d ? _1 : null;
}).call(this); Nothing wrong with that, but note that the object behind |
Here's another fun example. The simplifier enables interpreting This is wrong. (function () {
let n = __abstractOrNull("number", "(n)");
let m = __abstractOrNull("number", "(m)");
let c = __abstractOrNull("boolean", "(c)");
let d = __abstractOrNull("boolean", "(d)");
let s;
if (c) {
if (d) { if (n != undefined) s = "A" + n.toString(); }
else { if (n != undefined) s = "B" + n.toString(); }
}
global.s = s;
})(); Talking with @hermanventer, the way out is to make all a-temporal abstract values into temporal abstract values when they get simplified in a path-sensitive manner. |
A few things are happening here. First, the code with which these problems were reported is old. @trueadm's type-based refinement changes, i.e. 1986d76 make the problem go away, for Second, abstract-concrete unions get simplified based on the path condition. This simplification is correct only if subsequent operations on the union yield a-temporal results. The interesting case here is when path conditions simplify a temporal value into being a-temporal. There seem to be three approaches to dealing with this problem in general:
If we do (2) or (3) the |
Including implicit runtime calls, e.g. can |
I think what this boils down to is: any expression (not only call) that can throw or generate side effects conditionally should be temporal. Is there a way that implicit Even with An interesting one is the Probably, more auditing will be needed to temporalize all such cases. |
Take the given example:
In the output you can see that we're using
_$0
even though it may not be used:If I change the condition from
if (res1 > 0) {
toif (res1) {
, the issue goes away. If I disable the simplifier entirely, this also fixes the problem.The text was updated successfully, but these errors were encountered: