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 with variadic templates in function args #67395

Closed
brutalsavage opened this issue Sep 26, 2023 · 5 comments · Fixed by #67514
Closed

Clang frontend C++ crash with variadic templates in function args #67395

brutalsavage opened this issue Sep 26, 2023 · 5 comments · Fixed by #67514
Labels
clang:frontend Language frontend issues, e.g. anything involving "Sema" confirmed Verified by a second party crash-on-valid

Comments

@brutalsavage
Copy link

To quickly reproduce: https://gcc.godbolt.org/z/E6ceGq5eP (assertion-trunk)

#include <concepts>

template <typename... T>
void f1(bool B = (std::integral<T> ||...)) {
}

Compiling the above valid code crashes clang clang++ -x c++ --std=c++20 , crashes locally using clang-17.0 (a10019a), also on trunk with assertion (see godbolt link). Furthermore, GCC compiles the above code without any issue (see godbolt link)

@github-actions github-actions bot added the clang Clang issues not falling into any other category label Sep 26, 2023
@brutalsavage
Copy link
Author

Assertion

clang++: /root/llvm-project/llvm/include/llvm/Support/Casting.h:662: 
decltype(auto) llvm::dyn_cast(From*) [with To = clang::BinaryOperator; From = const clang::Stmt]: 
Assertion `detail::isPresent(Val) && "dyn_cast on a non-existent value"' 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 --std=c++20 <source>
1.	<source>:4:42: current parser token ')'
 #0 0x00000000037000b8 llvm::sys::PrintStackTrace(llvm::raw_ostream&, int) (/opt/compiler-explorer/clang-assertions-trunk/bin/clang+++0x37000b8)
 #1 0x00000000036fdd7c llvm::sys::CleanupOnSignal(unsigned long) (/opt/compiler-explorer/clang-assertions-trunk/bin/clang+++0x36fdd7c)
 #2 0x0000000003646908 CrashRecoverySignalHandler(int) CrashRecoveryContext.cpp:0:0
 #3 0x00007fc9941d0420 __restore_rt (/lib/x86_64-linux-gnu/libpthread.so.0+0x14420)
 #4 0x00007fc993c9300b raise (/lib/x86_64-linux-gnu/libc.so.6+0x4300b)
 #5 0x00007fc993c72859 abort (/lib/x86_64-linux-gnu/libc.so.6+0x22859)
 #6 0x00007fc993c72729 (/lib/x86_64-linux-gnu/libc.so.6+0x22729)
 #7 0x00007fc993c83fd6 (/lib/x86_64-linux-gnu/libc.so.6+0x33fd6)
 #8 0x00000000062679f1 clang::StmtVisitorBase<llvm::make_const_ptr, (anonymous namespace)::CheckDefaultArgumentVisitor, bool>::Visit(clang::Stmt const*) SemaDeclCXX.cpp:0:0
 #9 0x0000000006267f94 (anonymous namespace)::CheckDefaultArgumentVisitor::VisitExpr(clang::Expr const*) SemaDeclCXX.cpp:0:0
#10 0x00000000062675f1 clang::StmtVisitorBase<llvm::make_const_ptr, (anonymous namespace)::CheckDefaultArgumentVisitor, bool>::Visit(clang::Stmt const*) SemaDeclCXX.cpp:0:0
#11 0x0000000006267d64 clang::Sema::ActOnParamDefaultArgument(clang::Decl*, clang::SourceLocation, clang::Expr*) (/opt/compiler-explorer/clang-assertions-trunk/bin/clang+++0x6267d64)
#12 0x0000000005ea345d clang::Parser::ParseParameterDeclarationClause(clang::DeclaratorContext, clang::ParsedAttributes&, llvm::SmallVectorImpl<clang::DeclaratorChunk::ParamInfo>&, clang::SourceLocation&, bool) (/opt/compiler-explorer/clang-assertions-trunk/bin/clang+++0x5ea345d)
#13 0x0000000005ea3f78 clang::Parser::ParseFunctionDeclarator(clang::Declarator&, clang::ParsedAttributes&, clang::BalancedDelimiterTracker&, bool, bool) (/opt/compiler-explorer/clang-assertions-trunk/bin/clang+++0x5ea3f78)
#14 0x0000000005ea7c5f clang::Parser::ParseDirectDeclarator(clang::Declarator&) (/opt/compiler-explorer/clang-assertions-trunk/bin/clang+++0x5ea7c5f)
#15 0x0000000005e96e50 clang::Parser::ParseDeclaratorInternal(clang::Declarator&, void (clang::Parser::*)(clang::Declarator&)) (/opt/compiler-explorer/clang-assertions-trunk/bin/clang+++0x5e96e50)
#16 0x0000000005fb5111 clang::Sema::runWithSufficientStackSpace(clang::SourceLocation, llvm::function_ref<void ()>) (/opt/compiler-explorer/clang-assertions-trunk/bin/clang+++0x5fb5111)
#17 0x0000000005e8690f clang::Parser::ParseDeclarator(clang::Declarator&) (/opt/compiler-explorer/clang-assertions-trunk/bin/clang+++0x5e8690f)
#18 0x0000000005f5e822 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+++0x5f5e822)
#19 0x0000000005f648c8 clang::Parser::ParseTemplateDeclarationOrSpecialization(clang::DeclaratorContext, clang::SourceLocation&, clang::ParsedAttributes&, clang::AccessSpecifier) (.part.0) ParseTemplate.cpp:0:0
#20 0x0000000005f64b83 clang::Parser::ParseDeclarationStartingWithTemplate(clang::DeclaratorContext, clang::SourceLocation&, clang::ParsedAttributes&, clang::AccessSpecifier) (/opt/compiler-explorer/clang-assertions-trunk/bin/clang+++0x5f64b83)
#21 0x0000000005ea28bb clang::Parser::ParseDeclaration(clang::DeclaratorContext, clang::SourceLocation&, clang::ParsedAttributes&, clang::ParsedAttributes&, clang::SourceLocation*) (/opt/compiler-explorer/clang-assertions-trunk/bin/clang+++0x5ea28bb)
#22 0x0000000005e6d6c4 clang::Parser::ParseExternalDeclaration(clang::ParsedAttributes&, clang::ParsedAttributes&, clang::ParsingDeclSpec*) (/opt/compiler-explorer/clang-assertions-trunk/bin/clang+++0x5e6d6c4)
#23 0x0000000005e6e5cd clang::Parser::ParseTopLevelDecl(clang::OpaquePtr<clang::DeclGroupRef>&, clang::Sema::ModuleImportState&) (/opt/compiler-explorer/clang-assertions-trunk/bin/clang+++0x5e6e5cd)
#24 0x0000000005e6290a clang::ParseAST(clang::Sema&, bool, bool) (/opt/compiler-explorer/clang-assertions-trunk/bin/clang+++0x5e6290a)
#25 0x0000000004966c88 clang::CodeGenAction::ExecuteAction() (/opt/compiler-explorer/clang-assertions-trunk/bin/clang+++0x4966c88)
#26 0x00000000041cd289 clang::FrontendAction::Execute() (/opt/compiler-explorer/clang-assertions-trunk/bin/clang+++0x41cd289)
#27 0x000000000414dfde clang::CompilerInstance::ExecuteAction(clang::FrontendAction&) (/opt/compiler-explorer/clang-assertions-trunk/bin/clang+++0x414dfde)
#28 0x00000000042ac50e clang::ExecuteCompilerInvocation(clang::CompilerInstance*) (/opt/compiler-explorer/clang-assertions-trunk/bin/clang+++0x42ac50e)
#29 0x0000000000bdc4b6 cc1_main(llvm::ArrayRef<char const*>, char const*, void*) (/opt/compiler-explorer/clang-assertions-trunk/bin/clang+++0xbdc4b6)
#30 0x0000000000bd3d7a ExecuteCC1Tool(llvm::SmallVectorImpl<char const*>&, llvm::ToolContext const&) driver.cpp:0:0
#31 0x0000000003fabcc9 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
#32 0x0000000003646db4 llvm::CrashRecoveryContext::RunSafely(llvm::function_ref<void ()>) (/opt/compiler-explorer/clang-assertions-trunk/bin/clang+++0x3646db4)
#33 0x0000000003fac2bf 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
#34 0x0000000003f74605 clang::driver::Compilation::ExecuteCommand(clang::driver::Command const&, clang::driver::Command const*&, bool) const (/opt/compiler-explorer/clang-assertions-trunk/bin/clang+++0x3f74605)
#35 0x0000000003f7506d 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+++0x3f7506d)
#36 0x0000000003f7cf95 clang::driver::Driver::ExecuteCompilation(clang::driver::Compilation&, llvm::SmallVectorImpl<std::pair<int, clang::driver::Command const*>>&) (/opt/compiler-explorer/clang-assertions-trunk/bin/clang+++0x3f7cf95)
#37 0x0000000000bd995c clang_main(int, char**, llvm::ToolContext const&) (/opt/compiler-explorer/clang-assertions-trunk/bin/clang+++0xbd995c)
#38 0x0000000000ad4821 main (/opt/compiler-explorer/clang-assertions-trunk/bin/clang+++0xad4821)
#39 0x00007fc993c74083 __libc_start_main (/lib/x86_64-linux-gnu/libc.so.6+0x24083)
#40 0x0000000000bd385e _start (/opt/compiler-explorer/clang-assertions-trunk/bin/clang+++0xbd385e)
clang++: error: clang frontend command failed with exit code 134 (use -v to see invocation)
Compiler returned: 134

@tbaederr tbaederr added clang:frontend Language frontend issues, e.g. anything involving "Sema" crash-on-valid and removed clang Clang issues not falling into any other category labels Sep 26, 2023
@llvmbot
Copy link
Collaborator

llvmbot commented Sep 26, 2023

@llvm/issue-subscribers-clang-frontend

To quickly reproduce: https://gcc.godbolt.org/z/E6ceGq5eP (assertion-trunk)
#include &lt;concepts&gt;

template &lt;typename... T&gt;
void f1(bool B = (std::integral&lt;T&gt; ||...)) {
}

Compiling the above valid code crashes clang clang++ -x c++ --std=c++20 , crashes locally using clang-17.0 (a10019a), also on trunk with assertion (see godbolt link). Furthermore, GCC compiles the above code without any issue (see godbolt link)

@shafik
Copy link
Collaborator

shafik commented Sep 26, 2023

Removed need for header: https://gcc.godbolt.org/z/oGnvae7KK

template <typename T>
concept C = true;

template <typename... T>
void f1(bool B = (C<T> || ...)) {
}

@shafik
Copy link
Collaborator

shafik commented Sep 26, 2023

When I dump the CXXFoldExpr, we have this:

CXXFoldExpr 0x10f873d08 '<dependent type>'
|-<<<NULL>>>
|-ConceptSpecializationExpr 0x10f873ce0 '_Bool' Concept 0x10f873a78 'C'
| |-ImplicitConceptSpecializationDecl 0x10f873c28 
| | `-TemplateArgument type 'type-parameter-0-0'
| |   `-TemplateTypeParmType 0x10f873b20 'type-parameter-0-0' dependent contains_unexpanded_pack depth 0 index 0 pack
| `-TemplateArgument type 'T'
|   `-TemplateTypeParmType 0x10f873b50 'T' dependent contains_unexpanded_pack depth 0 index 0 pack
|     `-TemplateTypeParm 0x10f873ac8 'T'
`-<<<NULL>>>

but here:

bool CheckDefaultArgumentVisitor::VisitExpr(const Expr *Node) {
bool IsInvalid = false;
for (const Stmt *SubStmt : Node->children())
IsInvalid |= Visit(SubStmt);

we iterate over the children as if they can not be NULL which from what it looks like looking at other visitors that is not a correct assumption.

@shafik shafik added the confirmed Verified by a second party label Sep 26, 2023
@shafik
Copy link
Collaborator

shafik commented Sep 27, 2023

Simplified to not require concepts:

template <typename>
bool f();

template <typename... T>
void g(bool = (f<T>() || ...));

shafik added a commit to shafik/llvm-project that referenced this issue Sep 27, 2023
CheckDefaultArgumentVisitor::Visit(...) assumes that the children of Expr will
not be NULL. This is not a valid assumption and when we have a CXXFoldExpr
the children can be NULL and this causes a crash.

Fixes: llvm#67395
shafik added a commit that referenced this issue Sep 28, 2023
#67514)

CheckDefaultArgumentVisitor::Visit(...) assumes that the children of
Expr will not be NULL. This is not a valid assumption and when we have a
CXXFoldExpr the children can be NULL and this causes a crash.

Fixes: #67395
legrosbuffle pushed a commit to legrosbuffle/llvm-project that referenced this issue Sep 29, 2023
llvm#67514)

CheckDefaultArgumentVisitor::Visit(...) assumes that the children of
Expr will not be NULL. This is not a valid assumption and when we have a
CXXFoldExpr the children can be NULL and this causes a crash.

Fixes: llvm#67395
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-valid
Projects
None yet
Development

Successfully merging a pull request may close this issue.

4 participants