llvm / llvm-project

The LLVM Project is a collection of modular and reusable compiler and toolchain technologies.
http://llvm.org
Other
29.04k stars 11.98k forks source link

[seh] Jump out of finally causes verifier error #27196

Open 991901f3-cc14-4404-b340-165691b62a58 opened 8 years ago

991901f3-cc14-4404-b340-165691b62a58 commented 8 years ago
Bugzilla Link 26822
Version unspecified
OS Linux
CC @compnerd,@nico,@rnk

Extended Description

consider: void f() { try { } finally { goto lbl; } lbl:; } $ clang -cc1 -triple x86_64-pc-windows-msvc18.0.0 -fms-extensions -x c t.c -emit-llvm-only t.c:4:5: warning: jump out of __finally block has undefined behavior goto lbl; ^ Referring to a basic block in another function! br label %lbl fatal error: error in backend: Broken function found, compilation aborted!

991901f3-cc14-4404-b340-165691b62a58 commented 2 years ago

mentioned in issue llvm/llvm-bugzilla-archive#27378

rnk commented 8 years ago

Why not emit llvm.trap and unreachable?

991901f3-cc14-4404-b340-165691b62a58 commented 8 years ago

The code inside the finally is in a cleanuppad/cleanupret. We need a way to run all the inner finally blocks and end up at the lbl. The only way of implementing this is by modeling the control flow. The most natural way of doing this would be to provide an alternate instruction which leaves cleanuppads but doesn't unwind like cleanupret. Some sort of 'cleanupdone from ... label %xyz' or 'cleanupret from ... local label %xyz' which would take a non-pad basic block.

This construct would then get lowered to a call to _local_unwind.

991901f3-cc14-4404-b340-165691b62a58 commented 8 years ago

Bug llvm/llvm-bugzilla-archive#27378 has been marked as a duplicate of this bug.

Endilll commented 1 year ago

Still reproduces as of post-17 trunk: https://godbolt.org/z/jMWYax9x6

<source>:4:5: warning: jump out of __finally block has undefined behavior [-Wjump-seh-finally]
    4 |     goto lbl;
      |     ^
Referring to a basic block in another function!
  br label %lbl, !dbg !26
in function ?fin$0@0@f@@
fatal error: error in backend: Broken function found, compilation aborted!
PLEASE submit a bug report to https://github.com/llvm/llvm-project/issues/ and include the crash backtrace, preprocessed source, and associated run script.
Stack dump:
0.  Program arguments: /opt/compiler-explorer/clang-assertions-trunk/bin/clang++ -gdwarf-4 -g -o /app/output.s -mllvm --x86-asm-syntax=intel -S --gcc-toolchain=/opt/compiler-explorer/gcc-snapshot -fcolor-diagnostics -fno-crash-diagnostics -x c -Wno-implicit-int -Wno-implicit-function-declaration -target x86_64-pc-windows-msvc18.0.0 -fms-extensions <source>
1.  <eof> parser at end of file
2.  Code generation
3.  Running pass 'Function Pass Manager' on module '<source>'.
4.  Running pass 'Module Verifier' on function '@"?fin$0@0@f@@"'
 #0 0x00000000036b2f38 llvm::sys::PrintStackTrace(llvm::raw_ostream&, int) (/opt/compiler-explorer/clang-assertions-trunk/bin/clang+++0x36b2f38)
 #1 0x00000000036b0bfc llvm::sys::CleanupOnSignal(unsigned long) (/opt/compiler-explorer/clang-assertions-trunk/bin/clang+++0x36b0bfc)
 #2 0x00000000035fa596 llvm::CrashRecoveryContext::HandleExit(int) (/opt/compiler-explorer/clang-assertions-trunk/bin/clang+++0x35fa596)
 #3 0x00000000036a7f4e llvm::sys::Process::Exit(int, bool) (/opt/compiler-explorer/clang-assertions-trunk/bin/clang+++0x36a7f4e)
 #4 0x0000000000bd6e2a LLVMErrorHandler(void*, char const*, bool) cc1_main.cpp:0:0
 #5 0x0000000003604f83 llvm::report_fatal_error(llvm::Twine const&, bool) (/opt/compiler-explorer/clang-assertions-trunk/bin/clang+++0x3604f83)
 #6 0x00000000036050e8 (/opt/compiler-explorer/clang-assertions-trunk/bin/clang+++0x36050e8)
 #7 0x00000000030d9a22 (anonymous namespace)::VerifierLegacyPass::runOnFunction(llvm::Function&) Verifier.cpp:0:0
 #8 0x000000000303d579 llvm::FPPassManager::runOnFunction(llvm::Function&) (/opt/compiler-explorer/clang-assertions-trunk/bin/clang+++0x303d579)
 #9 0x000000000303d7b1 llvm::FPPassManager::runOnModule(llvm::Module&) (/opt/compiler-explorer/clang-assertions-trunk/bin/clang+++0x303d7b1)
