llvm / llvm-project

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

[clang] Ill-formed block expressions within a lambda can yield assert-failures #109148

Closed katzdm closed 4 weeks ago

katzdm commented 1 month ago

The following program produces an assert failure with a clang binary built with assertions, when compiled with -fblocks:

template<typename... Ts>
struct Cls {
  static_assert([] consteval -> void {
    (^Ts);
  });
};

The assertion:

Assertion failed: ((!Unexpanded.empty() || Visitor.containsFunctionParmPackExpr()) && "Unable to find unexpanded parameter packs"), function DiagnoseUnexpandedParameterPack, file SemaTemplateVariadic.cpp, line 467.
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: /Users/dkatz85/src/bloomberg/clang-p2996/build-llvm/bin/clang-20 -cc1 -triple arm64-apple-macosx14.0.0 -Wundef-prefix=TARGET_OS_ -Werror=undef-prefix -Wdeprecated-objc-isa-usage -Werror=deprecated-objc-isa-usage -emit-obj -dumpdir build-llvm/main.tsk- -disable-free -clear-ast-before-backend -main-file-name main.cpp -mrelocation-model pic -pic-level 2 -mframe-pointer=non-leaf -ffp-contract=on -fno-rounding-math -funwind-tables=1 -target-sdk-version=15.0 -fcompatibility-qualified-id-block-type-checking -fvisibility-inlines-hidden-static-local-var -fdefine-target-os-macros -fno-modulemap-allow-subdirectory-search -target-cpu apple-m1 -target-feature +zcm -target-feature +zcz -target-feature +v8.4a -target-feature +aes -target-feature +altnzcv -target-feature +ccdp -target-feature +complxnum -target-feature +crc -target-feature +dotprod -target-feature +fp-armv8 -target-feature +fp16fml -target-feature +fptoint -target-feature +fullfp16 -target-feature +jsconv -target-feature +lse -target-feature +neon -target-feature +pauth -target-feature +perfmon -target-feature +predres -target-feature +ras -target-feature +rcpc -target-feature +rdm -target-feature +sb -target-feature +sha2 -target-feature +sha3 -target-feature +specrestrict -target-feature +ssbs -target-abi darwinpcs -debug-info-kind=standalone -dwarf-version=4 -debugger-tuning=lldb -fdebug-compilation-dir=/Users/dkatz85/src/bloomberg/clang-p2996 -target-linker-version 1053.12 -fcoverage-compilation-dir=/Users/dkatz85/src/bloomberg/clang-p2996 -resource-dir /Users/dkatz85/src/bloomberg/clang-p2996/build-llvm/lib/clang/20 -isysroot /Library/Developer/CommandLineTools/SDKs/MacOSX.sdk -internal-isystem /Users/dkatz85/src/bloomberg/clang-p2996/build-llvm/bin/../include/c++/v1 -internal-isystem /Library/Developer/CommandLineTools/SDKs/MacOSX.sdk/usr/local/include -internal-isystem /Users/dkatz85/src/bloomberg/clang-p2996/build-llvm/lib/clang/20/include -internal-externc-isystem /Library/Developer/CommandLineTools/SDKs/MacOSX.sdk/usr/include -std=c++26 -fdeprecated-macro -fbracket-depth 1500 -ferror-limit 30 -stack-protector 1 -freflection -freflection-new-syntax -fparameter-reflection -fannotation-attributes -fconsteval-blocks -fexpansion-statements -fblocks -fencode-extended-block-signature -fregister-global-dtors-with-atexit -fgnuc-version=4.2.1 -fno-implicit-modules -fskip-odr-check-in-gmf -fcxx-exceptions -fexceptions -freflection-latest -fmax-type-align=16 -fcolor-diagnostics -D__GCC_HAVE_DWARF2_CFI_ASM=1 -o /var/folders/cp/8xfkfz156mx13fdc89796sv40000gq/T/main-f5020e.o -x c++ main.cpp
1.  main.cpp:2:57: current parser token ')'
 #0 0x00000001026f5684 llvm::sys::PrintStackTrace(llvm::raw_ostream&, int) (/Users/dkatz85/src/bloomberg/clang-p2996/build-llvm/bin/clang-20+0x102609684)
 #1 0x00000001026f3748 llvm::sys::RunSignalHandlers() (/Users/dkatz85/src/bloomberg/clang-p2996/build-llvm/bin/clang-20+0x102607748)
 #2 0x00000001026f5cf0 SignalHandler(int) (/Users/dkatz85/src/bloomberg/clang-p2996/build-llvm/bin/clang-20+0x102609cf0)
 #3 0x0000000182f3e584 (/usr/lib/system/libsystem_platform.dylib+0x18047a584)
 #4 0x0000000182f0dc20 (/usr/lib/system/libsystem_pthread.dylib+0x180449c20)
 #5 0x0000000182e1aa30 (/usr/lib/system/libsystem_c.dylib+0x180356a30)
 #6 0x0000000182e19d20 (/usr/lib/system/libsystem_c.dylib+0x180355d20)
 #7 0x00000001055ef650 clang::Sema::DiagnoseUnexpandedParameterPackInRequiresExpr(clang::RequiresExpr*) (.cold.1) (/Users/dkatz85/src/bloomberg/clang-p2996/build-llvm/bin/clang-20+0x105503650)
 #8 0x000000010496d01c clang::Sema::DiagnoseUnexpandedParameterPack(clang::Expr*, clang::Sema::UnexpandedParameterPackContext) (/Users/dkatz85/src/bloomberg/clang-p2996/build-llvm/bin/clang-20+0x10488101c)
 #9 0x00000001043569d8 clang::Sema::ActOnParamDefaultArgument(clang::Decl*, clang::SourceLocation, clang::Expr*) (/Users/dkatz85/src/bloomberg/clang-p2996/build-llvm/bin/clang-20+0x10426a9d8)
