mirror of
https://git.savannah.gnu.org/git/guile.git
synced 2025-04-30 03:40:34 +02:00
Add -Wmacro-use-before-definition
* module/ice-9/boot-9.scm (%auto-compilation-options): * am/guilec (GUILE_WARNINGS): Add -Wmacro-use-before-definition. * module/language/tree-il/analyze.scm (unbound-variable-analysis): Use match-lambda. (<macro-use-info>, macro-use-before-definition-analysis): New analysis. * module/system/base/message.scm (%warning-types): Add macro-use-before-definition warning type. * module/language/tree-il/compile-cps.scm (%warning-passes): Add support for macro-use-before-definition.
This commit is contained in:
parent
31c76f16c6
commit
3e719e0a35
5 changed files with 81 additions and 12 deletions
|
@ -1,7 +1,7 @@
|
||||||
# -*- makefile -*-
|
# -*- makefile -*-
|
||||||
GOBJECTS = $(SOURCES:%.scm=%.go) $(ELISP_SOURCES:%.el=%.go)
|
GOBJECTS = $(SOURCES:%.scm=%.go) $(ELISP_SOURCES:%.el=%.go)
|
||||||
|
|
||||||
GUILE_WARNINGS = -Wunbound-variable -Warity-mismatch -Wformat
|
GUILE_WARNINGS = -Wunbound-variable -Wmacro-use-before-definition -Warity-mismatch -Wformat
|
||||||
|
|
||||||
moddir = $(pkgdatadir)/$(GUILE_EFFECTIVE_VERSION)/$(modpath)
|
moddir = $(pkgdatadir)/$(GUILE_EFFECTIVE_VERSION)/$(modpath)
|
||||||
nobase_mod_DATA = $(SOURCES) $(ELISP_SOURCES) $(NOCOMP_SOURCES)
|
nobase_mod_DATA = $(SOURCES) $(ELISP_SOURCES) $(NOCOMP_SOURCES)
|
||||||
|
|
|
@ -3679,8 +3679,8 @@ but it fails to load."
|
||||||
|
|
||||||
(define %auto-compilation-options
|
(define %auto-compilation-options
|
||||||
;; Default `compile-file' option when auto-compiling.
|
;; Default `compile-file' option when auto-compiling.
|
||||||
'(#:warnings (unbound-variable arity-mismatch format
|
'(#:warnings (unbound-variable macro-use-before-definition arity-mismatch
|
||||||
duplicate-case-datum bad-case-datum)))
|
format duplicate-case-datum bad-case-datum)))
|
||||||
|
|
||||||
(define* (load-in-vicinity dir file-name #:optional reader)
|
(define* (load-in-vicinity dir file-name #:optional reader)
|
||||||
"Load source file FILE-NAME in vicinity of directory DIR. Use a
|
"Load source file FILE-NAME in vicinity of directory DIR. Use a
|
||||||
|
|
|
@ -35,6 +35,7 @@
|
||||||
unused-variable-analysis
|
unused-variable-analysis
|
||||||
unused-toplevel-analysis
|
unused-toplevel-analysis
|
||||||
unbound-variable-analysis
|
unbound-variable-analysis
|
||||||
|
macro-use-before-definition-analysis
|
||||||
arity-analysis
|
arity-analysis
|
||||||
format-analysis))
|
format-analysis))
|
||||||
|
|
||||||
|
@ -895,14 +896,75 @@ given `tree-il' element."
|
||||||
|
|
||||||
(lambda (toplevel env)
|
(lambda (toplevel env)
|
||||||
;; Post-process the result.
|
;; Post-process the result.
|
||||||
(vlist-for-each (lambda (name+loc)
|
(vlist-for-each (match-lambda
|
||||||
(let ((name (car name+loc))
|
((name . loc)
|
||||||
(loc (cdr name+loc)))
|
(warning 'unbound-variable loc name)))
|
||||||
(warning 'unbound-variable loc name)))
|
|
||||||
(vlist-reverse (toplevel-info-refs toplevel))))
|
(vlist-reverse (toplevel-info-refs toplevel))))
|
||||||
|
|
||||||
(make-toplevel-info vlist-null vlist-null)))
|
(make-toplevel-info vlist-null vlist-null)))
|
||||||
|
|
||||||
|
|
||||||
|
;;;
|
||||||
|
;;; Macro use-before-definition analysis.
|
||||||
|
;;;
|
||||||
|
|
||||||
|
;; <macro-use-info> records are used during tree traversal in search of
|
||||||
|
;; possibly uses of macros before they are defined. They contain a list
|
||||||
|
;; of references to top-level variables, and a list of the top-level
|
||||||
|
;; macro definitions that have been encountered. Any definition which
|
||||||
|
;; is a macro should in theory be expanded out already; if that's not
|
||||||
|
;; the case, the program likely has a bug.
|
||||||
|
(define-record-type <macro-use-info>
|
||||||
|
(make-macro-use-info uses defs)
|
||||||
|
macro-use-info?
|
||||||
|
(uses macro-use-info-uses) ;; ((VARIABLE-NAME . LOCATION) ...)
|
||||||
|
(defs macro-use-info-defs)) ;; ((VARIABLE-NAME . LOCATION) ...)
|
||||||
|
|
||||||
|
(define macro-use-before-definition-analysis
|
||||||
|
;; Report possibly unbound variables in the given tree.
|
||||||
|
(make-tree-analysis
|
||||||
|
(lambda (x info env locs)
|
||||||
|
;; Going down into X.
|
||||||
|
(define (nearest-loc src)
|
||||||
|
(or src (find pair? locs)))
|
||||||
|
(define (add-use name src)
|
||||||
|
(match info
|
||||||
|
(($ <macro-use-info> uses defs)
|
||||||
|
(make-macro-use-info (vhash-consq name src uses) defs))))
|
||||||
|
(define (add-def name src)
|
||||||
|
(match info
|
||||||
|
(($ <macro-use-info> uses defs)
|
||||||
|
(make-macro-use-info uses (vhash-consq name src defs)))))
|
||||||
|
(define (macro? x)
|
||||||
|
(match x
|
||||||
|
(($ <primcall> _ 'make-syntax-transformer) #t)
|
||||||
|
(_ #f)))
|
||||||
|
(match x
|
||||||
|
(($ <toplevel-ref> src name)
|
||||||
|
(add-use name (nearest-loc src)))
|
||||||
|
(($ <toplevel-set> src name)
|
||||||
|
(add-use name (nearest-loc src)))
|
||||||
|
(($ <toplevel-define> src name (? macro?))
|
||||||
|
(add-def name (nearest-loc src)))
|
||||||
|
(_ info)))
|
||||||
|
|
||||||
|
(lambda (x info env locs)
|
||||||
|
;; Leaving X's scope.
|
||||||
|
info)
|
||||||
|
|
||||||
|
(lambda (info env)
|
||||||
|
;; Post-process the result.
|
||||||
|
(match info
|
||||||
|
(($ <macro-use-info> uses defs)
|
||||||
|
(vlist-for-each
|
||||||
|
(match-lambda
|
||||||
|
((name . use-loc)
|
||||||
|
(when (vhash-assq name defs)
|
||||||
|
(warning 'macro-use-before-definition use-loc name))))
|
||||||
|
(vlist-reverse (macro-use-info-uses info))))))
|
||||||
|
|
||||||
|
(make-macro-use-info vlist-null vlist-null)))
|
||||||
|
|
||||||
|
|
||||||
;;;
|
;;;
|
||||||
;;; Arity analysis.
|
;;; Arity analysis.
|
||||||
|
|
|
@ -955,11 +955,12 @@ integer."
|
||||||
(define *comp-module* (make-fluid))
|
(define *comp-module* (make-fluid))
|
||||||
|
|
||||||
(define %warning-passes
|
(define %warning-passes
|
||||||
`((unused-variable . ,unused-variable-analysis)
|
`((unused-variable . ,unused-variable-analysis)
|
||||||
(unused-toplevel . ,unused-toplevel-analysis)
|
(unused-toplevel . ,unused-toplevel-analysis)
|
||||||
(unbound-variable . ,unbound-variable-analysis)
|
(unbound-variable . ,unbound-variable-analysis)
|
||||||
(arity-mismatch . ,arity-analysis)
|
(macro-use-before-definition . ,macro-use-before-definition-analysis)
|
||||||
(format . ,format-analysis)))
|
(arity-mismatch . ,arity-analysis)
|
||||||
|
(format . ,format-analysis)))
|
||||||
|
|
||||||
(define (optimize-tree-il x e opts)
|
(define (optimize-tree-il x e opts)
|
||||||
(define warnings
|
(define warnings
|
||||||
|
|
|
@ -115,6 +115,12 @@
|
||||||
(emit port "~A: warning: possibly unbound variable `~A'~%"
|
(emit port "~A: warning: possibly unbound variable `~A'~%"
|
||||||
loc name)))
|
loc name)))
|
||||||
|
|
||||||
|
(macro-use-before-definition
|
||||||
|
"report possibly mis-use of macros before they are defined"
|
||||||
|
,(lambda (port loc name)
|
||||||
|
(emit port "~A: warning: macro `~A' used before definition~%"
|
||||||
|
loc name)))
|
||||||
|
|
||||||
(arity-mismatch
|
(arity-mismatch
|
||||||
"report procedure arity mismatches (wrong number of arguments)"
|
"report procedure arity mismatches (wrong number of arguments)"
|
||||||
,(lambda (port loc name certain?)
|
,(lambda (port loc name certain?)
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue