Skip to content

Commit

Permalink
fix === when encountering null pointer (#44749)
Browse files Browse the repository at this point in the history
(cherry picked from commit 1a7355b)
  • Loading branch information
Moelf authored and staticfloat committed Dec 22, 2022
1 parent e5a9f55 commit 2c8d0b4
Show file tree
Hide file tree
Showing 2 changed files with 28 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 @@ -96,20 +96,25 @@ static int NOINLINE compare_fields(jl_value_t *a, jl_value_t *b, jl_datatype_t *
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
15 changes: 15 additions & 0 deletions test/core.jl
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,21 @@ const Bottom = Union{}
# For curmod_*
include("testenv.jl")

# 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}())
@test f47(Vector{Vector{Int}}()) == 0
Expand Down

0 comments on commit 2c8d0b4

Please sign in to comment.