llvm / llvm-project

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

Assertion error in `clang/lib/Sema/TreeTransform.h` #64400

Open zeroomega opened 1 year ago

zeroomega commented 1 year ago

When using a tip of tree clang built with assertion enabled on a recent add Fuchsia unit test, it triggered an assertion error in Sema with error message:

clang++: clang/lib/Sema/TreeTransform.h:5850: bool clang::TreeTransform<(anonymous namespace)::TemplateInstantiator>::TransformFunctionTypeParams(SourceLocation, ArrayRef<ParmVarDecl *>, const QualType *, const FunctionProtoType::ExtParameterInfo *, SmallVectorImpl<QualType> &, SmallVectorImpl<ParmVarDecl *> *, Sema::ExtParameterInfoBuilder &, unsigned int *) [Derived = (anonymous namespace)::TemplateInstantiator]: Assertion `OldParm->getFunctionScopeIndex() == i' failed.

Full error message can be found at: https://gist.github.com/zeroomega/b4ff701b87bf15ead69b9dc54127a11a

The clang revision we used was 6537181de420c5967c427b40f26ef2cf746c2227 but we have tested some clang built in June, 2023 and the assertion error persists. So it it probably not a recent regression. The crash reproducer reproducer.tar.gz is attached. The source code of unit test can be found at https://fuchsia.googlesource.com/fuchsia/+/038036813b9ab3791d48b3251297176de6a5f938/src/firmware/gigaboot/cpp/tests/network_test.cc and it matches the line number in the error message.

llvmbot commented 1 year ago

@llvm/issue-subscribers-clang-frontend

0x59616e commented 1 year ago

It seems that the cpp file in the reproducer is not a valid text file.

widberg commented 1 year ago

@0x59616e is right, the .cpp file in the reproducer was a gzipped tar file containing the run script, it is not a source file. I built Fuchsia to get the preprocessed source for this file and was able to reproduce the bug with Clang trunk (42c9354a928d4d9459504527085fccc91b46aed3) on Godbolt (https://godbolt.org/z/vTe9Tqn87). This preprocessed source is quite big so here is a reduction (https://godbolt.org/z/c9oj39GEb). It looks like the auto on line 4 is the troublemaker. The last version of Clang on Godbolt that the reduction compiles on without hitting the assertion is 11.0.0.

shafik commented 1 year ago

Code:

struct efi_managed_network_protocol {
    unsigned long (*GetModeData)(int, int, int) __attribute__((ms_abi));
    efi_managed_network_protocol *GetManagedNetworkProtocol0 {
        GetModeData = [](int, int, auto) __attribute__((ms_abi)) {
            return (unsigned long)10;
        };
    }
};

Assertion:

clang++: /root/llvm-project/clang/lib/Sema/TreeTransform.h:5850:
bool clang::TreeTransform<Derived>::TransformFunctionTypeParams(clang::SourceLocation, llvm::ArrayRef<clang::ParmVarDecl*>, const clang::QualType*, const clang::FunctionType::ExtParameterInfo*, llvm::SmallVectorImpl<clang::QualType>&, llvm::SmallVectorImpl<clang::ParmVarDecl*>*, clang::Sema::ExtParameterInfoBuilder&, unsigned int*) [with Derived = {anonymous}::TemplateInstantiator]:
Assertion `OldParm->getFunctionScopeIndex() == i' failed.

