MemSet() must not cast its pointer argument to int32* until after it has
authorTom Lane <[email protected]>
Mon, 18 Jul 2005 15:54:30 +0000 (15:54 +0000)
committerTom Lane <[email protected]>
Mon, 18 Jul 2005 15:54:30 +0000 (15:54 +0000)
checked that the pointer is actually word-aligned.  Casting a non-aligned
pointer to int32* is technically illegal per the C spec, and some recent
versions of gcc actually generate bad code for the memset() when given
such a pointer.  Per report from Andrew Morrow.

src/include/c.h

index 906000b74b333b045aa7438b4efdb2e3999c89af..660b7164c468d83b15880e0365ccb40f3874c634 100644 (file)
@@ -582,21 +582,22 @@ typedef NameData *Name;
 #define MemSet(start, val, len) \
        do \
        { \
-               int32 * _start = (int32 *) (start); \
+               void   *_vstart = (void *) (start); \
                int             _val = (val); \
                Size    _len = (len); \
 \
-               if ((((long) _start) & INT_ALIGN_MASK) == 0 && \
+               if ((((long) _vstart) & INT_ALIGN_MASK) == 0 && \
                        (_len & INT_ALIGN_MASK) == 0 && \
                        _val == 0 && \
                        _len <= MEMSET_LOOP_LIMIT) \
                { \
-                       int32 * _stop = (int32 *) ((char *) _start + _len); \
+                       int32 *_start = (int32 *) _vstart; \
+                       int32 *_stop = (int32 *) ((char *) _start + _len); \
                        while (_start < _stop) \
                                *_start++ = 0; \
                } \
                else \
-                       memset((char *) _start, _val, _len); \
+                       memset(_vstart, _val, _len); \
        } while (0)
 
 #define MEMSET_LOOP_LIMIT  1024