bug-bash
[Top][All Lists]
Advanced

[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


reply via email to

[Prev in Thread] Current Thread [Next in Thread]