Skip to content

Commit

Permalink
Migrate depwarn to new logging infrastructure
Browse files Browse the repository at this point in the history
* 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
  • Loading branch information
c42f committed Sep 30, 2017
1 parent 76300fa commit 2482202
Show file tree
Hide file tree
Showing 6 changed files with 48 additions and 31 deletions.
42 changes: 26 additions & 16 deletions base/deprecated.jl
Original file line number Diff line number Diff line change
Expand Up @@ -64,35 +64,45 @@ 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,))
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)
Expand All @@ -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)
Expand Down
2 changes: 1 addition & 1 deletion base/options.jl
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
2 changes: 1 addition & 1 deletion src/ast.c
Original file line number Diff line number Diff line change
Expand Up @@ -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);
Expand Down
10 changes: 5 additions & 5 deletions src/jloptions.c
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down Expand Up @@ -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
Expand Down Expand Up @@ -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"))
Expand Down
15 changes: 11 additions & 4 deletions src/julia.h
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down Expand Up @@ -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
Expand Down
8 changes: 4 additions & 4 deletions src/module.c
Original file line number Diff line number Diff line change
Expand Up @@ -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) {
Expand Down Expand Up @@ -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),
Expand Down

0 comments on commit 2482202

Please sign in to comment.