LibreOffice Module cppu (master) 1
check.cxx
Go to the documentation of this file.
1/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2/*
3 * This file is part of the LibreOffice project.
4 *
5 * This Source Code Form is subject to the terms of the Mozilla Public
6 * License, v. 2.0. If a copy of the MPL was not distributed with this
7 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
8 *
9 * This file incorporates work covered by the following license notice:
10 *
11 * Licensed to the Apache Software Foundation (ASF) under one or more
12 * contributor license agreements. See the NOTICE file distributed
13 * with this work for additional information regarding copyright
14 * ownership. The ASF licenses this file to you under the Apache
15 * License, Version 2.0 (the "License"); you may not use this file
16 * except in compliance with the License. You may obtain a copy of
17 * the License at http://www.apache.org/licenses/LICENSE-2.0 .
18 */
19
20#include <sal/config.h>
21
22#include <cassert>
23
24#include <cppu/macros.hxx>
25#include <rtl/ustring.hxx>
26#include <sal/types.h>
27#include <uno/any2.h>
28
29
30namespace {
31
32#if defined( _WIN32)
33#pragma pack(push, 8)
34#endif
35
36struct C1
37{
38 sal_Int16 n1;
39};
40struct C2 : public C1
41{
42 sal_Int32 n2 CPPU_GCC3_ALIGN( C1 );
43};
44struct C3 : public C2
45{
46 double d3;
47 sal_Int32 n3;
48};
49struct C4 : public C3
50{
51 sal_Int32 n4 CPPU_GCC3_ALIGN( C3 );
52 double d4;
53};
54struct C5 : public C4
55{
56 sal_Int64 n5;
57 sal_Bool b5;
58};
59struct C6 : public C1
60{
61 C5 c6 CPPU_GCC3_ALIGN( C1 );
62 sal_Bool b6;
63};
64
65struct D
66{
67 sal_Int16 d;
68 sal_Int32 e;
69};
70struct E
71{
72 // [-loplugin:fakebool] false positive:
73 sal_Bool a;
74 // [-loplugin:fakebool] false positive:
75 sal_Bool b;
76 // [-loplugin:fakebool] false positive:
77 sal_Bool c;
78 sal_Int16 d;
79 sal_Int32 e;
80};
81
82struct M
83{
84 sal_Int32 n;
85 sal_Int16 o;
86};
87
88struct N : public M
89{
90 sal_Int16 p CPPU_GCC3_ALIGN( M );
91};
92struct N2
93{
94 M m;
95 sal_Int16 p;
96};
97
98struct O : public M
99{
100 double p;
101 sal_Int16 q;
102};
103struct O2 : public O
104{
105 sal_Int16 p2 CPPU_GCC3_ALIGN( O );
106};
107
108struct P : public N
109{
110 double p2;
111};
112
113struct empty
114{
115};
116struct second : public empty
117{
118 int a;
119};
120
121struct AlignSize_Impl
122{
123 sal_Int16 nInt16;
124 double dDouble;
125};
126
127struct Char1
128{
129 char c1;
130};
131struct Char2 : public Char1
132{
133 char c2 CPPU_GCC3_ALIGN( Char1 );
134};
135struct Char3 : public Char2
136{
137 char c3 CPPU_GCC3_ALIGN( Char2 );
138};
139enum Enum
140{
142};
143
144#ifdef _WIN32
145# pragma pack(pop)
146#endif
147
148// [-loplugin:fakebool] false positive:
149static_assert( static_cast<sal_Bool>(true) == sal_True,
150 "must be binary compatible" );
151// [-loplugin:fakebool] false positive:
152static_assert( static_cast<sal_Bool>(false) == sal_False,
153 "must be binary compatible" );
154#if SAL_TYPES_ALIGNMENT8 == 2
155static_assert(offsetof(AlignSize_Impl, dDouble) == 2, "offsetof(AlignSize_Impl, dDouble) != 2");
156static_assert(sizeof(AlignSize_Impl) == 10, "sizeof(AlignSize_Impl) != 10");
157#elif SAL_TYPES_ALIGNMENT8 == 4
158static_assert(offsetof(AlignSize_Impl, dDouble) == 4, "offsetof(AlignSize_Impl, dDouble) != 4");
159static_assert(sizeof(AlignSize_Impl) == 12, "sizeof(AlignSize_Impl) != 12");
160#elif SAL_TYPES_ALIGNMENT8 == 8
161static_assert(offsetof(AlignSize_Impl, dDouble) == 8, "offsetof(AlignSize_Impl, dDouble) != 8");
162static_assert(sizeof(AlignSize_Impl) == 16, "sizeof(AlignSize_Impl) != 16");
163#else
164# error unexpected alignment of 8 byte types
165#endif
166
167// sequence
168static_assert((SAL_SEQUENCE_HEADER_SIZE % 8) == 0, "binary compatibility test failed: (SAL_SEQUENCE_HEADER_SIZE % 8) == 0!!!");
169// enum
170static_assert(sizeof(Enum) == sizeof(sal_Int32), "binary compatibility test failed: (sizeof(Enum) == sizeof(sal_Int32))");
171// any
172static_assert(sizeof(void *) >= sizeof(sal_Int32), "binary compatibility test failed: (sizeof(void *) >= sizeof(sal_Int32))");
173static_assert(sizeof(uno_Any) == sizeof(void *) * 3, "binary compatibility test failed: (sizeof(uno_Any) == sizeof(void *) * 3");
174static_assert(offsetof(uno_Any, pType) == 0, "offsetof(uno_Any, pType) != 0");
175static_assert(offsetof(uno_Any, pData) == 1 * sizeof(void *), "offsetof(uno_Any, pTData) != (1 * sizeof(void *))");
176static_assert(offsetof(uno_Any, pReserved) == 2 * sizeof(void *), "offsetof(uno_Any, pReserved) != (2 * sizeof(void *))");
177// string
178static_assert(sizeof(OUString) == sizeof(rtl_uString *), "binary compatibility test failed: sizeof(OUString) != sizeof(rtl_uString *)");
179// struct
180#if SAL_TYPES_ALIGNMENT8 == 2
181static_assert(sizeof(M) == 6, "sizeof(M) != 6");
182static_assert(sizeof(N) == 8, "sizeof(N) != 8");
183static_assert(sizeof(N2) == 8, "sizeof(N2) != 8");
184static_assert(offsetof(N2, p) == 6, "offsetof(N2, p) != 6");
185#else
186static_assert(sizeof(M) == 8, "sizeof(M) != 8");
187static_assert(sizeof(N) == 12, "sizeof(N) != 12");
188static_assert(sizeof(N2) == 12, "sizeof(N2) != 12");
189static_assert(offsetof(N2, p) == 8, "offsetof(N2, p) != 8");
190#endif
191static_assert(offsetof(M, o) == 4, "offsetof(M, o) != 4");
192
193#if SAL_TYPES_ALIGNMENT8 == 2
194static_assert(sizeof(O) == 16, "sizeof(O) != 16");
195#elif SAL_TYPES_ALIGNMENT8 == 4
196static_assert(sizeof(O) == 20, "sizeof(O) != 20");
197#elif SAL_TYPES_ALIGNMENT8 == 8
198static_assert(sizeof(O) == 24, "sizeof(O) != 24");
199#else
200# error unexpected alignment of 8 byte types
201#endif
202
203#if SAL_TYPES_ALIGNMENT8 == 2
204static_assert(sizeof(C2) == 6, "sizeof(C2) != 6");
205static_assert(sizeof(D) == 6, "sizeof(D) != 6");
206static_assert(offsetof(D, e) == 2, "offsetof(D, e) != 2");
207static_assert(offsetof(E, e) == 6, "offsetof(E, e) != 6");
208#else
209static_assert(sizeof(C2) == 8, "sizeof(C2) != 8");
210static_assert(sizeof(D) == 8, "sizeof(D) != 8");
211static_assert(offsetof(D, e) == 4, "offsetof(D, e) != 4");
212static_assert(offsetof(E, e) == 8, "offsetof(E, e) != 8");
213#endif
214
215static_assert(sizeof(C1) == 2, "sizeof(C1) != 2");
216static_assert(offsetof(E, d) == 4, "offsetof(E, d) != 4");
217
218#if SAL_TYPES_ALIGNMENT8 == 2
219static_assert(sizeof(C3) == 18, "sizeof(C3) != 18");
220static_assert(sizeof(C4) == 30, "sizeof(C4) != 30");
221static_assert(sizeof(C5) == 40, "sizeof(C5) != 40");
222static_assert(sizeof(C6) == 44, "sizeof(C6) != 44");
223
224static_assert(sizeof(O2) == 18, "sizeof(O2) != 18");
225#elif SAL_TYPES_ALIGNMENT8 == 4
226static_assert(sizeof(C3) == 20, "sizeof(C3) != 20");
227static_assert(sizeof(C4) == 32, "sizeof(C4) != 32");
228static_assert(sizeof(C5) == 44, "sizeof(C5) != 44");
229static_assert(sizeof(C6) == 52, "sizeof(C6) != 52");
230
231static_assert(sizeof(O2) == 24, "sizeof(O2) != 24");
232#elif SAL_TYPES_ALIGNMENT8 == 8
233static_assert(sizeof(C3) == 24, "sizeof(C3) != 24");
234static_assert(sizeof(C4) == 40, "sizeof(C4) != 40");
235static_assert(sizeof(C5) == 56, "sizeof(C5) != 56");
236static_assert(sizeof(C6) == 72, "sizeof(C6) != 72");
237
238static_assert(sizeof(O2) == 32, "sizeof(O2) != 32");
239#else
240# error unexpected alignment of 8 byte types
241#endif
242
243static_assert(sizeof(Char3) == 3, "sizeof(Char3) != 3");
244
245#if SAL_TYPES_ALIGNMENT8 == 2
246// max alignment is 2
247static_assert(sizeof(P) == 16, "sizeof(P) != 16");
248#elif SAL_TYPES_ALIGNMENT8 == 4
249// max alignment is 4
250static_assert(sizeof(P) == 20, "sizeof(P) != 20");
251#elif SAL_TYPES_ALIGNMENT8 == 8
252// alignment of P is 8, because of P[] ...
253static_assert(sizeof(P) == 24, "sizeof(P) != 24");
254static_assert(sizeof(second) == sizeof(int), "sizeof(second) != sizeof(int)");
255#else
256# error unexpected alignment of 8 byte types
257#endif
258
259#if OSL_DEBUG_LEVEL > 0 && !defined NDEBUG
260
261struct Char4
262{
263#if defined __GNUC__ && (__GNUC__ < 12 || (__GNUC__ == 12 && __GNUC_MINOR__ < 1)) && !defined __clang__
264#pragma GCC diagnostic push
265#pragma GCC diagnostic ignored "-Wattributes"
266#endif
267 [[maybe_unused]] Char3 chars;
268#if defined __GNUC__ && (__GNUC__ < 12 || (__GNUC__ == 12 && __GNUC_MINOR__ < 1)) && !defined __clang__
269#pragma GCC diagnostic pop
270#endif
271 char c;
272};
273
274template<typename T1, typename T2> std::size_t OFFSET_OF(T2 T1::* p) {
275 return reinterpret_cast< size_t >(reinterpret_cast<char *>(&(reinterpret_cast<T1 *>(16)->*p)) -16);
276}
277
278class BinaryCompatible_Impl
279{
280public:
281 BinaryCompatible_Impl();
282};
283BinaryCompatible_Impl::BinaryCompatible_Impl()
284{
285 assert(OFFSET_OF(&N::p) == 8);
286
287 assert(OFFSET_OF(&C2::n2) == 4);
288
289#if SAL_TYPES_ALIGNMENT8 == 2
290 assert(OFFSET_OF(&C3::d3) == 6);
291 assert(OFFSET_OF(&C3::n3) == 14);
292 assert(OFFSET_OF(&C4::n4) == 18);
293 assert(OFFSET_OF(&C4::d4) == 22);
294 assert(OFFSET_OF(&C5::n5) == 30);
295 assert(OFFSET_OF(&C5::b5) == 38);
296 assert(OFFSET_OF(&C6::c6) == 2);
297 assert(OFFSET_OF(&C6::b6) == 42);
298
299 assert(OFFSET_OF(&O2::p2) == 16);
300#elif SAL_TYPES_ALIGNMENT8 == 4
301 assert(OFFSET_OF(&C3::d3) == 8);
302 assert(OFFSET_OF(&C3::n3) == 16);
303 assert(OFFSET_OF(&C4::n4) == 20);
304 assert(OFFSET_OF(&C4::d4) == 24);
305 assert(OFFSET_OF(&C5::n5) == 32);
306 assert(OFFSET_OF(&C5::b5) == 40);
307 assert(OFFSET_OF(&C6::c6) == 4);
308 assert(OFFSET_OF(&C6::b6) == 48);
309
310 assert(OFFSET_OF(&O2::p2) == 20);
311#elif SAL_TYPES_ALIGNMENT8 == 8
312 assert(OFFSET_OF(&C3::d3) == 8);
313 assert(OFFSET_OF(&C3::n3) == 16);
314 assert(OFFSET_OF(&C4::n4) == 24);
315 assert(OFFSET_OF(&C4::d4) == 32);
316 assert(OFFSET_OF(&C5::n5) == 40);
317 assert(OFFSET_OF(&C5::b5) == 48);
318 assert(OFFSET_OF(&C6::c6) == 8);
319 assert(OFFSET_OF(&C6::b6) == 64);
320
321 assert(OFFSET_OF(&O2::p2) == 24);
322#else
323# error unexpected alignment of 8 byte types
324#endif
325
326 assert(OFFSET_OF(&Char4::c) == 3);
327}
328
329BinaryCompatible_Impl aTest;
330
331#endif
332
333}
334
335/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
double d
float v
void * p
sal_Int64 n
uno_Any a
int n2
int n1
struct _uno_Any uno_Any
sal_uInt32 n4
sal_uInt32 n5
sal_uInt32 n3
m
M
#define N
#define SAL_MAX_ENUM
unsigned char sal_Bool
#define SAL_SEQUENCE_HEADER_SIZE