#10 0x000000010401ec1c clang::Parser::ParseParameterDeclarationClause(clang::DeclaratorContext, clang::ParsedAttributes&, llvm::SmallVectorImpl<clang::DeclaratorChunk::ParamInfo>&, clang::SourceLocation&, bool) (/Users/dkatz85/src/bloomberg/clang-p2996/build-llvm/bin/clang-20+0x103f32c1c)
#11 0x000000010401bd88 clang::Parser::ParseFunctionDeclarator(clang::Declarator&, clang::ParsedAttributes&, clang::BalancedDelimiterTracker&, bool, bool) (/Users/dkatz85/src/bloomberg/clang-p2996/build-llvm/bin/clang-20+0x103f2fd88)
#12 0x0000000104019cb8 clang::Parser::ParseDirectDeclarator(clang::Declarator&) (/Users/dkatz85/src/bloomberg/clang-p2996/build-llvm/bin/clang-20+0x103f2dcb8)
#13 0x0000000104017fb8 clang::Parser::ParseDeclaratorInternal(clang::Declarator&, void (clang::Parser::*)(clang::Declarator&)) (/Users/dkatz85/src/bloomberg/clang-p2996/build-llvm/bin/clang-20+0x103f2bfb8)
#14 0x0000000104171358 clang::Sema::runWithSufficientStackSpace(clang::SourceLocation, llvm::function_ref<void ()>) (/Users/dkatz85/src/bloomberg/clang-p2996/build-llvm/bin/clang-20+0x104085358)
#15 0x0000000104008520 clang::Parser::ParseDeclGroup(clang::ParsingDeclSpec&, clang::DeclaratorContext, clang::ParsedAttributes&, clang::Parser::ParsedTemplateInfo&, clang::SourceLocation*, clang::Parser::ForRangeInit*) (/Users/dkatz85/src/bloomberg/clang-p2996/build-llvm/bin/clang-20+0x103f1c520)
#16 0x00000001040af4ec clang::Parser::ParseDeclarationAfterTemplate(clang::DeclaratorContext, clang::Parser::ParsedTemplateInfo&, clang::ParsingDeclRAIIObject&, clang::SourceLocation&, clang::ParsedAttributes&, clang::AccessSpecifier) (/Users/dkatz85/src/bloomberg/clang-p2996/build-llvm/bin/clang-20+0x103fc34ec)
#17 0x00000001040ae744 clang::Parser::ParseTemplateDeclarationOrSpecialization(clang::DeclaratorContext, clang::SourceLocation&, clang::ParsedAttributes&, clang::AccessSpecifier) (/Users/dkatz85/src/bloomberg/clang-p2996/build-llvm/bin/clang-20+0x103fc2744)
#18 0x00000001040ae070 clang::Parser::ParseDeclarationStartingWithTemplate(clang::DeclaratorContext, clang::SourceLocation&, clang::ParsedAttributes&) (/Users/dkatz85/src/bloomberg/clang-p2996/build-llvm/bin/clang-20+0x103fc2070)
#19 0x0000000104007374 clang::Parser::ParseDeclaration(clang::DeclaratorContext, clang::SourceLocation&, clang::ParsedAttributes&, clang::ParsedAttributes&, clang::SourceLocation*) (/Users/dkatz85/src/bloomberg/clang-p2996/build-llvm/bin/clang-20+0x103f1b374)
#20 0x00000001040be608 clang::Parser::ParseExternalDeclaration(clang::ParsedAttributes&, clang::ParsedAttributes&, clang::ParsingDeclSpec*) (/Users/dkatz85/src/bloomberg/clang-p2996/build-llvm/bin/clang-20+0x103fd2608)
#21 0x00000001040bcee8 clang::Parser::ParseTopLevelDecl(clang::OpaquePtr<clang::DeclGroupRef>&, clang::Sema::ModuleImportState&) (/Users/dkatz85/src/bloomberg/clang-p2996/build-llvm/bin/clang-20+0x103fd0ee8)
#22 0x00000001040bc6b8 clang::Parser::ParseFirstTopLevelDecl(clang::OpaquePtr<clang::DeclGroupRef>&, clang::Sema::ModuleImportState&) (/Users/dkatz85/src/bloomberg/clang-p2996/build-llvm/bin/clang-20+0x103fd06b8)
#23 0x0000000103ff1510 clang::ParseAST(clang::Sema&, bool, bool) (/Users/dkatz85/src/bloomberg/clang-p2996/build-llvm/bin/clang-20+0x103f05510)
#24 0x00000001031a35c4 clang::FrontendAction::Execute() (/Users/dkatz85/src/bloomberg/clang-p2996/build-llvm/bin/clang-20+0x1030b75c4)
#25 0x0000000103132998 clang::CompilerInstance::ExecuteAction(clang::FrontendAction&) (/Users/dkatz85/src/bloomberg/clang-p2996/build-llvm/bin/clang-20+0x103046998)
#26 0x000000010321e8e8 clang::ExecuteCompilerInvocation(clang::CompilerInstance*) (/Users/dkatz85/src/bloomberg/clang-p2996/build-llvm/bin/clang-20+0x1031328e8)
#27 0x00000001000f5844 cc1_main(llvm::ArrayRef<char const*>, char const*, void*) (/Users/dkatz85/src/bloomberg/clang-p2996/build-llvm/bin/clang-20+0x100009844)
#28 0x00000001000f2ee8 ExecuteCC1Tool(llvm::SmallVectorImpl<char const*>&, llvm::ToolContext const&) (/Users/dkatz85/src/bloomberg/clang-p2996/build-llvm/bin/clang-20+0x100006ee8)
#29 0x00000001000f236c clang_main(int, char**, llvm::ToolContext const&) (/Users/dkatz85/src/bloomberg/clang-p2996/build-llvm/bin/clang-20+0x10000636c)
#30 0x00000001000fe674 main (/Users/dkatz85/src/bloomberg/clang-p2996/build-llvm/bin/clang-20+0x100012674)
#31 0x0000000182b83154 
clang++: error: unable to execute command: Abort trap: 6
clang++: error: clang frontend command failed due to signal (use -v to see invocation)

