Skip to content

Clang crashes when having destructor called inside __except block with--async-exceptions #82917

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

Open
m4arhz opened this issue Feb 25, 2024 · 10 comments
Labels
clang:frontend Language frontend issues, e.g. anything involving "Sema" crash Prefer [crash-on-valid] or [crash-on-invalid]

Comments

@m4arhz
Copy link

m4arhz commented Feb 25, 2024

Here is the code and options I used to reproduce the problem: https://godbolt.org/z/8r8TYsbq7
While the code crashes at calculateSEHStateForAsynchEH I believe the actual problem is at EHScopeStack. There are two type of SEH scopes, llvm.seh.try and llvm.seh.scope, the problem seem to be that the scope of the temporary starts with llvm.seh.scope.begin and ends with llvm.seh.try.end which causes the crash.
Anyone knows which type of SEH scope should the temporary have?

@github-actions github-actions bot added the clang Clang issues not falling into any other category label Feb 25, 2024
@EugeneZelenko EugeneZelenko added backend:X86 crash Prefer [crash-on-valid] or [crash-on-invalid] llvm:SelectionDAG SelectionDAGISel as well and removed clang Clang issues not falling into any other category labels Feb 25, 2024
@llvmbot
Copy link
Member

llvmbot commented Feb 25, 2024

@llvm/issue-subscribers-backend-x86

Author: None (m4arhz)

Here is the code and options I used to reproduce the problem: https://godbolt.org/z/8r8TYsbq7 While the code crashes at `calculateSEHStateForAsynchEH` I believe the actual problem is at `EHScopeStack`. There are two type of `SEH` scopes, `llvm.seh.try` and `llvm.seh.scope`, the problem seem to be that the scope of the temporary starts with `llvm.seh.scope.begin` and ends with `llvm.seh.try.end` which causes the crash. Anyone knows which type of `SEH` scope should the temporary have?

@EugeneZelenko
Copy link
Contributor

Still crashes in main: https://godbolt.org/z/3dvf6T1jx

@m4arhz
Copy link
Author

m4arhz commented Feb 25, 2024

Even simpler example: https://godbolt.org/z/z6TWY6r4q

@phoebewang
Copy link
Contributor

Anyone knows which type of SEH scope should the temporary have?

I think it's llvm.seh.scope.begin/end, see https://godbolt.org/z/M7M3sMhY8
It looks like a front end bug. CC @jyu2-git

@phoebewang phoebewang added clang:frontend Language frontend issues, e.g. anything involving "Sema" and removed backend:X86 labels Feb 26, 2024
@llvmbot
Copy link
Member

llvmbot commented Feb 26, 2024

@llvm/issue-subscribers-clang-frontend

Author: None (m4arhz)

Here is the code and options I used to reproduce the problem: https://godbolt.org/z/8r8TYsbq7 While the code crashes at `calculateSEHStateForAsynchEH` I believe the actual problem is at `EHScopeStack`. There are two type of `SEH` scopes, `llvm.seh.try` and `llvm.seh.scope`, the problem seem to be that the scope of the temporary starts with `llvm.seh.scope.begin` and ends with `llvm.seh.try.end` which causes the crash. Anyone knows which type of `SEH` scope should the temporary have?

@m4arhz
Copy link
Author

m4arhz commented Feb 28, 2024

Looks like it should be an early failure instead of a crash: https://godbolt.org/z/TYKcM47K5
Where is the right place to put this kind of check?

@phoebewang
Copy link
Contributor

Thanks for the info! I think these check should be done in the front end SemaCheck part.

@Qwinci
Copy link
Contributor

Qwinci commented Feb 22, 2025

I also ran into this, it shouldn't be an error if c++ exceptions are disabled (it's not on msvc either if you pass /EHs- and my understanding is that msvc always supports catching async exceptions within __try regardless if the support for catching them in c++'s standard try statement is enabled). There are two places in https://github.com/llvm/llvm-project/blob/main/clang/lib/CodeGen/CGCleanup.cpp where the condition for choosing between llvm.seh.try.end and llvm.seh.scope.end is different from what is used to generate the corresponding begin intrinsic.
Here is where the scope begin is generated: https://github.com/llvm/llvm-project/blob/main/clang/lib/CodeGen/CGCleanup.cpp#L195
and as far as I understand the try end gets generated in here: https://github.com/llvm/llvm-project/blob/main/clang/lib/CodeGen/CGCleanup.cpp#L814 (and possibly in https://github.com/llvm/llvm-project/blob/main/clang/lib/CodeGen/CGCleanup.cpp#L856 too). I tried to change the logic of those two places to match the logic that's used to generate the scope begin and it does make it not crash but also makes https://github.com/llvm/llvm-project/blob/main/clang/test/CodeGen/windows-seh-EHa-TryInFinally.cpp test fail (maybe the test should also be changed but I am not sure, the changes that I made might also not be fully correct).

@phoebewang
Copy link
Contributor

it's not on msvc either if you pass /EHs- and my understanding is that msvc always supports catching async exceptions within __try regardless if the support for catching them in c++'s standard try statement is enabled

That's the currect difference between Clang and MSVC and we should improve it, see #62606
Did you check if it works if we don't emit llvm.seh.scope* when c++ exceptions disabled?
I'm not sure to what extent the current async exceptions implementation rely on the c++ exceptions and how easy we can decouple them, but would be a good direction for exploration.

@Qwinci
Copy link
Contributor

Qwinci commented Feb 22, 2025

it's not on msvc either if you pass /EHs- and my understanding is that msvc always supports catching async exceptions within __try regardless if the support for catching them in c++'s standard try statement is enabled

That's the currect difference between Clang and MSVC and we should improve it, see #62606 Did you check if it works if we don't emit llvm.seh.scope* when c++ exceptions disabled? I'm not sure to what extent the current async exceptions implementation rely on the c++ exceptions and how easy we can decouple them, but would be a good direction for exploration.

Looks like it does work if it is changed to not emit them at all when c++ exceptions are disabled, that's probably a decent solution along with a sema check for the other case when c++ exceptions are enabled.

@phoebewang phoebewang removed the llvm:SelectionDAG SelectionDAGISel as well label Feb 23, 2025
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
clang:frontend Language frontend issues, e.g. anything involving "Sema" crash Prefer [crash-on-valid] or [crash-on-invalid]
Projects
None yet
Development

No branches or pull requests

5 participants