@@ -4371,7 +4371,7 @@ f(x) = yt(x)
4371
4371
(if (eq? (cdr s) dest-tokens)
4372
4372
(cons (car s) l)
4373
4373
(loop (cdr s) (cons (car s) l))))))
4374
- (define (emit-return x )
4374
+ (define (emit-return tail x )
4375
4375
(define (emit- x )
4376
4376
(let* ((tmp (if ((if (null? catch-token-stack) valid-ir-return? simple-atom?) x)
4377
4377
#f
@@ -4380,8 +4380,12 @@ f(x) = yt(x)
4380
4380
(begin (emit `(= ,tmp ,x)) tmp)
4381
4381
x)))
4382
4382
(define (actually-return x )
4383
- (let* ((x (if rett
4384
- (compile (convert-for-type-decl (emit- x) rett #t lam) '() #t #f )
4383
+ (let* ((x (begin0 (emit- x)
4384
+ ; ; if we are adding an implicit return then mark it as having no location
4385
+ (if (not (eq? tail 'explicit ))
4386
+ (emit ' (line #f )))))
4387
+ (x (if rett
4388
+ (compile (convert-for-type-decl x rett #t lam) '() #t #f )
4385
4389
x))
4386
4390
(x (emit- x)))
4387
4391
(let ((pexc (pop-exc-expr catch-token-stack '() )))
@@ -4531,7 +4535,7 @@ f(x) = yt(x)
4531
4535
(eq? (car e) 'globalref ))
4532
4536
(underscore-symbol? (cadr e)))))
4533
4537
(error (string " all-underscore identifiers are write-only and their values cannot be used in expressions" (format-loc current-loc))))
4534
- (cond (tail (emit-return e1))
4538
+ (cond (tail (emit-return tail e1))
4535
4539
(value e1)
4536
4540
((symbol? e1) (emit e1) #f ) ; ; keep symbols for undefined-var checking
4537
4541
((and (pair? e1) (eq? (car e1) 'outerref )) (emit e1) #f ) ; ; keep globals for undefined-var checking
@@ -4577,7 +4581,7 @@ f(x) = yt(x)
4577
4581
(else
4578
4582
(compile-args (cdr e) break-labels))))
4579
4583
(callex (cons (car e) args)))
4580
- (cond (tail (emit-return callex))
4584
+ (cond (tail (emit-return tail callex))
4581
4585
(value callex)
4582
4586
(else (emit callex)))))
4583
4587
((=)
@@ -4594,7 +4598,7 @@ f(x) = yt(x)
4594
4598
(if (not (eq? rr rhs))
4595
4599
(emit `(= ,rr ,rhs)))
4596
4600
(emit `(= ,lhs ,rr))
4597
- (if tail (emit-return rr))
4601
+ (if tail (emit-return tail rr))
4598
4602
rr)
4599
4603
(emit-assignment lhs rhs))))))
4600
4604
((block)
@@ -4647,7 +4651,7 @@ f(x) = yt(x)
4647
4651
(if file-diff (set! filename last-fname))
4648
4652
v)))
4649
4653
((return)
4650
- (compile (cadr e) break-labels #t #t )
4654
+ (compile (cadr e) break-labels #t 'explicit )
4651
4655
#f )
4652
4656
((unnecessary)
4653
4657
; ; `unnecessary` marks expressions generated by lowering that
@@ -4662,7 +4666,8 @@ f(x) = yt(x)
4662
4666
(let ((v1 (compile (caddr e) break-labels value tail)))
4663
4667
(if val (emit-assignment val v1))
4664
4668
(if (and (not tail) (or (length> e 3 ) val))
4665
- (emit end-jump))
4669
+ (begin (emit `(line #f ))
4670
+ (emit end-jump)))
4666
4671
(let ((elselabel (make&mark-label)))
4667
4672
(for-each (lambda (test )
4668
4673
(set-car! (cddr test) elselabel))
@@ -4674,7 +4679,7 @@ f(x) = yt(x)
4674
4679
(if (not tail)
4675
4680
(set-car! (cdr end-jump) (make&mark-label))
4676
4681
(if (length= e 3 )
4677
- (emit-return v2)))
4682
+ (emit-return tail v2)))
4678
4683
val))))
4679
4684
((_while)
4680
4685
(let* ((endl (make-label))
@@ -4716,7 +4721,7 @@ f(x) = yt(x)
4716
4721
(emit `(label ,m))
4717
4722
(put! label-map (cadr e) (make&mark-label)))
4718
4723
(if tail
4719
- (emit-return ' (null))
4724
+ (emit-return tail ' (null))
4720
4725
(if value (error " misplaced label" )))))
4721
4726
((symbolicgoto)
4722
4727
(let* ((m (get label-map (cadr e) #f ))
@@ -4762,7 +4767,7 @@ f(x) = yt(x)
4762
4767
(begin (if els
4763
4768
(begin (if (and (not val) v1) (emit v1))
4764
4769
(emit `(leave ,handler-token)))
4765
- (if v1 (emit-return v1)))
4770
+ (if v1 (emit-return tail v1)))
4766
4771
(if (not finally) (set! endl #f )))
4767
4772
(begin (emit `(leave ,handler-token))
4768
4773
(emit `(goto ,(or els endl)))))
@@ -4794,7 +4799,7 @@ f(x) = yt(x)
4794
4799
(emit `(= ,tmp (call (core ===) ,finally ,(caar actions))))
4795
4800
(emit `(gotoifnot ,tmp ,skip))))
4796
4801
(let ((ac (cdar actions)))
4797
- (cond ((eq? (car ac) 'return ) (emit-return (cadr ac)))
4802
+ (cond ((eq? (car ac) 'return ) (emit-return tail (cadr ac)))
4798
4803
((eq? (car ac) 'break ) (emit-break (cadr ac)))
4799
4804
(else ; ; assumed to be a rethrow
4800
4805
(emit ac))))
@@ -4833,8 +4838,8 @@ f(x) = yt(x)
4833
4838
(set! global-const-error current-loc))
4834
4839
(emit e))))
4835
4840
((atomic) (error " misplaced atomic declaration" ))
4836
- ((isdefined) (if tail (emit-return e) e))
4837
- ((boundscheck) (if tail (emit-return e) e))
4841
+ ((isdefined) (if tail (emit-return tail e) e))
4842
+ ((boundscheck) (if tail (emit-return tail e) e))
4838
4843
4839
4844
((method)
4840
4845
(if (not (null? (cadr lam)))
@@ -4855,20 +4860,20 @@ f(x) = yt(x)
4855
4860
l))))
4856
4861
(emit `(method ,(or (cadr e) ' (false)) ,sig ,lam))
4857
4862
(if value (compile ' (null) break-labels value tail)))
4858
- (cond (tail (emit-return e))
4863
+ (cond (tail (emit-return tail e))
4859
4864
(value e)
4860
4865
(else (emit e)))))
4861
4866
((lambda)
4862
4867
(let ((temp (linearize e)))
4863
- (cond (tail (emit-return temp))
4868
+ (cond (tail (emit-return tail temp))
4864
4869
(value temp)
4865
4870
(else (emit temp)))))
4866
4871
4867
4872
; ; top level expressions
4868
4873
((thunk module)
4869
4874
(check-top-level e)
4870
4875
(emit e)
4871
- (if tail (emit-return ' (null)))
4876
+ (if tail (emit-return tail ' (null)))
4872
4877
' (null))
4873
4878
((toplevel-only)
4874
4879
(check-top-level (cdr e))
@@ -4878,7 +4883,7 @@ f(x) = yt(x)
4878
4883
(check-top-level e)
4879
4884
(let ((val (make-ssavalue)))
4880
4885
(emit `(= ,val ,e))
4881
- (if tail (emit-return val))
4886
+ (if tail (emit-return tail val))
4882
4887
val))
4883
4888
4884
4889
; ; other top level expressions
@@ -4887,7 +4892,7 @@ f(x) = yt(x)
4887
4892
(emit e)
4888
4893
(let ((have-ret? (and (pair? code) (pair? (car code)) (eq? (caar code) 'return ))))
4889
4894
(if (and tail (not have-ret?))
4890
- (emit-return ' (null))))
4895
+ (emit-return tail ' (null))))
4891
4896
' (null))
4892
4897
4893
4898
((gc_preserve_begin)
@@ -4911,7 +4916,7 @@ f(x) = yt(x)
4911
4916
(else
4912
4917
(emit e)))
4913
4918
(if (and tail (not have-ret?))
4914
- (emit-return ' (null)))
4919
+ (emit-return tail ' (null)))
4915
4920
' (null)))
4916
4921
4917
4922
; ; unsupported assignment operators
@@ -5027,6 +5032,7 @@ f(x) = yt(x)
5027
5032
(labltable (table))
5028
5033
(ssavtable (table))
5029
5034
(current-loc 0 )
5035
+ (nowhere #f )
5030
5036
(current-file file)
5031
5037
(current-line line)
5032
5038
(locstack '() )
@@ -5040,26 +5046,33 @@ f(x) = yt(x)
5040
5046
(set! current-loc 1 )))
5041
5047
(set! code (cons e code))
5042
5048
(set! i (+ i 1 ))
5043
- (set! locs (cons current-loc locs)))
5049
+ (set! locs (cons (if nowhere 0 current-loc) locs))
5050
+ (set! nowhere #f ))
5044
5051
(let loop ((stmts (cdr body)))
5045
5052
(if (pair? stmts)
5046
5053
(let ((e (car stmts)))
5047
5054
(cond ((atom? e) (emit e))
5048
5055
((eq? (car e) 'line )
5049
- (if (and (= current-line 0 ) (length= e 2 ) (pair? linetable))
5050
- ; ; (line n) after push_loc just updates the line for the new file
5051
- (begin (set-lineno! (car linetable) (cadr e))
5052
- (set! current-line (cadr e)))
5053
- (begin
5054
- (set! current-line (cadr e))
5055
- (if (pair? (cddr e))
5056
- (set! current-file (caddr e)))
5057
- (set! linetable (cons (if (null? locstack)
5058
- (make-lineinfo name current-file current-line)
5059
- (make-lineinfo name current-file current-line (caar locstack)))
5060
- linetable))
5061
- (set! linetablelen (+ linetablelen 1 ))
5062
- (set! current-loc linetablelen))))
5056
+ (cond ((and (length= e 2 ) (not (cadr e)))
5057
+ ; ; (line #f) marks that we are entering a generated statement
5058
+ ; ; that should not be counted as belonging to the previous marked location,
5059
+ ; ; for example `return` after a not-executed `if` arm in tail position.
5060
+ (set! nowhere #t ))
5061
+ ((and (= current-line 0 ) (length= e 2 ) (pair? linetable))
5062
+ ; ; (line n) after push_loc just updates the line for the new file
5063
+ (begin (set-lineno! (car linetable) (cadr e))
5064
+ (set! current-line (cadr e))))
5065
+ (else
5066
+ (begin
5067
+ (set! current-line (cadr e))
5068
+ (if (pair? (cddr e))
5069
+ (set! current-file (caddr e)))
5070
+ (set! linetable (cons (if (null? locstack)
5071
+ (make-lineinfo name current-file current-line)
5072
+ (make-lineinfo name current-file current-line (caar locstack)))
5073
+ linetable))
5074
+ (set! linetablelen (+ linetablelen 1 ))
5075
+ (set! current-loc linetablelen)))))
5063
5076
((and (length> e 2 ) (eq? (car e) 'meta ) (eq? (cadr e) 'push_loc ))
5064
5077
(set! locstack (cons (list current-loc current-line current-file) locstack))
5065
5078
(set! current-file (caddr e))
0 commit comments