Here is another example that fails the same assertion:

template <typename... Ts>
void fn(int = [] consteval -> int { (^Ts); return 0; }());

Both have the same root cause:

  1. While parsing the CompoundStmt body of the lambda, clang begins to parse ^Ts as a BlockExpr.
  2. The Sema::ActOnBlockArguments function invokes DiagnoseUnexpandedParameterPacks, which sets LambdaScopeInfo::ContainsUnexpandedParameterPacks to true, prior to recognizing that the BlockExpr is ill-formed.
  3. The ill-formed BlockExpr is diagnosed, and is subsequently discarded from the CompoundStmt representing the body of the lambda.
  4. The LambdaScopeInfo is used to initialize the LambdaExpr, resulting in LambdaExpr::ContainsUnexpandedParameterPack being set to true.
  5. The LambdaExpr becomes an argument to some other semantic construct (e.g., StaticAssertDecl, ParameterDecl), whose semantic analysis calls DiagnoseUnexpandedParameterPack.
  6. The above assertion triggers because the LambdaExpr reports that it contains an unexpanded parameter pack, but the tree walk fails to find any pack (since the ill-formed BlockExpr was discarded from the CompoundStmt).

Although I can imagine a few ways to patch this (e.g., keep an "error" representation of the ill-formed BlockExpr in CompoundStmt, rollback the setting of LambdaScopeInfo::ContainsUnexpandedParameterPack when the BlockExpr is ill-formed, just remove the assertion from DiagnoseUnexpandedParameterPacks), I'm not sure I love any of them. For now, I figured I'd just report the issue.

