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

Contents of the GMF from clangd's preamble will still have ODR checks run #2094

Open
refi64 opened this issue Jul 18, 2024 · 13 comments
Open

Comments

@refi64
Copy link

refi64 commented Jul 18, 2024

Quick disclaimer: I am not an expert on Clang's innards, I basically hit this issue and started exploring the source code a few weeks ago to see it was a simple fix. Unfortunately...it is not. (I think.)

Consider the following files (mostly ripped from #1892, though that issue unrelated because the includes aren't in a GMF):

mod.cc:

module;

#include <string>

export module SomeModule;

export std::string HelloWorld() { return "Hello, World!"; }

mod2.cc:

module;

#include <iostream>
#include <string>

export module SomeOtherModule;

import SomeModule;

export void PrintHelloWorld() { std::cout << HelloWorld(); }

clangd crashes with the following stack trace:

PLEASE submit a bug report to https://github.com/llvm/llvm-project/issues/ and include the crash backtrace.
Stack dump:
0.      /home/ryan/playground/clang-modules/mod2.cc:10:57: current parser token ')'
1.      /home/ryan/playground/clang-modules/mod2.cc:10:31: parsing function body 'PrintHelloWorld'
2.      /home/ryan/playground/clang-modules/mod2.cc:10:31: in compound statement ('{}')
  #0 0x0000000007b41ddc llvm::sys::PrintStackTrace(llvm::raw_ostream&, int) /home/ryan/code/llvm-project/llvm/lib/Support/Unix/Signals.inc:723:11
  #1 0x0000000007b422e4 PrintStackTraceSignalHandler(void*) /home/ryan/code/llvm-project/llvm/lib/Support/Unix/Signals.inc:798:1
  #2 0x0000000007b40478 llvm::sys::RunSignalHandlers() /home/ryan/code/llvm-project/llvm/lib/Support/Signals.cpp:105:5
  #3 0x0000000007b42b08 SignalHandler(int) /home/ryan/code/llvm-project/llvm/lib/Support/Unix/Signals.inc:413:1
  #4 0x0000ffff96068800 (linux-vdso.so.1+0x800)
  #5 0x0000ffff95a22280 __pthread_kill_implementation (/lib64/libc.so.6+0x92280)
  #6 0x0000ffff959d5800 gsignal (/lib64/libc.so.6+0x45800)
  #7 0x0000ffff959c0288 abort (/lib64/libc.so.6+0x30288)
  #8 0x0000000011fdb370 clang::ASTReader::GetExternalDeclStmt(unsigned long) /home/ryan/code/llvm-project/clang/lib/Serialization/ASTReader.cpp:0:5
  #9 0x0000000007edc810 clang::LazyOffsetPtr<clang::Stmt, unsigned long, &clang::ExternalASTSource::GetExternalDeclStmt(unsigned long)>::get(clang::ExternalASTSource*) const /home/ryan/code/llvm-project/clang/include/clang/AST/ExternalAST
 #10 0x0000000007ecab58 clang::VarDecl::getInit() /home/ryan/code/llvm-project/clang/lib/AST/Decl.cpp:2393:10
 #11 0x000000000797b384 clang::VarDecl::getInit() const /home/ryan/code/llvm-project/clang/include/clang/AST/Decl.h:1356:5
 #12 0x00000000083a6030 (anonymous namespace)::ODRDeclVisitor::VisitVarDecl(clang::VarDecl const*) /home/ryan/code/llvm-project/clang/lib/AST/ODRHash.cpp:321:18
 #13 0x00000000083a7118 clang::declvisitor::Base<llvm::make_const_ptr, (anonymous namespace)::ODRDeclVisitor, void>::VisitParmVarDecl(clang::ParmVarDecl const*) /home/ryan/code/llvm-project/_debug-build/tools/clang/include/clang/AST/DeclN
 #14 0x00000000083a60d0 (anonymous namespace)::ODRDeclVisitor::VisitParmVarDecl(clang::ParmVarDecl const*) /home/ryan/code/llvm-project/clang/lib/AST/ODRHash.cpp:329:3
 #15 0x00000000083a5074 clang::declvisitor::Base<llvm::make_const_ptr, (anonymous namespace)::ODRDeclVisitor, void>::Visit(clang::Decl const*) /home/ryan/code/llvm-project/_debug-build/tools/clang/include/clang/AST/DeclNodes.inc:296:1
 #16 0x00000000083a37d0 (anonymous namespace)::ODRDeclVisitor::Visit(clang::Decl const*) /home/ryan/code/llvm-project/clang/lib/AST/ODRHash.cpp:301:3
 #17 0x00000000083a342c clang::ODRHash::AddSubDecl(clang::Decl const*) /home/ryan/code/llvm-project/clang/lib/AST/ODRHash.cpp:566:1
 #18 0x00000000083a4530 clang::ODRHash::AddFunctionDecl(clang::FunctionDecl const*, bool) /home/ryan/code/llvm-project/clang/lib/AST/ODRHash.cpp:717:3
 #19 0x0000000007ed3094 clang::FunctionDecl::getODRHash() /home/ryan/code/llvm-project/clang/lib/AST/Decl.cpp:4516:8
 #20 0x00000000083a39e0 clang::ODRHash::AddCXXRecordDecl(clang::CXXRecordDecl const*) /home/ryan/code/llvm-project/clang/lib/AST/ODRHash.cpp:591:7
 #21 0x0000000007f1cc68 clang::CXXRecordDecl::getODRHash() const /home/ryan/code/llvm-project/clang/lib/AST/DeclCXX.cpp:504:8
 #22 0x000000001207874c clang::ASTDeclReader::MergeDefinitionData(clang::CXXRecordDecl*, clang::CXXRecordDecl::DefinitionData&&) /home/ryan/code/llvm-project/clang/lib/Serialization/ASTReaderDecl.cpp:2167:26
 #23 0x0000000012078994 clang::ASTDeclReader::ReadCXXRecordDefinition(clang::CXXRecordDecl*, bool, clang::Decl*, unsigned int) /home/ryan/code/llvm-project/clang/lib/Serialization/ASTReaderDecl.cpp:2207:5
 #24 0x0000000012078c98 clang::ASTDeclReader::VisitCXXRecordDeclImpl(clang::CXXRecordDecl*) /home/ryan/code/llvm-project/clang/lib/Serialization/ASTReaderDecl.cpp:2278:5
 #25 0x00000000120b35a0 clang::ASTDeclReader::VisitCXXRecordDecl(clang::CXXRecordDecl*) /home/ryan/code/llvm-project/clang/lib/Serialization/ASTReaderDecl.cpp:346:76
 #26 0x00000000120a4eb4 clang::declvisitor::Base<std::add_pointer, clang::ASTDeclReader, void>::Visit(clang::Decl*) /home/ryan/code/llvm-project/_debug-build/tools/clang/include/clang/AST/DeclNodes.inc:414:1
 #27 0x0000000012069244 clang::ASTDeclReader::Visit(clang::Decl*) /home/ryan/code/llvm-project/clang/lib/Serialization/ASTReaderDecl.cpp:543:37
 #28 0x00000000120a42c0 clang::ASTReader::ReadDeclRecord(clang::GlobalDeclID)::$_2::operator()() const /home/ryan/code/llvm-project/clang/lib/Serialization/ASTReaderDecl.cpp:4155:61
 #29 0x00000000120a4290 void llvm::function_ref<void ()>::callback_fn<clang::ASTReader::ReadDeclRecord(clang::GlobalDeclID)::$_2>(long) /home/ryan/code/llvm-project/llvm/include/llvm/ADT/STLFunctionalExtras.h:45:5
 #30 0x0000000007a630e0 llvm::function_ref<void ()>::operator()() const /home/ryan/code/llvm-project/llvm/include/llvm/ADT/STLFunctionalExtras.h:68:5
 #31 0x0000000008c97dc0 clang::runWithSufficientStackSpace(llvm::function_ref<void ()>, llvm::function_ref<void ()>) /home/ryan/code/llvm-project/clang/include/clang/Basic/Stack.h:46:7
 #32 0x00000000120a1510 clang::ASTReader::ReadDeclRecord(clang::GlobalDeclID) /home/ryan/code/llvm-project/clang/lib/Serialization/ASTReaderDecl.cpp:4159:40
 #33 0x0000000011fd3960 clang::ASTReader::GetDecl(clang::GlobalDeclID) /home/ryan/code/llvm-project/clang/lib/Serialization/ASTReader.cpp:7852:5
 #34 0x000000001203d694 clang::NamedDecl* clang::ASTReader::ReadDeclAs<clang::NamedDecl>(clang::serialization::ModuleFile&, llvm::SmallVectorImpl<unsigned long> const&, unsigned int&) /home/ryan/code/llvm-project/clang/include/clang/Seria
 #35 0x0000000011ff84cc clang::NamedDecl* clang::ASTRecordReader::readDeclAs<clang::NamedDecl>() /home/ryan/code/llvm-project/clang/include/clang/Serialization/ASTRecordReader.h:203:5
 #36 0x00000000120a6848 clang::NamedDecl* clang::ASTDeclReader::readDeclAs<clang::NamedDecl>() /home/ryan/code/llvm-project/clang/lib/Serialization/ASTReaderDecl.cpp:145:7
 #37 0x000000001207971c clang::ASTDeclReader::VisitTemplateDecl(clang::TemplateDecl*) /home/ryan/code/llvm-project/clang/lib/Serialization/ASTReaderDecl.cpp:2405:11
 #38 0x0000000012079a54 clang::ASTDeclReader::VisitRedeclarableTemplateDecl(clang::RedeclarableTemplateDecl*) /home/ryan/code/llvm-project/clang/lib/Serialization/ASTReaderDecl.cpp:2453:3
 #39 0x0000000012079ab8 clang::ASTDeclReader::VisitClassTemplateDecl(clang::ClassTemplateDecl*) /home/ryan/code/llvm-project/clang/lib/Serialization/ASTReaderDecl.cpp:2460:31
 #40 0x00000000120a4f84 clang::declvisitor::Base<std::add_pointer, clang::ASTDeclReader, void>::Visit(clang::Decl*) /home/ryan/code/llvm-project/_debug-build/tools/clang/include/clang/AST/DeclNodes.inc:524:1
 #41 0x0000000012069244 clang::ASTDeclReader::Visit(clang::Decl*) /home/ryan/code/llvm-project/clang/lib/Serialization/ASTReaderDecl.cpp:543:37
 #42 0x00000000120a42c0 clang::ASTReader::ReadDeclRecord(clang::GlobalDeclID)::$_2::operator()() const /home/ryan/code/llvm-project/clang/lib/Serialization/ASTReaderDecl.cpp:4155:61
 #43 0x00000000120a4290 void llvm::function_ref<void ()>::callback_fn<clang::ASTReader::ReadDeclRecord(clang::GlobalDeclID)::$_2>(long) /home/ryan/code/llvm-project/llvm/include/llvm/ADT/STLFunctionalExtras.h:45:5
 #44 0x0000000007a630e0 llvm::function_ref<void ()>::operator()() const /home/ryan/code/llvm-project/llvm/include/llvm/ADT/STLFunctionalExtras.h:68:5
 #45 0x0000000008c97dc0 clang::runWithSufficientStackSpace(llvm::function_ref<void ()>, llvm::function_ref<void ()>) /home/ryan/code/llvm-project/clang/include/clang/Basic/Stack.h:46:7
 #46 0x00000000120a1510 clang::ASTReader::ReadDeclRecord(clang::GlobalDeclID) /home/ryan/code/llvm-project/clang/lib/Serialization/ASTReaderDecl.cpp:4159:40
 #47 0x0000000011fd3960 clang::ASTReader::GetDecl(clang::GlobalDeclID) /home/ryan/code/llvm-project/clang/lib/Serialization/ASTReader.cpp:7852:5
 #48 0x0000000011fdbea8 clang::ASTReader::FindExternalVisibleDeclsByName(clang::DeclContext const*, clang::DeclarationName) /home/ryan/code/llvm-project/clang/lib/Serialization/ASTReader.cpp:8062:21
 #49 0x0000000007f09998 clang::DeclContext::lookup(clang::DeclarationName) const /home/ryan/code/llvm-project/clang/lib/AST/DeclBase.cpp:1871:60
 #50 0x0000000007f097c8 clang::DeclContext::lookup(clang::DeclarationName) const /home/ryan/code/llvm-project/clang/lib/AST/DeclBase.cpp:1840:28
 #51 0x0000000011fd9e40 clang::ASTReader::CompleteRedeclChain(clang::Decl const*) /home/ryan/code/llvm-project/clang/lib/Serialization/ASTReader.cpp:7585:13
 #52 0x000000000778d904 clang::LazyGenerationalUpdatePtr<clang::Decl const*, clang::Decl*, &clang::ExternalASTSource::CompleteRedeclChain(clang::Decl const*)>::get(clang::Decl const*) /home/ryan/code/llvm-project/clang/include/clang/AST/E
 #53 0x000000000779c168 clang::Redeclarable<clang::TagDecl>::DeclLink::getPrevious(clang::TagDecl const*) const /home/ryan/code/llvm-project/clang/include/clang/AST/Redeclarable.h:134:7
 #54 0x000000000779c0c0 clang::Redeclarable<clang::TagDecl>::getNextRedeclaration() const /home/ryan/code/llvm-project/clang/include/clang/AST/Redeclarable.h:190:5
 #55 0x000000000779bdc0 clang::Redeclarable<clang::TagDecl>::getMostRecentDecl() /home/ryan/code/llvm-project/clang/include/clang/AST/Redeclarable.h:227:5
 #56 0x000000000779bb08 clang::RecordDecl::getMostRecentDecl() /home/ryan/code/llvm-project/clang/include/clang/AST/Decl.h:4207:12
 #57 0x000000000779ba60 clang::CXXRecordDecl::getMostRecentDecl() /home/ryan/code/llvm-project/clang/include/clang/AST/DeclCXX.h:541:12
 #58 0x000000000779ba3c clang::CXXRecordDecl::getMostRecentDecl() const /home/ryan/code/llvm-project/clang/include/clang/AST/DeclCXX.h:546:5
 #59 0x000000000779ba10 clang::CXXRecordDecl::dataPtr() const /home/ryan/code/llvm-project/clang/include/clang/AST/DeclCXX.h:458:5
 #60 0x000000000779b928 clang::CXXRecordDecl::data() const /home/ryan/code/llvm-project/clang/include/clang/AST/DeclCXX.h:463:11
 #61 0x0000000007bc6058 clang::CXXRecordDecl::hasTrivialDestructor() const /home/ryan/code/llvm-project/clang/include/clang/AST/DeclCXX.h:1368:19
 #62 0x00000000085411ec clang::QualType::isDestructedTypeImpl(clang::QualType) /home/ryan/code/llvm-project/clang/lib/AST/Type.cpp:5063:11
 #63 0x0000000007bc60d0 clang::QualType::isDestructedType() const /home/ryan/code/llvm-project/clang/include/clang/AST/Type.h:1547:5
 #64 0x000000000890f108 clang::Sema::MaybeBindToTemporary(clang::Expr*) /home/ryan/code/llvm-project/clang/lib/Sema/SemaExprCXX.cpp:7520:39
 #65 0x0000000008df23b0 clang::Sema::BuildResolvedCallExpr(clang::Expr*, clang::NamedDecl*, clang::SourceLocation, llvm::ArrayRef<clang::Expr*>, clang::SourceLocation, clang::Expr*, bool, clang::CallExpr::ADLCallKind) /home/ryan/code/llvm
 #66 0x0000000009b57344 FinishOverloadedCallExpr(clang::Sema&, clang::Scope*, clang::Expr*, clang::UnresolvedLookupExpr*, clang::SourceLocation, llvm::MutableArrayRef<clang::Expr*>, clang::SourceLocation, clang::Expr*, clang::OverloadCand
 #67 0x0000000009b57018 clang::Sema::BuildOverloadedCallExpr(clang::Scope*, clang::Expr*, clang::UnresolvedLookupExpr*, clang::SourceLocation, llvm::MutableArrayRef<clang::Expr*>, clang::SourceLocation, clang::Expr*, bool, bool) /home/rya
 #68 0x0000000008dd89c0 clang::Sema::BuildCallExpr(clang::Scope*, clang::Expr*, clang::SourceLocation, llvm::MutableArrayRef<clang::Expr*>, clang::SourceLocation, clang::Expr*, bool, bool) /home/ryan/code/llvm-project/clang/lib/Sema/SemaE
 #69 0x0000000008def9c8 clang::Sema::ActOnCallExpr(clang::Scope*, clang::Expr*, clang::SourceLocation, llvm::MutableArrayRef<clang::Expr*>, clang::SourceLocation, clang::Expr*) /home/ryan/code/llvm-project/clang/lib/Sema/SemaExpr.cpp:6335
 #70 0x0000000011ebc47c clang::Parser::ParsePostfixExpressionSuffix(clang::ActionResult<clang::Expr*, true>) /home/ryan/code/llvm-project/clang/lib/Parse/ParseExpr.cpp:2221:23
 #71 0x0000000011ec3050 clang::Parser::ParseCastExpression(clang::Parser::CastParseKind, bool, bool&, clang::Parser::TypeCastState, bool, bool*) /home/ryan/code/llvm-project/clang/lib/Parse/ParseExpr.cpp:1923:9
 #72 0x0000000011ebac90 clang::Parser::ParseCastExpression(clang::Parser::CastParseKind, bool, clang::Parser::TypeCastState, bool, bool*) /home/ryan/code/llvm-project/clang/lib/Parse/ParseExpr.cpp:712:20
 #73 0x0000000011eb9f6c clang::Parser::ParseRHSOfBinaryExpression(clang::ActionResult<clang::Expr*, true>, clang::prec::Level) /home/ryan/code/llvm-project/clang/lib/Parse/ParseExpr.cpp:577:13
 #74 0x0000000011eb9640 clang::Parser::ParseAssignmentExpression(clang::Parser::TypeCastState) /home/ryan/code/llvm-project/clang/lib/Parse/ParseExpr.cpp:185:10
 #75 0x0000000011eb94cc clang::Parser::ParseExpression(clang::Parser::TypeCastState) /home/ryan/code/llvm-project/clang/lib/Parse/ParseExpr.cpp:133:18
 #76 0x0000000011f3aa54 clang::Parser::ParseExprStatement(clang::Parser::ParsedStmtContext) /home/ryan/code/llvm-project/clang/lib/Parse/ParseStmt.cpp:551:19
 #77 0x0000000011f39534 clang::Parser::ParseStatementOrDeclarationAfterAttributes(llvm::SmallVector<clang::Stmt*, 32u>&, clang::Parser::ParsedStmtContext, clang::SourceLocation*, clang::ParsedAttributes&, clang::ParsedAttributes&) /home/r
 #78 0x0000000011f38d3c clang::Parser::ParseStatementOrDeclaration(llvm::SmallVector<clang::Stmt*, 32u>&, clang::Parser::ParsedStmtContext, clang::SourceLocation*) /home/ryan/code/llvm-project/clang/lib/Parse/ParseStmt.cpp:121:20
 #79 0x0000000011f408dc clang::Parser::ParseCompoundStatementBody(bool) /home/ryan/code/llvm-project/clang/lib/Parse/ParseStmt.cpp:1245:11
 #80 0x0000000011f41db8 clang::Parser::ParseFunctionStatementBody(clang::Decl*, clang::Parser::ParseScope&) /home/ryan/code/llvm-project/clang/lib/Parse/ParseStmt.cpp:2523:21
 #81 0x0000000011e8c5b8 clang::Parser::ParseFunctionDefinition(clang::ParsingDeclarator&, clang::Parser::ParsedTemplateInfo const&, clang::Parser::LateParsedAttrList*) /home/ryan/code/llvm-project/clang/lib/Parse/Parser.cpp:1525:3
 #82 0x0000000011f16a9c clang::Parser::ParseDeclGroup(clang::ParsingDeclSpec&, clang::DeclaratorContext, clang::ParsedAttributes&, clang::Parser::ParsedTemplateInfo&, clang::SourceLocation*, clang::Parser::ForRangeInit*) /home/ryan/code/l
 #83 0x0000000011e8b63c clang::Parser::ParseDeclOrFunctionDefInternal(clang::ParsedAttributes&, clang::ParsedAttributes&, clang::ParsingDeclSpec&, clang::AccessSpecifier) /home/ryan/code/llvm-project/clang/lib/Parse/Parser.cpp:1249:10
 #84 0x0000000011e8ac2c clang::Parser::ParseDeclarationOrFunctionDefinition(clang::ParsedAttributes&, clang::ParsedAttributes&, clang::ParsingDeclSpec*, clang::AccessSpecifier) /home/ryan/code/llvm-project/clang/lib/Parse/Parser.cpp:1271:
 #85 0x0000000011e8a570 clang::Parser::ParseExternalDeclaration(clang::ParsedAttributes&, clang::ParsedAttributes&, clang::ParsingDeclSpec*) /home/ryan/code/llvm-project/clang/lib/Parse/Parser.cpp:1074:14
 #86 0x0000000011ee37b4 clang::Parser::ParseExportDeclaration() /home/ryan/code/llvm-project/clang/lib/Parse/ParseDeclCXX.cpp:470:5
 #87 0x0000000011e8a09c clang::Parser::ParseExternalDeclaration(clang::ParsedAttributes&, clang::ParsedAttributes&, clang::ParsingDeclSpec*) /home/ryan/code/llvm-project/clang/lib/Parse/Parser.cpp:975:20
 #88 0x0000000011e8871c clang::Parser::ParseTopLevelDecl(clang::OpaquePtr<clang::DeclGroupRef>&, clang::Sema::ModuleImportState&) /home/ryan/code/llvm-project/clang/lib/Parse/Parser.cpp:763:12
 #89 0x0000000011e83be4 clang::ParseAST(clang::Sema&, bool, bool) /home/ryan/code/llvm-project/clang/lib/Parse/ParseAST.cpp:163:16
 #90 0x0000000011b4f5a4 clang::ASTFrontendAction::ExecuteAction() /home/ryan/code/llvm-project/clang/lib/Frontend/FrontendAction.cpp:1194:1
 #91 0x0000000011b4f010 clang::FrontendAction::Execute() /home/ryan/code/llvm-project/clang/lib/Frontend/FrontendAction.cpp:1078:8
 #92 0x000000000a7b08e0 clang::clangd::ParsedAST::build(llvm::StringRef, clang::clangd::ParseInputs const&, std::unique_ptr<clang::CompilerInvocation, std::default_delete<clang::CompilerInvocation>>, llvm::ArrayRef<clang::clangd::Diag>, s
 #93 0x000000000aa0afd4 clang::clangd::(anonymous namespace)::ASTWorker::generateDiagnostics(std::unique_ptr<clang::CompilerInvocation, std::default_delete<clang::CompilerInvocation>>, clang::clangd::ParseInputs, std::vector<clang::clangd
 #94 0x000000000aa0ad24 clang::clangd::(anonymous namespace)::ASTWorker::updatePreamble(std::unique_ptr<clang::CompilerInvocation, std::default_delete<clang::CompilerInvocation>>, clang::clangd::ParseInputs, std::shared_ptr<clang::clangd:
 #95 0x000000000aa0ca30 void llvm::detail::UniqueFunctionBase<void>::CallImpl<clang::clangd::(anonymous namespace)::ASTWorker::updatePreamble(std::unique_ptr<clang::CompilerInvocation, std::default_delete<clang::CompilerInvocation>>, clan
 #96 0x000000000a49d470 llvm::unique_function<void ()>::operator()() /home/ryan/code/llvm-project/llvm/include/llvm/ADT/FunctionExtras.h:384:5
 #97 0x000000000aa13918 void llvm::function_ref<void ()>::callback_fn<llvm::unique_function<void ()>>(long) /home/ryan/code/llvm-project/llvm/include/llvm/ADT/STLFunctionalExtras.h:45:5
 #98 0x0000000007a630e0 llvm::function_ref<void ()>::operator()() const /home/ryan/code/llvm-project/llvm/include/llvm/ADT/STLFunctionalExtras.h:68:5
 #99 0x000000000aa05a28 clang::clangd::(anonymous namespace)::ASTWorker::runTask(llvm::StringRef, llvm::function_ref<void ()>) /home/ryan/code/llvm-project/clang-tools-extra/clangd/TUScheduler.cpp:1324:3
#100 0x000000000aa05204 clang::clangd::(anonymous namespace)::ASTWorker::run() /home/ryan/code/llvm-project/clang-tools-extra/clangd/TUScheduler.cpp:1458:7
#101 0x000000000aa04be0 clang::clangd::(anonymous namespace)::ASTWorker::create(llvm::StringRef, clang::clangd::GlobalCompilationDatabase const&, clang::clangd::TUScheduler::ASTCache&, clang::clangd::TUScheduler::HeaderIncluderCache&, cla
#102 0x000000000aa04b68 void llvm::detail::UniqueFunctionBase<void>::CallImpl<clang::clangd::(anonymous namespace)::ASTWorker::create(llvm::StringRef, clang::clangd::GlobalCompilationDatabase const&, clang::clangd::TUScheduler::ASTCache&,
#103 0x000000000a49d470 llvm::unique_function<void ()>::operator()() /home/ryan/code/llvm-project/llvm/include/llvm/ADT/FunctionExtras.h:384:5
#104 0x000000000ae304c4 clang::clangd::AsyncTaskRunner::runAsync(llvm::Twine const&, llvm::unique_function<void ()>)::$_1::operator()() /home/ryan/code/llvm-project/clang-tools-extra/clangd/support/Threading.cpp:101:5
#105 0x000000000ae30480 auto void llvm::thread::GenericThreadProxy<std::tuple<clang::clangd::AsyncTaskRunner::runAsync(llvm::Twine const&, llvm::unique_function<void ()>)::$_1>>(void*)::'lambda'(auto&&, auto&&...)::operator()<clang::clang
#106 0x000000000ae30458 auto std::__invoke_impl<void, void llvm::thread::GenericThreadProxy<std::tuple<clang::clangd::AsyncTaskRunner::runAsync(llvm::Twine const&, llvm::unique_function<void ()>)::$_1>>(void*)::'lambda'(auto&&, auto&&...)
#107 0x000000000ae30404 std::__invoke_result<auto, auto...>::type std::__invoke<void llvm::thread::GenericThreadProxy<std::tuple<clang::clangd::AsyncTaskRunner::runAsync(llvm::Twine const&, llvm::unique_function<void ()>)::$_1>>(void*)::'lambda'(auto&&, auto&&...), clang::clangd::AsyncTaskRunner::runAsync(llvm::Twine const&, llvm::unique_function<void ()>)::$_1&>(auto&&, auto&&...) /usr/bin/../lib/gcc/aarch64-redhat-linux/13/../../../../include/c++/13/bits/invoke.h:96:7
#108 0x000000000ae303d4 decltype(auto) std::__apply_impl<void llvm::thread::GenericThreadProxy<std::tuple<clang::clangd::AsyncTaskRunner::runAsync(llvm::Twine const&, llvm::unique_function<void ()>)::$_1>>(void*)::'lambda'(auto&&, auto&&...), std::tuple<clang::clangd::AsyncTaskRunner::runAsync(llvm::Twine const&, llvm::unique_function<void ()>)::$_1>&, 0ul>(auto&&, std::tuple<clang::clangd::AsyncTaskRunner::runAsync(llvm::Twine const&, llvm::unique_function<void ()>)::$_1>&, std::integer_sequence<unsigned long, 0ul>) /usr/bin/../lib/gcc/aarch64-redhat-linux/13/../../../../include/c++/13/tuple:2288:7
#109 0x000000000ae30328 decltype(auto) std::apply<void llvm::thread::GenericThreadProxy<std::tuple<clang::clangd::AsyncTaskRunner::runAsync(llvm::Twine const&, llvm::unique_function<void ()>)::$_1>>(void*)::'lambda'(auto&&, auto&&...), std::tuple<clang::clangd::AsyncTaskRunner::runAsync(llvm::Twine const&, llvm::unique_function<void ()>)::$_1>&>(auto&&, std::tuple<clang::clangd::AsyncTaskRunner::runAsync(llvm::Twine const&, llvm::unique_function<void ()>)::$_1>&) /usr/bin/../lib/gcc/aarch64-redhat-linux/13/../../../../include/c++/13/tuple:2299:7
#110 0x000000000ae302f0 void llvm::thread::GenericThreadProxy<std::tuple<clang::clangd::AsyncTaskRunner::runAsync(llvm::Twine const&, llvm::unique_function<void ()>)::$_1>>(void*) /home/ryan/code/llvm-project/llvm/include/llvm/Support/thread.h:41:5
#111 0x000000000ae2ff9c void* llvm::thread::ThreadProxy<std::tuple<clang::clangd::AsyncTaskRunner::runAsync(llvm::Twine const&, llvm::unique_function<void ()>)::$_1>>(void*) /home/ryan/code/llvm-project/llvm/include/llvm/Support/thread.h:56:5
#112 0x0000ffff95a20584 start_thread (/lib64/libc.so.6+0x90584)
#113 0x0000ffff95a8fc4c thread_start (/lib64/libc.so.6+0xffc4c)

This was a bit confusing to me, because the clang CLI reports no issues, and after llvm/llvm-project@a0b6747, ODR checks shouldn't run for these anyway, right?

As it turns out, this is because of clangd's auto-generated prelude. Submodule IDs are never written to PCH files, so the module ownership never gets set to anything other than Unowned, and that + the missing owner module results in isExplicitGlobalModule() and shouldSkipCheckingODR being false.

I don't know what an ideal fix for this is. My initial thought was to, when deserializing a PCH, just detect the ShouldSkipCheckingODR bit and set the corresponding decls to be owned by the current module's GMF. But deserialized decls can't have a local owning module, and I'm not really comfortable with changing that or trying to wire it up to the module IDs instead.

This is reproducible with @ChuanqiXu9's clangd-with-modules branch and #66462. Based on the stack trace, I also think that llvm/llvm-project#82180 is also the same root cause, but I'm not sure.

@refi64
Copy link
Author

refi64 commented Jul 18, 2024

(Also apologies if this should have gone on llvm-project, I wasn't sure where to file it.)

@ChuanqiXu9
Copy link

This is slightly odd to me since I've skipped the ODR check in my branch: ChuanqiXu9/clangd-for-modules@13b00ff

@refi64
Copy link
Author

refi64 commented Jul 18, 2024

I started testing this a few days ago and might not have that change in if it's actually 2 days old 😅

That being said off the top of my head I think this issue would still persist? Because the problem isn't that skipping ODR checks in the GMF is off, it's that the stuff in the prelude isn't getting detected as being part of the GMF in the first place.

But I also wrote this after staring at the source code for like, 6 hours straight, so I could be a bit off base.

@ChuanqiXu9
Copy link

I started testing this a few days ago and might not have that change in if it's actually 2 days old 😅

That being said off the top of my head I think this issue would still persist? Because the problem isn't that skipping ODR checks in the GMF is off, it's that the stuff in the prelude isn't getting detected as being part of the GMF in the first place.

But I also wrote this after staring at the source code for like, 6 hours straight, so I could be a bit off base.

Maybe we'd best to handle this in clang. See the comments of llvm/llvm-project@c184b94 for details.

@refi64
Copy link
Author

refi64 commented Jul 19, 2024

So I tested on the latest clangd-with-modules branch, and it does no longer crash! But it does still give spurious ODR errors, since like I mentioned above, clang can't actually tell the definitions in the preamble were part of the GMF:

mod2.cc:8:1: error: In included file: 'std::fpos' has different definitions in different modules; first difference is definition in module 'SomeModule.<global>' found constructor with body
/home/ryan/code/llvm-project/install/usr/local/include/c++/v1/__ios/fpos.h:29:3: Error occurred here
/home/ryan/code/llvm-project/install/usr/local/include/c++/v1/__ios/fpos.h:29:3: But in '' found constructor with different body
mod2.cc:3:10: error: In included file: 'std::basic_string<char>::~basic_string' from module '' is not present in definition of 'std::basic_string<char>' in module 'SomeModule.<global>'
/home/ryan/code/llvm-project/install/usr/local/include/c++/v1/string:1138:40: Error occurred here
/home/ryan/code/llvm-project/install/usr/local/include/c++/v1/string:711:7: Definition has no member '~basic_string'

@ChuanqiXu9
Copy link

Yeah, that is somewhat a fundamental problem. Let me see if there is any workarounds...

@ChuanqiXu9
Copy link

The compatibility of named modules and PCH and header like modules are always in a dark corner case. We feel it is not compatible. But due to (seems) no one do that in practice. We don't know any problems yet. Until we tried to support modules in clangd, where the PCHs are automatically used. This looks fundamental or we have to disable PCH in module units. But it is a long term topic. I tried to work around it in llvm/llvm-project@2f0910d. I think you can try again.

@ChuanqiXu9
Copy link

I filed llvm/llvm-project#99612. You can look at it if you're interested.

@refi64
Copy link
Author

refi64 commented Jul 28, 2024

That did fix the first fpos error! But the second one still sticks around:

mod2.cc:3:10: error: In included file: 'std::basic_string<char>::~basic_string' from module '' is not present in definition of 'std::basic_string<char>' in module 'SomeModule.<global>'
/home/ryan/code/llvm-project/install/usr/local/include/c++/v1/string:1138:40: Error occurred here
/home/ryan/code/llvm-project/install/usr/local/include/c++/v1/string:711:7: Definition has no member '~basic_string'

If I modify ASTReaderDecl::findExisting like you did here:

  if (MergedDCIt != Reader.MergedDeclContexts.end() &&
      !shouldSkipCheckingODR(D) &&
      !shouldSkipCheckingODR(cast<Decl>(MergedDCIt->second)) &&  // <-- this is new
      MergedDCIt->second == D->getDeclContext())
    Reader.PendingOdrMergeChecks.push_back(D);

though I'm not entirely sure if this is correct. Trying to check why this was a violation (why is it saying an obviously present member is missing?) in the first place was a bit of a rabbit hole, but it led me to [ASTReader::diagnoseOdrViolations]:

    const Decl *DCanon = D->getCanonicalDecl();

    // [...]

    for (auto *CanonMember : CanonDef->decls()) {
      if (CanonMember->getCanonicalDecl() == DCanon) {
        // This can happen if the declaration is merely mergeable and not
        // actually redeclarable (we looked for redeclarations earlier).
        //
        // FIXME: We should be able to detect this more efficiently, without
        // pulling in all of the members of CanonDef.
        Found = true;
        break;
      }
      if (auto *ND = dyn_cast<NamedDecl>(CanonMember))
        if (ND->getDeclName() == D->getDeclName())
          Candidates.push_back(ND);
    }

In this case, both of these checks fail:

  • The first fails because CanonMember->getCanonicalDecl() and D->getCanonicalDexl() seem to always just point to their direct parent? I spent ages in this code and don't get why it's happening, but I'm guessing it's the same root cause as all the other ODR violations, so it's not too exciting.
  • The second (more interesting) check fails because the two DeclNames have the same string value but different internal IDs. I'm guessing this is a side effect of being read from the PCH and a module, but it's why the error specifically says that ~basic_string is missing, rather than just not matching.

Anyway, the reason I'm not sure that line is correct is because changing that fixes the ODR error but results in, uhh, this mess:

mod2.cc:10:43: error: Invalid operands to binary expression ('ostream' (aka 'basic_ostream<char>') and 'std::string' (aka 'basic_string<char>'))
/home/ryan/code/llvm-project/install/usr/local/include/c++/v1/__ostream/basic_ostream.h:530:55: Candidate function template not viable: no known conversion from 'std::string' (aka 'basic_string<char>') to 'char' for 2nd argument
/home/ryan/code/llvm-project/install/usr/local/include/c++/v1/__ostream/basic_ostream.h:557:53: Candidate function template not viable: no known conversion from 'std::string' (aka 'basic_string<char>') to 'char' for 2nd argument
/home/ryan/code/llvm-project/install/usr/local/include/c++/v1/__ostream/basic_ostream.h:562:53: Candidate function template not viable: no known conversion from 'std::string' (aka 'basic_string<char>') to 'signed char' for 2nd argument
/home/ryan/code/llvm-project/install/usr/local/include/c++/v1/__ostream/basic_ostream.h:567:53: Candidate function template not viable: no known conversion from 'std::string' (aka 'basic_string<char>') to 'unsigned char' for 2nd argument
/home/ryan/code/llvm-project/install/usr/local/include/c++/v1/__ostream/basic_ostream.h:579:1: Candidate function template not viable: no known conversion from 'std::string' (aka 'basic_string<char>') to 'const char *' for 2nd argument
/home/ryan/code/llvm-project/install/usr/local/include/c++/v1/__ostream/basic_ostream.h:618:53: Candidate function template not viable: no known conversion from 'std::string' (aka 'basic_string<char>') to 'const char *' for 2nd argument
/home/ryan/code/llvm-project/install/usr/local/include/c++/v1/__ostream/basic_ostream.h:624:1: Candidate function template not viable: no known conversion from 'std::string' (aka 'basic_string<char>') to 'const signed char *' for 2nd argument
/home/ryan/code/llvm-project/install/usr/local/include/c++/v1/__ostream/basic_ostream.h:631:1: Candidate function template not viable: no known conversion from 'std::string' (aka 'basic_string<char>') to 'const unsigned char *' for 2nd argument
/home/ryan/code/llvm-project/install/usr/local/include/c++/v1/__ostream/basic_ostream.h:769:1: Candidate function template not viable: no known conversion from 'std::string' (aka 'basic_string<char>') to 'const error_code' for 2nd argument
/home/ryan/code/llvm-project/install/usr/local/include/c++/v1/__ostream/basic_ostream.h:804:31: Candidate function template not viable: no known conversion from 'std::string' (aka 'basic_string<char>') to 'wchar_t' for 2nd argument
/home/ryan/code/llvm-project/install/usr/local/include/c++/v1/__ostream/basic_ostream.h:807:31: Candidate function template not viable: no known conversion from 'std::string' (aka 'basic_string<char>') to 'const wchar_t *' for 2nd argument
/home/ryan/code/llvm-project/install/usr/local/include/c++/v1/__ostream/basic_ostream.h:825:31: Candidate function template not viable: no known conversion from 'std::string' (aka 'basic_string<char>') to 'char8_t' for 2nd argument
/home/ryan/code/llvm-project/install/usr/local/include/c++/v1/__ostream/basic_ostream.h:831:31: Candidate function template not viable: no known conversion from 'std::string' (aka 'basic_string<char>') to 'const char8_t *' for 2nd argument
/home/ryan/code/llvm-project/install/usr/local/include/c++/v1/__ostream/basic_ostream.h:838:31: Candidate function template not viable: no known conversion from 'std::string' (aka 'basic_string<char>') to 'char16_t' for 2nd argument
/home/ryan/code/llvm-project/install/usr/local/include/c++/v1/__ostream/basic_ostream.h:841:31: Candidate function template not viable: no known conversion from 'std::string' (aka 'basic_string<char>') to 'char32_t' for 2nd argument
/home/ryan/code/llvm-project/install/usr/local/include/c++/v1/__ostream/basic_ostream.h:844:31: Candidate function template not viable: no known conversion from 'std::string' (aka 'basic_string<char>') to 'const char16_t *' for 2nd argument
/home/ryan/code/llvm-project/install/usr/local/include/c++/v1/__ostream/basic_ostream.h:847:31: Candidate function template not viable: no known conversion from 'std::string' (aka 'basic_string<char>') to 'const char32_t *' for 2nd argument
/home/ryan/code/llvm-project/install/usr/local/include/c++/v1/__ostream/basic_ostream.h:525:55: Candidate template ignored: deduced conflicting types for parameter '_CharT' ('char' vs. 'std::string' (aka 'basic_string<char>'))
/home/ryan/code/llvm-project/install/usr/local/include/c++/v1/cstddef:110:38: Candidate template ignored: requirement 'is_integral<std::basic_string<char, std::char_traits<char>, std::allocator<char>>>::value' was not satisfied [with _Integer = std::string]
/home/ryan/code/llvm-project/install/usr/local/include/c++/v1/__ostream/basic_ostream.h:573:1: Candidate template ignored: could not match 'const _CharT *' against 'std::string' (aka 'basic_string<char>')
/home/ryan/code/llvm-project/install/usr/local/include/c++/v1/__ostream/basic_ostream.h:750:33: Candidate template ignored: requirement 'integral_constant<bool, false>::value' was not satisfied [with _Stream = ostream &, _Tp = std::string]
/home/ryan/code/llvm-project/install/usr/local/include/c++/v1/__ostream/basic_ostream.h:757:1: Candidate template ignored: deduced type 'const basic_string<...>' of 2nd parameter does not match adjusted type 'basic_string<...>' of argument [with _CharT = char, _Traits = std::char_traits<char>, _Allocator = std::allocator<char>]
/home/ryan/code/llvm-project/install/usr/local/include/c++/v1/__ostream/basic_ostream.h:763:1: Candidate template ignored: could not match 'basic_string_view' against 'std::basic_string'
/home/ryan/code/llvm-project/install/usr/local/include/c++/v1/__ostream/basic_ostream.h:775:1: Candidate template ignored: could not match 'shared_ptr' against 'std::basic_string'
/home/ryan/code/llvm-project/install/usr/local/include/c++/v1/__ostream/basic_ostream.h:789:1: Candidate template ignored: could not match 'unique_ptr' against 'std::basic_string'
/home/ryan/code/llvm-project/install/usr/local/include/c++/v1/__ostream/basic_ostream.h:795:1: Candidate template ignored: could not match 'bitset' against 'std::basic_string'
/home/ryan/code/llvm-project/install/usr/local/include/c++/v1/__ostream/basic_ostream.h:810:34: Candidate template ignored: could not match 'wchar_t' against 'char'
/home/ryan/code/llvm-project/install/usr/local/include/c++/v1/__ostream/basic_ostream.h:813:34: Candidate template ignored: could not match 'wchar_t' against 'char'
/home/ryan/code/llvm-project/install/usr/local/include/c++/v1/__ostream/basic_ostream.h:816:34: Candidate template ignored: could not match 'wchar_t' against 'char'
/home/ryan/code/llvm-project/install/usr/local/include/c++/v1/__ostream/basic_ostream.h:819:34: Candidate template ignored: could not match 'wchar_t' against 'char'
/home/ryan/code/llvm-project/install/usr/local/include/c++/v1/__ostream/basic_ostream.h:828:34: Candidate template ignored: could not match 'wchar_t' against 'char'
/home/ryan/code/llvm-project/install/usr/local/include/c++/v1/__ostream/basic_ostream.h:834:34: Candidate template ignored: could not match 'wchar_t' against 'char'
/home/ryan/code/llvm-project/install/usr/local/include/c++/v1/__ostream/basic_ostream.h:73:56: Candidate function not viable: no known conversion from 'std::string' (aka 'basic_string<char>') to 'ostream &(*)(ostream &)' for 1st argument
/home/ryan/code/llvm-project/install/usr/local/include/c++/v1/__ostream/basic_ostream.h:78:3: Candidate function not viable: no known conversion from 'std::string' (aka 'basic_string<char>') to 'basic_ios<char_type, traits_type> &(*)(basic_ios<char_type, traits_type> &)' (aka 'basic_ios<char, std::char_traits<char>> &(*)(basic_ios<char, std::char_traits<char>> &)') for 1st argument
/home/ryan/code/llvm-project/install/usr/local/include/c++/v1/__ostream/basic_ostream.h:83:56: Candidate function not viable: no known conversion from 'std::string' (aka 'basic_string<char>') to 'ios_base &(*)(ios_base &)' for 1st argument
/home/ryan/code/llvm-project/install/usr/local/include/c++/v1/__ostream/basic_ostream.h:88:18: Candidate function not viable: no known conversion from 'std::string' (aka 'basic_string<char>') to 'bool' for 1st argument
/home/ryan/code/llvm-project/install/usr/local/include/c++/v1/__ostream/basic_ostream.h:89:18: Candidate function not viable: no known conversion from 'std::string' (aka 'basic_string<char>') to 'short' for 1st argument
/home/ryan/code/llvm-project/install/usr/local/include/c++/v1/__ostream/basic_ostream.h:90:18: Candidate function not viable: no known conversion from 'std::string' (aka 'basic_string<char>') to 'unsigned short' for 1st argument
/home/ryan/code/llvm-project/install/usr/local/include/c++/v1/__ostream/basic_ostream.h:91:18: Candidate function not viable: no known conversion from 'std::string' (aka 'basic_string<char>') to 'int' for 1st argument
/home/ryan/code/llvm-project/install/usr/local/include/c++/v1/__ostream/basic_ostream.h:92:18: Candidate function not viable: no known conversion from 'std::string' (aka 'basic_string<char>') to 'unsigned int' for 1st argument
/home/ryan/code/llvm-project/install/usr/local/include/c++/v1/__ostream/basic_ostream.h:93:18: Candidate function not viable: no known conversion from 'std::string' (aka 'basic_string<char>') to 'long' for 1st argument
/home/ryan/code/llvm-project/install/usr/local/include/c++/v1/__ostream/basic_ostream.h:94:18: Candidate function not viable: no known conversion from 'std::string' (aka 'basic_string<char>') to 'unsigned long' for 1st argument
/home/ryan/code/llvm-project/install/usr/local/include/c++/v1/__ostream/basic_ostream.h:95:18: Candidate function not viable: no known conversion from 'std::string' (aka 'basic_string<char>') to 'long long' for 1st argument
/home/ryan/code/llvm-project/install/usr/local/include/c++/v1/__ostream/basic_ostream.h:96:18: Candidate function not viable: no known conversion from 'std::string' (aka 'basic_string<char>') to 'unsigned long long' for 1st argument
/home/ryan/code/llvm-project/install/usr/local/include/c++/v1/__ostream/basic_ostream.h:97:18: Candidate function not viable: no known conversion from 'std::string' (aka 'basic_string<char>') to 'float' for 1st argument
/home/ryan/code/llvm-project/install/usr/local/include/c++/v1/__ostream/basic_ostream.h:98:18: Candidate function not viable: no known conversion from 'std::string' (aka 'basic_string<char>') to 'double' for 1st argument
/home/ryan/code/llvm-project/install/usr/local/include/c++/v1/__ostream/basic_ostream.h:99:18: Candidate function not viable: no known conversion from 'std::string' (aka 'basic_string<char>') to 'long double' for 1st argument
/home/ryan/code/llvm-project/install/usr/local/include/c++/v1/__ostream/basic_ostream.h:100:18: Candidate function not viable: no known conversion from 'std::string' (aka 'basic_string<char>') to 'const void *' for 1st argument
/home/ryan/code/llvm-project/install/usr/local/include/c++/v1/__ostream/basic_ostream.h:103:40: Candidate function not viable: no known conversion from 'std::string' (aka 'basic_string<char>') to 'const volatile void *' for 1st argument
/home/ryan/code/llvm-project/install/usr/local/include/c++/v1/__ostream/basic_ostream.h:108:18: Candidate function not viable: no known conversion from 'std::string' (aka 'basic_string<char>') to 'basic_streambuf<char_type, traits_type> *' (aka 'basic_streambuf<char, std::char_traits<char>> *') for 1st argument
/home/ryan/code/llvm-project/install/usr/local/include/c++/v1/__ostream/basic_ostream.h:113:40: Candidate function not viable: no known conversion from 'std::string' (aka 'basic_string<char>') to 'nullptr_t' (aka 'std::nullptr_t') for 1st argument

If I cut out all the irrelevant lines, what remains is:

mod2.cc:10:43: error: Invalid operands to binary expression ('ostream' (aka 'basic_ostream<char>') and 'std::string' (aka 'basic_string<char>'))
[...]
/home/ryan/code/llvm-project/install/usr/local/include/c++/v1/__ostream/basic_ostream.h:757:1: Candidate template ignored: deduced type 'const basic_string<...>' of 2nd parameter does not match adjusted type 'basic_string<...>' of argument [with _CharT = char, _Traits = std::char_traits<char>, _Allocator = std::allocator<char>]

But, it gets even weirder! If I change PrintHelloWorld to:

export void PrintHelloWorld() {
  std::string s;
  std::cout << HelloWorld();
}

then it...works? Notice the problematic line std::cout << HelloWorld() is still there; the only difference is that a std::string is now also created in the function.

In fact, creating a std::string anywhere in the file also fixes this:

std::string s;

export void PrintHelloWorld() { std::cout << HelloWorld(); }

I'm not sure if this is related or a separate issue altogether? I tried debugging it but failed to come up with anything concrete.

@ChuanqiXu9
Copy link

That did fix the first fpos error! But the second one still sticks around:

mod2.cc:3:10: error: In included file: 'std::basic_string<char>::~basic_string' from module '' is not present in definition of 'std::basic_string<char>' in module 'SomeModule.<global>'
/home/ryan/code/llvm-project/install/usr/local/include/c++/v1/string:1138:40: Error occurred here
/home/ryan/code/llvm-project/install/usr/local/include/c++/v1/string:711:7: Definition has no member '~basic_string'

If I modify ASTReaderDecl::findExisting like you did here:

  if (MergedDCIt != Reader.MergedDeclContexts.end() &&
      !shouldSkipCheckingODR(D) &&
      !shouldSkipCheckingODR(cast<Decl>(MergedDCIt->second)) &&  // <-- this is new
      MergedDCIt->second == D->getDeclContext())
    Reader.PendingOdrMergeChecks.push_back(D);

This may not be correct. Since it prevents merging too. But what we want is to avoid complaining about the ODR violations.

I don't have time to look into the codes now. But I have a guess. Can you compile your projects with -fexperimental-modules-reduced-bmi again and use the compile commands produced from that?

@refi64
Copy link
Author

refi64 commented Jul 30, 2024

I seem to get the same results, the compile_commands.json looks like:

{
  "directory": "/home/ryan/playground/clang-modules",
  "arguments": ["/home/ryan/code/llvm-project/install/usr/local/bin/clang", "-c", "-Qunused-arguments", "-O3", "-std=c++23", "-stdlib=libc++", "-fexperimental-modules-reduced-bmi", "-DNDEBUG", "-x", "c++-module", "-fmodule-output=build/.gens/mod/linux/arm64-v8a/release/rules/bmi/cache/modules/81262397/SomeModule.pcm", "-o", "build/.objs/mod/linux/arm64-v8a/release/mod.cc.o", "mod.cc"],
  "file": "mod.cc"
},
{
  "directory": "/home/ryan/playground/clang-modules",
  "arguments": ["/home/ryan/code/llvm-project/install/usr/local/bin/clang", "-c", "-Qunused-arguments", "-O3", "-std=c++23", "-stdlib=libc++", "-fexperimental-modules-reduced-bmi", "-DNDEBUG", "-fmodule-file=SomeModule=build/.gens/mod/linux/arm64-v8a/release/rules/bmi/cache/modules/81262397/SomeModule.pcm", "-x", "c++-module", "-fmodule-output=build/.gens/mod/linux/arm64-v8a/release/rules/bmi/cache/modules/81262397/SomeOtherModule.pcm", "-o", "build/.objs/mod/linux/arm64-v8a/release/mod2.cc.o", "mod2.cc"],
  "file": "mod2.cc"
}

@ChuanqiXu9
Copy link

I finally got some time to look into the codes. And it looks like your suggested change is correct. The name is misleading. It named PendingOdrMergeChecks but it won't merge anything if the check passes. The check happens after the merge.

I want to land that. But I need to reduce a minimal example for it (without any standard headers)

ChuanqiXu9 added a commit to llvm/llvm-project that referenced this issue Aug 30, 2024
Solve clangd/clangd#2094

Due clangd will enable PCH automatically, the previous mechanism to skip
ODR check in GMF may be invalid. This patch fixes this for a case.
@ChuanqiXu9
Copy link

I've land this: llvm/llvm-project@ca2351d @refi64 please test again

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants