Skip to content

[llvm-libc] Import setjmp from llvm-libc #24765

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 3 commits into from
Jul 30, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion system/lib/libc/musl/include/setjmp.h
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ typedef struct __jmp_buf_tag {
|| defined(_BSD_SOURCE)
typedef jmp_buf sigjmp_buf;
/* XXX EMSCRIPTEN: No signals support, alias sigsetjmp and siglongjmp to their non-signals counterparts. */
#if __EMSCRIPTEN__
#if __EMSCRIPTEN__ && !defined(LLVM_LIBC)
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I wonder if we could remove this musl patch and instead do this redirection in source files, then our musl patch would be smaller and we could avoid the need for this new LLVM_LIBC macro.

I'm fine landing this patch either way, we can always clean this up as a followup.

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I am fine either way as well.
On the hand, this should no longer be of any issue once we switch over to use llvm-libc public headers over the musl ones.

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

True, but I honestly think that process will take O(years). We can't delete musl until llvm-libc is has complete parity, or at least close enough that we accept some minor regressions.

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Certainly. As I expect to see more of these as we import more llvm-libc, I feel like we should probably try to address this properly.

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

PTAL. The forwarding is now done in source files.

#define sigsetjmp(buf, x) setjmp((buf))
#define siglongjmp(buf, val) longjmp(buf, val)
#else
Expand Down
3 changes: 3 additions & 0 deletions system/lib/libc/musl/src/setjmp/longjmp.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
#ifdef __EMSCRIPTEN__
#define sigsetjmp(buf, x) setjmp((buf))
#endif
3 changes: 3 additions & 0 deletions system/lib/libc/musl/src/setjmp/setjmp.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
#ifdef __EMSCRIPTEN__
#define siglongjmp(buf, val) longjmp(buf, val)
#endif
34 changes: 34 additions & 0 deletions system/lib/llvm-libc/src/setjmp/longjmp.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
//===-- Implementation header for longjmp -----------------------*- C++ -*-===//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//

#ifndef LLVM_LIBC_SRC_SETJMP_LONGJMP_H
#define LLVM_LIBC_SRC_SETJMP_LONGJMP_H

#include "hdr/types/jmp_buf.h"
#include "src/__support/macros/config.h"
#include "src/__support/macros/properties/compiler.h"

namespace LIBC_NAMESPACE_DECL {

// TODO(https://github.com/llvm/llvm-project/issues/112427)
// Some of the architecture-specific definitions are marked `naked`, which in
// GCC implies `nothrow`.
//
// Right now, our aliases aren't marked `nothrow`, so we wind up in a situation
// where clang will emit -Wmissing-exception-spec if we add `nothrow` here, but
// GCC will emit -Wmissing-attributes here without `nothrow`. We need to update
// LLVM_LIBC_FUNCTION to denote when a function throws or not.

#ifdef LIBC_COMPILER_IS_GCC
[[gnu::nothrow]]
#endif
void longjmp(jmp_buf buf, int val);

} // namespace LIBC_NAMESPACE_DECL

#endif // LLVM_LIBC_SRC_SETJMP_LONGJMP_H
37 changes: 37 additions & 0 deletions system/lib/llvm-libc/src/setjmp/setjmp_impl.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
//===-- Implementation header for setjmp ------------------------*- C++ -*-===//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//

#ifndef LLVM_LIBC_SRC_SETJMP_SETJMP_IMPL_H
#define LLVM_LIBC_SRC_SETJMP_SETJMP_IMPL_H

// This header has the _impl prefix in its name to avoid conflict with the
// public header setjmp.h which is also included. here.
#include "hdr/types/jmp_buf.h"
#include "src/__support/macros/config.h"
#include "src/__support/macros/properties/compiler.h"

namespace LIBC_NAMESPACE_DECL {

// TODO(https://github.com/llvm/llvm-project/issues/112427)
// Some of the architecture-specific definitions are marked `naked`, which in
// GCC implies `nothrow`.
//
// Right now, our aliases aren't marked `nothrow`, so we wind up in a situation
// where clang will emit -Wmissing-exception-spec if we add `nothrow` here, but
// GCC will emit -Wmissing-attributes here without `nothrow`. We need to update
// LLVM_LIBC_FUNCTION to denote when a function throws or not.

#ifdef LIBC_COMPILER_IS_GCC
[[gnu::nothrow]]
#endif
[[gnu::returns_twice]] int
setjmp(jmp_buf buf);

} // namespace LIBC_NAMESPACE_DECL

#endif // LLVM_LIBC_SRC_SETJMP_SETJMP_IMPL_H
23 changes: 23 additions & 0 deletions system/lib/llvm-libc/src/setjmp/siglongjmp.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
//===-- Implementation of siglongjmp --------------------------------------===//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//

#include "src/setjmp/siglongjmp.h"
#include "src/__support/common.h"
#include "src/setjmp/longjmp.h"

namespace LIBC_NAMESPACE_DECL {

// siglongjmp is the same as longjmp. The additional recovery work is done in
// the epilogue of the sigsetjmp function.
// TODO: move this inside the TU of longjmp and making it an alias after
// sigsetjmp is implemented for all architectures.
LLVM_LIBC_FUNCTION(void, siglongjmp, (jmp_buf buf, int val)) {
return LIBC_NAMESPACE::longjmp(buf, val);
}

} // namespace LIBC_NAMESPACE_DECL
25 changes: 25 additions & 0 deletions system/lib/llvm-libc/src/setjmp/siglongjmp.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
//===-- Implementation header for siglongjmp --------------------*- C++ -*-===//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//

#ifndef LLVM_LIBC_SRC_SETJMP_SIGLONGJMP_H
#define LLVM_LIBC_SRC_SETJMP_SIGLONGJMP_H

#include "hdr/types/jmp_buf.h"
#include "src/__support/macros/config.h"
#include "src/__support/macros/properties/compiler.h"

namespace LIBC_NAMESPACE_DECL {

#ifdef LIBC_COMPILER_IS_GCC
[[gnu::nothrow]]
#endif
void siglongjmp(jmp_buf buf, int val);

} // namespace LIBC_NAMESPACE_DECL

#endif // LLVM_LIBC_SRC_SETJMP_SIGLONGJMP_H
26 changes: 26 additions & 0 deletions system/lib/llvm-libc/src/setjmp/sigsetjmp.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
//===-- Implementation header for sigsetjmp ---------------------*- C++ -*-===//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//

#ifndef LLVM_LIBC_SRC_SETJMP_SIGSETJMP_H
#define LLVM_LIBC_SRC_SETJMP_SIGSETJMP_H

#include "hdr/types/jmp_buf.h"
#include "src/__support/macros/config.h"
#include "src/__support/macros/properties/compiler.h"

namespace LIBC_NAMESPACE_DECL {

#ifdef LIBC_COMPILER_IS_GCC
[[gnu::nothrow]]
#endif
[[gnu::returns_twice]] int
sigsetjmp(sigjmp_buf buf, int savesigs);

} // namespace LIBC_NAMESPACE_DECL

#endif // LLVM_LIBC_SRC_SETJMP_SIGSETJMP_H
19 changes: 19 additions & 0 deletions system/lib/llvm-libc/src/setjmp/sigsetjmp_epilogue.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
//===-- Implementation header for sigsetjmp epilogue ------------*- C++ -*-===//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//

#ifndef LLVM_LIBC_SRC_SETJMP_SIGSETJMP_EPILOGUE_H
#define LLVM_LIBC_SRC_SETJMP_SIGSETJMP_EPILOGUE_H

#include "hdr/types/jmp_buf.h"
#include "src/__support/common.h"

namespace LIBC_NAMESPACE_DECL {
[[gnu::returns_twice]] int sigsetjmp_epilogue(jmp_buf buffer, int retval);
} // namespace LIBC_NAMESPACE_DECL

#endif // LLVM_LIBC_SRC_SETJMP_SIGSETJMP_EPILOGUE_H
14 changes: 14 additions & 0 deletions system/lib/llvm-libc/src/setjmp/wasm/sigsetjmp.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
#include "src/setjmp/sigsetjmp.h"
#include "hdr/offsetof_macros.h"
#include "src/__support/common.h"
#include "src/__support/macros/config.h"

#if !defined(LIBC_TARGET_ARCH_IS_WASM)
#error "Invalid file include"
#endif

namespace LIBC_NAMESPACE_DECL {
[[gnu::returns_twice]] int sigsetjmp(jmp_buf sigjmp_buf, int savesigs) {
return setjmp(sigjmp_buf);
}
}
2 changes: 2 additions & 0 deletions system/lib/update_llvm_libc.py
Original file line number Diff line number Diff line change
Expand Up @@ -32,11 +32,13 @@
'src/inttypes',
'src/stdio/printf_core',
'src/wchar',
'src/setjmp'
]

