Skip to content
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

Clang frontend C++ crash on invalid code in template-parameter-list #63244

Closed
brutalsavage opened this issue Jun 10, 2023 · 6 comments · Fixed by #79788
Closed

Clang frontend C++ crash on invalid code in template-parameter-list #63244

brutalsavage opened this issue Jun 10, 2023 · 6 comments · Fixed by #79788
Labels
clang:frontend Language frontend issues, e.g. anything involving "Sema" confirmed Verified by a second party crash-on-invalid

Comments

@brutalsavage
Copy link

To quickly reproduce: https://gcc.godbolt.org/z/1jqzhEdTE

template <class... T // invalid instantiation (note adding an "," removes the crash)
          T... Args> 
struct tuple;

template<auto... Vs,
    T... Vs3>
auto foo() { 
    tuple a;
    return a;
}

Compiling the above invalid code crashes clang clang++ -x c++, crashes locally using clang-17.0 (a10019a), also on trunk (see godbolt link)

Note: changing the first template to

template <class... T, // add comma 
          T... Args> 
struct tuple;

removes the crash

@EugeneZelenko EugeneZelenko added clang:frontend Language frontend issues, e.g. anything involving "Sema" crash-on-invalid and removed new issue labels Jun 11, 2023
@llvmbot
Copy link
Collaborator

llvmbot commented Jun 11, 2023

@llvm/issue-subscribers-clang-frontend

@brutalsavage
Copy link
Author

assertion-trunk godbolt: https://gcc.godbolt.org/z/E8Yz7fEYq

Assertion:

