[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
Bogus (intptr_t) casts
From: |
Martin D Kealey |
Subject: |
Bogus (intptr_t) casts |
Date: |
Thu, 1 Aug 2024 18:12:09 +1000 |
Hi Chet
According to ISO/IEC 9899-2017, §6.3.2.3(3):
*“An integer constant expression with the value 0, or such an expression
cast to type void * , is called a null pointer constant. If a null pointer
constant is converted to a pointer type, the resulting pointer, called a
null pointer, is guaranteed to compare unequal to a pointer to any object
or function.”*
These constraints do *not* imply that NULL has to be implemented as
all-zero-bits, and there have been real compilers which implemented NULL as
all-one-bits values (mainly to ensure a dereference would result in a
misaligned word access, without requiring extra hardware to trap on the 0
address).
In addition, conversion between pointers and integers is permitted by
§6.3.2.3(5) & (6), but is implementation defined (and may be undefined).
*An integer may be converted to any pointer type. Except as previously
specified, the result is imple-mentation-defined, might not be correctly
aligned, might not point to an entity of the referencedtype, and might be a
trap representation.Any pointer type may be converted to an integer type.
Except as previously specified, the resultis implementation-defined. If the
result cannot be represented in the integer type, the behavior isundefined.
The result need not be in the range of values of any integer type.*
§7.20.14(1) requires the optional types intptr_t and uintptr_t, if they
exist, to provide round-tripping from and back to void* pointer values,
including NULL (meaning that the last sentence of §6.3.2.3(6) above would
not apply):
*The following type designates a signed integer type with the property that
any valid pointer to voidcan be converted to this type, then converted back
to pointer to void , and the result will compareequal to the original
pointer:*
>
> *intptr_t*
>
*The following type designates an unsigned integer type with the property
that any valid pointerto void can be converted to this type, then converted
back to pointer to void , and the result willcompare equal to the original
pointer:*
>
> *uintptr_t*
*These types are optional.*
It follows that the following assertions are allowed to fail:
intptr_t i = 0;
assert(*(void*)i == (void*)0*);
void *p = 0;
assert(*(intptr_t)p == 0*);
Accordingly I provide the following patch:
diff --git a/*subst.c* b/subst.c
index 37e0bfa7..140a3a92 100644
--- a/subst.c
+++ b/subst.c
@@ -6875,7 +6875,7 @@ uw_restore_pipeline (void *discard)
static void
uw_restore_errexit (void *eflag)
{
*- change_flag ('e', (intptr_t) eflag ? FLAG_ON : FLAG_OFF);+ change_flag
('e', eflag ? FLAG_ON : FLAG_OFF);*
set_shellopts ();
}
diff --git a/*variables.c* b/variables.c
index cd336c85..d44453fe 100644
--- a/variables.c
+++ b/variables.c
@@ -5444,7 +5444,7 @@ pop_scope (void *is_special)
FREE (vcxt->name);
if (vcxt->table)
{
*- if ((intptr_t) is_special)+ if (is_special)*
hash_flush (vcxt->table, push_builtin_var);
else
hash_flush (vcxt->table, push_exported_var);
-Martin
- Bogus (intptr_t) casts,
Martin D Kealey <=