Skip to content

[clang] ICE with dynamic_cast and multiple inheritance: Shouldn't query vtable linkage without key function #64088

Closed
llvm/llvm-project-release-prs
#486
@BertalanD

Description

Starting with 9d525bf ("Optimize emission of dynamic_cast to final classes", @zygoloid) the following code triggers an assertion at -O0 -g0:

struct Foo {
    virtual void foo();
};
struct Bar {
    virtual void bar();
};
struct Baz final : Foo, Bar {
    void bar() override;
};

bool test(Foo *f) {
    return dynamic_cast<Baz*>(f);
}
clang++: /root/llvm-project/clang/lib/CodeGen/CGVTables.cpp:1060: llvm::GlobalValue::LinkageTypes clang::CodeGen::CodeGenModule::getVTableLinkage(const clang::CXXRecordDecl*): Assertion `(def || CodeGenOpts.OptimizationLevel > 0 || CodeGenOpts.getDebugInfo() != llvm::codegenoptions::NoDebugInfo) && "Shouldn't query vtable linkage without key function, " "optimizations, or debug info"' failed.
Full backtrace
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 -g0 <source>
1.	<eof> parser at end of file
2.	<source>:11:6: LLVM IR generation of declaration 'test'
3.	<source>:11:6: Generating code for declaration 'test'
 #0 0x000000000367ff18 llvm::sys::PrintStackTrace(llvm::raw_ostream&, int) (/opt/compiler-explorer/clang-assertions-trunk/bin/clang+++0x367ff18)
 #1 0x000000000367dd9c llvm::sys::CleanupOnSignal(unsigned long) (/opt/compiler-explorer/clang-assertions-trunk/bin/clang+++0x367dd9c)
 #2 0x00000000035cb398 CrashRecoverySignalHandler(int) CrashRecoveryContext.cpp:0:0
 #3 0x00007f4275ecb420 __restore_rt (/lib/x86_64-linux-gnu/libpthread.so.0+0x14420)
 #4 0x00007f427598e00b raise (/lib/x86_64-linux-gnu/libc.so.6+0x4300b)
 #5 0x00007f427596d859 abort (/lib/x86_64-linux-gnu/libc.so.6+0x22859)
 #6 0x00007f427596d729 (/lib/x86_64-linux-gnu/libc.so.6+0x22729)
 #7 0x00007f427597efd6 (/lib/x86_64-linux-gnu/libc.so.6+0x33fd6)
 #8 0x00000000039f1d00 clang::CodeGen::CodeGenModule::getVTableLinkage(clang::CXXRecordDecl const*) (/opt/compiler-explorer/clang-assertions-trunk/bin/clang+++0x39f1d00)
 #9 0x0000000003acdff4 (anonymous namespace)::ItaniumCXXABI::shouldEmitExactDynamicCast(clang::QualType) ItaniumCXXABI.cpp:0:0
#10 0x0000000003d99f5f clang::CodeGen::CodeGenFunction::EmitDynamicCast(clang::CodeGen::Address, clang::CXXDynamicCastExpr const*) (/opt/compiler-explorer/clang-assertions-trunk/bin/clang+++0x3d99f5f)
#11 0x0000000003dc8c2b (anonymous namespace)::ScalarExprEmitter::VisitCastExpr(clang::CastExpr*) CGExprScalar.cpp:0:0
#12 0x0000000003dc355c clang::StmtVisitorBase<std::add_pointer, (anonymous namespace)::ScalarExprEmitter, llvm::Value*>::Visit(clang::Stmt*) CGExprScalar.cpp:0:0
#13 0x0000000003dc531b (anonymous namespace)::ScalarExprEmitter::Visit(clang::Expr*) CGExprScalar.cpp:0:0
#14 0x0000000003dc7d98 (anonymous namespace)::ScalarExprEmitter::VisitCastExpr(clang::CastExpr*) CGExprScalar.cpp:0:0
#15 0x0000000003dc38e7 clang::StmtVisitorBase<std::add_pointer, (anonymous namespace)::ScalarExprEmitter, llvm::Value*>::Visit(clang::Stmt*) CGExprScalar.cpp:0:0
#16 0x0000000003dcb67c clang::CodeGen::CodeGenFunction::EmitScalarExpr(clang::Expr const*, bool) (/opt/compiler-explorer/clang-assertions-trunk/bin/clang+++0x3dcb67c)
#17 0x00000000039913c4 clang::CodeGen::CodeGenFunction::EmitReturnStmt(clang::ReturnStmt const&) (/opt/compiler-explorer/clang-assertions-trunk/bin/clang+++0x39913c4)
#18 0x000000000399888b clang::CodeGen::CodeGenFunction::EmitStmt(clang::Stmt const*, llvm::ArrayRef<clang::Attr const*>) (/opt/compiler-explorer/clang-assertions-trunk/bin/clang+++0x399888b)
#19 0x000000000399eb9c clang::CodeGen::CodeGenFunction::EmitCompoundStmtWithoutScope(clang::CompoundStmt const&, bool, clang::CodeGen::AggValueSlot) (/opt/compiler-explorer/clang-assertions-trunk/bin/clang+++0x399eb9c)
#20 0x00000000039fc686 clang::CodeGen::CodeGenFunction::EmitFunctionBody(clang::Stmt const*) (/opt/compiler-explorer/clang-assertions-trunk/bin/clang+++0x39fc686)
#21 0x0000000003a0f8e8 clang::CodeGen::CodeGenFunction::GenerateCode(clang::GlobalDecl, llvm::Function*, clang::CodeGen::CGFunctionInfo const&) (/opt/compiler-explorer/clang-assertions-trunk/bin/clang+++0x3a0f8e8)
#22 0x0000000003a70fad clang::CodeGen::CodeGenModule::EmitGlobalFunctionDefinition(clang::GlobalDecl, llvm::GlobalValue*) (/opt/compiler-explorer/clang-assertions-trunk/bin/clang+++0x3a70fad)
#23 0x0000000003a6c185 clang::CodeGen::CodeGenModule::EmitGlobalDefinition(clang::GlobalDecl, llvm::GlobalValue*) (/opt/compiler-explorer/clang-assertions-trunk/bin/clang+++0x3a6c185)
#24 0x0000000003a6c743 clang::CodeGen::CodeGenModule::EmitGlobal(clang::GlobalDecl) (/opt/compiler-explorer/clang-assertions-trunk/bin/clang+++0x3a6c743)
#25 0x0000000003a758f3 clang::CodeGen::CodeGenModule::EmitTopLevelDecl(clang::Decl*) (.part.0) CodeGenModule.cpp:0:0
#26 0x00000000048d05a6 (anonymous namespace)::CodeGeneratorImpl::HandleTopLevelDecl(clang::DeclGroupRef) ModuleBuilder.cpp:0:0
#27 0x00000000048c2d48 clang::BackendConsumer::HandleTopLevelDecl(clang::DeclGroupRef) (/opt/compiler-explorer/clang-assertions-trunk/bin/clang+++0x48c2d48)
#28 0x0000000005d7ae14 clang::ParseAST(clang::Sema&, bool, bool) (/opt/compiler-explorer/clang-assertions-trunk/bin/clang+++0x5d7ae14)
#29 0x00000000048cd618 clang::CodeGenAction::ExecuteAction() (/opt/compiler-explorer/clang-assertions-trunk/bin/clang+++0x48cd618)
#30 0x0000000004133f09 clang::FrontendAction::Execute() (/opt/compiler-explorer/clang-assertions-trunk/bin/clang+++0x4133f09)
#31 0x00000000040b9c1e clang::CompilerInstance::ExecuteAction(clang::FrontendAction&) (/opt/compiler-explorer/clang-assertions-trunk/bin/clang+++0x40b9c1e)
#32 0x0000000004213e66 clang::ExecuteCompilerInvocation(clang::CompilerInstance*) (/opt/compiler-explorer/clang-assertions-trunk/bin/clang+++0x4213e66)
#33 0x0000000000bc9242 cc1_main(llvm::ArrayRef<char const*>, char const*, void*) (/opt/compiler-explorer/clang-assertions-trunk/bin/clang+++0xbc9242)
#34 0x0000000000bc1a2a ExecuteCC1Tool(llvm::SmallVectorImpl<char const*>&, llvm::ToolContext const&) driver.cpp:0:0
#35 0x0000000003f1adb9 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
#36 0x00000000035cb844 llvm::CrashRecoveryContext::RunSafely(llvm::function_ref<void ()>) (/opt/compiler-explorer/clang-assertions-trunk/bin/clang+++0x35cb844)
#37 0x0000000003f1b3af 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
#38 0x0000000003ee30a5 clang::driver::Compilation::ExecuteCommand(clang::driver::Command const&, clang::driver::Command const*&, bool) const (/opt/compiler-explorer/clang-assertions-trunk/bin/clang+++0x3ee30a5)
#39 0x0000000003ee3b0d 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+++0x3ee3b0d)
#40 0x0000000003eeb63d clang::driver::Driver::ExecuteCompilation(clang::driver::Compilation&, llvm::SmallVectorImpl<std::pair<int, clang::driver::Command const*>>&) (/opt/compiler-explorer/clang-assertions-trunk/bin/clang+++0x3eeb63d)
#41 0x0000000000bc74f7 clang_main(int, char**, llvm::ToolContext const&) (/opt/compiler-explorer/clang-assertions-trunk/bin/clang+++0xbc74f7)
#42 0x0000000000ac1ff1 main (/opt/compiler-explorer/clang-assertions-trunk/bin/clang+++0xac1ff1)
#43 0x00007f427596f083 __libc_start_main (/lib/x86_64-linux-gnu/libc.so.6+0x24083)
#44 0x0000000000bc150e _start (/opt/compiler-explorer/clang-assertions-trunk/bin/clang+++0xbc150e)

(Godbolt link)

This was reduced from a larger program where this commit caused the emission of the derived type's vtable even though the key function was not defined in that TU. This caused a linker error, as some of the non-inline virtual functions were defined in a different shared object and had hidden visibility.

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions