llvm / llvm-project

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

[Microsoft codegen] `__thiscall` function with non-trivially-destructible first arg crashes #90336

Open MitalAshok opened 6 months ago

MitalAshok commented 6 months ago

https://godbolt.org/z/ofozszdr7

Compiled with clang++ --target=i686-win32

struct A { ~A(); };

void __thiscall f(A) {}
clang-18: /llvm-project/llvm/include/llvm/IR/DataLayout.h:652: llvm::TypeSize llvm::StructLayout::getElementOffset(unsigned int) const: Assertion `Idx < NumElements && "Invalid element idx!"' failed.
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: /cmake-build-debug/bin/clang-18 -cc1 -triple i686-unknown-windows-msvc19.33.0 -emit-obj -mincremental-linker-compatible -dumpdir a- -disable-free -clear-ast-before-backend -main-file-name this_call_non_trivial.cpp -mrelocation-model static -mframe-pointer=all -fmath-errno -ffp-contract=on -fno-rounding-math -mconstructor-aliases -target-cpu pentium4 -tune-cpu generic -fdebug-compilation-dir=/llvm/llvm-project -fcoverage-compilation-dir=/llvm-project -resource-dir /cmake-build-debug/lib/clang/19 -internal-isystem /cmake-build-debug/lib/clang/19/include -fdeprecated-macro -ferror-limit 19 -fno-use-cxa-atexit -fms-extensions -fms-compatibility -fms-compatibility-version=19.33 -std=c++14 -fskip-odr-check-in-gmf -fdelayed-template-parsing -fcxx-exceptions -fexceptions -fcolor-diagnostics -faddrsig -o /tmp/-1f0735.o -x c++ this_call_non_trivial.cpp
1.      <eof> parser at end of file
2.      this_call_non_trivial.cpp:3:17: LLVM IR generation of declaration 'f'
3.      this_call_non_trivial.cpp:3:17: Generating code for declaration 'f'
 #0 0x000055b8540c3c6d llvm::sys::PrintStackTrace(llvm::raw_ostream&, int) /llvm-project/llvm/lib/Support/Unix/Signals.inc:723:11
 #1 0x000055b8540c415b PrintStackTraceSignalHandler(void*) /llvm-project/llvm/lib/Support/Unix/Signals.inc:798:1
 #2 0x000055b8540c21c6 llvm::sys::RunSignalHandlers() /llvm-project/llvm/lib/Support/Signals.cpp:105:5
 #3 0x000055b8540c4915 SignalHandler(int) /llvm-project/llvm/lib/Support/Unix/Signals.inc:413:1
 #4 0x00007fd2c1e2c520 (/lib/x86_64-linux-gnu/libc.so.6+0x42520)
 #5 0x00007fd2c1e809fc __pthread_kill_implementation ./nptl/pthread_kill.c:44:76
 #6 0x00007fd2c1e809fc __pthread_kill_internal ./nptl/pthread_kill.c:78:10
 #7 0x00007fd2c1e809fc pthread_kill ./nptl/pthread_kill.c:89:10
 #8 0x00007fd2c1e2c476 gsignal ./signal/../sysdeps/posix/raise.c:27:6
 #9 0x00007fd2c1e127f3 abort ./stdlib/abort.c:81:7
#10 0x00007fd2c1e1271b _nl_load_domain ./intl/loadmsgcat.c:1177:9
#11 0x00007fd2c1e23e96 (/lib/x86_64-linux-gnu/libc.so.6+0x39e96)
#12 0x000055b85262222e llvm::StructLayout::getElementOffset(unsigned int) const /llvm/include/llvm/IR/DataLayout.h:0:5
#13 0x000055b854745ba9 clang::CodeGen::CGBuilderTy::CreateStructGEP(clang::CodeGen::Address, unsigned int, llvm::Twine const&) /llvm-project/clang/lib/CodeGen/CGBuilder.h:224:51
#14 0x000055b854729dc5 clang::CodeGen::CodeGenFunction::EmitFunctionProlog(clang::CodeGen::CGFunctionInfo const&, llvm::Function*, clang::CodeGen::FunctionArgList const&) /llvm-project/clang/lib/CodeGen/CGCall.cpp:3018:11
#15 0x000055b85478eeb9 clang::CodeGen::CodeGenFunction::StartFunction(clang::GlobalDecl, clang::QualType, llvm::Function*, clang::CodeGen::CGFunctionInfo const&, clang::CodeGen::FunctionArgList const&, clang::SourceLocation, clang::SourceLocation) /llvm-project/clang/lib/CodeGen/CodeGenFunction.cpp:1186:68
#16 0x000055b854790d70 clang::CodeGen::CodeGenFunction::GenerateCode(clang::GlobalDecl, llvm::Function*, clang::CodeGen::CGFunctionInfo const&) /llvm-project/clang/lib/CodeGen/CodeGenFunction.cpp:1463:7
#17 0x000055b85449cbeb clang::CodeGen::CodeGenModule::EmitGlobalFunctionDefinition(clang::GlobalDecl, llvm::GlobalValue*) /llvm-project/clang/lib/CodeGen/CodeGenModule.cpp:5862:3
#18 0x000055b8544931ec clang::CodeGen::CodeGenModule::EmitGlobalDefinition(clang::GlobalDecl, llvm::GlobalValue*) /llvm-project/clang/lib/CodeGen/CodeGenModule.cpp:4074:12
#19 0x000055b854498909 clang::CodeGen::CodeGenModule::EmitGlobal(clang::GlobalDecl) /llvm-project/clang/lib/CodeGen/CodeGenModule.cpp:3785:5
#20 0x000055b8544918ea clang::CodeGen::CodeGenModule::EmitTopLevelDecl(clang::Decl*) /llvm-project/clang/lib/CodeGen/CodeGenModule.cpp:6754:5
#21 0x000055b854ff032d (anonymous namespace)::CodeGeneratorImpl::HandleTopLevelDecl(clang::DeclGroupRef) /llvm-project/clang/lib/CodeGen/ModuleBuilder.cpp:189:73
#22 0x000055b854fde5c0 clang::BackendConsumer::HandleTopLevelDecl(clang::DeclGroupRef) /llvm-project/clang/lib/CodeGen/CodeGenAction.cpp:205:8
#23 0x000055b858a4915d clang::ParseAST(clang::Sema&, bool, bool) /llvm-project/clang/lib/Parse/ParseAST.cpp:167:11
#24 0x000055b8555a9881 clang::ASTFrontendAction::ExecuteAction() /llvm-project/clang/lib/Frontend/FrontendAction.cpp:1194:1
#25 0x000055b854fe3568 clang::CodeGenAction::ExecuteAction() /llvm-project/clang/lib/CodeGen/CodeGenAction.cpp:1183:5
#26 0x000055b8555a929c clang::FrontendAction::Execute() /llvm-project/clang/lib/Frontend/FrontendAction.cpp:1082:7
#27 0x000055b8554c8e6a clang::CompilerInstance::ExecuteAction(clang::FrontendAction&) /llvm-project/clang/lib/Frontend/CompilerInstance.cpp:1062:23
#28 0x000055b8557813de clang::ExecuteCompilerInvocation(clang::CompilerInstance*) /llvm-project/clang/lib/FrontendTool/ExecuteCompilerInvocation.cpp:278:8
#29 0x000055b852231911 cc1_main(llvm::ArrayRef<char const*>, char const*, void*) /llvm-project/clang/tools/driver/cc1_main.cpp:232:13
#30 0x000055b852224332 ExecuteCC1Tool(llvm::SmallVectorImpl<char const*>&, llvm::ToolContext const&) /llvm-project/clang/tools/driver/driver.cpp:215:5
#31 0x000055b85222309b clang_main(int, char**, llvm::ToolContext const&) /llvm-project/clang/tools/driver/driver.cpp:256:5
#32 0x000055b852256985 main /cmake-build-debug/tools/clang/tools/driver/clang-driver.cpp:17:3
#33 0x00007fd2c1e13d90 __libc_start_call_main ./csu/../sysdeps/nptl/libc_start_call_main.h:58:16
#34 0x00007fd2c1e13e40 call_init ./csu/../csu/libc-start.c:128:20
#35 0x00007fd2c1e13e40 __libc_start_main ./csu/../csu/libc-start.c:379:5
#36 0x000055b852222b25 _start (/cmake-build-debug/bin/clang-18+0x59f3b25)
clang++: error: unable to execute command: Aborted
clang++: error: clang frontend command failed due to signal (use -v to see invocation)
clang version 19.0.0git (https://github.com/llvm/llvm-project.git c229f767e48c7190b7568e6ebd1688bb08795744)
Target: i686-unknown-windows-msvc
Thread model: posix
InstalledDir: /cmake-build-debug/bin
Build config: +unoptimized, +assertions
clang++: note: diagnostic msg:
********************

PLEASE ATTACH THE FOLLOWING FILES TO THE BUG REPORT:
Preprocessed source(s) and associated run script(s) are located at:
clang++: note: diagnostic msg: /tmp/-5e89b8.cpp
clang++: note: diagnostic msg: /tmp/-5e89b8.sh
clang++: note: diagnostic msg:

********************
# Crash reproducer for clang version 19.0.0git (https://github.com/llvm/llvm-project.git c229f767e48c7190b7568e6ebd1688bb08795744)
# Driver args: "--driver-mode=g++" "--target=i686-win32" "this_call_non_trivial.cpp"
# Original command:  "/cmake-build-debug/bin/clang-18" "-cc1" "-triple" "i686-unknown-windows-msvc19.33.0" "-emit-obj" "-mincremental-linker-compatible" "-dumpdir" "a-" "-disable-free" "-clear-ast-before-backend" "-main-file-name" "this_call_non_trivial.cpp" "-mrelocation-model" "static" "-mframe-pointer=all" "-fmath-errno" "-ffp-contract=on" "-fno-rounding-math" "-mconstructor-aliases" "-target-cpu" "pentium4" "-tune-cpu" "generic" "-fdebug-compilation-dir=/llvm/llvm-project" "-fcoverage-compilation-dir=/llvm/llvm-project" "-resource-dir" "/cmake-build-debug/lib/clang/19" "-internal-isystem" "/cmake-build-debug/lib/clang/19/include" "-fdeprecated-macro" "-ferror-limit" "19" "-fno-use-cxa-atexit" "-fms-extensions" "-fms-compatibility" "-fms-compatibility-version=19.33" "-std=c++14" "-fskip-odr-check-in-gmf" "-fdelayed-template-parsing" "-fcxx-exceptions" "-fexceptions" "-fcolor-diagnostics" "-faddrsig" "-o" "/tmp/-1f0735.o" "-x" "c++" "this_call_non_trivial.cpp"
 "/cmake-build-debug/bin/clang-18" "-cc1" "-triple" "i686-unknown-windows-msvc19.33.0" "-emit-obj" "-mincremental-linker-compatible" "-dumpdir" "a-" "-disable-free" "-clear-ast-before-backend" "-main-file-name" "this_call_non_trivial.cpp" "-mrelocation-model" "static" "-mframe-pointer=all" "-fmath-errno" "-ffp-contract=on" "-fno-rounding-math" "-mconstructor-aliases" "-target-cpu" "pentium4" "-tune-cpu" "generic" "-fdebug-compilation-dir=/llvm/llvm-project" "-fcoverage-compilation-dir=/llvm/llvm-project" "-fdeprecated-macro" "-ferror-limit" "19" "-fno-use-cxa-atexit" "-fms-extensions" "-fms-compatibility" "-fms-compatibility-version=19.33" "-std=c++14" "-fskip-odr-check-in-gmf" "-fdelayed-template-parsing" "-fcxx-exceptions" "-fexceptions" "-fcolor-diagnostics" "-faddrsig" "-x" "c++" "-5e89b8.cpp"

The first argument is supposed to be a pointer, but it is not here.

MSVC seems to compile it fine. I don't know if it silently rewrites __thiscall to __cdecl or what. It does properly call the destructor too.

In a similar situation where a function can't be __thiscall because it has variadic arguments https://godbolt.org/z/cKr9dWKb3:

void __thiscall g(...) {}

Clang has an error that g can't be __thiscall. Maybe that's what needs to happen for non-pointer first args?

llvmbot commented 6 months ago

@llvm/issue-subscribers-clang-codegen

Author: Mital Ashok (MitalAshok)

https://godbolt.org/z/ofozszdr7 Compiled with `clang++ --target=i686-win32` ```c++ struct A { ~A(); }; void __thiscall f(A) {} ``` ``` clang-18: /llvm-project/llvm/include/llvm/IR/DataLayout.h:652: llvm::TypeSize llvm::StructLayout::getElementOffset(unsigned int) const: Assertion `Idx < NumElements && "Invalid element idx!"' failed. 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: /cmake-build-debug/bin/clang-18 -cc1 -triple i686-unknown-windows-msvc19.33.0 -emit-obj -mincremental-linker-compatible -dumpdir a- -disable-free -clear-ast-before-backend -main-file-name this_call_non_trivial.cpp -mrelocation-model static -mframe-pointer=all -fmath-errno -ffp-contract=on -fno-rounding-math -mconstructor-aliases -target-cpu pentium4 -tune-cpu generic -fdebug-compilation-dir=/llvm/llvm-project -fcoverage-compilation-dir=/llvm-project -resource-dir /cmake-build-debug/lib/clang/19 -internal-isystem /cmake-build-debug/lib/clang/19/include -fdeprecated-macro -ferror-limit 19 -fno-use-cxa-atexit -fms-extensions -fms-compatibility -fms-compatibility-version=19.33 -std=c++14 -fskip-odr-check-in-gmf -fdelayed-template-parsing -fcxx-exceptions -fexceptions -fcolor-diagnostics -faddrsig -o /tmp/-1f0735.o -x c++ this_call_non_trivial.cpp 1. <eof> parser at end of file 2. this_call_non_trivial.cpp:3:17: LLVM IR generation of declaration 'f' 3. this_call_non_trivial.cpp:3:17: Generating code for declaration 'f' #0 0x000055b8540c3c6d llvm::sys::PrintStackTrace(llvm::raw_ostream&, int) /llvm-project/llvm/lib/Support/Unix/Signals.inc:723:11 #1 0x000055b8540c415b PrintStackTraceSignalHandler(void*) /llvm-project/llvm/lib/Support/Unix/Signals.inc:798:1 #2 0x000055b8540c21c6 llvm::sys::RunSignalHandlers() /llvm-project/llvm/lib/Support/Signals.cpp:105:5 #3 0x000055b8540c4915 SignalHandler(int) /llvm-project/llvm/lib/Support/Unix/Signals.inc:413:1 #4 0x00007fd2c1e2c520 (/lib/x86_64-linux-gnu/libc.so.6+0x42520) #5 0x00007fd2c1e809fc __pthread_kill_implementation ./nptl/pthread_kill.c:44:76 #6 0x00007fd2c1e809fc __pthread_kill_internal ./nptl/pthread_kill.c:78:10 #7 0x00007fd2c1e809fc pthread_kill ./nptl/pthread_kill.c:89:10 #8 0x00007fd2c1e2c476 gsignal ./signal/../sysdeps/posix/raise.c:27:6 #9 0x00007fd2c1e127f3 abort ./stdlib/abort.c:81:7 #10 0x00007fd2c1e1271b _nl_load_domain ./intl/loadmsgcat.c:1177:9 #11 0x00007fd2c1e23e96 (/lib/x86_64-linux-gnu/libc.so.6+0x39e96) #12 0x000055b85262222e llvm::StructLayout::getElementOffset(unsigned int) const /llvm/include/llvm/IR/DataLayout.h:0:5 #13 0x000055b854745ba9 clang::CodeGen::CGBuilderTy::CreateStructGEP(clang::CodeGen::Address, unsigned int, llvm::Twine const&) /llvm-project/clang/lib/CodeGen/CGBuilder.h:224:51 #14 0x000055b854729dc5 clang::CodeGen::CodeGenFunction::EmitFunctionProlog(clang::CodeGen::CGFunctionInfo const&, llvm::Function*, clang::CodeGen::FunctionArgList const&) /llvm-project/clang/lib/CodeGen/CGCall.cpp:3018:11 #15 0x000055b85478eeb9 clang::CodeGen::CodeGenFunction::StartFunction(clang::GlobalDecl, clang::QualType, llvm::Function*, clang::CodeGen::CGFunctionInfo const&, clang::CodeGen::FunctionArgList const&, clang::SourceLocation, clang::SourceLocation) /llvm-project/clang/lib/CodeGen/CodeGenFunction.cpp:1186:68 #16 0x000055b854790d70 clang::CodeGen::CodeGenFunction::GenerateCode(clang::GlobalDecl, llvm::Function*, clang::CodeGen::CGFunctionInfo const&) /llvm-project/clang/lib/CodeGen/CodeGenFunction.cpp:1463:7 #17 0x000055b85449cbeb clang::CodeGen::CodeGenModule::EmitGlobalFunctionDefinition(clang::GlobalDecl, llvm::GlobalValue*) /llvm-project/clang/lib/CodeGen/CodeGenModule.cpp:5862:3 #18 0x000055b8544931ec clang::CodeGen::CodeGenModule::EmitGlobalDefinition(clang::GlobalDecl, llvm::GlobalValue*) /llvm-project/clang/lib/CodeGen/CodeGenModule.cpp:4074:12 #19 0x000055b854498909 clang::CodeGen::CodeGenModule::EmitGlobal(clang::GlobalDecl) /llvm-project/clang/lib/CodeGen/CodeGenModule.cpp:3785:5 #20 0x000055b8544918ea clang::CodeGen::CodeGenModule::EmitTopLevelDecl(clang::Decl*) /llvm-project/clang/lib/CodeGen/CodeGenModule.cpp:6754:5 #21 0x000055b854ff032d (anonymous namespace)::CodeGeneratorImpl::HandleTopLevelDecl(clang::DeclGroupRef) /llvm-project/clang/lib/CodeGen/ModuleBuilder.cpp:189:73 #22 0x000055b854fde5c0 clang::BackendConsumer::HandleTopLevelDecl(clang::DeclGroupRef) /llvm-project/clang/lib/CodeGen/CodeGenAction.cpp:205:8 #23 0x000055b858a4915d clang::ParseAST(clang::Sema&, bool, bool) /llvm-project/clang/lib/Parse/ParseAST.cpp:167:11 #24 0x000055b8555a9881 clang::ASTFrontendAction::ExecuteAction() /llvm-project/clang/lib/Frontend/FrontendAction.cpp:1194:1 #25 0x000055b854fe3568 clang::CodeGenAction::ExecuteAction() /llvm-project/clang/lib/CodeGen/CodeGenAction.cpp:1183:5 #26 0x000055b8555a929c clang::FrontendAction::Execute() /llvm-project/clang/lib/Frontend/FrontendAction.cpp:1082:7 #27 0x000055b8554c8e6a clang::CompilerInstance::ExecuteAction(clang::FrontendAction&) /llvm-project/clang/lib/Frontend/CompilerInstance.cpp:1062:23 #28 0x000055b8557813de clang::ExecuteCompilerInvocation(clang::CompilerInstance*) /llvm-project/clang/lib/FrontendTool/ExecuteCompilerInvocation.cpp:278:8 #29 0x000055b852231911 cc1_main(llvm::ArrayRef<char const*>, char const*, void*) /llvm-project/clang/tools/driver/cc1_main.cpp:232:13 #30 0x000055b852224332 ExecuteCC1Tool(llvm::SmallVectorImpl<char const*>&, llvm::ToolContext const&) /llvm-project/clang/tools/driver/driver.cpp:215:5 #31 0x000055b85222309b clang_main(int, char**, llvm::ToolContext const&) /llvm-project/clang/tools/driver/driver.cpp:256:5 #32 0x000055b852256985 main /cmake-build-debug/tools/clang/tools/driver/clang-driver.cpp:17:3 #33 0x00007fd2c1e13d90 __libc_start_call_main ./csu/../sysdeps/nptl/libc_start_call_main.h:58:16 #34 0x00007fd2c1e13e40 call_init ./csu/../csu/libc-start.c:128:20 #35 0x00007fd2c1e13e40 __libc_start_main ./csu/../csu/libc-start.c:379:5 #36 0x000055b852222b25 _start (/cmake-build-debug/bin/clang-18+0x59f3b25) clang++: error: unable to execute command: Aborted clang++: error: clang frontend command failed due to signal (use -v to see invocation) clang version 19.0.0git (https://github.com/llvm/llvm-project.git c229f767e48c7190b7568e6ebd1688bb08795744) Target: i686-unknown-windows-msvc Thread model: posix InstalledDir: /cmake-build-debug/bin Build config: +unoptimized, +assertions clang++: note: diagnostic msg: ******************** PLEASE ATTACH THE FOLLOWING FILES TO THE BUG REPORT: Preprocessed source(s) and associated run script(s) are located at: clang++: note: diagnostic msg: /tmp/-5e89b8.cpp clang++: note: diagnostic msg: /tmp/-5e89b8.sh clang++: note: diagnostic msg: ******************** ``` ```sh # Crash reproducer for clang version 19.0.0git (https://github.com/llvm/llvm-project.git c229f767e48c7190b7568e6ebd1688bb08795744) # Driver args: "--driver-mode=g++" "--target=i686-win32" "this_call_non_trivial.cpp" # Original command: "/cmake-build-debug/bin/clang-18" "-cc1" "-triple" "i686-unknown-windows-msvc19.33.0" "-emit-obj" "-mincremental-linker-compatible" "-dumpdir" "a-" "-disable-free" "-clear-ast-before-backend" "-main-file-name" "this_call_non_trivial.cpp" "-mrelocation-model" "static" "-mframe-pointer=all" "-fmath-errno" "-ffp-contract=on" "-fno-rounding-math" "-mconstructor-aliases" "-target-cpu" "pentium4" "-tune-cpu" "generic" "-fdebug-compilation-dir=/llvm/llvm-project" "-fcoverage-compilation-dir=/llvm/llvm-project" "-resource-dir" "/cmake-build-debug/lib/clang/19" "-internal-isystem" "/cmake-build-debug/lib/clang/19/include" "-fdeprecated-macro" "-ferror-limit" "19" "-fno-use-cxa-atexit" "-fms-extensions" "-fms-compatibility" "-fms-compatibility-version=19.33" "-std=c++14" "-fskip-odr-check-in-gmf" "-fdelayed-template-parsing" "-fcxx-exceptions" "-fexceptions" "-fcolor-diagnostics" "-faddrsig" "-o" "/tmp/-1f0735.o" "-x" "c++" "this_call_non_trivial.cpp" "/cmake-build-debug/bin/clang-18" "-cc1" "-triple" "i686-unknown-windows-msvc19.33.0" "-emit-obj" "-mincremental-linker-compatible" "-dumpdir" "a-" "-disable-free" "-clear-ast-before-backend" "-main-file-name" "this_call_non_trivial.cpp" "-mrelocation-model" "static" "-mframe-pointer=all" "-fmath-errno" "-ffp-contract=on" "-fno-rounding-math" "-mconstructor-aliases" "-target-cpu" "pentium4" "-tune-cpu" "generic" "-fdebug-compilation-dir=/llvm/llvm-project" "-fcoverage-compilation-dir=/llvm/llvm-project" "-fdeprecated-macro" "-ferror-limit" "19" "-fno-use-cxa-atexit" "-fms-extensions" "-fms-compatibility" "-fms-compatibility-version=19.33" "-std=c++14" "-fskip-odr-check-in-gmf" "-fdelayed-template-parsing" "-fcxx-exceptions" "-fexceptions" "-fcolor-diagnostics" "-faddrsig" "-x" "c++" "-5e89b8.cpp" ``` The first argument is supposed to be a pointer, but it is not here. MSVC seems to compile it fine. I don't know if it silently rewrites `__thiscall` to `__cdecl` or what. It does properly call the destructor too. In a similar situation where a function can't be `__thiscall` because it has variadic arguments <https://godbolt.org/z/cKr9dWKb3>: ```c++ void __thiscall g(...) {} ``` Clang has an error that `g` can't be `__thiscall`. Maybe that's what needs to happen for non-pointer first args?