mirror of
git://git.sv.gnu.org/emacs.git
synced 2026-04-27 08:43:40 -07:00
Explain how to call mps_root_create_table() safely (avoiding type punning). fix example for mps_root_create_table_masked(). use the recommended approach in qs.c.
Copied from Perforce Change: 185223 ServerID: perforce.ravenbrook.com
This commit is contained in:
parent
feaa22a74f
commit
6ef4b6e0c6
4 changed files with 36 additions and 9 deletions
|
|
@ -334,7 +334,6 @@ static void *go(void *p, size_t s)
|
|||
mps_fmt_t format;
|
||||
mps_chain_t chain;
|
||||
mps_addr_t base;
|
||||
mps_addr_t *addr;
|
||||
|
||||
testlib_unused(p);
|
||||
testlib_unused(s);
|
||||
|
|
@ -357,9 +356,7 @@ static void *go(void *p, size_t s)
|
|||
"RootCreateTable");
|
||||
|
||||
base = &activationStack;
|
||||
addr = base;
|
||||
die(mps_root_create_table(&actroot, arena, mps_rank_ambig(), 0,
|
||||
addr, sizeof(QSCell)/sizeof(mps_addr_t)),
|
||||
die(mps_root_create_table(&actroot, arena, mps_rank_ambig(), 0, base, 1),
|
||||
"RootCreateTable");
|
||||
|
||||
/* makes a random list */
|
||||
|
|
|
|||
|
|
@ -905,6 +905,10 @@ changes size::
|
|||
3. The order of operations at the end is important: the old root
|
||||
must be de-registered before its memory is freed.
|
||||
|
||||
4. When calling :c:func:`mps_root_create_table`, take care to
|
||||
avoid undefined behaviour due to :term:`type punning`. See the
|
||||
:ref:`warning <topic-root-type-pun>`.
|
||||
|
||||
.. topics::
|
||||
|
||||
:ref:`topic-root`.
|
||||
|
|
|
|||
|
|
@ -205,11 +205,11 @@ Instead, we recommend this approach::
|
|||
struct foo *fp;
|
||||
res = mps_alloc(&p, pool, sizeof(struct foo));
|
||||
if(res) /* handle error case */;
|
||||
fp = (struct foo *)p;
|
||||
fp = p;
|
||||
|
||||
This is portable because conversion from ``void *`` to any other
|
||||
:term:`object pointer` type is defined by :ref:`ISO/IEC 9899:1990
|
||||
<ISO90>` §6.3.2.3.1.
|
||||
This has defined behaviour because conversion from ``void *`` to any
|
||||
other :term:`object pointer` type is defined by :ref:`ISO/IEC
|
||||
9899:1990 <ISO90>` §6.3.2.3.1.
|
||||
|
||||
|
||||
.. index::
|
||||
|
|
|
|||
|
|
@ -514,6 +514,28 @@ Root interface
|
|||
The registered root description persists until it is destroyed by
|
||||
calling :c:func:`mps_root_destroy`.
|
||||
|
||||
.. _topic-root-type-pun:
|
||||
|
||||
.. warning::
|
||||
|
||||
The ``base`` argument has type ``mps_addr_t *`` (a typedef for
|
||||
``void **``) but the table of references most likely has some
|
||||
other pointer type, ``my_object *`` say. It is tempting to
|
||||
write::
|
||||
|
||||
mps_root_create_table(..., (mps_addr_t *)my_table, ...)
|
||||
|
||||
but this is :term:`type punning`, and its behaviour is not
|
||||
defined in ANSI/ISO Standard C. (GCC and Clang have a warning
|
||||
flag ``-Wstrict-aliasing`` which detects some errors of this
|
||||
form.)
|
||||
|
||||
To ensure well-defined behaviour, the pointer must be
|
||||
converted via ``void *`` (or via :c:type:`mps_addr_t`, which
|
||||
is a typedef for ``void *``), like this::
|
||||
|
||||
mps_addr_t base = my_table;
|
||||
mps_root_create_table(..., base, ...)
|
||||
|
||||
.. c:function:: mps_res_t mps_root_create_table_masked(mps_root_t *root_o, mps_arena_t arena, mps_rank_t rank, mps_rm_t rm, mps_addr_t *base, size_t count, mps_word_t mask)
|
||||
|
||||
|
|
@ -558,13 +580,17 @@ Root interface
|
|||
|
||||
mps_res_t res;
|
||||
mps_root_t root;
|
||||
mps_addr_t base = symtab;
|
||||
res = mps_root_create_table_masked(&root, arena,
|
||||
mps_rank_exact(),
|
||||
(mps_rm_t)0,
|
||||
symtab, symtab_size * 2,
|
||||
base, symtab_size * 2,
|
||||
(mps_word_t)TAG_MASK);
|
||||
if (res != MPS_RES_OK) errror("can't create symtab root");
|
||||
|
||||
.. warning::
|
||||
|
||||
See the warning for :c:func:`mps_root_create_table` above.
|
||||
|
||||
.. c:function:: void mps_root_destroy(mps_root_t root)
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue