Skip to content

Commit

Permalink
Emit the correct kind of error for an eliminated getfield
Browse files Browse the repository at this point in the history
I meant to do this when I implemented the codegen, but looks like
that never happened. We use a special symbol (##getfield##) to
indicate that an error is an UndefRefError rather than an
UndefVarError. Otherwise however, we use the same machinery
as undef var errors.
  • Loading branch information
Keno committed Jun 30, 2018
1 parent 792cd7b commit 4592816
Show file tree
Hide file tree
Showing 6 changed files with 21 additions and 6 deletions.
4 changes: 2 additions & 2 deletions base/compiler/ssair/passes.jl
Original file line number Diff line number Diff line change
Expand Up @@ -662,9 +662,9 @@ function getfield_elim_pass!(ir::IRCode, domtree)
# Insert the undef check if necessary
if any_undef && !is_unchecked
if val === nothing
insert_node!(compact, SSAValue(idx), Nothing, Expr(:throw_undef_if_not, :getfield, false))
insert_node!(compact, SSAValue(idx), Nothing, Expr(:throw_undef_if_not, Symbol("##getfield##"), false))
else
insert_node!(compact, SSAValue(idx), Nothing, Expr(:undefcheck, :getfield, val.x))
insert_node!(compact, SSAValue(idx), Nothing, Expr(:undefcheck, Symbol("##getfield##"), val.x))
end
else
@assert val !== nothing
Expand Down
3 changes: 2 additions & 1 deletion src/ast.c
Original file line number Diff line number Diff line change
Expand Up @@ -67,7 +67,7 @@ jl_sym_t *macrocall_sym; jl_sym_t *colon_sym;
jl_sym_t *hygienicscope_sym;
jl_sym_t *escape_sym;
jl_sym_t *gc_preserve_begin_sym; jl_sym_t *gc_preserve_end_sym;
jl_sym_t *throw_undef_if_not_sym;
jl_sym_t *throw_undef_if_not_sym; jl_sym_t *getfield_undefref_sym;

static uint8_t flisp_system_image[] = {
#include <julia_flisp.boot.inc>
Expand Down Expand Up @@ -392,6 +392,7 @@ void jl_init_frontend(void)
generated_sym = jl_symbol("generated");
generated_only_sym = jl_symbol("generated_only");
throw_undef_if_not_sym = jl_symbol("throw_undef_if_not");
getfield_undefref_sym = jl_symbol("##getfield##");
do_sym = jl_symbol("do");
}

Expand Down
10 changes: 8 additions & 2 deletions src/codegen.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -3928,8 +3928,14 @@ static jl_cgval_t emit_expr(jl_codectx_t &ctx, jl_value_t *expr, ssize_t ssaval)
return emit_isdefined(ctx, args[0]);
}
else if (head == throw_undef_if_not_sym) {
Value *cond = emit_unbox(ctx, T_int8, emit_expr(ctx, args[1]), (jl_value_t*)jl_bool_type);
undef_var_error_ifnot(ctx, ctx.builder.CreateTrunc(cond, T_int1), (jl_sym_t*)args[0]);
jl_sym_t *var = (jl_sym_t*)args[0];
Value *cond = ctx.builder.CreateTrunc(emit_unbox(ctx, T_int8, emit_expr(ctx, args[1]), (jl_value_t*)jl_bool_type), T_int1);
if (var == getfield_undefref_sym) {
raise_exception_unless(ctx, cond,
literal_pointer_val(ctx, jl_undefref_exception));
} else {
undef_var_error_ifnot(ctx, cond, var);
}
return ghostValue(jl_void_type);
}
else if (head == invoke_sym) {
Expand Down
6 changes: 5 additions & 1 deletion src/interpreter.c
Original file line number Diff line number Diff line change
Expand Up @@ -466,7 +466,11 @@ SECT_INTERP static jl_value_t *eval_value(jl_value_t *e, interpreter_state *s)
jl_value_t *cond = eval_value(args[1], s);
assert(jl_is_bool(cond));
if (cond == jl_false) {
jl_undefined_var_error((jl_sym_t*)args[0]);
jl_sym_t *var = (jl_sym_t*)args[0];
if (var == getfield_undefref_sym)
jl_throw(jl_undefref_exception);
else
jl_undefined_var_error(var);
}
return jl_nothing;
}
Expand Down
1 change: 1 addition & 0 deletions src/julia_internal.h
Original file line number Diff line number Diff line change
Expand Up @@ -973,6 +973,7 @@ extern jl_sym_t *gc_preserve_begin_sym; extern jl_sym_t *gc_preserve_end_sym;
extern jl_sym_t *generated_sym;
extern jl_sym_t *generated_only_sym;
extern jl_sym_t *throw_undef_if_not_sym;
extern jl_sym_t *getfield_undefref_sym;

struct _jl_sysimg_fptrs_t;

Expand Down
3 changes: 3 additions & 0 deletions test/core.jl
Original file line number Diff line number Diff line change
Expand Up @@ -6267,3 +6267,6 @@ get27770(n::Nullable27770, v::Handle27770) = n.hasvalue ? n.value : v

foo27770() = get27770(Nullable27770(), Handle27770())
@test foo27770().ptr == Ptr{Cvoid}(UInt(0xfeedface))

bar27770() = Nullable27770().value
@test_throws UndefRefError bar27770()

0 comments on commit 4592816

Please sign in to comment.