]> git.ipfire.org Git - thirdparty/gnulib.git/commitdiff
obstack: avoid undefined pointer comparison
authorPaul Eggert <eggert@cs.ucla.edu>
Wed, 7 May 2025 19:03:29 +0000 (12:03 -0700)
committerPaul Eggert <eggert@cs.ucla.edu>
Wed, 7 May 2025 19:04:30 +0000 (12:04 -0700)
* lib/obstack.in.h (_OBSTACK_CPTR): New macro.
(obstack_free): Use it instead of comparing pointers directly,
when the pointers might not point into the same object.

ChangeLog
lib/obstack.in.h

index dc81c8c72614ab6a916a7105a5aedd82ce22ae47..e63d92728a6d5bd1cda164a4c1525b46719c782e 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,5 +1,10 @@
 2025-05-07  Paul Eggert  <eggert@cs.ucla.edu>
 
+       obstack: avoid undefined pointer comparison
+       * lib/obstack.in.h (_OBSTACK_CPTR): New macro.
+       (obstack_free): Use it instead of comparing pointers directly,
+       when the pointers might not point into the same object.
+
        obstack: check def before use in macros
        * lib/obstack.in.h (__attribute_noreturn__, __extension__):
        Be more careful about checking whether a macro is defined before
index 7d2327977ec125b509b4d6ac705dec619c57310f..4b133c32cce919154fd7d4f46bc89d21fce37d47 100644 (file)
 # endif
 #endif
 
+/* A type suitable for comparing pointers regardless of whether they
+   point into the same object, e.g., (_OBSTACK_CPTR) p < (_OBSTACK_CPTR) q.
+   If possible, use uintptr_t to avoid undefined behavior and pacify
+   sanitizers.  Otherwise, use a pointer directly and hope for the best.  */
+#ifdef _OBSTACK_UINTPTR_TYPE
+typedef _OBSTACK_UINTPTR_TYPE _OBSTACK_CPTR;
+#else
+typedef char *_OBSTACK_CPTR;
+#endif
+
 /* These macros highlight the places where this implementation
    is different from the one in GNU libc.  */
 #if defined __GL_GNULIB_HEADER
@@ -478,7 +488,8 @@ extern int obstack_exit_failure;
   __extension__                                                                      \
     ({ struct obstack *__o = (OBSTACK);                                              \
        void *__obj = (void *) (OBJ);                                         \
-       if (__obj > (void *) __o->chunk && __obj < (void *) __o->chunk_limit)  \
+       if ((_OBSTACK_CPTR) __o->chunk < (_OBSTACK_CPTR) __obj                \
+           && (_OBSTACK_CPTR) __obj < (_OBSTACK_CPTR) __o->chunk_limit)              \
          __o->next_free = __o->object_base = (char *) __obj;                 \
        else                                                                  \
          __obstack_free (__o, __obj); })
@@ -579,8 +590,8 @@ extern int obstack_exit_failure;
 
 # define obstack_free(h, obj)                                                \
   ((h)->temp.tempptr = (void *) (obj),                                       \
-   (((h)->temp.tempptr > (void *) (h)->chunk                                 \
-     && (h)->temp.tempptr < (void *) (h)->chunk_limit)                       \
+   (((_OBSTACK_CPTR) (h)->chunk < (OBSTACK_CPTR) (h)->temp.tempptr           \
+     && (_OBSTACK_CPTR) (h)->temp.tempptr < (_OBSTACK_CPTR) (h)->chunk_limit) \
     ? (void) ((h)->next_free = (h)->object_base = (char *) (h)->temp.tempptr) \
     : __obstack_free ((h), (h)->temp.tempptr)))