Files
clang-p2996/clang/test/CodeGen/ms-setjmp.c
David Majnemer 310e3a8f60 MS ABI: Implement proper support for setjmp
On targets which use the MSVCRT, setjmp is a macro which expands to
_setjmp or _setjmpex.

_setjmp and _setjmpex have a secret, hidden argument which is not listed
in the function prototype on X64 and WoA.  This hidden argument always
seems to be the frame pointer.

_setjmpex isn't used on X86, _setjmp is magically replaced with a call
to _setjmp3.  The second argument is zero for 'normal' setjmp/longjmp
pairs, otherwise it is a count of additional variadic arguments.  This
is used when setjmp appears inside of a try or __try.

It is not safe to use a pointer to setjmp because _setjmp, _setjmpex and
_setmp3 are not compatible with setjmp.

llvm-svn: 227426
2015-01-29 09:29:21 +00:00

30 lines
1.1 KiB
C

// RUN: %clang_cc1 -fms-extensions -triple i686-windows-msvc -emit-llvm %s -o - | FileCheck --check-prefix=I386 %s
// RUN: %clang_cc1 -fms-extensions -triple x86_64-windows-msvc -emit-llvm %s -o - | FileCheck --check-prefix=X64 %s
typedef char jmp_buf[1];
int _setjmp(jmp_buf env);
int _setjmpex(jmp_buf env);
jmp_buf jb;
int test_setjmp() {
return _setjmp(jb);
// I386-LABEL: define i32 @test_setjmp
// I386: %[[call:.*]] = call i32 (i8*, i32, ...)* @_setjmp3(i8* getelementptr inbounds ([1 x i8]* @jb, i32 0, i32 0), i32 0)
// I386-NEXT: ret i32 %[[call]]
// X64-LABEL: define i32 @test_setjmp
// X64: %[[addr:.*]] = call i8* @llvm.frameaddress(i32 0)
// X64: %[[call:.*]] = call i32 @_setjmp(i8* getelementptr inbounds ([1 x i8]* @jb, i32 0, i32 0), i8* %[[addr]])
// X64-NEXT: ret i32 %[[call]]
}
int test_setjmpex() {
return _setjmpex(jb);
// X64-LABEL: define i32 @test_setjmpex
// X64: %[[addr:.*]] = call i8* @llvm.frameaddress(i32 0)
// X64: %[[call:.*]] = call i32 @_setjmpex(i8* getelementptr inbounds ([1 x i8]* @jb, i32 0, i32 0), i8* %[[addr]])
// X64-NEXT: ret i32 %[[call]]
}