Skip to content

Commit

Permalink
fix over-eager removal of newvar nodes in the presence of isdefined
Browse files Browse the repository at this point in the history
  • Loading branch information
JeffBezanson committed Aug 21, 2017
1 parent 288dbb0 commit 792fb1d
Show file tree
Hide file tree
Showing 2 changed files with 27 additions and 5 deletions.
23 changes: 18 additions & 5 deletions src/julia-syntax.scm
Expand Up @@ -3768,12 +3768,23 @@ f(x) = yt(x)
'() arg-map))
body))))

;; find newvar nodes that are unnecessary because (1) the variable is not
(define (for-each-isdefined f e)
(cond ((or (atom? e) (quoted? e)) #f)
((and (pair? e) (eq? (car e) 'isdefined))
(f (cadr e)))
(else
(for-each (lambda (x) (for-each-isdefined f x))
(cdr e)))))

;; Find newvar nodes that are unnecessary because (1) the variable is not
;; captured, and (2) the variable is assigned before any branches.
;; this is used to remove newvar nodes that are not needed for re-initializing
;; variables to undefined (see issue #11065). it doesn't look for variable
;; *uses*, because any variables used-before-def that also pass this test
;; are *always* used undefined, and therefore don't need to be *re*-initialized.
;; This is used to remove newvar nodes that are not needed for re-initializing
;; variables to undefined (see issue #11065).
;; It doesn't look for variable *uses*, because any variables used-before-def
;; that also pass this test are *always* used undefined, and therefore don't need
;; to be *re*-initialized.
;; The one exception to that is `@isdefined`, which can observe an undefined
;; variable without throwing an error.
(define (definitely-initialized-vars stmts vi)
(let ((vars (table))
(di (table)))
Expand All @@ -3782,6 +3793,8 @@ f(x) = yt(x)
di
(begin
(let ((e (car stmts)))
(for-each-isdefined (lambda (x) (if (has? vars x) (del! vars x)))
e)
(cond ((and (pair? e) (eq? (car e) 'newvar))
(let ((vinf (var-info-for (cadr e) vi)))
(if (and vinf (not (vinfo:capt vinf)))
Expand Down
9 changes: 9 additions & 0 deletions test/core.jl
Expand Up @@ -5117,6 +5117,15 @@ f_isdefined_va(::T...) where {T} = @isdefined T
@test !f_isdefined_va()
@test f_isdefined_va(1, 2, 3)

# @isdefined in a loop
let a = []
for i = 1:2
push!(a, @isdefined(j))
local j = 1
end
@test a == [false, false]
end

mutable struct MyStruct22929
x::MyStruct22929
MyStruct22929() = new()
Expand Down

0 comments on commit 792fb1d

Please sign in to comment.