2016-08-16 23:19 GMT+02:00 John Brant <[email protected]>:

> I’m guessing that it is using the read before written tester from the
> refactoring browser. It treats ifTrue:ifFalse:/ifFalse:ifTrue: blocks and
> the receiver blocks of whileTrue/False: specially. All other blocks are
> considered potentially not executed. Therefore, it says that the or: block
> may not be executed so the “element” reference in the whileFalse: argument
> block may be read without any assignment.
>
>
Since or: and: are pretty much like ifTrue: ifFalse: they should better be
treated as specially.


> The RB’s read before written tester is different from the compilers. The
> compiler’s version lets some things through that it shouldn’t, and I think
> the compiler should use the RB version instead. Here’s an example where the
> compiler generates incorrect code for the optimized “v” variable in the
> whileTrue:
>
> | stream count |
> count := 0.
> stream := ReadStream on: #(true true true false false).
> [ stream next and: [ | v | stream next ifTrue: [ v := 1 ]. v notNil ] ]
>         whileTrue: [ count := count + 1 ].
> count = 1
>
> This should answer true, but answers false. The compiler should see that
> “v” may potentially be read before written, and therefore assign it to nil
> at the beginning of the or: block like would be done for an unoptimized
> block temporary. If you perform the #whileTrue: instead (to get a real
> block), you get the correct result:
>
> | stream count |
> count := 0.
> stream := ReadStream on: #(true true true false false).
> [ stream next and: [ | v | stream next ifTrue: [ v := 1 ]. v notNil ] ]
>         perform: #whileTrue: with: [ count := count + 1 ].
> count = 1
>
>
> John Brant
>
>
Yes, you're right, that's a Compiler bug.
The result shall not change whether blocks are optimized or not.



> > On Aug 16, 2016, at 3:23 PM, Nicolas Cellier <nicolas.cellier.aka.nice@
> gmail.com> wrote:
> >
> > initialization of element is conditional (in the or: block).
> > I'm amazed, that's a new behavior, is it a consequence of using AST?
> > But a dumb compiler not knowing the semantic of or: (it is a message
> like others) could conclude that element may be used uninitialized in the
> whileFalse block...
> > A compiler that is inlining or: with a well known semantic has no excuse
> ;)
> >
> > 2016-08-16 22:12 GMT+02:00 stepharo <[email protected]>:
> > While browsing the system I saw that the following method raised a temp
> read before written...
> >
> > It did not jump to my eyes. Working on something else....
> >
> >
> > PositionableStream>>upTo: anObject
> >     "Answer a subcollection from the current access position to the
> >     occurrence (if any, but not inclusive) of anObject in the receiver.
> If
> >     anObject is not in the collection, answer the entire rest of the
> receiver."
> >     | newStream element |
> >     newStream := (collection species new: 100) writeStream.
> >     [self atEnd or: [(element := self next) = anObject]]
> >         whileFalse: [newStream nextPut: element].
> >     ^newStream contents
> >
> >
> >
>
>
>

Reply via email to