1--- configure
2+++ configure
3@@ -21349,7 +21349,7 @@
4     char a;
5     long long b;
6   };
7-  exit((int)&((struct s*)0)->b);
8+  exit((int)&((struct s*)1024)->b - 1024);
9 }
10 _ACEOF
11 if ac_fn_c_try_run "$LINENO"; then :
12@@ -21384,7 +21384,7 @@
13     char a;
14     double b;
15   };
16-  exit((int)&((struct s*)0)->b);
17+  exit((int)&((struct s*)1024)->b - 1024);
18 }
19 _ACEOF
20 if ac_fn_c_try_run "$LINENO"; then :
21--- src/common/classes/array.h
22+++ src/common/classes/array.h
23@@ -149,7 +149,7 @@
24 	void copyFrom(const Array<T, Storage>& source)
25 	{
26 		ensureCapacity(source.count, false);
27-		memcpy(data, source.data, sizeof(T) * source.count);
28+		if (source.count != 0) memcpy(data, source.data, sizeof(T) * source.count);
29 		count = source.count;
30 	}
31
32@@ -227,7 +227,7 @@
33 		fb_assert(count <= FB_MAX_SIZEOF - itemsCount);
34 		ensureCapacity(count + itemsCount);
35 		memmove(data + index + itemsCount, data + index, sizeof(T) * (count - index));
36-		memcpy(data + index, items, sizeof(T) * itemsCount);
37+		if (itemsCount != 0) memcpy(data + index, items, sizeof(T) * itemsCount);
38 		count += itemsCount;
39 	}
40
41@@ -242,7 +242,7 @@
42 	{
43 		fb_assert(count <= FB_MAX_SIZEOF - itemsCount);
44 		ensureCapacity(count + itemsCount);
45-		memcpy(data + count, items, sizeof(T) * itemsCount);
46+		if (itemsCount != 0) memcpy(data + count, items, sizeof(T) * itemsCount);
47 		count += itemsCount;
48 	}
49
50@@ -294,7 +294,7 @@
51 	{
52 		fb_assert(newCount >= count);
53 		ensureCapacity(newCount);
54-		memset(data + count, 0, sizeof(T) * (newCount - count));
55+		if (newCount != count) memset(data + count, 0, sizeof(T) * (newCount - count));
56 		count = newCount;
57 	}
58
59@@ -328,7 +328,7 @@
60 	{
61 		fb_assert(count <= FB_MAX_SIZEOF - L.count);
62 		ensureCapacity(count + L.count);
63-		memcpy(data + count, L.data, sizeof(T) * L.count);
64+		if (L.count != 0) memcpy(data + count, L.data, sizeof(T) * L.count);
65 		count += L.count;
66 	}
67
68@@ -462,7 +462,7 @@
69
70 			T* newdata = static_cast<T*>
71 				(this->getPool().allocate(sizeof(T) * newcapacity ALLOC_ARGS));
72-			if (preserve)
73+			if (preserve && count != 0)
74 				memcpy(newdata, data, sizeof(T) * count);
75 			freeData();
76 			data = newdata;
77--- src/common/classes/fb_string.h
78+++ src/common/classes/fb_string.h
79@@ -674,7 +674,8 @@
80 		}
81 		StringType& assign(const void* s, size_type n)
82 		{
83-			memcpy(baseAssign(n), s, n);
84+			auto const p = baseAssign(n);
85+			if (n != 0) memcpy(p, s, n);
86 			return *this;
87 		}
88 		StringType& assign(const_pointer s)
89--- src/common/unicode_util.cpp
90+++ src/common/unicode_util.cpp
91@@ -187,7 +187,7 @@
92 	Mutex ciAiTransCacheMutex;
93 	Array<UTransliterator*> ciAiTransCache;
94
95-	void (U_EXPORT2 *uVersionToString)(UVersionInfo versionArray, char* versionString);
96+	void (U_EXPORT2 *uVersionToString)(UVersionInfo const versionArray, char* versionString);
97
98 	int32_t (U_EXPORT2 *ulocCountAvailable)();
99 	const char* (U_EXPORT2 *ulocGetAvailable)(int32_t n);
100--- src/dsql/StmtNodes.cpp
101+++ src/dsql/StmtNodes.cpp
102@@ -6643,7 +6643,7 @@
103
104 void StoreNode::genBlr(DsqlCompilerScratch* dsqlScratch)
105 {
106-	const dsql_msg* message = dsqlGenDmlHeader(dsqlScratch, dsqlRse->as<RseNode>());
107+	const dsql_msg* message = dsqlGenDmlHeader(dsqlScratch, dsqlRse == nullptr ? nullptr : dsqlRse->as<RseNode>());
108
109 	dsqlScratch->appendUChar(statement2 ? blr_store2 : blr_store);
110 	GEN_expr(dsqlScratch, dsqlRelation);
111--- src/gpre/hsh.cpp
112+++ src/gpre/hsh.cpp
113@@ -232,7 +232,7 @@
114 {
115 	SCHAR c;
116
117-	SLONG value = 0;
118+	ULONG value = 0;
119
120 	while (c = *string++)
121 		value = (value << 1) + UPPER(c);
122--- src/jrd/GlobalRWLock.cpp
123+++ src/jrd/GlobalRWLock.cpp
124@@ -78,7 +78,7 @@
125
126 	cachedLock = FB_NEW_RPT(getPool(), lockLen)
127 		Lock(tdbb, lockLen, lckType, this, lockCaching ? blocking_ast_cached_lock : NULL);
128-	memcpy(&cachedLock->lck_key, lockStr, lockLen);
129+	if (lockLen != 0) memcpy(&cachedLock->lck_key, lockStr, lockLen);
130 }
131
132 GlobalRWLock::~GlobalRWLock()
133--- src/jrd/Optimizer.cpp
134+++ src/jrd/Optimizer.cpp
135@@ -368,7 +368,7 @@
136
137 	// Allocate needed indexScratches
138
139-	index_desc* idx = csb_tail->csb_idx->items;
140+	index_desc* idx = csb_tail->csb_idx == nullptr ? nullptr : csb_tail->csb_idx->items;
141 	for (int i = 0; i < csb_tail->csb_indices; ++i, ++idx)
142 		indexScratches.add(IndexScratch(p, tdbb, idx, csb_tail));
143 }
144--- src/jrd/blb.cpp
145+++ src/jrd/blb.cpp
146@@ -1786,7 +1786,7 @@
147 	arg.slice_base = array->arr_data;
148
149 	SLONG variables[64];
150-	memcpy(variables, param, MIN(sizeof(variables), param_length));
151+	if (param_length != 0) memcpy(variables, param, MIN(sizeof(variables), param_length));
152
153 	if (SDL_walk(tdbb->tdbb_status_vector, sdl, array->arr_data, &array_desc->arr_desc,
154 				 variables, slice_callback, &arg))
155--- src/jrd/btn.cpp
156+++ src/jrd/btn.cpp
157@@ -387,7 +387,7 @@
158
159 	put_short(pagePointer, offset);
160 	pagePointer += sizeof(USHORT);
161-	memmove(pagePointer, data, length);
162+	if (length != 0) memmove(pagePointer, data, length);
163 	pagePointer += length;
164 	return pagePointer;
165 }
166@@ -622,7 +622,7 @@
167 	}
168
169 	// Store data
170-	if (withData) {
171+	if (withData && length != 0) {
172 		memcpy(pagePointer, data, length);
173 	}
174 	pagePointer += length;
175--- src/jrd/btr.cpp
176+++ src/jrd/btr.cpp
177@@ -5206,7 +5206,7 @@
178 			// Push node on end in list
179 			jumpNodes->add(jumpNode);
180 			// Store new data in jumpKey, so a new jump node can calculate prefix
181-			memcpy(jumpData + jumpNode.prefix, jumpNode.data, jumpNode.length);
182+			if (jumpNode.length != 0) memcpy(jumpData + jumpNode.prefix, jumpNode.data, jumpNode.length);
183 			jumpLength = jumpNode.length + jumpNode.prefix;
184
185 			// Check if this could be our split point (if we need to split)
186@@ -5391,7 +5391,7 @@
187 	// First, store needed data for beforeInsertNode into tempData.
188 	HalfStaticArray<UCHAR, MAX_KEY> tempBuf;
189 	UCHAR* tempData = tempBuf.getBuffer(newLength);
190-	memcpy(tempData, beforeInsertNode.data + newPrefix - beforeInsertNode.prefix, newLength);
191+	if (newLength != 0) memcpy(tempData, beforeInsertNode.data + newPrefix - beforeInsertNode.prefix, newLength);
192
193 	beforeInsertNode.prefix = newPrefix;
194 	beforeInsertNode.length = newLength;
195@@ -5611,7 +5611,7 @@
196 			for (size_t i = 0; i < jumpNodes->getCount(); i++, index++)
197 			{
198 				UCHAR* q = new_key->key_data + walkJumpNode[i].prefix;
199-				memcpy(q, walkJumpNode[i].data, walkJumpNode[i].length);
200+				if (walkJumpNode[i].length != 0) memcpy(q, walkJumpNode[i].data, walkJumpNode[i].length);
201 				if (index == splitJumpNodeIndex)
202 				{
203 					jn = &walkJumpNode[i];
204@@ -5636,7 +5636,7 @@
205 					const USHORT length = walkJumpNode[i].prefix + walkJumpNode[i].length;
206 					UCHAR* newData = FB_NEW_POOL(*tdbb->getDefaultPool()) UCHAR[length];
207 					memcpy(newData, new_key->key_data, walkJumpNode[i].prefix);
208-					memcpy(newData + walkJumpNode[i].prefix, walkJumpNode[i].data,
209+					if (walkJumpNode[i].length != 0) memcpy(newData + walkJumpNode[i].prefix, walkJumpNode[i].data,
210 						walkJumpNode[i].length);
211 					delete[] walkJumpNode[i].data;
212 					walkJumpNode[i].prefix = 0;
213--- src/jrd/evl.cpp
214+++ src/jrd/evl.cpp
215@@ -415,7 +415,7 @@
216 	case dtype_real:
217 	case dtype_sql_time:
218 	case dtype_sql_date:
219-		value->vlu_misc.vlu_long = *((SLONG*) from.dsc_address);
220+		memcpy(&value->vlu_misc.vlu_long, from.dsc_address, sizeof (SLONG));
221 		return;
222
223 	case dtype_int64:
224--- src/jrd/lck.cpp
225+++ src/jrd/lck.cpp
226@@ -488,7 +488,7 @@
227 		break;
228 	}
229
230-	dbb->dbb_lock_mgr->shutdownOwner(tdbb, owner_handle_ptr);
231+	LockManager::shutdownOwner(dbb->dbb_lock_mgr, tdbb, owner_handle_ptr);
232 }
233
234
235--- src/lock/lock.cpp
236+++ src/lock/lock.cpp
237@@ -441,7 +441,7 @@
238 }
239
240
241-void LockManager::shutdownOwner(thread_db* tdbb, SRQ_PTR* owner_handle)
242+void LockManager::shutdownOwner(LockManager* This, thread_db* tdbb, SRQ_PTR* owner_handle)
243 {
244 /**************************************
245  *
246@@ -460,8 +460,9 @@
247 	if (!owner_offset)
248 		return;
249
250-	LockTableGuard guard(this, FB_FUNCTION, owner_offset);
251+	LockTableGuard guard(This, FB_FUNCTION, owner_offset);
252
253+#define SRQ_BASE                    ((UCHAR*) This->m_sharedMemory->getHeader())
254 	own* owner = (own*) SRQ_ABS_PTR(owner_offset);
255 	if (!owner->own_count)
256 		return;
257@@ -472,7 +473,7 @@
258 	while (owner->own_ast_count)
259 	{
260 		{ // checkout scope
261-			LockTableCheckout checkout(this, FB_FUNCTION);
262+			LockTableCheckout checkout(This, FB_FUNCTION);
263 			EngineCheckout cout(tdbb, FB_FUNCTION, true);
264 			Thread::sleep(10);
265 		}
266@@ -484,8 +485,9 @@
267 	// released before destroying the lock owner. This is not strictly required,
268 	// but it enforces the proper object lifetime discipline through the codebase.
269 	fb_assert(SRQ_EMPTY(owner->own_requests));
270+#define SRQ_BASE                    ((UCHAR*) m_sharedMemory->getHeader())
271
272-	purge_owner(owner_offset, owner);
273+	This->purge_owner(owner_offset, owner);
274
275 	*owner_handle = 0;
276 }
277--- src/lock/lock_proto.h
278+++ src/lock/lock_proto.h
279@@ -402,7 +402,7 @@
280 	static void destroy(LockManager*);
281
282 	bool initializeOwner(Firebird::CheckStatusWrapper*, LOCK_OWNER_T, UCHAR, SRQ_PTR*);
283-	void shutdownOwner(thread_db*, SRQ_PTR*);
284+	static void shutdownOwner(LockManager* This, thread_db*, SRQ_PTR*);
285
286 	SRQ_PTR enqueue(thread_db*, Firebird::CheckStatusWrapper*, SRQ_PTR, const USHORT,
287 		const UCHAR*, const USHORT, UCHAR, lock_ast_t, void*, SINT64, SSHORT, SRQ_PTR);
288