Skip to content

[SEH] Scopes shouldn't end on a call instruction #54922

Open
@namazso

Description

@namazso

call is a special instruction for SEH, as exceptions thrown in a lower frame manifest at the return address (ie the end of the call instruction), rather than the start of it. This means that SEH ranges must always cover the end of the call instruction. This is all fine and working, however this range will also accidentally catch exceptions raised by the next instruction, that is code-wise outside the range. Here's an example:

#include <intrin.h>
#include <cstdio>

__declspec(noinline) void do_nothing() {}
__declspec(noinline) void test()
{
	__try {
		do_nothing();
	} __except(1) {
		printf("hello\n");
	}
	__debugbreak();
}
int main()
{
	__try {
		test();
	} __except(1) {
		printf("world\n");
	}
	return 0;
}

This will print "hello" in an infinite loop on LLVM 14.0. This is because the int3 is erroneously caught by the __try

The way MSVC solves this is by inserting a nop after a call that falls on the end of a SEH scope range. Some more discussion on related matters can be found in #46803

Metadata

Metadata

Assignees

No one assigned

    Labels

    clang:codegenIR generation bugs: mangling, exceptions, etc.

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions