llvm-project
llvm-project copied to clipboard
Clang crash instantiating lambda with a calling convention specified on it.
Stack dump:
0. Program arguments: D:\\dev\\toolchain\\llvm-mingw\\llvm-mingw-20220906-ucrt-x86_64\\bin\\clang-15 --start-no-unused-arguments --driver-mode=g++ -target x86_64-w64-mingw32 -rtlib=compiler-rt -unwindlib=libunwind -stdlib=libc++ -fuse-ld=lld --end-no-unused-arguments -DCPPWINRT_VERSION_STRING=\"2.3.4.5\" -DNEEDS_UUIDOF_ICONTEXTCALLBACK_HACK -D_WIN32_WINNT=0x0602 -ID:/dev/mingw-winrt/cppwinrt/test -ID:/dev/mingw-winrt/cppwinrt/mingw-support -ID:/dev/mingw-winrt/cppwinrt/cppwinrt -ID:/dev/mingw-winrt/cppwinrt/build/x64/test/cppwinrt -g -std=gnu++20 -Winvalid-pch -Xclang -include-pch -Xclang D:/dev/mingw-winrt/cppwinrt/build/x64/test/CMakeFiles/cppwinrt-test.dir/cmake_pch.hxx.pch -Xclang -include -Xclang D:/dev/mingw-winrt/cppwinrt/build/x64/test/CMakeFiles/cppwinrt-test.dir/cmake_pch.hxx -MD -MT test/CMakeFiles/cppwinrt-test.dir/test/disconnected.cpp.obj -MF test\\CMakeFiles\\cppwinrt-test.dir\\test\\disconnected.cpp.obj.d -o test/CMakeFiles/cppwinrt-test.dir/test/disconnected.cpp.obj -c D:/dev/mingw-winrt/cppwinrt/test/test/disconnected.cpp
1. <eof> parser at end of file
2. D:/dev/mingw-winrt/cppwinrt/test/test/disconnected.cpp:192:10: instantiating function definition '(anonymous namespace)::InvokeInContext<(lambda at D:/dev/mingw-winrt/cppwinrt/test/test/disconnected.cpp:207:40)>'
Exception Code: 0xC0000005
#0 0x00007ffa996e80ee llvm::DenseMap<std::__1::pair<clang::Decl*, unsigned int>, llvm::detail::DenseSetEmpty, llvm::DenseMapInfo<std::__1::pair<clang::Decl*, unsigned int>, void>, llvm::detail::DenseSetPair<std::__1::pair<clang::Decl*, unsigned int>>>::grow(unsigned int) (D:\dev\toolchain\llvm-mingw\llvm-mingw-20220906-ucrt-x86_64\bin\libclang-cpp.dll+0xfc80ee)
#1 0x00007ffa996de815 llvm::DenseMap<std::__1::pair<clang::Decl*, unsigned int>, llvm::detail::DenseSetEmpty, llvm::DenseMapInfo<std::__1::pair<clang::Decl*, unsigned int>, void>, llvm::detail::DenseSetPair<std::__1::pair<clang::Decl*, unsigned int>>>::grow(unsigned int) (D:\dev\toolchain\llvm-mingw\llvm-mingw-20220906-ucrt-x86_64\bin\libclang-cpp.dll+0xfbe815)
#2 0x00007ffa996d64a3 clang::Sema::SubstExprs(llvm::ArrayRef<clang::Expr*>, bool, clang::MultiLevelTemplateArgumentList const&, llvm::SmallVectorImpl<clang::Expr*>&) (D:\dev\toolchain\llvm-mingw\llvm-mingw-20220906-ucrt-x86_64\bin\libclang-cpp.dll+0xfb64a3)
#3 0x00007ffa996dc504 llvm::DenseMap<std::__1::pair<clang::Decl*, unsigned int>, llvm::detail::DenseSetEmpty, llvm::DenseMapInfo<std::__1::pair<clang::Decl*, unsigned int>, void>, llvm::detail::DenseSetPair<std::__1::pair<clang::Decl*, unsigned int>>>::grow(unsigned int) (D:\dev\toolchain\llvm-mingw\llvm-mingw-20220906-ucrt-x86_64\bin\libclang-cpp.dll+0xfbc504)
#4 0x00007ffa996d64a3 clang::Sema::SubstExprs(llvm::ArrayRef<clang::Expr*>, bool, clang::MultiLevelTemplateArgumentList const&, llvm::SmallVectorImpl<clang::Expr*>&) (D:\dev\toolchain\llvm-mingw\llvm-mingw-20220906-ucrt-x86_64\bin\libclang-cpp.dll+0xfb64a3)
#5 0x00007ffa996dc504 llvm::DenseMap<std::__1::pair<clang::Decl*, unsigned int>, llvm::detail::DenseSetEmpty, llvm::DenseMapInfo<std::__1::pair<clang::Decl*, unsigned int>, void>, llvm::detail::DenseSetPair<std::__1::pair<clang::Decl*, unsigned int>>>::grow(unsigned int) (D:\dev\toolchain\llvm-mingw\llvm-mingw-20220906-ucrt-x86_64\bin\libclang-cpp.dll+0xfbc504)
#6 0x00007ffa996d47c5 clang::Sema::SubstStmt(clang::Stmt*, clang::MultiLevelTemplateArgumentList const&) (D:\dev\toolchain\llvm-mingw\llvm-mingw-20220906-ucrt-x86_64\bin\libclang-cpp.dll+0xfb47c5)
#7 0x00007ffa996ed12d clang::PackExpansionExpr::PackExpansionExpr(clang::QualType, clang::Expr*, clang::SourceLocation, llvm::Optional<unsigned int>) (D:\dev\toolchain\llvm-mingw\llvm-mingw-20220906-ucrt-x86_64\bin\libclang-cpp.dll+0xfcd12d)
#8 0x00007ffa996d4762 clang::Sema::SubstStmt(clang::Stmt*, clang::MultiLevelTemplateArgumentList const&) (D:\dev\toolchain\llvm-mingw\llvm-mingw-20220906-ucrt-x86_64\bin\libclang-cpp.dll+0xfb4762)
#9 0x00007ffa99716e62 clang::Sema::InstantiateFunctionDefinition(clang::SourceLocation, clang::FunctionDecl*, bool, bool, bool) (D:\dev\toolchain\llvm-mingw\llvm-mingw-20220906-ucrt-x86_64\bin\libclang-cpp.dll+0xff6e62)
#10 0x00007ffa9971910b clang::Sema::PerformPendingInstantiations(bool) (D:\dev\toolchain\llvm-mingw\llvm-mingw-20220906-ucrt-x86_64\bin\libclang-cpp.dll+0xff910b)
#11 0x00007ffa98ff660b clang::Sema::ActOnEndOfTranslationUnitFragment(clang::Sema::TUFragmentKind) (D:\dev\toolchain\llvm-mingw\llvm-mingw-20220906-ucrt-x86_64\bin\libclang-cpp.dll+0x8d660b)
#12 0x00007ffa98ff74a3 clang::Sema::ActOnEndOfTranslationUnit() (D:\dev\toolchain\llvm-mingw\llvm-mingw-20220906-ucrt-x86_64\bin\libclang-cpp.dll+0x8d74a3)
#13 0x00007ffa9895fcb6 clang::Parser::ParseTopLevelDecl(clang::OpaquePtr<clang::DeclGroupRef>&, clang::Sema::ModuleImportState&) (D:\dev\toolchain\llvm-mingw\llvm-mingw-20220906-ucrt-x86_64\bin\libclang-cpp.dll+0x23fcb6)
#14 0x00007ffa9887f08e clang::ParseAST(clang::Sema&, bool, bool) (D:\dev\toolchain\llvm-mingw\llvm-mingw-20220906-ucrt-x86_64\bin\libclang-cpp.dll+0x15f08e)
#15 0x00007ffa9a4a3794 clang::FrontendAction::Execute() (D:\dev\toolchain\llvm-mingw\llvm-mingw-20220906-ucrt-x86_64\bin\libclang-cpp.dll+0x1d83794)
#16 0x00007ffa9a42e014 clang::CompilerInstance::ExecuteAction(clang::FrontendAction&) (D:\dev\toolchain\llvm-mingw\llvm-mingw-20220906-ucrt-x86_64\bin\libclang-cpp.dll+0x1d0e014)
#17 0x00007ffa9a51de80 clang::ExecuteCompilerInvocation(clang::CompilerInstance*) (D:\dev\toolchain\llvm-mingw\llvm-mingw-20220906-ucrt-x86_64\bin\libclang-cpp.dll+0x1dfde80)
#18 0x00007ff6f4d36a71 (D:\dev\toolchain\llvm-mingw\llvm-mingw-20220906-ucrt-x86_64\bin\clang-15.exe+0x6a71)
#19 0x00007ff6f4d34b25 (D:\dev\toolchain\llvm-mingw\llvm-mingw-20220906-ucrt-x86_64\bin\clang-15.exe+0x4b25)
#20 0x00007ffa9a0c5ac6 llvm::SmallVectorTemplateBase<llvm::SmallString<128u>, false>::grow(unsigned long long) (D:\dev\toolchain\llvm-mingw\llvm-mingw-20220906-ucrt-x86_64\bin\libclang-cpp.dll+0x19a5ac6)
#21 0x00007ffaaaa97be3 llvm::CrashRecoveryContext::RunSafely(llvm::function_ref<void ()>) (D:\dev\toolchain\llvm-mingw\llvm-mingw-20220906-ucrt-x86_64\bin\libLLVM-15.dll+0x97be3)
#22 0x00007ffa9a0c56a9 clang::driver::CC1Command::Execute(llvm::ArrayRef<llvm::Optional<llvm::StringRef>>, std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char>>*, bool*) const (D:\dev\toolchain\llvm-mingw\llvm-mingw-20220906-ucrt-x86_64\bin\libclang-cpp.dll+0x19a56a9)
#23 0x00007ffa9a08f646 clang::driver::Compilation::ExecuteCommand(clang::driver::Command const&, clang::driver::Command const*&, bool) const (D:\dev\toolchain\llvm-mingw\llvm-mingw-20220906-ucrt-x86_64\bin\libclang-cpp.dll+0x196f646)
#24 0x00007ffa9a08f8ad clang::driver::Compilation::ExecuteJobs(clang::driver::JobList const&, llvm::SmallVectorImpl<std::__1::pair<int, clang::driver::Command const*>>&, bool) const (D:\dev\toolchain\llvm-mingw\llvm-mingw-20220906-ucrt-x86_64\bin\libclang-cpp.dll+0x196f8ad)
#25 0x00007ffa9a0a8bcb clang::driver::Driver::ExecuteCompilation(clang::driver::Compilation&, llvm::SmallVectorImpl<std::__1::pair<int, clang::driver::Command const*>>&) (D:\dev\toolchain\llvm-mingw\llvm-mingw-20220906-ucrt-x86_64\bin\libclang-cpp.dll+0x1988bcb)
#26 0x00007ff6f4d3441e (D:\dev\toolchain\llvm-mingw\llvm-mingw-20220906-ucrt-x86_64\bin\clang-15.exe+0x441e)
#27 0x00007ff6f4d313d6 (D:\dev\toolchain\llvm-mingw\llvm-mingw-20220906-ucrt-x86_64\bin\clang-15.exe+0x13d6)
#28 0x00007ff6f4d31426 (D:\dev\toolchain\llvm-mingw\llvm-mingw-20220906-ucrt-x86_64\bin\clang-15.exe+0x1426)
#29 0x00007ffb2eb47034 (C:\WINDOWS\System32\KERNEL32.DLL+0x17034)
#30 0x00007ffb2f602651 (C:\WINDOWS\SYSTEM32\ntdll.dll+0x52651)
clang-15: error: clang frontend command failed due to signal (use -v to see invocation)
clang version 15.0.0 (https://github.com/llvm/llvm-project.git 4ba6a9c9f65bbc8bd06e3652cb20fd4dfc846137)
Target: x86_64-w64-windows-gnu
Thread model: posix
InstalledDir: D:/dev/toolchain/llvm-mingw/llvm-mingw-20220906-ucrt-x86_64/bin
clang-15: note: diagnostic msg:
********************
PLEASE ATTACH THE FOLLOWING FILES TO THE BUG REPORT:
Preprocessed source(s) and associated run script(s) are located at:
clang-15: note: diagnostic msg: C:/Users/Alvin/AppData/Local/Temp/disconnected-40302b.cpp
clang-15: note: diagnostic msg: C:/Users/Alvin/AppData/Local/Temp/disconnected-40302b.sh
clang-15: note: diagnostic msg:
********************
Original code: disconnected-40302b.zip Toolchain: https://github.com/mstorsjo/llvm-mingw/releases/tag/20220906
Reduced reproducer: https://godbolt.org/z/hM47hEbq8
using func_t = int (__attribute__((stdcall)) *)(void *);
void call(void *, func_t);
template<typename T>
void a(T &&lambda) {
void *d = λ
call(d, [](void *x) __attribute__((stdcall)) -> int {
auto &lambda = *reinterpret_cast<T*>(x);
lambda();
return 0;
});
}
extern "C" int puts(const char *);
void b() {
a([]() {
puts("xxx");
});
}
Simplified: https://godbolt.org/z/8v16T7PMT
template<typename T>
void foo(void *x) {
[](void*x) __attribute__((stdcall)) { return 0;};
}
void bar() {
foo<int>(0);
}
@llvm/issue-subscribers-clang-frontend
This is happening during the call to TransformFunctionProtoType in TreeTransform.h's TransformLambdaExpr because the OldCallOpFPTL is actually an AttributedTypeTypeLoc, not a FunctionProtoTypeLoc. I find myself wondering whether the lambda should be calling TransformFunctionProtoType and not just TransformType.
@MaskRay ended up doing this implementation it looks like, and I'm not completely sure what the exception-specifier stuff is doing, AND TransformFunctionProtoType seems to need quite a bit more work to get exceptions and the context to work correctly. I might look at this again, but hopefully @MaskRay can bring his knowledge of that code and just figure it out :)
Hi, thanks for looking into this initially. Any chance you can revisit this?
I did try to hack this and got something that can compile without crashing, but to be honest I have no idea what is going on here. I am attaching my hack in case it helps... (No lit tests added btw.)
Hack patch
diff --git a/clang/lib/Sema/TreeTransform.h b/clang/lib/Sema/TreeTransform.h
index f0d3a5ca089a..1dfb6178e8c9 100644
--- a/clang/lib/Sema/TreeTransform.h
+++ b/clang/lib/Sema/TreeTransform.h
@@ -13128,10 +13128,21 @@ TreeTransform<Derived>::TransformLambdaExpr(LambdaExpr *E) {
// it introduces a mapping of the original to the newly created
// transformed parameters.
TypeSourceInfo *NewCallOpTSI = nullptr;
+ FunctionProtoTypeLoc NewCallOpFPTL;
{
TypeSourceInfo *OldCallOpTSI = E->getCallOperator()->getTypeSourceInfo();
FunctionProtoTypeLoc OldCallOpFPTL =
OldCallOpTSI->getTypeLoc().getAs<FunctionProtoTypeLoc>();
+ AttributedTypeLoc OldCallOpATTL;
+ bool IsAttributed = false;
+ if (!OldCallOpFPTL) {
+ OldCallOpATTL = OldCallOpTSI->getTypeLoc().getAs<AttributedTypeLoc>();
+ assert(OldCallOpATTL);
+ OldCallOpFPTL =
+ OldCallOpATTL.getModifiedLoc().getAs<FunctionProtoTypeLoc>();
+ assert(OldCallOpFPTL);
+ IsAttributed = true;
+ }
TypeLocBuilder NewCallOpTLBuilder;
SmallVector<QualType, 4> ExceptionStorage;
@@ -13144,8 +13155,36 @@ TreeTransform<Derived>::TransformLambdaExpr(LambdaExpr *E) {
});
if (NewCallOpType.isNull())
return ExprError();
- NewCallOpTSI = NewCallOpTLBuilder.getTypeSourceInfo(getSema().Context,
- NewCallOpType);
+
+ if (IsAttributed) {
+ const AttributedType *oldType = OldCallOpATTL.getTypePtr();
+
+ const Attr *newAttr = getDerived().TransformAttr(OldCallOpATTL.getAttr());
+ if (!newAttr)
+ return ExprError();
+
+ QualType equivalentType =
+ getDerived().TransformType(oldType->getEquivalentType());
+ if (equivalentType.isNull())
+ return ExprError();
+ QualType result = SemaRef.Context.getAttributedType(
+ OldCallOpATTL.getAttrKind(), NewCallOpType, equivalentType);
+
+ AttributedTypeLoc newTL =
+ NewCallOpTLBuilder.push<AttributedTypeLoc>(result);
+ newTL.setAttr(newAttr);
+
+ NewCallOpTSI =
+ NewCallOpTLBuilder.getTypeSourceInfo(getSema().Context, result);
+ NewCallOpFPTL = NewCallOpTSI->getTypeLoc()
+ .castAs<AttributedTypeLoc>()
+ .getModifiedLoc()
+ .castAs<FunctionProtoTypeLoc>();
+ } else {
+ NewCallOpTSI = NewCallOpTLBuilder.getTypeSourceInfo(getSema().Context,
+ NewCallOpType);
+ NewCallOpFPTL = NewCallOpTSI->getTypeLoc().castAs<FunctionProtoTypeLoc>();
+ }
}
// Create the local class that will describe the lambda.
@@ -13179,8 +13218,7 @@ TreeTransform<Derived>::TransformLambdaExpr(LambdaExpr *E) {
// Build the call operator.
CXXMethodDecl *NewCallOperator = getSema().startLambdaDefinition(
Class, E->getIntroducerRange(), NewCallOpTSI,
- E->getCallOperator()->getEndLoc(),
- NewCallOpTSI->getTypeLoc().castAs<FunctionProtoTypeLoc>().getParams(),
+ E->getCallOperator()->getEndLoc(), NewCallOpFPTL.getParams(),
E->getCallOperator()->getConstexprKind(),
E->getCallOperator()->getStorageClass(),
E->getCallOperator()->getTrailingRequiresClause());
Fixed in trunk (post 17)