Fix a bug in PR9742: in naked pointers mode, the code could

dereference a pointer before checking it is not a naked pointer.

Algo fix a debug macro changed in PR9742 which could potentially
modify its parameter. It turns out this is not a bug, but the macro
was still particularly dangerous.
master
Jacques-Henri Jourdan 2020-10-24 22:08:06 +02:00
parent f449d9b298
commit 0f64cc87b0
2 changed files with 14 additions and 13 deletions

View File

@ -145,9 +145,9 @@ OCaml 4.12.0
compaction algorithm and remove its dependence on the page table compaction algorithm and remove its dependence on the page table
(Damien Doligez, review by Jacques-Henri Jourdan and Xavier Leroy) (Damien Doligez, review by Jacques-Henri Jourdan and Xavier Leroy)
- #9742: Ephemerons are now compatible with infix pointers occurring - #9742, #9989: Ephemerons are now compatible with infix pointers occurring
when using mutually recursive functions. when using mutually recursive functions.
(Jacques-Henri Jourdan, review François Bobot) (Jacques-Henri Jourdan, review by François Bobot)
* #1128, #7503, #9036, #9722: EINTR-based signal handling. * #1128, #7503, #9036, #9722: EINTR-based signal handling.
When a signal arrives, avoid running its OCaml handler in the middle When a signal arrives, avoid running its OCaml handler in the middle

View File

@ -47,13 +47,14 @@ value caml_ephe_none = (value) &ephe_dummy;
}while(0) }while(0)
#ifdef DEBUG #ifdef DEBUG
#define CAMLassert_not_dead_value(v) do{ \ #define CAMLassert_not_dead_value(v) do{ \
if (caml_gc_phase == Phase_clean \ value __v = v; \
&& Is_block(v) \ if (caml_gc_phase == Phase_clean \
&& Is_in_heap (v)) { \ && Is_block(__v) \
if (Tag_val (v) == Infix_tag) v -= Infix_offset_val (v); \ && Is_in_heap (__v)) { \
CAMLassert ( !Is_white_val(v) ); \ if (Tag_val (__v) == Infix_tag) __v -= Infix_offset_val (__v); \
} \ CAMLassert ( !Is_white_val(__v) ); \
} \
}while(0) }while(0)
#else #else
#define CAMLassert_not_dead_value(v) #define CAMLassert_not_dead_value(v)
@ -72,13 +73,13 @@ Caml_inline int Is_Dead_during_clean(value x)
{ {
CAMLassert (x != caml_ephe_none); CAMLassert (x != caml_ephe_none);
CAMLassert (caml_gc_phase == Phase_clean); CAMLassert (caml_gc_phase == Phase_clean);
if (!Is_block(x)) return 0;
if (Tag_val(x) == Infix_tag) x -= Infix_offset_val(x);
#ifdef NO_NAKED_POINTERS #ifdef NO_NAKED_POINTERS
return Is_white_val(x) && !Is_young (x); if (!Is_block(x) || Is_young (x)) return 0;
#else #else
return Is_white_val(x) && Is_in_heap (x); if (!Is_block(x) || !Is_in_heap(x)) return 0;
#endif #endif
if (Tag_val(x) == Infix_tag) x -= Infix_offset_val(x);
return Is_white_val(x);
} }
/** The minor heap doesn't have to be marked, outside they should /** The minor heap doesn't have to be marked, outside they should
already be black already be black