Skip to content

Commit

Permalink
remove implicitly inherited globals
Browse files Browse the repository at this point in the history
  • Loading branch information
vtjnash committed Sep 14, 2017
1 parent a26b7d0 commit c997f14
Show file tree
Hide file tree
Showing 2 changed files with 75 additions and 56 deletions.
32 changes: 19 additions & 13 deletions src/julia-syntax.scm
Original file line number Diff line number Diff line change
Expand Up @@ -1718,9 +1718,9 @@
(define (expand-for while lhs X body)
;; (for (= lhs X) body)
(let* ((coll (make-ssavalue))
(state (gensy))
(outer? (and (pair? lhs) (eq? (car lhs) 'outer)))
(lhs (if outer? (cadr lhs) lhs)))
(state (gensy))
(outer? (and (pair? lhs) (eq? (car lhs) 'outer)))
(lhs (if outer? (cadr lhs) lhs)))
`(block (= ,coll ,(expand-forms X))
(= ,state (call (top start) ,coll))
;; TODO avoid `local declared twice` error from this
Expand Down Expand Up @@ -2284,15 +2284,15 @@
'while
(lambda (e)
`(break-block loop-exit
(_while ,(expand-forms (cadr e))
(break-block loop-cont
(scope-block ,(blockify (expand-forms (caddr e))))))))
(_while ,(expand-forms (cadr e))
(break-block loop-cont
(scope-block ,(blockify (expand-forms (caddr e))))))))

'inner-while
(lambda (e)
`(_while ,(expand-forms (cadr e))
(break-block loop-cont
(scope-block ,(blockify (expand-forms (caddr e)))))))
(break-block loop-cont
(scope-block ,(blockify (expand-forms (caddr e)))))))

'break
(lambda (e)
Expand Down Expand Up @@ -2571,10 +2571,15 @@
(define (find-local-def-decls e) (find-decls 'local-def e))
(define (find-global-decls e) (find-decls 'global e))

(define (implicit-locals e env glob)
(define (implicit-locals e env deprecated-env glob)
;; const decls on non-globals introduce locals
(append! (diff (find-decls 'const e) glob)
(find-assigned-vars e env)))
(filter
(lambda (v)
(if (memq v deprecated-env)
(begin (syntax-deprecation #f (string "implicit assignment to global variable `" v "`") (string "global " v)) #f)
#t))
(find-assigned-vars e env))))

(define (unbound-vars e bound tab)
(cond ((or (eq? e 'true) (eq? e 'false) (eq? e UNUSED)) tab)
Expand Down Expand Up @@ -2624,15 +2629,16 @@
((eq? (car e) 'scope-block)
(let* ((blok (cadr e)) ;; body of scope-block expression
(other-locals (if lam (caddr lam) '())) ;; locals that are explicitly part of containing lambda expression
(iglo (find-decls 'implicit-global blok)) ;; globals defined implicitly outside blok
(iglo (find-decls 'implicit-global blok)) ;; globals possibly defined implicitly outside blok
(glob (diff (find-global-decls blok) iglo)) ;; all globals declared in blok
(vars-def (check-dups (find-local-def-decls blok) '()))
(locals-declared (check-dups (find-local-decls blok) vars-def))
(locals-implicit (implicit-locals
blok
;; being declared global prevents a variable
;; assignment from introducing a local
(append env glob iglo outerglobals locals-declared vars-def)
(append env glob iglo locals-declared vars-def)
outerglobals
(append glob iglo)))
(vars (delete-duplicates (append! locals-declared locals-implicit)))
(all-vars (append vars vars-def))
Expand Down Expand Up @@ -2669,7 +2675,7 @@
(memq var implicitglobals) ;; remove anything only added implicitly in the last scope block
(memq var glob))))) ;; remove anything that's now global
renames)))
(new-oglo (append iglo outerglobals)) ;; list of all outer-globals from outside blok
(new-oglo (append iglo outerglobals)) ;; list of all implicit-globals from outside blok
(body (resolve-scopes- blok new-env new-oglo new-iglo lam new-renames #f))
(real-new-vars (append (diff vars need-rename) renamed))
(real-new-vars-def (append (diff vars-def need-rename-def) renamed-def)))
Expand Down
99 changes: 56 additions & 43 deletions test/core.jl
Original file line number Diff line number Diff line change
Expand Up @@ -371,7 +371,7 @@ begin
global f7234_cnt += -10000
end
end
@test_throws UndefVarError f7234_a()
@test_throws UndefVarError(:glob_x2) f7234_a()
@test f7234_cnt == 1
begin
global glob_x2 = 24
Expand All @@ -381,11 +381,11 @@ begin
global f7234_cnt += -10000
end
end
@test_throws UndefVarError f7234_b()
@test_throws UndefVarError(:glob_x2) f7234_b()
@test f7234_cnt == 2
# existing globals can be inherited by non-function blocks
# globals can accessed if declared
for i = 1:2
glob_x2 += 1
global glob_x2 += 1
end
@test glob_x2 == 26
# globals declared as such in a non-global scope are inherited
Expand Down Expand Up @@ -454,15 +454,15 @@ function const_implies_local()
end
@test const_implies_local() === (1, 0)

a = Vector{Any}(3)
for i=1:3
a_global_closure_vector = Vector{Any}(3)
for i = 1:3
let ii = i
a[i] = x->x+ii
a_global_closure_vector[i] = x -> x + ii
end
end
@test a[1](10) == 11
@test a[2](10) == 12
@test a[3](10) == 13
@test a_global_closure_vector[1](10) == 11
@test a_global_closure_vector[2](10) == 12
@test a_global_closure_vector[3](10) == 13

# issue #22032
let a = [], fs = []
Expand Down Expand Up @@ -499,8 +499,10 @@ end
@test_throws UndefVarError f21900()
@test f21900_cnt == 1

@test_throws UndefVarError @eval begin
# use @eval so this runs as a toplevel scope block
@test_throws UndefVarError(:foo21900) @eval begin
for i21900 = 1:10
local bar21900
for j21900 = 1:10
foo21900 = 10
end
Expand All @@ -511,8 +513,9 @@ end
@test !@isdefined(foo21900)
@test !@isdefined(bar21900)
bar21900 = 0
@test_throws UndefVarError @eval begin
@test_throws UndefVarError(:foo21900) @eval begin
for i21900 = 1:10
global bar21900
for j21900 = 1:10
foo21900 = 10
end
Expand All @@ -523,8 +526,9 @@ end
@test bar21900 == -1
@test !@isdefined foo21900
foo21900 = 0
@test nothing === @eval begin
@test nothing === begin
for i21900 = 1:10
global bar21900, foo21900
for j21900 = 1:10
foo21900 = 10
end
Expand Down Expand Up @@ -682,40 +686,47 @@ end

# try/finally
begin
after = 0
b = try
try_finally_glo_after = 0
try_finally_loc_after = 0
try_finally_glo_b = try
1+2
finally
after = 1
# try_finally_loc_after = 1 # enable with #19324
global try_finally_glo_after = 1
end
@test b == 3
@test after == 1
@test try_finally_loc_after == 0
@test try_finally_glo_b == 3
@test try_finally_glo_after == 1

after = 0
try_finally_glo_after = 0
gothere = 0
try
try
error(" ")
finally
after = 1
# try_finally_loc_after = 1 # enable with #19324
global try_finally_glo_after = 1
end
gothere = 1
global gothere = 1
end
@test after == 1
@test try_finally_loc_after == 0
@test try_finally_glo_after == 1
@test gothere == 0

after = 0
b = try
try_finally_glo_after = 0
try_finally_glo_b = try
error(" ")
catch
42
finally
after = 1
# try_finally_loc_after = 1 # enable with #19324
global try_finally_glo_after = 1
end
@test b == 42
@test after == 1
@test try_finally_loc_after == 0
@test try_finally_glo_b == 42
@test try_finally_glo_after == 1

glo = 0
global glo = 0
function retfinally()
try
return 5
Expand Down Expand Up @@ -1223,7 +1234,7 @@ C3729{D} = Vector{Vector{D}}
# issue #3789
x3789 = 0
while(all([false for idx in 1:10]))
x3789 = 1
global x3789 = 1
end
@test x3789 == 0

Expand Down Expand Up @@ -1446,7 +1457,7 @@ b4688(y) = "not an Int"
begin
a4688(y::Int) = "an Int"
let x = true
b4688(y::Int) = x == true ? a4688(y) : a4688(y)
global b4688(y::Int) = x == true ? a4688(y) : a4688(y)
end
end
@test b4688(1) == "an Int"
Expand Down Expand Up @@ -1540,9 +1551,8 @@ function tupledispatch(a::TupleParam{(1,:a)})
a.x
end

let
# tuples can be used as type params
t1 = TupleParam{(1,:a)}(true)
# tuples can be used as type params
let t1 = TupleParam{(1,:a)}(true),
t2 = TupleParam{(1,:b)}(true)

# tuple type params can't contain invalid type params
Expand Down Expand Up @@ -2003,11 +2013,13 @@ function issue7897!(data, arr)
a = arr[1]
end

a = ones(UInt8, 10)
sa = view(a,4:6)
# This can throw an error, but shouldn't segfault
try
issue7897!(sa, zeros(10))
let
a = ones(UInt8, 10)
sa = view(a, 4:6)
# This can throw an error, but shouldn't segfault
try
issue7897!(sa, zeros(10))
end
end

# issue #7582
Expand Down Expand Up @@ -3813,7 +3825,8 @@ end
# issue #15283
j15283 = 0
let
k15283 = j15283+=1
global j15283
k15283 = (j15283 += 1)
end
@test j15283 == 1
@test !@isdefined k15283
Expand Down Expand Up @@ -4467,12 +4480,12 @@ end
@test_throws ErrorException main18986()

# issue #18085
f18085(a,x...) = (0,)
for (f,g) in ((:asin,:sin), (:acos,:cos))
f18085(a, x...) = (0, )
for (f, g) in ((:asin, :sin), (:acos, :cos))
gx = eval(g)
f18085(::Type{Val{f}},x...) = map(x->2gx(x), f18085(Val{g},x...))
global f18085(::Type{Val{f}}, x...) = map(x -> 2gx(x), f18085(Val{g}, x...))
end
@test f18085(Val{:asin},3) === (0.0,)
@test f18085(Val{:asin}, 3) === (0.0,)

# issue #18236 constant VecElement in ast triggers codegen assertion/undef
# VecElement of scalar
Expand Down

0 comments on commit c997f14

Please sign in to comment.