Skip to content

Commit 2c8d0b4

Browse files
Moelfstaticfloat
authored andcommitted
fix === when encountering null pointer (#44749)
(cherry picked from commit 1a7355b)
1 parent e5a9f55 commit 2c8d0b4

File tree

2 files changed

+28
-8
lines changed

2 files changed

+28
-8
lines changed

src/builtins.c

Lines changed: 13 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -96,20 +96,25 @@ static int NOINLINE compare_fields(jl_value_t *a, jl_value_t *b, jl_datatype_t *
9696
else {
9797
jl_datatype_t *ft = (jl_datatype_t*)jl_field_type_concrete(dt, f);
9898
if (jl_is_uniontype(ft)) {
99-
uint8_t asel = ((uint8_t*)ao)[jl_field_size(dt, f) - 1];
100-
uint8_t bsel = ((uint8_t*)bo)[jl_field_size(dt, f) - 1];
99+
size_t idx = jl_field_size(dt, f) - 1;
100+
uint8_t asel = ((uint8_t*)ao)[idx];
101+
uint8_t bsel = ((uint8_t*)bo)[idx];
101102
if (asel != bsel)
102103
return 0;
103104
ft = (jl_datatype_t*)jl_nth_union_component((jl_value_t*)ft, asel);
104105
}
105106
else if (ft->layout->first_ptr >= 0) {
106-
// If the field is a inline immutable that can be can be undef
107-
// we need to check to check for undef first since undef struct
107+
// If the field is a inline immutable that can be undef
108+
// we need to check for undef first since undef struct
108109
// may have fields that are different but should still be treated as equal.
109-
jl_value_t *ptra = ((jl_value_t**)ao)[ft->layout->first_ptr];
110-
jl_value_t *ptrb = ((jl_value_t**)bo)[ft->layout->first_ptr];
111-
if (ptra == NULL && ptrb == NULL) {
112-
return 1;
110+
int32_t idx = ft->layout->first_ptr;
111+
jl_value_t *ptra = ((jl_value_t**)ao)[idx];
112+
jl_value_t *ptrb = ((jl_value_t**)bo)[idx];
113+
if ((ptra == NULL) != (ptrb == NULL)) {
114+
return 0;
115+
}
116+
else if (ptra == NULL) { // implies ptrb == NULL
117+
continue; // skip this field (it is #undef)
113118
}
114119
}
115120
if (!ft->layout->haspadding) {

test/core.jl

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,21 @@ const Bottom = Union{}
99
# For curmod_*
1010
include("testenv.jl")
1111

12+
# test `===` handling null pointer in struct #44712
13+
struct N44712
14+
a::Some{Any}
15+
b::Int
16+
N44712() = new()
17+
end
18+
let a = Int[0, 1], b = Int[0, 2]
19+
GC.@preserve a b begin
20+
@test unsafe_load(Ptr{N44712}(pointer(a))) !== unsafe_load(Ptr{N44712}(pointer(b)))
21+
end
22+
end
23+
24+
# another possible issue in #44712
25+
@test (("", 0),) !== (("", 1),)
26+
1227
f47(x::Vector{Vector{T}}) where {T} = 0
1328
@test_throws MethodError f47(Vector{Vector}())
1429
@test f47(Vector{Vector{Int}}()) == 0

0 commit comments

Comments
 (0)