#10 0x000000000303dfd2 llvm::legacy::PassManagerImpl::run(llvm::Module&) (/opt/compiler-explorer/clang-assertions-trunk/bin/clang+++0x303dfd2)
#11 0x0000000003927440 (anonymous namespace)::EmitAssemblyHelper::EmitAssembly(clang::BackendAction, std::unique_ptr<llvm::raw_pwrite_stream, std::default_delete<llvm::raw_pwrite_stream>>) BackendUtil.cpp:0:0
#12 0x0000000003927d69 clang::EmitBackendOutput(clang::DiagnosticsEngine&, clang::HeaderSearchOptions const&, clang::CodeGenOptions const&, clang::TargetOptions const&, clang::LangOptions const&, llvm::StringRef, llvm::Module*, clang::BackendAction, llvm::IntrusiveRefCntPtr<llvm::vfs::FileSystem>, std::unique_ptr<llvm::raw_pwrite_stream, std::default_delete<llvm::raw_pwrite_stream>>) (/opt/compiler-explorer/clang-assertions-trunk/bin/clang+++0x3927d69)
#13 0x00000000049137bf clang::BackendConsumer::HandleTranslationUnit(clang::ASTContext&) (/opt/compiler-explorer/clang-assertions-trunk/bin/clang+++0x49137bf)
#14 0x0000000005e08319 clang::ParseAST(clang::Sema&, bool, bool) (/opt/compiler-explorer/clang-assertions-trunk/bin/clang+++0x5e08319)
#15 0x0000000004911f68 clang::CodeGenAction::ExecuteAction() (/opt/compiler-explorer/clang-assertions-trunk/bin/clang+++0x4911f68)
#16 0x000000000417ab89 clang::FrontendAction::Execute() (/opt/compiler-explorer/clang-assertions-trunk/bin/clang+++0x417ab89)
#17 0x00000000040fad7e clang::CompilerInstance::ExecuteAction(clang::FrontendAction&) (/opt/compiler-explorer/clang-assertions-trunk/bin/clang+++0x40fad7e)
#18 0x0000000004258ebe clang::ExecuteCompilerInvocation(clang::CompilerInstance*) (/opt/compiler-explorer/clang-assertions-trunk/bin/clang+++0x4258ebe)
#19 0x0000000000bd8dde cc1_main(llvm::ArrayRef<char const*>, char const*, void*) (/opt/compiler-explorer/clang-assertions-trunk/bin/clang+++0xbd8dde)
#20 0x0000000000bd096a ExecuteCC1Tool(llvm::SmallVectorImpl<char const*>&, llvm::ToolContext const&) driver.cpp:0:0
#21 0x0000000003f5c0c9 void llvm::function_ref<void ()>::callback_fn<clang::driver::CC1Command::Execute(llvm::ArrayRef<std::optional<llvm::StringRef>>, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char>>*, bool*) const::'lambda'()>(long) Job.cpp:0:0
#22 0x00000000035fa4d4 llvm::CrashRecoveryContext::RunSafely(llvm::function_ref<void ()>) (/opt/compiler-explorer/clang-assertions-trunk/bin/clang+++0x35fa4d4)
#23 0x0000000003f5c6bf clang::driver::CC1Command::Execute(llvm::ArrayRef<std::optional<llvm::StringRef>>, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char>>*, bool*) const (.part.0) Job.cpp:0:0
#24 0x0000000003f24a35 clang::driver::Compilation::ExecuteCommand(clang::driver::Command const&, clang::driver::Command const*&, bool) const (/opt/compiler-explorer/clang-assertions-trunk/bin/clang+++0x3f24a35)
#25 0x0000000003f2549d clang::driver::Compilation::ExecuteJobs(clang::driver::JobList const&, llvm::SmallVectorImpl<std::pair<int, clang::driver::Command const*>>&, bool) const (/opt/compiler-explorer/clang-assertions-trunk/bin/clang+++0x3f2549d)
#26 0x0000000003f2d3c5 clang::driver::Driver::ExecuteCompilation(clang::driver::Compilation&, llvm::SmallVectorImpl<std::pair<int, clang::driver::Command const*>>&) (/opt/compiler-explorer/clang-assertions-trunk/bin/clang+++0x3f2d3c5)
#27 0x0000000000bd654c clang_main(int, char**, llvm::ToolContext const&) (/opt/compiler-explorer/clang-assertions-trunk/bin/clang+++0xbd654c)
#28 0x0000000000ad2cf1 main (/opt/compiler-explorer/clang-assertions-trunk/bin/clang+++0xad2cf1)
#29 0x00007fab3c8c1083 __libc_start_main (/lib/x86_64-linux-gnu/libc.so.6+0x24083)
#30 0x0000000000bd044e _start (/opt/compiler-explorer/clang-assertions-trunk/bin/clang+++0xbd044e)
clang++: error: clang frontend command failed with exit code 70 (use -v to see invocation)