Skip to content

Commit

Permalink
fix === when encountering null pointer (#44749)
Browse files Browse the repository at this point in the history
  • Loading branch information
Moelf authored Mar 29, 2022
1 parent e2ea152 commit 1a7355b
Show file tree
Hide file tree
Showing 2 changed files with 27 additions and 8 deletions.
21 changes: 13 additions & 8 deletions src/builtins.c
Original file line number Diff line number Diff line change
Expand Up @@ -94,20 +94,25 @@ static int NOINLINE compare_fields(const jl_value_t *a, const jl_value_t *b, jl_
else {
jl_datatype_t *ft = (jl_datatype_t*)jl_field_type_concrete(dt, f);
if (jl_is_uniontype(ft)) {
uint8_t asel = ((uint8_t*)ao)[jl_field_size(dt, f) - 1];
uint8_t bsel = ((uint8_t*)bo)[jl_field_size(dt, f) - 1];
size_t idx = jl_field_size(dt, f) - 1;
uint8_t asel = ((uint8_t*)ao)[idx];
uint8_t bsel = ((uint8_t*)bo)[idx];
if (asel != bsel)
return 0;
ft = (jl_datatype_t*)jl_nth_union_component((jl_value_t*)ft, asel);
}
else if (ft->layout->first_ptr >= 0) {
// If the field is a inline immutable that can be can be undef
// we need to check to check for undef first since undef struct
// If the field is a inline immutable that can be undef
// we need to check for undef first since undef struct
// may have fields that are different but should still be treated as equal.
jl_value_t *ptra = ((jl_value_t**)ao)[ft->layout->first_ptr];
jl_value_t *ptrb = ((jl_value_t**)bo)[ft->layout->first_ptr];
if (ptra == NULL && ptrb == NULL) {
return 1;
int32_t idx = ft->layout->first_ptr;
jl_value_t *ptra = ((jl_value_t**)ao)[idx];
jl_value_t *ptrb = ((jl_value_t**)bo)[idx];
if ((ptra == NULL) != (ptrb == NULL)) {
return 0;
}
else if (ptra == NULL) { // implies ptrb == NULL
continue; // skip this field (it is #undef)
}
}
if (!ft->layout->haspadding) {
Expand Down
14 changes: 14 additions & 0 deletions test/core.jl
Original file line number Diff line number Diff line change
Expand Up @@ -92,6 +92,20 @@ let abcd = ABCDconst(1, 2, 3, 4)
@test (1, 2, "not constant", 4) === (abcd.a, abcd.b, abcd.c, abcd.d)
end

# test `===` handling null pointer in struct #44712
struct N44712
a::Some{Any}
b::Int
N44712() = new()
end
let a = Int[0, 1], b = Int[0, 2]
GC.@preserve a b begin
@test unsafe_load(Ptr{N44712}(pointer(a))) !== unsafe_load(Ptr{N44712}(pointer(b)))
end
end

# another possible issue in #44712
@test (("", 0),) !== (("", 1),)

f47(x::Vector{Vector{T}}) where {T} = 0
@test_throws MethodError f47(Vector{Vector}())
Expand Down

0 comments on commit 1a7355b

Please sign in to comment.