Skip to content

Commit 3630336

Browse files
authored
Allow unused destructors to be completely elided (#20519)
Depends on llvm/llvm-project#68758 Fixes: #19993
1 parent a8b3be1 commit 3630336

File tree

4 files changed

+26
-3
lines changed

4 files changed

+26
-3
lines changed

test/other/test_unused_destructor.c

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
#include <stdio.h>
2+
#include <stdlib.h>
3+
4+
__attribute((destructor)) void dtor() {
5+
printf("hello from dtor");
6+
abort();
7+
}
8+
9+
int main() {
10+
printf("in main\n");
11+
return 0;
12+
}

test/test_other.py

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14051,3 +14051,8 @@ def test_emmalloc_in_addition(self, args):
1405114051
emmalloc = path_from_root('system', 'lib', 'emmalloc.c')
1405214052
self.run_process([EMCC, test_file('other/test_emmalloc_in_addition.c'), emmalloc] + args)
1405314053
self.assertContained('success', self.run_js('a.out.js'))
14054+
14055+
def test_unused_destructor(self):
14056+
self.do_runf(test_file('other/test_unused_destructor.c'), emcc_args=['-flto', '-O2'])
14057+
# Verify that the string constant in the destructor is not included in the binary
14058+
self.assertNotIn(b'hello from dtor', read_binary('test_unused_destructor.wasm'))

tools/building.py

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -178,6 +178,15 @@ def lld_flags_for_executable(external_symbols):
178178
if settings.LINKABLE:
179179
cmd.append('--export-dynamic')
180180

181+
if settings.LTO and not settings.EXIT_RUNTIME:
182+
# The WebAssembly backend can generate new references to `__cxa_atexit` at
183+
# LTO time. This `-u` flag forces the `__cxa_atexit` symbol to be
184+
# included at LTO time. For other such symbols we exclude them from LTO
185+
# and always build them as normal object files, but that would inhibit the
186+
# LowerGlobalDtors optimization which allows destructors to be completely
187+
# removed when __cxa_atexit is a no-op.
188+
cmd.append('-u__cxa_atexit')
189+
181190
c_exports = [e for e in settings.EXPORTED_FUNCTIONS if is_c_symbol(e)]
182191
# Strip the leading underscores
183192
c_exports = [demangle_c_symbol_name(e) for e in c_exports]

tools/system_libs.py

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -890,9 +890,6 @@ class libcompiler_rt(MTLibrary, SjLjLibrary):
890890

891891
class libnoexit(Library):
892892
name = 'libnoexit'
893-
# __cxa_atexit calls can be generated during LTO the implemenation cannot
894-
# itself be LTO. See `get_libcall_files` below for more details.
895-
force_object_files = True
896893
src_dir = 'system/lib/libc'
897894
src_files = ['atexit_dummy.c']
898895

0 commit comments

Comments
 (0)