t_static_destructor.sh revision 1.11
1#	$NetBSD: t_static_destructor.sh,v 1.11 2025/11/05 21:24:48 christos Exp $
2#
3# Copyright (c) 2017 The NetBSD Foundation, Inc.
4# All rights reserved.
5#
6# This code is derived from software contributed to The NetBSD Foundation
7# by Kamil Rytarowski.
8#
9# Redistribution and use in source and binary forms, with or without
10# modification, are permitted provided that the following conditions
11# are met:
12# 1. Redistributions of source code must retain the above copyright
13#    notice, this list of conditions and the following disclaimer.
14# 2. Redistributions in binary form must reproduce the above copyright
15#    notice, this list of conditions and the following disclaimer in the
16#    documentation and/or other materials provided with the distribution.
17#
18# THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
19# ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
20# TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
21# PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
22# BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
23# CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
24# SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
25# INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
26# CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
27# ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
28# POSSIBILITY OF SUCH DAMAGE.
29#
30
31mktest() {
32	cat > $@.cpp << EOF
33#include <iostream>
34struct A {
35	int i;
36	A(int i):i(i){std::cout << "CTOR A" << std::endl;}
37	~A() {std::cout << "DTOR A:" << i << std::endl;}
38};
39struct B {
40	A *m_a;
41	B(){static A s_a(10);m_a=&s_a;std::cout << "CTOR B" << std::endl;}
42	~B(){std::cout << "DTOR B:" << (*m_a).i << std::endl;(*m_a).i = 20;}
43};
44int $@(void) {struct B b;return 0;}
45EOF
46}
47
48check() {
49	atf_check -s exit:0 -o inline:"CTOR A\nCTOR B\nDTOR B:10\nDTOR A:20\n" $@
50}
51
52ccmain() {
53	atf_check -s exit:0 -o ignore -e ignore c++ $@ -o main main.cpp
54	check ./main
55}
56
57
58mkmain() {
59	cat > main.cpp << EOF
60#include <cstdlib>
61int $@(void);
62int main(void) {$@();exit(0);}
63EOF
64}
65
66cclib() {
67	atf_check -s exit:0 -o ignore -e ignore \
68	    c++ "$@" -fPIC -shared -o libpic.so pic.cpp
69}
70
71check32() {
72	# check whether this arch is 64bit
73	if ! c++ -dM -E - < /dev/null | fgrep -q _LP64; then
74		atf_skip "this is not a 64 bit architecture"
75		return 1
76	fi
77	if ! c++ -m32 -dM -E - < /dev/null 2>/dev/null > ./def32; then
78		atf_skip "c++ -m32 not supported on this architecture"
79		return 1
80	else
81		if fgrep -q _LP64 ./def32; then
82			atf_fail "c++ -m32 does not generate netbsd32 binaries"
83			return 1
84		fi
85	fi
86	return 0
87}
88
89check59301() {
90	case `uname -m` in
91	riscv)	atf_expect_fail "PR port-riscv/59301:" \
92		    " riscv: missing MKPROFILE=yes support"
93		return 1
94		;;
95	esac
96	return 0
97}
98
99atf_test_case static_destructor
100static_destructor_head() {
101	atf_set "descr" "compile and run \"hello world\""
102	atf_set "require.progs" "c++"
103}
104
105atf_test_case static_destructor_profile
106static_destructor_profile_head() {
107	atf_set "descr" "compile and run \"hello world\" with profiling option"
108	atf_set "require.progs" "c++"
109}
110
111atf_test_case static_destructor_static
112static_destructor_static_head() {
113	atf_set "descr" "compile and run \"hello world\" with static option"
114	atf_set "require.progs" "c++"
115}
116
117atf_test_case static_destructor_pic
118static_destructor_pic_head() {
119	atf_set "descr" "compile and run PIC \"hello world\""
120	atf_set "require.progs" "c++"
121}
122
123atf_test_case static_destructor_pic_32
124static_destructor_pic_32_head() {
125	atf_set "descr" "compile and run 32-bit PIC \"hello world\""
126	atf_set "require.progs" "c++"
127}
128
129atf_test_case static_destructor_pic_profile
130static_destructor_pic_profile_head() {
131	atf_set "descr" "compile and run PIC \"hello world\" with profiling option"
132	atf_set "require.progs" "c++"
133}
134
135atf_test_case static_destructor_pic_profile_32
136static_destructor_pic_profile_32_head() {
137	atf_set "descr" "compile and run 32-bit PIC \"hello world\" with profiling option"
138	atf_set "require.progs" "c++"
139}
140
141atf_test_case static_destructor_profile_32
142static_destructor_profile_32_head() {
143	atf_set "descr" "compile and run 32-bit \"hello world\" with profiling option"
144	atf_set "require.progs" "c++"
145}
146
147atf_test_case static_destructor_pie
148static_destructor_pie_head() {
149	atf_set "descr" "compile and run position independent (PIE) \"hello world\""
150	atf_set "require.progs" "c++"
151}
152
153atf_test_case static_destructor32
154static_destructor32_head() {
155	atf_set "descr" "compile and run \"hello world\" for/in netbsd32 emulation"
156	atf_set "require.progs" "c++ file diff cat"
157}
158
159static_destructor_body() {
160	mktest main
161	ccmain
162}
163
164static_destructor_profile_body() {
165	check59301 || return
166
167	mktest main
168	ccmain -static -pg
169}
170
171static_destructor_profile_32_body() {
172	check32 || return
173	check59301 || return
174
175	mktest main
176	ccmain -static -pg -m32
177}
178
179
180static_destructor_static_body() {
181	mktest main
182	ccmain -static
183}
184
185static_destructor_pic_body() {
186	mktest pic
187	mkmain pic
188	cclib
189	ccmain -L${PWD} -Wl,-R${PWD} -lpic
190}
191
192static_destructor_pic_32_body() {
193	check32 || return
194	mktest pic
195	mkmain pic
196	cclib -m32
197	ccmain -m32 -L${PWD} -Wl,-R${PWD} -lpic
198}
199
200static_destructor_pic_profile_body() {
201	check59301 || return
202
203	mktest pic
204	mkmain pic
205	cclib -pg 
206	ccmain -pg -L${PWD} -Wl,-R${PWD} -lpic
207}
208
209static_destructor_pic_profile_32_body() {
210	check32 || return
211	check59301 || return
212
213	mktest pic
214	mkmain pic
215	cclib -m32 -pg 
216	ccmain -m32 -pg -L${PWD} -Wl,-R${PWD} -lpic
217}
218
219static_destructor_pie_body() {
220	# check whether this arch supports -pie
221	if ! c++ -pie -dM -E - < /dev/null 2>/dev/null >/dev/null; then
222		atf_skip "c++ -pie not supported on this architecture"
223	fi
224	mktest main
225	ccmain -fpie -pie 
226}
227
228static_destructor32_body() {
229	check32 || return
230
231	mktest main
232	atf_check -s exit:0 -o ignore -e ignore c++ -o hello32 -m32 main.cpp
233	atf_check -s exit:0 -o ignore -e ignore c++ -o hello64 main.cpp
234	file -b ./hello32 > ./ftype32
235	file -b ./hello64 > ./ftype64
236	if diff ./ftype32 ./ftype64 >/dev/null; then
237		atf_fail "generated binaries do not differ"
238	fi
239	echo "32bit binaries on this platform are:"
240	cat ./ftype32
241	echo "While native (64bit) binaries are:"
242	cat ./ftype64
243	check ./hello32
244	atf_check -s exit:0 -o ignore -e ignore c++ -o hello -m32 \
245	    -static main.cpp
246	check ./hello
247}
248
249atf_init_test_cases()
250{
251
252	atf_add_test_case static_destructor
253	atf_add_test_case static_destructor_profile
254	atf_add_test_case static_destructor_pic
255	atf_add_test_case static_destructor_pie
256	atf_add_test_case static_destructor32
257	atf_add_test_case static_destructor_static
258	atf_add_test_case static_destructor_pic_32
259	atf_add_test_case static_destructor_pic_profile
260	atf_add_test_case static_destructor_pic_profile_32
261	atf_add_test_case static_destructor_profile_32
262}
263