Assertion "trying to emit a call to an immediate function" when a consteval ctor with braces is used as a temporary inside a function template
- Dominant language
- LLVM
- Stars
- 40.5k
- Forks
- 18.7k
- PR merge metrics
- PR metrics pending
Description
In below example the call to the `consteval` constructor `bar::bar` in the function template `broken` trips an assertion; on release builds, there is no diagnostic and a an out-of-line definition of the ctor is emitted and called at runtime, leading to a failing link.
Note this is independent of optimization level, and happens only in a very specific combination: the call must be from a function template, the ctor call must be with braces, the constructed object must be a temporary. `consteval` free functions are not affected.
Repro at [godbolt](https://godbolt.org/z/efq7c1orq)
Code:
```c++
consteval void foo() {}
struct bar {
consteval bar(int v) { foo(); }
};
consteval void baz(int v) { foo(); }
// broken:
template
void broken(T) { (void)bar{1}; }
template void broken(int);
// ok:
template
void ok_parens(T) { (void)bar(1); }
template
void ok_named(T) { bar g{1}; (void)g; }
template
void ok_free_function(T) { (void)baz(1); }
void ok_not_a_template() { (void)bar{1}; }
template void ok_parens(int);
template void ok_named(int);
template void ok_free_function(int);
// just so godbolt can link and execute:
int main() { return 0; }
```
Assertion:
```
clang++: /root/llvm-project/llvm/tools/clang/lib/CodeGen/CGExpr.cpp:6976: clang::CodeGen::RValue clang::CodeGen::CodeGenFunction::EmitCall(clang::QualType, const clang::CodeGen::CGCallee&, const clang::CallExpr*, clang::CodeGen::ReturnValueSlot, llvm::Value*, llvm::CallBase**, const clang::CodeGen::CGFunctionInfo**): Assertion `(!isa_and_present(TargetDecl) || !cast(TargetDecl)->isImmediateFunction()) && "trying to emit a call to an immediate function"' failed.
PLEASE submit a bug report to https://github.com/llvm/llvm-project/issues/ and include the crash backtrace and dumped files.
Stack dump:
0. Program arguments: /opt/compiler-explorer/clang-assertions-trunk/bin/clang++ -g -o /app/output.s -mllvm --x86-asm-syntax=intel -fno-verbose-asm -S --gcc-toolchain=/opt/compiler-explorer/gcc-snapshot -fcolor-diagnostics -fno-crash-diagnostics -std=c++23
1. parser at end of file
2. Per-file LLVM IR generation
3. :4:12: Generating code for declaration 'bar::bar'
4. :4:23: LLVM IR generation of compound statement ('{}')
#0 0x000000000440d188 llvm::sys::PrintStackTrace(llvm::raw_ostream&, int) (/opt/compiler-explorer/clang-assertions-trunk/bin/clang+++0x440d188)
#1 0x000000000440a034 llvm::sys::RunSignalHandlers() (/opt/compiler-explorer/clang-assertions-trunk/bin/clang+++0x440a034)
#2 0x000000000440a66c llvm::sys::CleanupOnSignal(unsigned long) (/opt/compiler-explorer/clang-assertions-trunk/bin/clang+++0x440a66c)
#3 0x00000000043482a8 CrashRecoverySignalHandler(int) CrashRecoveryContext.cpp:0:0
#4 0x00007d9217e45330 (/lib/x86_64-linux-gnu/libc.so.6+0x45330)
#5 0x00007d9217e9ec0c pthread_kill (/lib/x86_64-linux-gnu/libc.so.6+0x9ec0c)
#6 0x00007d9217e4527e raise (/lib/x86_64-linux-gnu/libc.so.6+0x4527e)
#7 0x00007d9217e288ff abort (/lib/x86_64-linux-gnu/libc.so.6+0x288ff)
#8 0x00007d9217e2881b (/lib/x86_64-linux-gnu/libc.so.6+0x2881b)
#9 0x00007d9217e3b517 (/lib/x86_64-linux-gnu/libc.so.6+0x3b517)
#10 0x0000000004901631 clang::CodeGen::CodeGenFunction::EmitCall(clang::QualType, clang::CodeGen::CGCallee const&, clang::CallExpr const*, clang::CodeGen::ReturnValueSlot, llvm::Value*, llvm::CallBase**, clang::CodeGen::CGFunctionInfo const**) (/opt/compiler-explorer/clang-assertions-trunk/bin/clang+++0x4901631)
#11 0x0000000004902bdd clang::CodeGen::CodeGenFunction::EmitCallExpr(clang::CallExpr const*, clang::CodeGen::ReturnValueSlot, llvm::CallBase**) (/opt/compiler-explorer/clang-assertions-trunk/bin/clang+++0x4902bdd)
#12 0x000000000497208c (anonymous namespace)::ScalarExprEmitter::VisitCallExpr(clang::CallExpr const*) CGExprScalar.cpp:0:0
#13 0x0000000004967580 clang::StmtVisitorBase::Visit(clang::Stmt*) CGExprScalar.cpp:0:0
#14 0x000000000496cf4c clang::CodeGen::CodeGenFunction::EmitScalarExpr(clang::Expr const*, bool) (/opt/compiler-explorer/clang-assertions-trunk/bin/clang+++0x496cf4c)
#15 0x00000000048d5e1e clang::CodeGen::CodeGenFunction::EmitAnyExpr(clang::Expr const*, clang::CodeGen::AggValueSlot, bool) (/opt/compiler-explorer/clang-assertions-trunk/bin/clang+++0x48d5e1e)
#16 0x00000000048fda6d clang::CodeGen::CodeGenFunction::EmitIgnoredExpr(clang::Expr const*) (/opt/compiler-explorer/clang-assertions-trunk/bin/clang+++0x48fda6d)
#17 0x0000000004a9a84b clang::CodeGen::CodeGenFunction::EmitStmt(clang::Stmt const*, llvm::ArrayRef) (/opt/compiler-explorer/clang-assertions-trunk/bin/clang+++0x4a9a84b)
#18 0x0000000004aa2b0b clang::CodeGen::CodeGenFunction::EmitCompoundStmtWithoutScope(clang::CompoundStmt const&, bool, clang::CodeGen::AggValueSlot) (/opt/compiler-explorer/clang-assertions-trunk/bin/clang+++0x4aa2b0b)
#19 0x0000000004aa2e2d clang::CodeGen::CodeGenFunction::EmitCompoundStmt(clang::CompoundStmt const&, bool, clang::CodeGen::AggValueSlot) (/opt/compiler-explorer/clang-assertions-trunk/bin/clang+++0x4aa2e2d)
#20 0x0000000004aa2fbb clang::CodeGen::CodeGenFunction::EmitSimpleStmt(clang::Stmt const*, llvm::ArrayRef) (/opt/compiler-explorer/clang-assertions-trunk/bin/clang+++0x4aa2fbb)
#21 0x0000000004a9a798 clang::CodeGen::CodeGenFunction::EmitStmt(clang::Stmt const*, llvm::ArrayRef) (/opt/compiler-explorer/clang-assertions-trunk/bin/clang+++0x4a9a798)
#22 0x0000000004e3f496 clang::CodeGen::CodeGenFunction::EmitConstructorBody(clang::CodeGen::FunctionArgList&) (/opt/compiler-explorer/clang-assertions-trunk/bin/clang+++0x4e3f496)
#23 0x0000000004b212cd clang::CodeGen::CodeGenFunction::GenerateCode(clang::GlobalDecl, llvm::Function*, clang::CodeGen::CGFunctionInfo const&) (/opt/compiler-explorer/clang-assertions-trunk/bin/clang+++0x4b212cd)
#24 0x0000000004df2fbc clang::CodeGen::CodeGenModule::codegenCXXStructor(clang::GlobalDecl) (/opt/compiler-explorer/clang-assertions-trunk/bin/clang+++0x4df2fbc)
#25 0x0000000004c14470 (anonymous namespace)::ItaniumCXXABI::emitCXXStructor(clang::GlobalDecl) ItaniumCXXABI.cpp:0:0
#26 0x0000000004b8a796 clang::CodeGen::CodeGenModule::EmitGlobalDefinition(clang::GlobalDecl, llvm::GlobalValue*) (/opt/compiler-explorer/clang-assertions-trunk/bin/clang+++0x4b8a796)
#27 0x0000000004b9a1ec clang::CodeGen::CodeGenModule::EmitDeferred() (/opt/compiler-explorer/clang-assertions-trunk/bin/clang+++0x4b9a1ec)
#28 0x0000000004b9a108 clang::CodeGen::CodeGenModule::EmitDeferred() (/opt/compiler-explorer/clang-assertions-trunk/bin/clang+++0x4b9a108)
#29 0x0000000004b9d993 clang::CodeGen::CodeGenModule::Release() (/opt/compiler-explorer/clang-assertions-trunk/bin/clang+++0x4b9d993)
#30 0x0000000004f18c0e (anonymous namespace)::CodeGeneratorImpl::HandleTranslationUnit(clang::ASTContext&) ModuleBuilder.cpp:0:0
#31 0x0000000004f165e5 clang::BackendConsumer::HandleTranslationUnit(clang::ASTContext&) (/opt/compiler-explorer/clang-assertions-trunk/bin/clang+++0x4f165e5)
#32 0x0000000006d41fdc clang::ParseAST(clang::Sema&, bool, bool) (/opt/compiler-explorer/clang-assertions-trunk/bin/clang+++0x6d41fdc)
#33 0x0000000004f16da8 clang::CodeGenAction::ExecuteAction() (/opt/compiler-explorer/clang-assertions-trunk/bin/clang+++0x4f16da8)
#34 0x00000000052439e8 clang::FrontendAction::Execute() (/opt/compiler-explorer/clang-assertions-trunk/bin/clang+++0x52439e8)
#35 0x00000000051d15ed clang::CompilerInstance::ExecuteAction(clang::FrontendAction&) (/opt/compiler-explorer/clang-assertions-trunk/bin/clang+++0x51d15ed)
#36 0x0000000005318e7d clang::ExecuteCompilerInvocation(clang::CompilerInstance*) (/opt/compiler-explorer/clang-assertions-trunk/bin/clang+++0x5318e7d)
#37 0x0000000000d8ff0c cc1_main(llvm::ArrayRef, char const*, void*) (/opt/compiler-explorer/clang-assertions-trunk/bin/clang+++0xd8ff0c)
#38 0x0000000000d86c0a ExecuteCC1Tool(llvm::SmallVectorImpl&, llvm::ToolContext const&, llvm::IntrusiveRefCntPtr) driver.cpp:0:0
#39 0x0000000000d86d8d int llvm::function_ref&)>::callback_fn&)>(long, llvm::SmallVectorImpl&) driver.cpp:0:0
#40 0x0000000004f8f749 void llvm::function_ref::callback_fn>, std::__cxx11::basic_string, std::allocator>*, bool*) const::'lambda'()>(long) Job.cpp:0:0
#41 0x00000000043486e4 llvm::CrashRecoveryContext::RunSafely(llvm::function_ref) (/opt/compiler-explorer/clang-assertions-trunk/bin/clang+++0x43486e4)
#42 0x0000000004f902b5 clang::driver::CC1Command::Execute(llvm::ArrayRef>, std::__cxx11::basic_string, std::allocator>*, bool*) const (.part.0) Job.cpp:0:0
#43 0x0000000004f48122 clang::driver::Compilation::ExecuteCommand(clang::driver::Command const&, clang::driver::Command const*&, bool) const (/opt/compiler-explorer/clang-assertions-trunk/bin/clang+++0x4f48122)
#44 0x0000000004f4ca87 clang::driver::Compilation::ExecuteJobs(clang::driver::JobList const&, llvm::SmallVectorImpl>&, bool) const (/opt/compiler-explorer/clang-assertions-trunk/bin/clang+++0x4f4ca87)
#45 0x0000000004f57075 clang::driver::Driver::ExecuteCompilation(clang::driver::Compilation&, llvm::SmallVectorImpl>&) (/opt/compiler-explorer/clang-assertions-trunk/bin/clang+++0x4f57075)
#46 0x0000000000d8c3fa clang_main(int, char**, llvm::ToolContext const&) (/opt/compiler-explorer/clang-assertions-trunk/bin/clang+++0xd8c3fa)
#47 0x0000000000cca6ca main (/opt/compiler-explorer/clang-assertions-trunk/bin/clang+++0xcca6ca)
#48 0x00007d9217e2a1ca (/lib/x86_64-linux-gnu/libc.so.6+0x2a1ca)
#49 0x00007d9217e2a28b __libc_start_main (/lib/x86_64-linux-gnu/libc.so.6+0x2a28b)
#50 0x0000000000d865b5 _start (/opt/compiler-explorer/clang-assertions-trunk/bin/clang+++0xd865b5)
clang++: error: clang frontend command failed due to signal (use -v to see invocation)
Compiler returned: 134
```
Contributor guide
Research direction
Reproduce the case from the issue in Clang using the linked Godbolt example and inspect clang/lib/CodeGen/CGExpr.cpp around CodeGenFunction::EmitCall, identified by the assertion stack. Compare braced temporary construction in the function template with the working parenthesized, named-object, free-function, and non-template cases. Done means the reproducer no longer asserts and release builds neither emit an invalid runtime call nor fail to link.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- cpp
- Domain
- compilers
- Issue type
- Bug
- Difficulty
- 4/5
- Estimated time
- 3-5 days
- Activity status
- Active
- Clarity
- Mostly clear
- Newbie friendliness
- 55/100