clang++: /root/llvm-project/clang/lib/AST/RecordLayoutBuilder.cpp:3295: 
const clang::ASTRecordLayout& clang::ASTContext::getASTRecordLayout(const clang::RecordDecl*) const: 
Assertion `D && "Cannot get layout of forward declarations!"' 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.	<source>:9:13: current parser token ';'
2.	<source>:7:12: parsing function body 'foo'
3.	<source>:7:12: in compound statement ('{}')
 #0 0x000055e6a899824f llvm::sys::PrintStackTrace(llvm::raw_ostream&, int) (/opt/compiler-explorer/clang-assertions-trunk/bin/clang+++0x3c2824f)
 #1 0x000055e6a8995fbc llvm::sys::CleanupOnSignal(unsigned long) (/opt/compiler-explorer/clang-assertions-trunk/bin/clang+++0x3c25fbc)
 #2 0x000055e6a88df3b8 CrashRecoverySignalHandler(int) CrashRecoveryContext.cpp:0:0
 #3 0x00007f05b0b54420 __restore_rt (/lib/x86_64-linux-gnu/libpthread.so.0+0x14420)
 #4 0x00007f05b062100b raise (/lib/x86_64-linux-gnu/libc.so.6+0x4300b)
 #5 0x00007f05b0600859 abort (/lib/x86_64-linux-gnu/libc.so.6+0x22859)
 #6 0x00007f05b0600729 (/lib/x86_64-linux-gnu/libc.so.6+0x22729)
 #7 0x00007f05b0611fd6 (/lib/x86_64-linux-gnu/libc.so.6+0x33fd6)
 #8 0x000055e6ac44cb98 clang::ASTContext::getASTRecordLayout(clang::RecordDecl const*) const (/opt/compiler-explorer/clang-assertions-trunk/bin/clang+++0x76dcb98)
 #9 0x000055e6abff4c21 clang::ASTContext::getTypeInfoImpl(clang::Type const*) const (/opt/compiler-explorer/clang-assertions-trunk/bin/clang+++0x7284c21)
#10 0x000055e6abff3d2f clang::ASTContext::getTypeInfo(clang::Type const*) const (/opt/compiler-explorer/clang-assertions-trunk/bin/clang+++0x7283d2f)
#11 0x000055e6abff3f9f clang::ASTContext::getTypeInfoImpl(clang::Type const*) const (/opt/compiler-explorer/clang-assertions-trunk/bin/clang+++0x7283f9f)
#12 0x000055e6abff3d2f clang::ASTContext::getTypeInfo(clang::Type const*) const (/opt/compiler-explorer/clang-assertions-trunk/bin/clang+++0x7283d2f)
#13 0x000055e6abff3f9f clang::ASTContext::getTypeInfoImpl(clang::Type const*) const (/opt/compiler-explorer/clang-assertions-trunk/bin/clang+++0x7283f9f)
#14 0x000055e6abff3d2f clang::ASTContext::getTypeInfo(clang::Type const*) const (/opt/compiler-explorer/clang-assertions-trunk/bin/clang+++0x7283d2f)
#15 0x000055e6ac0061db clang::ASTContext::getTypeAlignInChars(clang::QualType) const (/opt/compiler-explorer/clang-assertions-trunk/bin/clang+++0x72961db)
#16 0x000055e6aba37b4d clang::Sema::getNamedReturnInfo(clang::VarDecl const*) (/opt/compiler-explorer/clang-assertions-trunk/bin/clang+++0x6cc7b4d)
#17 0x000055e6aba37ca8 clang::Sema::getNamedReturnInfo(clang::Expr*&, clang::Sema::SimplerImplicitMoveMode) (/opt/compiler-explorer/clang-assertions-trunk/bin/clang+++0x6cc7ca8)
#18 0x000055e6aba6b8d4 clang::Sema::BuildReturnStmt(clang::SourceLocation, clang::Expr*, bool) (/opt/compiler-explorer/clang-assertions-trunk/bin/clang+++0x6cfb8d4)
#19 0x000055e6aba6dbff clang::Sema::ActOnReturnStmt(clang::SourceLocation, clang::Expr*, clang::Scope*) (/opt/compiler-explorer/clang-assertions-trunk/bin/clang+++0x6cfdbff)
#20 0x000055e6ab1ca08f clang::Parser::ParseReturnStatement() (/opt/compiler-explorer/clang-assertions-trunk/bin/clang+++0x645a08f)
#21 0x000055e6ab1cd280 clang::Parser::ParseStatementOrDeclarationAfterAttributes(llvm::SmallVector<clang::Stmt*, 32u>&, clang::Parser::ParsedStmtContext, clang::SourceLocation*, clang::ParsedAttributes&, clang::ParsedAttributes&) (/opt/compiler-explorer/clang-assertions-trunk/bin/clang+++0x645d280)
#22 0x000055e6ab1ce9b1 clang::Parser::ParseStatementOrDeclaration(llvm::SmallVector<clang::Stmt*, 32u>&, clang::Parser::ParsedStmtContext, clang::SourceLocation*) (/opt/compiler-explorer/clang-assertions-trunk/bin/clang+++0x645e9b1)
#23 0x000055e6ab1cf9a9 clang::Parser::ParseCompoundStatementBody(bool) (/opt/compiler-explorer/clang-assertions-trunk/bin/clang+++0x645f9a9)
#24 0x000055e6ab1d135a clang::Parser::ParseFunctionStatementBody(clang::Decl*, clang::Parser::ParseScope&) (/opt/compiler-explorer/clang-assertions-trunk/bin/clang+++0x646135a)
#25 0x000055e6ab0fbe81 clang::Parser::ParseFunctionDefinition(clang::ParsingDeclarator&, clang::Parser::ParsedTemplateInfo const&, clang::Parser::LateParsedAttrList*) (/opt/compiler-explorer/clang-assertions-trunk/bin/clang+++0x638be81)
#26 0x000055e6ab1eb08a clang::Parser::ParseSingleDeclarationAfterTemplate(clang::DeclaratorContext, clang::Parser::ParsedTemplateInfo const&, clang::ParsingDeclRAIIObject&, clang::SourceLocation&, clang::ParsedAttributes&, clang::AccessSpecifier) (/opt/compiler-explorer/clang-assertions-trunk/bin/clang+++0x647b08a)
#27 0x000055e6ab1f0cb6 clang::Parser::ParseTemplateDeclarationOrSpecialization(clang::DeclaratorContext, clang::SourceLocation&, clang::ParsedAttributes&, clang::AccessSpecifier) (.part.0) ParseTemplate.cpp:0:0
#28 0x000055e6ab1f0f33 clang::Parser::ParseDeclarationStartingWithTemplate(clang::DeclaratorContext, clang::SourceLocation&, clang::ParsedAttributes&, clang::AccessSpecifier) (/opt/compiler-explorer/clang-assertions-trunk/bin/clang+++0x6480f33)
#29 0x000055e6ab12b19e clang::Parser::ParseDeclaration(clang::DeclaratorContext, clang::SourceLocation&, clang::ParsedAttributes&, clang::ParsedAttributes&, clang::SourceLocation*) (/opt/compiler-explorer/clang-assertions-trunk/bin/clang+++0x63bb19e)
#30 0x000055e6ab0f63b4 clang::Parser::ParseExternalDeclaration(clang::ParsedAttributes&, clang::ParsedAttributes&, clang::ParsingDeclSpec*) (/opt/compiler-explorer/clang-assertions-trunk/bin/clang+++0x63863b4)
#31 0x000055e6ab0f72f6 clang::Parser::ParseTopLevelDecl(clang::OpaquePtr<clang::DeclGroupRef>&, clang::Sema::ModuleImportState&) (/opt/compiler-explorer/clang-assertions-trunk/bin/clang+++0x63872f6)
#32 0x000055e6ab0eb0ba clang::ParseAST(clang::Sema&, bool, bool) (/opt/compiler-explorer/clang-assertions-trunk/bin/clang+++0x637b0ba)
#33 0x000055e6a9beb598 clang::CodeGenAction::ExecuteAction() (/opt/compiler-explorer/clang-assertions-trunk/bin/clang+++0x4e7b598)
#34 0x000055e6a943bc79 clang::FrontendAction::Execute() (/opt/compiler-explorer/clang-assertions-trunk/bin/clang+++0x46cbc79)
#35 0x000055e6a93c0316 clang::CompilerInstance::ExecuteAction(clang::FrontendAction&) (/opt/compiler-explorer/clang-assertions-trunk/bin/clang+++0x4650316)
#36 0x000055e6a951e0b6 clang::ExecuteCompilerInvocation(clang::CompilerInstance*) (/opt/compiler-explorer/clang-assertions-trunk/bin/clang+++0x47ae0b6)
#37 0x000055e6a5e4116d cc1_main(llvm::ArrayRef<char const*>, char const*, void*) (/opt/compiler-explorer/clang-assertions-trunk/bin/clang+++0x10d116d)
#38 0x000055e6a5e3ce6a ExecuteCC1Tool(llvm::SmallVectorImpl<char const*>&, llvm::ToolContext const&) driver.cpp:0:0
#39 0x000055e6a9228c1d 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
#40 0x000055e6a88df8c0 llvm::CrashRecoveryContext::RunSafely(llvm::function_ref<void ()>) (/opt/compiler-explorer/clang-assertions-trunk/bin/clang+++0x3b6f8c0)
#41 0x000055e6a922923f 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
#42 0x000055e6a91f0a1c clang::driver::Compilation::ExecuteCommand(clang::driver::Command const&, clang::driver::Command const*&, bool) const (/opt/compiler-explorer/clang-assertions-trunk/bin/clang+++0x4480a1c)
#43 0x000055e6a91f14ad 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+++0x44814ad)
#44 0x000055e6a91f958d clang::driver::Driver::ExecuteCompilation(clang::driver::Compilation&, llvm::SmallVectorImpl<std::pair<int, clang::driver::Command const*>>&) (/opt/compiler-explorer/clang-assertions-trunk/bin/clang+++0x448958d)
#45 0x000055e6a5e3f3ca clang_main(int, char**, llvm::ToolContext const&) (/opt/compiler-explorer/clang-assertions-trunk/bin/clang+++0x10cf3ca)
#46 0x000055e6a5d462b5 main (/opt/compiler-explorer/clang-assertions-trunk/bin/clang+++0xfd62b5)
#47 0x00007f05b0602083 __libc_start_main (/lib/x86_64-linux-gnu/libc.so.6+0x24083)
#48 0x000055e6a5e37c4e _start (/opt/compiler-explorer/clang-assertions-trunk/bin/clang+++0x10c7c4e)
clang++: error: clang frontend command failed with exit code 134 (use -v to see invocation)
ASM generation compiler returned: 134

@shafik
Copy link
Collaborator

shafik commented Jun 11, 2023

Confirmed

@shafik
Copy link
Collaborator

shafik commented Jan 28, 2024

The case in: #79745 might be slightly simpler

@AMS21
Copy link
Contributor

AMS21 commented Jan 28, 2024

Looked a bit around and adding this patch prevents this crash and passes check-clang. Although I'm not sure if that would be the correct way to fix this since I'm not very familiar with the clang code base.

diff --git a/clang/lib/AST/ASTContext.cpp b/clang/lib/AST/ASTContext.cpp
index f7c9e4521b5f..d335df53679d 100644
--- a/clang/lib/AST/ASTContext.cpp
+++ b/clang/lib/AST/ASTContext.cpp
@@ -2284,6 +2284,9 @@ TypeInfo ASTContext::getTypeInfoImpl(const Type *T) const {
 
     const auto *RT = cast<RecordType>(TT);
     const RecordDecl *RD = RT->getDecl();
+    if (!RD->getDefinition())
+      break;
+
     const ASTRecordLayout &Layout = getASTRecordLayout(RD);
     Width = toBits(Layout.getSize());
     Align = toBits(Layout.getAlignment());

shafik added a commit to shafik/llvm-project that referenced this issue Jan 29, 2024
…rrors

In Sema in `BuildReturnStmt(...)` when we try to determine is the type is move
eligable or copy elidable we don't currently check of the init of the `VarDecl`
contain errors or not. This can lead to a crash since we may send a type that
is not complete into `getTypeInfo(...)` which does not allow this.

This fixes: llvm#63244
llvm#79745
@shafik
Copy link
Collaborator

shafik commented Jan 29, 2024

@AMS21 we assume we have a complete type at that point, so that is not a proper fix.

I had a fix earlier and just posted it: #79788

shafik added a commit to shafik/llvm-project that referenced this issue Jan 29, 2024
…rrors

In Sema in `BuildReturnStmt(...)` when we try to determine is the type is move
eligable or copy elidable we don't currently check of the init of the `VarDecl`
contain errors or not. This can lead to a crash since we may send a type that
is not complete into `getTypeInfo(...)` which does not allow this.

This fixes: llvm#63244
llvm#79745
shafik added a commit to shafik/llvm-project that referenced this issue Jan 29, 2024
…rrors

In Sema in `BuildReturnStmt(...)` when we try to determine is the type is move
eligable or copy elidable we don't currently check of the init of the `VarDecl`
contain errors or not. This can lead to a crash since we may send a type that
is not complete into `getTypeInfo(...)` which does not allow this.

This fixes: llvm#63244
llvm#79745
shafik added a commit that referenced this issue Jan 29, 2024
…rrors (#79788)

In Sema in `BuildReturnStmt(...)` when we try to determine is the type
is move eligible or copy elidable we don't currently check of the init
of the `VarDecl` contain errors or not. This can lead to a crash since
we may send a type that is not complete into `getTypeInfo(...)` which
does not allow this.

This fixes: #63244
#79745
ankurepa pushed a commit to ankurepa/llvm-project that referenced this issue Feb 7, 2024
…rrors (llvm#79788)

In Sema in `BuildReturnStmt(...)` when we try to determine is the type
is move eligible or copy elidable we don't currently check of the init
of the `VarDecl` contain errors or not. This can lead to a crash since
we may send a type that is not complete into `getTypeInfo(...)` which
does not allow this.

This fixes: llvm#63244
llvm#79745
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" confirmed Verified by a second party crash-on-invalid
Projects
None yet
Development

Successfully merging a pull request may close this issue.

5 participants