From ac43da8466971553001e7105e03d514b72721814 Mon Sep 17 00:00:00 2001
From: Tom Lane <tgl@sss.pgh.pa.us>
Date: Mon, 18 Jul 2005 15:53:28 +0000
Subject: [PATCH] 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.

---
 src/include/c.h | 9 +++++----
 1 file changed, 5 insertions(+), 4 deletions(-)

diff --git a/src/include/c.h b/src/include/c.h
index 4567e2102d5..7752e1ae02d 100644
--- a/src/include/c.h
+++ b/src/include/c.h
@@ -12,7 +12,7 @@
  * Portions Copyright (c) 1996-2005, PostgreSQL Global Development Group
  * Portions Copyright (c) 1994, Regents of the University of California
  *
- * $PostgreSQL: pgsql/src/include/c.h,v 1.187 2005/07/02 17:01:52 momjian Exp $
+ * $PostgreSQL: pgsql/src/include/c.h,v 1.188 2005/07/18 15:53:28 tgl Exp $
  *
  *-------------------------------------------------------------------------
  */
@@ -630,21 +630,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 *_start = (int32 *) _vstart; \
 			int32 *_stop = (int32 *) ((char *) _start + _len); \
 			while (_start < _stop) \
 				*_start++ = 0; \
 		} \
 		else \
-			memset(_start, _val, _len); \
+			memset(_vstart, _val, _len); \
 	} while (0)
 
 #define MEMSET_LOOP_LIMIT  1024
-- 
GitLab