3m bug fix for function calls chained with &&, ||, etc

svn: r4072
This commit is contained in:
Matthew Flatt 2006-08-16 23:08:24 +00:00
parent 6cedffd7c0
commit 87e78e0f96

View File

@ -613,15 +613,23 @@
"SET_GC_VARIABLE_STACK(__gc_var_stack__), ")
"__gc_var_stack__[1] = (void *)x)~n"))
;; Debugging support:
(printf "#ifdef MZ_3M_CHECK_VAR_STACK\n")
(printf "static int _bad_var_stack_() { *(long *)0x0 = 1; return 0; }\n")
(printf "# define CHECK_GC_V_S ((GC_VARIABLE_STACK == __gc_var_stack__) ? 0 : _bad_var_stack_()),\n")
(printf "#else\n")
(printf "# define CHECK_GC_V_S /*empty*/\n")
(printf "#endif\n")
;; Call a function where the number of registered variables can change in
;; nested blocks:
(printf "#define FUNCCALL_each(setup, x) (setup, x)~n")
(printf "#define FUNCCALL_each(setup, x) (CHECK_GC_V_S setup, x)~n")
;; The same, but a "tail" call:
(printf "#define FUNCCALL_EMPTY_each(x) FUNCCALL_each(SET_GC_VARIABLE_STACK((void **)__gc_var_stack__[0]), x)~n")
(printf "#define FUNCCALL_EMPTY_each(x) (SET_GC_VARIABLE_STACK((void **)__gc_var_stack__[0]), x)~n")
;; The same, but the number of registered variables for this call is definitely
;; the same as for the previous call:
(printf (if callee-restore?
"#define FUNCCALL_AGAIN_each(x) x~n"
"#define FUNCCALL_AGAIN_each(x) (CHECK_GC_V_S x)~n"
"#define FUNCCALL_AGAIN_each(x) FUNCCALL_each(SET_GC_VARIABLE_STACK(__gc_var_stack__), x)~n"))
;; As above, but when the number of registered variables never changes
@ -3091,11 +3099,11 @@
;; because they're blessed by the lifter]
(let ([e- (reverse e)]
[orig-num-calls (live-var-info-num-calls live-vars)])
(let loop ([e- e-][result null][live-vars live-vars])
(let loop ([e- e-][result null][live-vars live-vars][converted-sub? #f])
(cond
[(null? e-) (values result live-vars)]
[(ignored-stuff? e-)
(loop (cdr e-) (cons (car e-) result) live-vars)]
(loop (cdr e-) (cons (car e-) result) live-vars converted-sub?)]
[(eq? 'return (tok-n (car e-)))
;; Look forward in result to semicolon, and wrap that:
(let rloop ([result result][l null])
@ -3107,15 +3115,20 @@
(if (null? l)
(cons (make-tok RET_NOTHING (tok-line (car e-)) (tok-file (car e-)))
result)
(let ([has-empty-funccall? (let loop ([l l])
(let ([has-empty-funccall?
;; All calls must be empty calls, otherwise
;; the result might not depend on the empty call
;; (e.g., f() && empty(f()) )
(let loop ([l l][one? #f])
(cond
[(null? l) #f]
[(and (call? (car l))
(null? (call-live (car l))))
#t]
[(null? l) one?]
[(call? (car l))
(if (null? (call-live (car l)))
(loop (cdr l) #t)
#f)]
[(seq? (car l))
(or (loop (seq->list (seq-in (car l))))
(loop (cdr l)))]
(and (loop (seq->list (seq-in (car l))) one?)
(loop (cdr l) one?))]
[else #f]))])
(list* (make-tok (if has-empty-funccall?
RET_VALUE_EMPTY_START
@ -3129,7 +3142,8 @@
RET_VALUE_END)
(tok-line (car e-)) (tok-file (car e-)))
result)))
live-vars)]
live-vars
converted-sub?)]
[else (rloop (cdr result) (cons (car result) l))]))]
[(looks-like-call? e-)
;; Looks like a function call, maybe a cast:
@ -3141,7 +3155,8 @@
(convert-paren-interior (car e-) vars &-vars c++-class live-vars complain-not-in #f)])
(loop (cddr e-)
(list* (cadr e-) v result)
live-vars)))
live-vars
#t)))
(lambda ()
;; It's a function call; find the start
(let-values ([(args) (car e-)]
@ -3246,7 +3261,8 @@
(or (and (null? (cdr func))
(memq (tok-n (car func)) non-returning-functions))
(and (pair? rest-)
(eq? 'return (tok-n (car rest-)))))
(eq? 'return (tok-n (car rest-)))
(not converted-sub?)))
;; no arrays of pointers in this scope, or addresses of
;; local vars taken in the function.
(not (or (ormap (lambda (var)
@ -3316,11 +3332,15 @@
(+ (if non-returning? 1 0)
(live-var-info-num-noreturn-calls live-vars))
(or this-nonempty?
(live-var-info-nonempty-calls? live-vars)))))))))]
(live-var-info-nonempty-calls? live-vars)))
(or converted-sub?
(null? rest-)
(not (memq (tok-n (car rest-)) '(return else))))))))))]
[(eq? 'goto (tok-n (car e-)))
;; Goto - assume all vars are live
(loop (cdr e-) (cons (car e-) result)
(replace-live-vars live-vars vars))]
(replace-live-vars live-vars vars)
#t)]
[(eq? '= (tok-n (car e-)))
;; Check for assignments where the LHS can move due to
;; a function call on the RHS. [Note that special support
@ -3369,7 +3389,8 @@
(live-var-info-pushed-vars live-vars)
(live-var-info-num-calls live-vars)
(live-var-info-num-noreturn-calls live-vars)
(live-var-info-nonempty-calls? live-vars))))
(live-var-info-nonempty-calls? live-vars))
#t))
(begin
(when (and (not (null? assignee))
(or (if (brackets? (car assignee))
@ -3402,8 +3423,8 @@
(log-warning "[ASSIGN] ~a in ~a: suspicious assignment with a function call, LHS ends ~s."
(tok-line (car e-)) (tok-file (car e-))
(tok-n (cadr e-))))
(loop (cdr e-) (cons (car e-) result) live-vars)))))
(loop (cdr e-) (cons (car e-) result) live-vars))]
(loop (cdr e-) (cons (car e-) result) live-vars #t)))))
(loop (cdr e-) (cons (car e-) result) live-vars #t))]
[(and (braces? (car e-)) (not braces-are-aggregates?))
(let*-values ([(v) (car e-)]
;; do/while/for: we'll need a fixpoint for live-vars
@ -3490,7 +3511,8 @@
(seq-close v)
(list->seq e)))
result)
(filter-live-vars live-vars)))]
(filter-live-vars live-vars)
#t))]
[(seq? (car e-))
;; Do nested body.
;; For (v = new x, ...) parens, check for special conversion
@ -3505,7 +3527,7 @@
(and (brackets? (car e-))
"array access"))
#f)])
(loop (cdr e-) (cons v result) live-vars)))]
(loop (cdr e-) (cons v result) live-vars #t)))]
[(and (assq (tok-n (car e-)) vars)
(not (assq (tok-n (car e-)) (live-var-info-vars live-vars))))
;; Add a live variable:
@ -3513,7 +3535,8 @@
(cons (car e-) result)
(replace-live-vars live-vars
(cons (assq (tok-n (car e-)) vars)
(live-var-info-vars live-vars))))]
(live-var-info-vars live-vars)))
#t)]
[(and (memq (tok-n (car e-)) '(while do for))
(case (tok-n (car e-))
[(do)
@ -3525,7 +3548,7 @@
(braces? (cadr result))))]))
(log-error "[LOOP] ~a in ~a: while/do/for with body not in braces."
(tok-line (car e-)) (tok-file (car e-)))
(loop (cdr e-) (cons (car e-) result) live-vars)]
(loop (cdr e-) (cons (car e-) result) live-vars #t)]
[else
(when (and check-arith? (not memcpy?)
(positive? (live-var-info-num-calls live-vars)))
@ -3544,7 +3567,7 @@
(log-warning "[ARITH] ~a in ~a: suspicious arithmetic, LHS ends ~s."
(tok-line (car e-)) (tok-file (car e-))
(tok-n (cadr e-))))))
(loop (cdr e-) (cons (car e-) result) live-vars)]))))
(loop (cdr e-) (cons (car e-) result) live-vars converted-sub?)]))))
(define (convert-seq-interior v comma-sep? vars &-vars c++-class live-vars complain-not-in memcpy?)
(let ([e (seq->list (seq-in v))])