Backtrace:

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 <source>
1.  <eof> parser at end of file
2.  <source>:1:1: parsing struct/union/class body 'efi_managed_network_protocol'
 #0 0x0000000003673648 llvm::sys::PrintStackTrace(llvm::raw_ostream&, int) (/opt/compiler-explorer/clang-assertions-trunk/bin/clang+++0x3673648)
 #1 0x00000000036714cc llvm::sys::CleanupOnSignal(unsigned long) (/opt/compiler-explorer/clang-assertions-trunk/bin/clang+++0x36714cc)
 #2 0x00000000035bed28 CrashRecoverySignalHandler(int) CrashRecoveryContext.cpp:0:0
 #3 0x00007f02a889d420 __restore_rt (/lib/x86_64-linux-gnu/libpthread.so.0+0x14420)
 #4 0x00007f02a836000b raise (/lib/x86_64-linux-gnu/libc.so.6+0x4300b)
 #5 0x00007f02a833f859 abort (/lib/x86_64-linux-gnu/libc.so.6+0x22859)
 #6 0x00007f02a833f729 (/lib/x86_64-linux-gnu/libc.so.6+0x22729)
 #7 0x00007f02a8350fd6 (/lib/x86_64-linux-gnu/libc.so.6+0x33fd6)
 #8 0x00000000068ab24c clang::TreeTransform<(anonymous namespace)::TemplateInstantiator>::TransformFunctionTypeParams(clang::SourceLocation, llvm::ArrayRef<clang::ParmVarDecl*>, clang::QualType const*, clang::FunctionType::ExtParameterInfo const*, llvm::SmallVectorImpl<clang::QualType>&, llvm::SmallVectorImpl<clang::ParmVarDecl*>*, clang::Sema::ExtParameterInfoBuilder&, unsigned int*) SemaTemplateInstantiate.cpp:0:0
 #9 0x00000000068ab3be clang::Sema::SubstParmTypes(clang::SourceLocation, llvm::ArrayRef<clang::ParmVarDecl*>, clang::FunctionType::ExtParameterInfo const*, clang::MultiLevelTemplateArgumentList const&, llvm::SmallVectorImpl<clang::QualType>&, llvm::SmallVectorImpl<clang::ParmVarDecl*>*, clang::Sema::ExtParameterInfoBuilder&) (/opt/compiler-explorer/clang-assertions-trunk/bin/clang+++0x68ab3be)
