Issue 109148
Summary [clang] Ill-formed block expressions within a lambda can yield assert-failures
Labels clang
Assignees
Reporter 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.
_______________________________________________
llvm-bugs mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-bugs

Reply via email to