From 9e306ad4600c4d3392c194a8be88919ee758425c Mon Sep 17 00:00:00 2001 From: Jan Svoboda Date: Thu, 22 May 2025 12:33:52 -0700 Subject: [clang] Remove intrusive reference count from `DiagnosticOptions` (#139584) The `DiagnosticOptions` class is currently intrusively reference-counted, which makes reasoning about its lifetime very difficult in some cases. For example, `CompilerInvocation` owns the `DiagnosticOptions` instance (wrapped in `llvm::IntrusiveRefCntPtr`) and only exposes an accessor returning `DiagnosticOptions &`. One would think this gives `CompilerInvocation` exclusive ownership of the object, but that's not the case: ```c++ void shareOwnership(CompilerInvocation &CI) { llvm::IntrusiveRefCntPtr CoOwner = &CI.getDiagnosticOptions(); // ... } ``` This is a perfectly valid pattern that is being actually used in the codebase. I would like to ensure the ownership of `DiagnosticOptions` by `CompilerInvocation` is guaranteed to be exclusive. This can be leveraged for a copy-on-write optimization later on. This PR changes usages of `DiagnosticOptions` across `clang`, `clang-tools-extra` and `lldb` to not be intrusively reference-counted. --- clang/unittests/Basic/SourceManagerTest.cpp | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) (limited to 'clang/unittests/Basic/SourceManagerTest.cpp') diff --git a/clang/unittests/Basic/SourceManagerTest.cpp b/clang/unittests/Basic/SourceManagerTest.cpp index 1f0986f..cbe047b 100644 --- a/clang/unittests/Basic/SourceManagerTest.cpp +++ b/clang/unittests/Basic/SourceManagerTest.cpp @@ -40,11 +40,9 @@ namespace { class SourceManagerTest : public ::testing::Test { protected: SourceManagerTest() - : FileMgr(FileMgrOpts), - DiagID(new DiagnosticIDs()), - Diags(DiagID, new DiagnosticOptions, new IgnoringDiagConsumer()), - SourceMgr(Diags, FileMgr), - TargetOpts(new TargetOptions) { + : FileMgr(FileMgrOpts), DiagID(new DiagnosticIDs()), + Diags(DiagID, DiagOpts, new IgnoringDiagConsumer()), + SourceMgr(Diags, FileMgr), TargetOpts(new TargetOptions) { TargetOpts->Triple = "x86_64-apple-darwin11.1.0"; Target = TargetInfo::CreateTargetInfo(Diags, *TargetOpts); } @@ -52,6 +50,7 @@ protected: FileSystemOptions FileMgrOpts; FileManager FileMgr; IntrusiveRefCntPtr DiagID; + DiagnosticOptions DiagOpts; DiagnosticsEngine Diags; SourceManager SourceMgr; LangOptions LangOpts; -- cgit v1.1