llvmbot commented 1 month ago

@llvm/issue-subscribers-clang-frontend

Author: Daniel M. Katz (katzdm)

The following program produces an assert failure with a `clang` binary built with assertions, when compiled with `-fblocks`: ```cpp template<typename... Ts> struct Cls { static_assert([] consteval -> void { (^Ts); }); }; ``` The assertion: ``` Assertion failed: ((!Unexpanded.empty() || Visitor.containsFunctionParmPackExpr()) && "Unable to find unexpanded parameter packs"), function DiagnoseUnexpandedParameterPack, file SemaTemplateVariadic.cpp, line 467. 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: /Users/dkatz85/src/bloomberg/clang-p2996/build-llvm/bin/clang-20 -cc1 -triple arm64-apple-macosx14.0.0 -Wundef-prefix=TARGET_OS_ -Werror=undef-prefix -Wdeprecated-objc-isa-usage -Werror=deprecated-objc-isa-usage -emit-obj -dumpdir build-llvm/main.tsk- -disable-free -clear-ast-before-backend -main-file-name main.cpp -mrelocation-model pic -pic-level 2 -mframe-pointer=non-leaf -ffp-contract=on -fno-rounding-math -funwind-tables=1 -target-sdk-version=15.0 -fcompatibility-qualified-id-block-type-checking -fvisibility-inlines-hidden-static-local-var -fdefine-target-os-macros -fno-modulemap-allow-subdirectory-search -target-cpu apple-m1 -target-feature +zcm -target-feature +zcz -target-feature +v8.4a -target-feature +aes -target-feature +altnzcv -target-feature +ccdp -target-feature +complxnum -target-feature +crc -target-feature +dotprod -target-feature +fp-armv8 -target-feature +fp16fml -target-feature +fptoint -target-feature +fullfp16 -target-feature +jsconv -target-feature +lse -target-feature +neon -target-feature +pauth -target-feature +perfmon -target-feature +predres -target-feature +ras -target-feature +rcpc -target-feature +rdm -target-feature +sb -target-feature +sha2 -target-feature +sha3 -target-feature +specrestrict -target-feature +ssbs -target-abi darwinpcs -debug-info-kind=standalone -dwarf-version=4 -debugger-tuning=lldb -fdebug-compilation-dir=/Users/dkatz85/src/bloomberg/clang-p2996 -target-linker-version 1053.12 -fcoverage-compilation-dir=/Users/dkatz85/src/bloomberg/clang-p2996 -resource-dir /Users/dkatz85/src/bloomberg/clang-p2996/build-llvm/lib/clang/20 -isysroot /Library/Developer/CommandLineTools/SDKs/MacOSX.sdk -internal-isystem /Users/dkatz85/src/bloomberg/clang-p2996/build-llvm/bin/../include/c++/v1 -internal-isystem /Library/Developer/CommandLineTools/SDKs/MacOSX.sdk/usr/local/include -internal-isystem /Users/dkatz85/src/bloomberg/clang-p2996/build-llvm/lib/clang/20/include -internal-externc-isystem /Library/Developer/CommandLineTools/SDKs/MacOSX.sdk/usr/include -std=c++26 -fdeprecated-macro -fbracket-depth 1500 -ferror-limit 30 -stack-protector 1 -freflection -freflection-new-syntax -fparameter-reflection -fannotation-attributes -fconsteval-blocks -fexpansion-statements -fblocks -fencode-extended-block-signature -fregister-global-dtors-with-atexit -fgnuc-version=4.2.1 -fno-implicit-modules -fskip-odr-check-in-gmf -fcxx-exceptions -fexceptions -freflection-latest -fmax-type-align=16 -fcolor-diagnostics -D__GCC_HAVE_DWARF2_CFI_ASM=1 -o /var/folders/cp/8xfkfz156mx13fdc89796sv40000gq/T/main-f5020e.o -x c++ main.cpp 1. main.cpp:2:57: current parser token ')' #0 0x00000001026f5684 llvm::sys::PrintStackTrace(llvm::raw_ostream&, int) (/Users/dkatz85/src/bloomberg/clang-p2996/build-llvm/bin/clang-20+0x102609684) #1 0x00000001026f3748 llvm::sys::RunSignalHandlers() (/Users/dkatz85/src/bloomberg/clang-p2996/build-llvm/bin/clang-20+0x102607748) #2 0x00000001026f5cf0 SignalHandler(int) (/Users/dkatz85/src/bloomberg/clang-p2996/build-llvm/bin/clang-20+0x102609cf0) #3 0x0000000182f3e584 (/usr/lib/system/libsystem_platform.dylib+0x18047a584) #4 0x0000000182f0dc20 (/usr/lib/system/libsystem_pthread.dylib+0x180449c20) #5 0x0000000182e1aa30 (/usr/lib/system/libsystem_c.dylib+0x180356a30) #6 0x0000000182e19d20 (/usr/lib/system/libsystem_c.dylib+0x180355d20) #7 0x00000001055ef650 clang::Sema::DiagnoseUnexpandedParameterPackInRequiresExpr(clang::RequiresExpr*) (.cold.1) (/Users/dkatz85/src/bloomberg/clang-p2996/build-llvm/bin/clang-20+0x105503650) #8 0x000000010496d01c clang::Sema::DiagnoseUnexpandedParameterPack(clang::Expr*, clang::Sema::UnexpandedParameterPackContext) (/Users/dkatz85/src/bloomberg/clang-p2996/build-llvm/bin/clang-20+0x10488101c) #9 0x00000001043569d8 clang::Sema::ActOnParamDefaultArgument(clang::Decl*, clang::SourceLocation, clang::Expr*) (/Users/dkatz85/src/bloomberg/clang-p2996/build-llvm/bin/clang-20+0x10426a9d8) #10 0x000000010401ec1c clang::Parser::ParseParameterDeclarationClause(clang::DeclaratorContext, clang::ParsedAttributes&, llvm::SmallVectorImpl<clang::DeclaratorChunk::ParamInfo>&, clang::SourceLocation&, bool) (/Users/dkatz85/src/bloomberg/clang-p2996/build-llvm/bin/clang-20+0x103f32c1c) #11 0x000000010401bd88 clang::Parser::ParseFunctionDeclarator(clang::Declarator&, clang::ParsedAttributes&, clang::BalancedDelimiterTracker&, bool, bool) (/Users/dkatz85/src/bloomberg/clang-p2996/build-llvm/bin/clang-20+0x103f2fd88) #12 0x0000000104019cb8 clang::Parser::ParseDirectDeclarator(clang::Declarator&) (/Users/dkatz85/src/bloomberg/clang-p2996/build-llvm/bin/clang-20+0x103f2dcb8) #13 0x0000000104017fb8 clang::Parser::ParseDeclaratorInternal(clang::Declarator&, void (clang::Parser::*)(clang::Declarator&)) (/Users/dkatz85/src/bloomberg/clang-p2996/build-llvm/bin/clang-20+0x103f2bfb8) #14 0x0000000104171358 clang::Sema::runWithSufficientStackSpace(clang::SourceLocation, llvm::function_ref<void ()>) (/Users/dkatz85/src/bloomberg/clang-p2996/build-llvm/bin/clang-20+0x104085358) #15 0x0000000104008520 clang::Parser::ParseDeclGroup(clang::ParsingDeclSpec&, clang::DeclaratorContext, clang::ParsedAttributes&, clang::Parser::ParsedTemplateInfo&, clang::SourceLocation*, clang::Parser::ForRangeInit*) (/Users/dkatz85/src/bloomberg/clang-p2996/build-llvm/bin/clang-20+0x103f1c520) #16 0x00000001040af4ec clang::Parser::ParseDeclarationAfterTemplate(clang::DeclaratorContext, clang::Parser::ParsedTemplateInfo&, clang::ParsingDeclRAIIObject&, clang::SourceLocation&, clang::ParsedAttributes&, clang::AccessSpecifier) (/Users/dkatz85/src/bloomberg/clang-p2996/build-llvm/bin/clang-20+0x103fc34ec) #17 0x00000001040ae744 clang::Parser::ParseTemplateDeclarationOrSpecialization(clang::DeclaratorContext, clang::SourceLocation&, clang::ParsedAttributes&, clang::AccessSpecifier) (/Users/dkatz85/src/bloomberg/clang-p2996/build-llvm/bin/clang-20+0x103fc2744) #18 0x00000001040ae070 clang::Parser::ParseDeclarationStartingWithTemplate(clang::DeclaratorContext, clang::SourceLocation&, clang::ParsedAttributes&) (/Users/dkatz85/src/bloomberg/clang-p2996/build-llvm/bin/clang-20+0x103fc2070) #19 0x0000000104007374 clang::Parser::ParseDeclaration(clang::DeclaratorContext, clang::SourceLocation&, clang::ParsedAttributes&, clang::ParsedAttributes&, clang::SourceLocation*) (/Users/dkatz85/src/bloomberg/clang-p2996/build-llvm/bin/clang-20+0x103f1b374) #20 0x00000001040be608 clang::Parser::ParseExternalDeclaration(clang::ParsedAttributes&, clang::ParsedAttributes&, clang::ParsingDeclSpec*) (/Users/dkatz85/src/bloomberg/clang-p2996/build-llvm/bin/clang-20+0x103fd2608) #21 0x00000001040bcee8 clang::Parser::ParseTopLevelDecl(clang::OpaquePtr<clang::DeclGroupRef>&, clang::Sema::ModuleImportState&) (/Users/dkatz85/src/bloomberg/clang-p2996/build-llvm/bin/clang-20+0x103fd0ee8) #22 0x00000001040bc6b8 clang::Parser::ParseFirstTopLevelDecl(clang::OpaquePtr<clang::DeclGroupRef>&, clang::Sema::ModuleImportState&) (/Users/dkatz85/src/bloomberg/clang-p2996/build-llvm/bin/clang-20+0x103fd06b8) #23 0x0000000103ff1510 clang::ParseAST(clang::Sema&, bool, bool) (/Users/dkatz85/src/bloomberg/clang-p2996/build-llvm/bin/clang-20+0x103f05510) #24 0x00000001031a35c4 clang::FrontendAction::Execute() (/Users/dkatz85/src/bloomberg/clang-p2996/build-llvm/bin/clang-20+0x1030b75c4) #25 0x0000000103132998 clang::CompilerInstance::ExecuteAction(clang::FrontendAction&) (/Users/dkatz85/src/bloomberg/clang-p2996/build-llvm/bin/clang-20+0x103046998) #26 0x000000010321e8e8 clang::ExecuteCompilerInvocation(clang::CompilerInstance*) (/Users/dkatz85/src/bloomberg/clang-p2996/build-llvm/bin/clang-20+0x1031328e8) #27 0x00000001000f5844 cc1_main(llvm::ArrayRef<char const*>, char const*, void*) (/Users/dkatz85/src/bloomberg/clang-p2996/build-llvm/bin/clang-20+0x100009844) #28 0x00000001000f2ee8 ExecuteCC1Tool(llvm::SmallVectorImpl<char const*>&, llvm::ToolContext const&) (/Users/dkatz85/src/bloomberg/clang-p2996/build-llvm/bin/clang-20+0x100006ee8) #29 0x00000001000f236c clang_main(int, char**, llvm::ToolContext const&) (/Users/dkatz85/src/bloomberg/clang-p2996/build-llvm/bin/clang-20+0x10000636c) #30 0x00000001000fe674 main (/Users/dkatz85/src/bloomberg/clang-p2996/build-llvm/bin/clang-20+0x100012674) #31 0x0000000182b83154 clang++: error: unable to execute command: Abort trap: 6 clang++: error: clang frontend command failed due to signal (use -v to see invocation) ``` Here is another example that fails the same assertion: ```cpp template <typename... Ts> void fn(int = [] consteval -> int { (^Ts); return 0; }()); ``` Both have the same root cause: 1. While parsing the `CompoundStmt` body of the lambda, clang begins to parse `^Ts` as a `BlockExpr`. 2. The `Sema::ActOnBlockArguments` function invokes `DiagnoseUnexpandedParameterPacks`, which sets `LambdaScopeInfo::ContainsUnexpandedParameterPacks` to `true`, prior to recognizing that the `BlockExpr` is ill-formed. 3. The ill-formed `BlockExpr` is diagnosed, and is subsequently discarded from the `CompoundStmt` representing the body of the lambda. 4. The `LambdaScopeInfo` is used to initialize the `LambdaExpr`, resulting in `LambdaExpr::ContainsUnexpandedParameterPack` being set to `true`. 5. The `LambdaExpr` becomes an argument to some other semantic construct (e.g., `StaticAssertDecl`, `ParameterDecl`), whose semantic analysis calls `DiagnoseUnexpandedParameterPack`. 6. The above assertion triggers because the `LambdaExpr` reports that it contains an unexpanded parameter pack, but the tree walk fails to find any pack (since the ill-formed `BlockExpr` was discarded from the `CompoundStmt`). Although I can imagine a few ways to patch this (e.g., keep an "error" representation of the ill-formed `BlockExpr` in `CompoundStmt`, rollback the setting of `LambdaScopeInfo::ContainsUnexpandedParameterPack` when the `BlockExpr` is ill-formed, just remove the assertion from `DiagnoseUnexpandedParameterPacks`), I'm not sure I love any of them. For now, I figured I'd just report the issue.
shafik commented 1 month ago

Looks like this goes back to clang-13: https://godbolt.org/z/PMshGMY3E

It does not require -fblocks if we use assertions build, they are usually more useful b/c they crash earlier and usually are closer to the core problem.

Sirraide commented 1 month ago

I haven’t tried messing with this yet, but this feels like it might be the issue: https://github.com/llvm/llvm-project/blob/9ec229dd3ede6368ee5fecf9b9731d8d21d8b1d2/clang/lib/Sema/SemaExpr.cpp#L16080-L16089

We diagnose unexpanded parameter packs... and then promptly drop them. I think the ‘proper’ solution would be to resolve this fixme; This comment is from 2012, so maybe we can handle blocks with unexpanded paramter packs just fine now? I’ll try that, and if that doesn’t work, I think we can just reset the LambdaScopeInfo’s flag to whatever value it had before the DiagnoseUnexpandedParameterPack() call in here.

Sirraide commented 1 month ago

Actually, that would only return true on error, so that doesn’t seem too plausible...

Sirraide commented 1 month ago

Oh wait, duh, I just confused myself: it does seem to happen here, it just returns false because we’re in a lambda, so it’s fine, and we then crash later.