From 248220215f7e28ddac6b5a1f09d26749f4cbdb98 Mon Sep 17 00:00:00 2001 From: Chris Foster Date: Thu, 14 Sep 2017 23:30:14 +1000 Subject: [PATCH] Migrate depwarn to new logging infrastructure * Forward depwarn() calls to new backend * Use caller frame pointer as message id. This makes initial first-pass deduplication of depwarns quite a lot faster. * Change --depwarn=error to --depwarn=throw for clarity * Introduce defines for log levels into julia.h --- base/deprecated.jl | 42 ++++++++++++++++++++++++++---------------- base/options.jl | 2 +- src/ast.c | 2 +- src/jloptions.c | 10 +++++----- src/julia.h | 15 +++++++++++---- src/module.c | 8 ++++---- 6 files changed, 48 insertions(+), 31 deletions(-) diff --git a/base/deprecated.jl b/base/deprecated.jl index 552d7f45d2343..e449269d76452 100644 --- a/base/deprecated.jl +++ b/base/deprecated.jl @@ -64,21 +64,27 @@ end function depwarn(msg, funcsym) opts = JLOptions() - if opts.depwarn > 0 - bt = backtrace() - _depwarn(msg, opts, bt, firstcaller(bt, funcsym)) - end - nothing -end -function _depwarn(msg, opts, bt, caller) - ln = Int(unsafe_load(cglobal(:jl_lineno, Cint))) - fn = unsafe_string(unsafe_load(cglobal(:jl_filename, Ptr{Cchar}))) - if opts.depwarn == 1 # raise a warning - warn(msg, once=(caller != StackTraces.UNKNOWN), key=(caller,fn,ln), bt=bt, - filename=fn, lineno=ln) - elseif opts.depwarn == 2 # raise an error + if opts.depwarn == typemax(Int32) throw(ErrorException(msg)) end + deplevel = Logging.LogLevel(opts.depwarn) + @logmsg( + deplevel, + msg, + _module=begin + bt = backtrace() + frame, caller = firstcaller(bt, funcsym) + # FIXME - The isnull handling isn't great here. + !isnull(caller.linfo) ? caller.linfo.value.def.module : Base + end, + _file=caller.file, + _line=caller.line, + _id=(frame,funcsym), + _group=:depwarn, + caller=caller, + max_log=1 + ) + nothing end firstcaller(bt::Array{Ptr{Void},1}, funcsym::Symbol) = firstcaller(bt, (funcsym,)) @@ -86,13 +92,17 @@ function firstcaller(bt::Array{Ptr{Void},1}, funcsyms) # Identify the calling line found = false lkup = StackTraces.UNKNOWN + found_frame = Ptr{Void}(0) for frame in bt lkups = StackTraces.lookup(frame) for outer lkup in lkups if lkup == StackTraces.UNKNOWN continue end - found && @goto found + if found + found_frame = frame + @goto found + end found = lkup.func in funcsyms # look for constructor type name if !found && !isnull(lkup.linfo) @@ -105,9 +115,9 @@ function firstcaller(bt::Array{Ptr{Void},1}, funcsyms) end end end - return StackTraces.UNKNOWN + return found_frame, StackTraces.UNKNOWN @label found - return lkup + return found_frame, lkup end deprecate(m::Module, s::Symbol, flag=1) = ccall(:jl_deprecate_binding, Void, (Any, Any, Cint), m, s, flag) diff --git a/base/options.jl b/base/options.jl index 432ca9e205d32..84f17b4a64645 100644 --- a/base/options.jl +++ b/base/options.jl @@ -21,7 +21,7 @@ struct JLOptions opt_level::Int8 debug_level::Int8 check_bounds::Int8 - depwarn::Int8 + depwarn::Int32 warn_overwrite::Int8 can_inline::Int8 polly::Int8 diff --git a/src/ast.c b/src/ast.c index 8b9117ff3b25c..716c1ddd8c22d 100644 --- a/src/ast.c +++ b/src/ast.c @@ -203,7 +203,7 @@ static void jl_init_ast_ctx(jl_ast_context_t *ast_ctx) ctx->module = NULL; // Enable / disable syntax deprecation warnings - if (jl_options.depwarn == JL_OPTIONS_DEPWARN_ERROR) + if (jl_options.depwarn == JL_OPTIONS_DEPWARN_THROW) jl_parse_deperror(fl_ctx, 1); else jl_parse_depwarn_(fl_ctx, (int)jl_options.depwarn); diff --git a/src/jloptions.c b/src/jloptions.c index 7bd9729eaaccc..e52851e398537 100644 --- a/src/jloptions.c +++ b/src/jloptions.c @@ -57,7 +57,7 @@ jl_options_t jl_options = { 0, // quiet 1, // debug_level [release build] #endif JL_OPTIONS_CHECK_BOUNDS_DEFAULT, // check_bounds - 1, // deprecation warning + JL_OPTIONS_DEPWARN_ON, // deprecation warning 0, // method overwrite warning 1, // can_inline JL_OPTIONS_POLLY_ON, // polly @@ -110,7 +110,7 @@ static const char opts[] = " --history-file={yes|no} Load or save history\n\n" // error and warning options - " --depwarn={yes|no|error} Enable or disable syntax and method deprecation warnings (\"error\" turns warnings into errors)\n" + " --depwarn={yes|no|throw} Enable or disable syntax and method deprecation warnings (\"throw\" turns warnings into exceptions)\n" " --warn-overwrite={yes|no} Enable or disable method overwrite warnings\n\n" // code generation options @@ -528,10 +528,10 @@ JL_DLLEXPORT void jl_parse_opts(int *argcp, char ***argvp) jl_options.depwarn = JL_OPTIONS_DEPWARN_ON; else if (!strcmp(optarg,"no")) jl_options.depwarn = JL_OPTIONS_DEPWARN_OFF; - else if (!strcmp(optarg,"error")) - jl_options.depwarn = JL_OPTIONS_DEPWARN_ERROR; + else if (!strcmp(optarg,"throw") || !strcmp(optarg,"error")) + jl_options.depwarn = JL_OPTIONS_DEPWARN_THROW; else - jl_errorf("julia: invalid argument to --depwarn={yes|no|error} (%s)", optarg); + jl_errorf("julia: invalid argument to --depwarn={yes|no|throw} (%s)", optarg); break; case opt_warn_overwrite: if (!strcmp(optarg,"yes")) diff --git a/src/julia.h b/src/julia.h index 30e2c26548c70..809ae2832694a 100644 --- a/src/julia.h +++ b/src/julia.h @@ -1694,7 +1694,7 @@ typedef struct { int8_t opt_level; int8_t debug_level; int8_t check_bounds; - int8_t depwarn; + int32_t depwarn; int8_t warn_overwrite; int8_t can_inline; int8_t polly; @@ -1752,9 +1752,16 @@ JL_DLLEXPORT int jl_generating_output(void); #define JL_OPTIONS_STARTUPFILE_ON 1 #define JL_OPTIONS_STARTUPFILE_OFF 2 -#define JL_OPTIONS_DEPWARN_OFF 0 -#define JL_OPTIONS_DEPWARN_ON 1 -#define JL_OPTIONS_DEPWARN_ERROR 2 +#define JL_LOGLEVEL_BELOWMIN INT32_MIN +#define JL_LOGLEVEL_DEBUG -1000 +#define JL_LOGLEVEL_INFO 0 +#define JL_LOGLEVEL_WARN 1000 +#define JL_LOGLEVEL_ERROR 2000 +#define JL_LOGLEVEL_ABOVEMAX INT32_MAX + +#define JL_OPTIONS_DEPWARN_OFF JL_LOGLEVEL_BELOWMIN +#define JL_OPTIONS_DEPWARN_ON JL_LOGLEVEL_WARN +#define JL_OPTIONS_DEPWARN_THROW JL_LOGLEVEL_ABOVEMAX #define JL_OPTIONS_WARN_OVERWRITE_OFF 0 #define JL_OPTIONS_WARN_OVERWRITE_ON 1 diff --git a/src/module.c b/src/module.c index 91514d1503454..7c3b2013b4d9d 100644 --- a/src/module.c +++ b/src/module.c @@ -510,8 +510,8 @@ void jl_binding_deprecation_warning(jl_binding_t *b) // Only print a warning for deprecated == 1 (renamed). // For deprecated == 2 (moved to a package) the binding is to a function // that throws an error, so we don't want to print a warning too. - if (b->deprecated == 1 && jl_options.depwarn) { - if (jl_options.depwarn != JL_OPTIONS_DEPWARN_ERROR) + if (b->deprecated == 1 && jl_options.depwarn != JL_OPTIONS_DEPWARN_OFF) { + if (jl_options.depwarn != JL_OPTIONS_DEPWARN_THROW) jl_printf(JL_STDERR, "WARNING: "); jl_binding_t *dep_message_binding = NULL; if (b->owner) { @@ -554,10 +554,10 @@ void jl_binding_deprecation_warning(jl_binding_t *b) } jl_printf(JL_STDERR, ".\n"); - if (jl_options.depwarn != JL_OPTIONS_DEPWARN_ERROR) + if (jl_options.depwarn != JL_OPTIONS_DEPWARN_THROW) jl_printf(JL_STDERR, " likely near %s:%d\n", jl_filename, jl_lineno); - if (jl_options.depwarn == JL_OPTIONS_DEPWARN_ERROR) { + if (jl_options.depwarn == JL_OPTIONS_DEPWARN_THROW) { if (b->owner) jl_errorf("deprecated binding: %s.%s", jl_symbol_name(b->owner->name),