MemSet() must not cast its pointer argument to int32* until after it has

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.
This commit is contained in:
Tom Lane 2005-07-18 15:55:01 +00:00
parent 84e5ce7eb9
commit a55a75f02d

View File

@ -12,7 +12,7 @@
* Portions Copyright (c) 1996-2001, PostgreSQL Global Development Group
* Portions Copyright (c) 1994, Regents of the University of California
*
* $Id: c.h,v 1.114 2002/01/22 19:02:39 tgl Exp $
* $Id: c.h,v 1.114.2.1 2005/07/18 15:55:01 tgl Exp $
*
*-------------------------------------------------------------------------
*/
@ -560,21 +560,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 64