libc_exclusion_patterns = [
'src/math/generic/*f16*', # float16 is unsupported in Emscripten.
'src/strings/str*casecmp_l*', # locale_t is unsupported in Overlay Mode.
'src/setjmp/**/*', # setjmp in Emscripten is implemented by the clang backend.
]

def clean_dir(dirname):
Expand Down
4 changes: 3 additions & 1 deletion tools/system_libs.py
Original file line number Diff line number Diff line change
Expand Up @@ -1001,7 +1001,7 @@ class llvmlibc(DebugLibrary, AsanInstrumentedLibrary, MTLibrary):
name = 'libllvmlibc'
never_force = True
includes = ['system/lib/llvm-libc']
cflags = ['-Os', '-DLIBC_NAMESPACE=__llvm_libc', '-DLIBC_COPT_PUBLIC_PACKAGING']
cflags = ['-Os', '-DLIBC_NAMESPACE=__llvm_libc', '-DLLVM_LIBC', '-DLIBC_COPT_PUBLIC_PACKAGING']

def get_files(self):
files = glob_in_path('system/lib/llvm-libc/src/string', '**/*.cpp')
Expand All @@ -1010,6 +1010,8 @@ def get_files(self):
files += glob_in_path('system/lib/llvm-libc/src/errno', '**/*.cpp')
files += glob_in_path('system/lib/llvm-libc/src/math', '*.cpp')
files += glob_in_path('system/lib/llvm-libc/src/wchar', '*.cpp')
files += glob_in_path('system/lib/llvm-libc/src/setjmp', '*.cpp')
files += glob_in_path('system/lib/llvm-libc/src/setjmp', '**/*.cpp')
files += glob_in_path('system/lib/llvm-libc/src/stdlib', '*.cpp', excludes=['at_quick_exit.cpp',
'quick_exit.cpp',
'atexit.cpp',
Expand Down