Skip to content

Commit

Permalink
fix #33370, avoid collisions between gensyms and anon function names (#…
Browse files Browse the repository at this point in the history
…33426)

(cherry picked from commit 888d32a)
  • Loading branch information
JeffBezanson authored and KristofferC committed Oct 3, 2019
1 parent 889d7e7 commit 1b4b7ef
Show file tree
Hide file tree
Showing 3 changed files with 41 additions and 5 deletions.
19 changes: 17 additions & 2 deletions src/datatype.c
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,11 @@ extern "C" {

// allocating TypeNames -----------------------------------------------------------

static int is10digit(char c) JL_NOTSAFEPOINT
{
return (c >= '0' && c <= '9');
}

jl_sym_t *jl_demangle_typename(jl_sym_t *s) JL_NOTSAFEPOINT
{
char *n = jl_symbol_name(s);
Expand All @@ -29,7 +34,9 @@ jl_sym_t *jl_demangle_typename(jl_sym_t *s) JL_NOTSAFEPOINT
if (end == n || end == n+1)
len = strlen(n) - 1;
else
len = (end-n) - 1;
len = (end-n) - 1; // extract `f` from `#f#...`
if (is10digit(n[1]))
return jl_symbol_n(n, len+1);
return jl_symbol_n(&n[1], len);
}

Expand Down Expand Up @@ -446,6 +453,14 @@ void jl_compute_field_offsets(jl_datatype_t *st)
jl_errorf("type %s has field offset %d that exceeds the page size", jl_symbol_name(st->name->name), descsz);
}

static int is_anonfn_typename(char *name)
{
if (name[0] != '#')
return 0;
char *other = strrchr(name, '#');
return (name[1] != '#' && other > &name[1] && is10digit(other[1]));
}

JL_DLLEXPORT jl_datatype_t *jl_new_datatype(
jl_sym_t *name,
jl_module_t *module,
Expand Down Expand Up @@ -485,7 +500,7 @@ JL_DLLEXPORT jl_datatype_t *jl_new_datatype(
}
else {
tn = jl_new_typename_in((jl_sym_t*)name, module);
if (super == jl_function_type || super == jl_builtin_type || jl_symbol_name(name)[0] == '#') {
if (super == jl_function_type || super == jl_builtin_type || is_anonfn_typename(jl_symbol_name(name))) {
// Callable objects (including compiler-generated closures) get independent method tables
// as an optimization
tn->mt = jl_new_method_table(name, module);
Expand Down
13 changes: 10 additions & 3 deletions src/julia-syntax.scm
Original file line number Diff line number Diff line change
Expand Up @@ -432,8 +432,12 @@
sparams)))
(let ((kw (gensy))
(rkw (if (null? restkw) (make-ssavalue) (symbol (string (car restkw) "..."))))
(mangled (symbol (string "#" (if name (undot-name name) 'call) "#"
(string (current-julia-module-counter))))))
(mangled (let ((und (and name (undot-name name))))
(symbol (string (if (and name (= (string.char (string name) 0) #\#))
""
"#")
(or und '_) "#"
(string (current-julia-module-counter)))))))
;; this is a hack: nest these statements inside a call so they get closure
;; converted together, allowing all needed types to be defined before any methods.
`(call (core ifelse) false false (block
Expand Down Expand Up @@ -3267,7 +3271,10 @@ f(x) = yt(x)
(let* ((exists (get defined name #f))
(type-name (or (get namemap name #f)
(and name
(symbol (string "#" name "#" (current-julia-module-counter))))))
(symbol (string (if (= (string.char (string name) 0) #\#)
""
"#")
name "#" (current-julia-module-counter))))))
(alldefs (expr-find-all
(lambda (ex) (and (length> ex 2) (eq? (car ex) 'method)
(not (eq? ex e))
Expand Down
14 changes: 14 additions & 0 deletions test/core.jl
Original file line number Diff line number Diff line change
Expand Up @@ -2404,6 +2404,20 @@ for f in (:(Core.arrayref), :((::typeof(Core.arrayref))), :((::Core.IntrinsicFun
@test_throws ErrorException("cannot add methods to a builtin function") @eval $f() = 1
end

# issue #33370
abstract type B33370 end

let n = gensym(), c(x) = B33370[x][1]()
@eval begin
struct $n <: B33370
end

function (::$n)()
end
end
@test c(eval(n)()) === nothing
end

# issue #8798
let
npy_typestrs = Dict("b1"=>Bool,
Expand Down

0 comments on commit 1b4b7ef

Please sign in to comment.