PR# 19080 Object test succeeds but delivers Void local

Problem Report Summary
Submitter: ctillman
Category: EiffelStudio
Priority: Medium
Date: 2015/06/20
Class: Bug
Severity: Serious
Number: 19080
Release: 15.01
Confidential: No
Status: Analyzed
Environment: Mozilla/5.0 (X11; Linux i686; rv:31.0) Gecko/20100101 Firefox/31.0 Iceweasel/31.7.0
Synopsis: Object test succeeds but delivers Void local

I've had this occur a few times in the last several days, in the project I'm working on. And it's been the same symptoms in at least 3 different places in the app. What happens is that an object test succeeds, but the "as" local it delivers turns out to be Void.

I attached two screen shots of the debugger showing the Void delivered local in 2 of the different cases.

In the first case, I thought it was something to do with the complexity of the ifelse structure. Notice the object I'm seeking in the object test has been attached to a different variable, labeled_statement ... which variable has not even come into scope yet. I worked around that one by creating a new local variable and doing the object test before getting into the ifelse. (I assigned the successful object test local to the declared local variable.)

In the second case it was a very simple test right at the beginning of the feature. It also started to happen after I did a Freeze, the program had been running past this point before that. I tried re-running, quitting EiffelStudio and re-running, but neither was successful.

I also did a compile from scratch, that did not change it either. Then I added a declared local variable to which to assign the result of the object test, similar to the workaround I arrived at in the other case. But ... get this, I didn't even use the local variable. I just added that line above the other failing line, and having once done that, the failing line started to succeed.

Right after that I had a 3rd case, and I've attached that one too. In that case the object test local was apparently valid, but not long enough for the "and then" check that succeeded it.

So ... seems like it could be a serious issue.

To Reproduce
Not sure about that ... I tried to reproduce the first case for a couple of hours in a simple app, but couldn't.
Problem Report Interactions
From:manus_eiffel    Date:2015/06/22    Download   
Just a clarification on what I told you earlier. By telling the compiler it was attached, I meant that the type of the expression of the object test was attached. This is why it gets optimized away.

From:ctillman    Date:2015/06/21    Download   
Thanks for your reply, Manu. But I did not tell the compiler it was attached. That would be using "check attached" right? I am using "if attached".

This only happens in a few spots in the application. One in particular involves agents, and I can kind of understand how the compiler might not be able to get her head around an agent's dealings.

However it is repeatable in those spots and it is definitely related to the Conformance level. I've determined an effective workaround is the belt-and suspenders approach:

if attached a.b as c and then c /= Void then

I suspect you're right though, that it is only an issue with the Conformance level. I've got that working using the workaround now, and after I commit I'll move up the next level. I'll let you know if the workarounds are still necessary at the next level.


From:manus_eiffel    Date:2015/06/21    Download   
Actually the compiler is right from making this assumption. You told him it was attached. What the compiler could probably tell you is that it was useless to do an object test in this particular case.

I believe that you are going too far in your conversion for the conformance mode of void-safety. In that stage, you decide which queries are attached, which are detachable. Once done, you simply fix conformance errors without introducing any object tests. Even if you were using an object test before, it meant that the expression was detachable, so it should stay that way. If during your conversion you made it attached, you should look at the callers and update them accordingly.

Once the conformance level is done, you can go to one level up in the migration to void-safe and this will really perform check about void-safety which would detect your original error.

A final note, do not reply to the email since it goes to a barely monitored email address. Thanks.

From:manus_eiffel    Date:2015/06/20    Status: Analyzed    Download   
In order to benefit from Void-safety all classes in the system have to be compiled in void-safe mode. In the event it is not done the compiler might trust code that it shouldn't. In your case the expression is of an attached type but actually is not. The compiler optimize this by getting rid of the test and a call on a Void target occurs. 

To confirm this assumption could you provide your ECF?

From:ctillman    Date:2015/06/20    Download   
Attachments for problem report #19080

Attachment: ghost_local.png     Size:246971
Attachment: ghost_local2.png     Size:248280
Attachment: ghost_local3.png     Size:221475