#10 0x00000000068c8305 clang::TemplateDeclInstantiator::SubstFunctionType(clang::FunctionDecl*, llvm::SmallVectorImpl<clang::ParmVarDecl*>&) (/opt/compiler-explorer/clang-assertions-trunk/bin/clang+++0x68c8305)
#11 0x0000000006915a2a clang::TemplateDeclInstantiator::VisitCXXMethodDecl(clang::CXXMethodDecl*, clang::TemplateParameterList*, std::optional<clang::ASTTemplateArgumentListInfo const*>, clang::TemplateDeclInstantiator::RewriteKind) (/opt/compiler-explorer/clang-assertions-trunk/bin/clang+++0x6915a2a)
#12 0x0000000006917714 void llvm::function_ref<void ()>::callback_fn<clang::Sema::SubstDecl(clang::Decl*, clang::DeclContext*, clang::MultiLevelTemplateArgumentList const&)::'lambda'()>(long) SemaTemplateInstantiateDecl.cpp:0:0
#13 0x0000000005ed0d01 clang::Sema::runWithSufficientStackSpace(clang::SourceLocation, llvm::function_ref<void ()>) (/opt/compiler-explorer/clang-assertions-trunk/bin/clang+++0x5ed0d01)
#14 0x00000000068c80da clang::Sema::SubstDecl(clang::Decl*, clang::DeclContext*, clang::MultiLevelTemplateArgumentList const&) (/opt/compiler-explorer/clang-assertions-trunk/bin/clang+++0x68c80da)
#15 0x00000000068c9104 clang::Sema::InstantiateFunctionDeclaration(clang::FunctionTemplateDecl*, clang::TemplateArgumentList const*, clang::SourceLocation) (/opt/compiler-explorer/clang-assertions-trunk/bin/clang+++0x68c9104)
#16 0x00000000061c7ec1 clang::Sema::DefineImplicitLambdaToFunctionPointerConversion(clang::SourceLocation, clang::CXXConversionDecl*) (/opt/compiler-explorer/clang-assertions-trunk/bin/clang+++0x61c7ec1)
#17 0x0000000006300d2b void llvm::function_ref<void ()>::callback_fn<clang::Sema::MarkFunctionReferenced(clang::SourceLocation, clang::FunctionDecl*, bool)::'lambda'()>(long) SemaExpr.cpp:0:0
#18 0x0000000005ed0d01 clang::Sema::runWithSufficientStackSpace(clang::SourceLocation, llvm::function_ref<void ()>) (/opt/compiler-explorer/clang-assertions-trunk/bin/clang+++0x5ed0d01)
#19 0x00000000062f78e4 clang::Sema::MarkFunctionReferenced(clang::SourceLocation, clang::FunctionDecl*, bool) (/opt/compiler-explorer/clang-assertions-trunk/bin/clang+++0x62f78e4)
#20 0x00000000062f7e25 MarkExprReferenced(clang::Sema&, clang::SourceLocation, clang::Decl*, clang::Expr*, bool, llvm::DenseMap<clang::VarDecl const*, int, llvm::DenseMapInfo<clang::VarDecl const*, void>, llvm::detail::DenseMapPair<clang::VarDecl const*, int>>&) SemaExpr.cpp:0:0
#21 0x00000000064856d1 clang::Sema::BuildMemberExpr(clang::Expr*, bool, clang::SourceLocation, clang::NestedNameSpecifierLoc, clang::SourceLocation, clang::ValueDecl*, clang::DeclAccessPair, bool, clang::DeclarationNameInfo const&, clang::QualType, clang::ExprValueKind, clang::ExprObjectKind, clang::TemplateArgumentListInfo const*) (/opt/compiler-explorer/clang-assertions-trunk/bin/clang+++0x64856d1)
#22 0x00000000063dcd5a clang::Sema::BuildCXXMemberCallExpr(clang::Expr*, clang::NamedDecl*, clang::CXXConversionDecl*, bool) (/opt/compiler-explorer/clang-assertions-trunk/bin/clang+++0x63dcd5a)
#23 0x00000000063ebd81 clang::Sema::PerformImplicitConversion(clang::Expr*, clang::QualType, clang::ImplicitConversionSequence const&, clang::Sema::AssignmentAction, clang::Sema::CheckedConversionKind) (/opt/compiler-explorer/clang-assertions-trunk/bin/clang+++0x63ebd81)
#24 0x0000000006667833 clang::Sema::PerformImplicitConversion(clang::Expr*, clang::QualType, clang::Sema::AssignmentAction, bool) (/opt/compiler-explorer/clang-assertions-trunk/bin/clang+++0x6667833)
#25 0x000000000631c671 clang::Sema::CheckSingleAssignmentConstraints(clang::QualType, clang::ActionResult<clang::Expr*, true>&, bool, bool, bool) (/opt/compiler-explorer/clang-assertions-trunk/bin/clang+++0x631c671)
#26 0x000000000631ca6c clang::Sema::CheckAssignmentOperands(clang::Expr*, clang::ActionResult<clang::Expr*, true>&, clang::SourceLocation, clang::QualType, clang::BinaryOperatorKind) (/opt/compiler-explorer/clang-assertions-trunk/bin/clang+++0x631ca6c)
#27 0x000000000631de90 clang::Sema::CreateBuiltinBinOp(clang::SourceLocation, clang::BinaryOperatorKind, clang::Expr*, clang::Expr*) (/opt/compiler-explorer/clang-assertions-trunk/bin/clang+++0x631de90)
#28 0x000000000667aea0 clang::Sema::CreateOverloadedBinOp(clang::SourceLocation, clang::BinaryOperatorKind, clang::UnresolvedSetImpl const&, clang::Expr*, clang::Expr*, bool, bool, clang::FunctionDecl*) (/opt/compiler-explorer/clang-assertions-trunk/bin/clang+++0x667aea0)
#29 0x000000000629a0de BuildOverloadedBinOp(clang::Sema&, clang::Scope*, clang::SourceLocation, clang::BinaryOperatorKind, clang::Expr*, clang::Expr*) SemaExpr.cpp:0:0
#30 0x000000000631f107 clang::Sema::BuildBinOp(clang::Scope*, clang::SourceLocation, clang::BinaryOperatorKind, clang::Expr*, clang::Expr*) (/opt/compiler-explorer/clang-assertions-trunk/bin/clang+++0x631f107)
#31 0x000000000631f9b3 clang::Sema::ActOnBinOp(clang::Scope*, clang::SourceLocation, clang::tok::TokenKind, clang::Expr*, clang::Expr*) (/opt/compiler-explorer/clang-assertions-trunk/bin/clang+++0x631f9b3)
#32 0x0000000005de9a61 clang::Parser::ParseRHSOfBinaryExpression(clang::ActionResult<clang::Expr*, true>, clang::prec::Level) (/opt/compiler-explorer/clang-assertions-trunk/bin/clang+++0x5de9a61)
#33 0x0000000005e0f3b9 clang::Parser::ParseBraceInitializer() (/opt/compiler-explorer/clang-assertions-trunk/bin/clang+++0x5e0f3b9)
#34 0x0000000005dc8488 clang::Parser::ParseCXXMemberInitializer(clang::Decl*, bool, clang::SourceLocation&) (/opt/compiler-explorer/clang-assertions-trunk/bin/clang+++0x5dc8488)
#35 0x0000000005d91440 clang::Parser::ParseLexedMemberInitializer(clang::Parser::LateParsedMemberInitializer&) (.part.0) ParseCXXInlineMethods.cpp:0:0
#36 0x0000000005d925bd clang::Parser::ParseLexedMemberInitializers(clang::Parser::ParsingClass&) (/opt/compiler-explorer/clang-assertions-trunk/bin/clang+++0x5d925bd)
#37 0x0000000005ddccab clang::Parser::ParseCXXMemberSpecification(clang::SourceLocation, clang::SourceLocation, clang::ParsedAttributes&, unsigned int, clang::Decl*) (/opt/compiler-explorer/clang-assertions-trunk/bin/clang+++0x5ddccab)
#38 0x0000000005ddeb40 clang::Parser::ParseClassSpecifier(clang::tok::TokenKind, clang::SourceLocation, clang::DeclSpec&, clang::Parser::ParsedTemplateInfo const&, clang::AccessSpecifier, bool, clang::Parser::DeclSpecContext, clang::ParsedAttributes&) (/opt/compiler-explorer/clang-assertions-trunk/bin/clang+++0x5ddeb40)
#39 0x0000000005db82e8 clang::Parser::ParseDeclarationSpecifiers(clang::DeclSpec&, clang::Parser::ParsedTemplateInfo const&, clang::AccessSpecifier, clang::Parser::DeclSpecContext, clang::Parser::LateParsedAttrList*, clang::ImplicitTypenameContext) (/opt/compiler-explorer/clang-assertions-trunk/bin/clang+++0x5db82e8)
#40 0x0000000005d84144 clang::Parser::ParseDeclOrFunctionDefInternal(clang::ParsedAttributes&, clang::ParsedAttributes&, clang::ParsingDeclSpec&, clang::AccessSpecifier) (/opt/compiler-explorer/clang-assertions-trunk/bin/clang+++0x5d84144)
#41 0x0000000005d84a7f clang::Parser::ParseDeclarationOrFunctionDefinition(clang::ParsedAttributes&, clang::ParsedAttributes&, clang::ParsingDeclSpec*, clang::AccessSpecifier) (.part.0) Parser.cpp:0:0
#42 0x0000000005d8b061 clang::Parser::ParseExternalDeclaration(clang::ParsedAttributes&, clang::ParsedAttributes&, clang::ParsingDeclSpec*) (/opt/compiler-explorer/clang-assertions-trunk/bin/clang+++0x5d8b061)
#43 0x0000000005d8b962 clang::Parser::ParseTopLevelDecl(clang::OpaquePtr<clang::DeclGroupRef>&, clang::Sema::ModuleImportState&) (/opt/compiler-explorer/clang-assertions-trunk/bin/clang+++0x5d8b962)
#44 0x0000000005d8bdb0 clang::Parser::ParseFirstTopLevelDecl(clang::OpaquePtr<clang::DeclGroupRef>&, clang::Sema::ModuleImportState&) (/opt/compiler-explorer/clang-assertions-trunk/bin/clang+++0x5d8bdb0)
#45 0x0000000005d7fcc2 clang::ParseAST(clang::Sema&, bool, bool) (/opt/compiler-explorer/clang-assertions-trunk/bin/clang+++0x5d7fcc2)
#46 0x00000000048c50c8 clang::CodeGenAction::ExecuteAction() (/opt/compiler-explorer/clang-assertions-trunk/bin/clang+++0x48c50c8)
#47 0x000000000412d7d9 clang::FrontendAction::Execute() (/opt/compiler-explorer/clang-assertions-trunk/bin/clang+++0x412d7d9)
#48 0x00000000040b1b6e clang::CompilerInstance::ExecuteAction(clang::FrontendAction&) (/opt/compiler-explorer/clang-assertions-trunk/bin/clang+++0x40b1b6e)
#49 0x000000000420da46 clang::ExecuteCompilerInvocation(clang::CompilerInstance*) (/opt/compiler-explorer/clang-assertions-trunk/bin/clang+++0x420da46)
#50 0x0000000000bcb732 cc1_main(llvm::ArrayRef<char const*>, char const*, void*) (/opt/compiler-explorer/clang-assertions-trunk/bin/clang+++0xbcb732)
#51 0x0000000000bc3f1a ExecuteCC1Tool(llvm::SmallVectorImpl<char const*>&, llvm::ToolContext const&) driver.cpp:0:0
#52 0x0000000003f11a19 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
#53 0x00000000035bf1d4 llvm::CrashRecoveryContext::RunSafely(llvm::function_ref<void ()>) (/opt/compiler-explorer/clang-assertions-trunk/bin/clang+++0x35bf1d4)
#54 0x0000000003f1200f 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
#55 0x0000000003ed9f75 clang::driver::Compilation::ExecuteCommand(clang::driver::Command const&, clang::driver::Command const*&, bool) const (/opt/compiler-explorer/clang-assertions-trunk/bin/clang+++0x3ed9f75)
#56 0x0000000003eda9dd 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+++0x3eda9dd)
#57 0x0000000003ee2505 clang::driver::Driver::ExecuteCompilation(clang::driver::Compilation&, llvm::SmallVectorImpl<std::pair<int, clang::driver::Command const*>>&) (/opt/compiler-explorer/clang-assertions-trunk/bin/clang+++0x3ee2505)
#58 0x0000000000bc99e7 clang_main(int, char**, llvm::ToolContext const&) (/opt/compiler-explorer/clang-assertions-trunk/bin/clang+++0xbc99e7)
#59 0x0000000000ac3ab1 main (/opt/compiler-explorer/clang-assertions-trunk/bin/clang+++0xac3ab1)
#60 0x00007f02a8341083 __libc_start_main (/lib/x86_64-linux-gnu/libc.so.6+0x24083)
#61 0x0000000000bc39fe _start (/opt/compiler-explorer/clang-assertions-trunk/bin/clang+++0xbc39fe)
clang++: error: clang frontend command failed with exit code 134 (use -v to see invocation)
Compiler returned: 134
zeroomega commented 1 year ago

It seems that the cpp file in the reproducer is not a valid text file.

My bad. I typed the wrong args when I pack up the reproducer. Here is the corrected one. reproducer.tar.gz . The simplified reproducer above is probably easier to use.

Looking at the reproducer in https://godbolt.org/z/c9oj39GEb , it reminds me a clangd segfault issue we are investigating. Reproducer: clangd-repro.tar.gz . The code inside the package is:

#define EFIAPI __attribute__((ms_abi))

int main() {
  auto func = []() EFIAPI { return 0; };
}

When using emacs with eglot, to open this project, the clangd will segfault with following error: https://gist.github.com/zeroomega/d24cd45a97ca16e8f8742939749622f7 . It looks like the error is related to this assertion error. Same pattern, auto with function signature containing a ms_abi attribute. However, this code won't cause the assertion error like the https://godbolt.org/z/c9oj39GEb